fix: subdomain-aware routing for zine pages

On zine.mycofi.earth, URLs should be /create not /zine/create.
Added useZinePath hook to adjust paths based on hostname.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Jeff Emmett 2025-12-23 16:30:52 -05:00
parent 3309f7e5de
commit 19764d7df4
2 changed files with 42 additions and 7 deletions

View File

@ -16,6 +16,22 @@ import {
CheckCircle, CheckCircle,
} from "lucide-react"; } from "lucide-react";
// Helper to get correct path based on subdomain
function useZinePath() {
const [isSubdomain, setIsSubdomain] = useState(false);
useEffect(() => {
setIsSubdomain(window.location.hostname.startsWith("zine."));
}, []);
return (path: string) => {
if (isSubdomain) {
return path.replace(/^\/zine/, "") || "/";
}
return path;
};
}
interface PageOutline { interface PageOutline {
pageNumber: number; pageNumber: number;
type: string; type: string;
@ -46,6 +62,7 @@ const STEP_LABELS = {
export default function CreatePage() { export default function CreatePage() {
const router = useRouter(); const router = useRouter();
const getPath = useZinePath();
const [state, setState] = useState<ZineState | null>(null); const [state, setState] = useState<ZineState | null>(null);
const [loading, setLoading] = useState(true); const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>(null); const [error, setError] = useState<string | null>(null);
@ -58,7 +75,7 @@ export default function CreatePage() {
useEffect(() => { useEffect(() => {
const input = sessionStorage.getItem("zineInput"); const input = sessionStorage.getItem("zineInput");
if (!input) { if (!input) {
router.push("/zine"); router.push(getPath("/zine"));
return; return;
} }
@ -255,7 +272,7 @@ export default function CreatePage() {
const copyShareLink = async () => { const copyShareLink = async () => {
if (!state) return; if (!state) return;
const shareUrl = `${window.location.origin}/zine/z/${state.id}`; const shareUrl = `${window.location.origin}${getPath(`/zine/z/${state.id}`)}`;
await navigator.clipboard.writeText(shareUrl); await navigator.clipboard.writeText(shareUrl);
setCopied(true); setCopied(true);
setTimeout(() => setCopied(false), 2000); setTimeout(() => setCopied(false), 2000);
@ -279,7 +296,7 @@ export default function CreatePage() {
<h2 className="text-2xl font-bold punk-text mb-4">Error</h2> <h2 className="text-2xl font-bold punk-text mb-4">Error</h2>
<p className="text-red-600 mb-4">{error}</p> <p className="text-red-600 mb-4">{error}</p>
<button <button
onClick={() => router.push("/zine")} onClick={() => router.push(getPath("/zine"))}
className="px-6 py-2 bg-black text-white punk-text hover:bg-green-600" className="px-6 py-2 bg-black text-white punk-text hover:bg-green-600"
> >
Try Again Try Again
@ -297,7 +314,7 @@ export default function CreatePage() {
<div className="max-w-4xl mx-auto mb-8"> <div className="max-w-4xl mx-auto mb-8">
<div className="flex items-center justify-between mb-4"> <div className="flex items-center justify-between mb-4">
<button <button
onClick={() => router.push("/zine")} onClick={() => router.push(getPath("/zine"))}
className="flex items-center gap-2 text-gray-600 hover:text-black" className="flex items-center gap-2 text-gray-600 hover:text-black"
> >
<ArrowLeft className="w-4 h-4" /> <ArrowLeft className="w-4 h-4" />
@ -666,7 +683,7 @@ export default function CreatePage() {
<button <button
onClick={() => { onClick={() => {
sessionStorage.removeItem("zineInput"); sessionStorage.removeItem("zineInput");
router.push("/zine"); router.push(getPath("/zine"));
}} }}
className="text-gray-600 hover:text-black punk-text underline" className="text-gray-600 hover:text-black punk-text underline"
> >

View File

@ -1,10 +1,27 @@
"use client"; "use client";
import { useState } from "react"; import { useState, useEffect } from "react";
import { useRouter } from "next/navigation"; import { useRouter } from "next/navigation";
import Link from "next/link"; import Link from "next/link";
import { Mic, MicOff, Sparkles, BookOpen, Printer, ArrowLeft } from "lucide-react"; import { Mic, MicOff, Sparkles, BookOpen, Printer, ArrowLeft } from "lucide-react";
// Helper to get correct path based on subdomain
function useZinePath() {
const [isSubdomain, setIsSubdomain] = useState(false);
useEffect(() => {
setIsSubdomain(window.location.hostname.startsWith("zine."));
}, []);
return (path: string) => {
if (isSubdomain) {
// On subdomain, /zine/create becomes /create
return path.replace(/^\/zine/, "") || "/";
}
return path;
};
}
const STYLES = [ const STYLES = [
{ value: "punk-zine", label: "Punk Zine", description: "Xerox texture, high contrast, DIY collage" }, { value: "punk-zine", label: "Punk Zine", description: "Xerox texture, high contrast, DIY collage" },
{ value: "mycelial", label: "Mycelial", description: "Organic networks, spore patterns, earth tones" }, { value: "mycelial", label: "Mycelial", description: "Organic networks, spore patterns, earth tones" },
@ -23,6 +40,7 @@ const TONES = [
export default function ZinePage() { export default function ZinePage() {
const router = useRouter(); const router = useRouter();
const getPath = useZinePath();
const [topic, setTopic] = useState(""); const [topic, setTopic] = useState("");
const [style, setStyle] = useState("mycelial"); const [style, setStyle] = useState("mycelial");
const [tone, setTone] = useState("regenerative"); const [tone, setTone] = useState("regenerative");
@ -65,7 +83,7 @@ export default function ZinePage() {
// Store the input in sessionStorage and navigate to create page // Store the input in sessionStorage and navigate to create page
sessionStorage.setItem("zineInput", JSON.stringify({ topic, style, tone })); sessionStorage.setItem("zineInput", JSON.stringify({ topic, style, tone }));
router.push("/zine/create"); router.push(getPath("/zine/create"));
}; };
return ( return (