import { useState, useEffect, useCallback } from "react"; import { useSearchParams, useNavigate } from "react-router-dom"; import { apiFetch } from "../lib/api"; import { useAuth } from "../lib/auth"; import FloatingButton from "../components/FloatingButton"; import StampPopup from "../components/StampPopup"; import RegisterModal from "../components/RegisterModal"; const PENDING_STAMP_KEY = "stamp_pending_collect"; type StampDetail = { id: string; name: string; note: string | null; imageColor: string; imageGrey: string; }; type CollectState = "idle" | "loading" | "show_stamp" | "needs_register" | "collecting" | "collected" | "already_collected"; const STEPS = [ { num: "01", title: "前往点位", desc: "跟随路线,探索散落在城市中的文化地标" }, { num: "02", title: "触碰集章", desc: "手机轻触点位 NFC 芯片,图章即刻收入囊中" }, { num: "03", title: "兑换好礼", desc: "集满图章,兑换城市限定纪念品" }, ]; export default function LandingPage() { const [searchParams] = useSearchParams(); const navigate = useNavigate(); const { user, isLoading: authLoading } = useAuth(); const stampId = searchParams.get("stamp"); const [stamp, setStamp] = useState(null); const [collectState, setCollectState] = useState("idle"); // Fetch stamp info when stampId is present useEffect(() => { if (!stampId || authLoading) return; setCollectState("loading"); apiFetch(`/stamps/${stampId}`) .then((data) => { setStamp(data); setCollectState("show_stamp"); }) .catch(() => { setCollectState("idle"); }); }, [stampId, authLoading]); const doCollect = useCallback(async () => { if (!stampId) return; setCollectState("collecting"); try { await apiFetch(`/stamps/${stampId}/collect`, { method: "POST" }); setCollectState("collected"); sessionStorage.removeItem(PENDING_STAMP_KEY); } catch (e) { const msg = e instanceof Error ? e.message : ""; if (msg.includes("已经收集")) { setCollectState("already_collected"); } else { setCollectState("idle"); } } }, [stampId]); // Auto-collect if user just registered and has a pending stamp useEffect(() => { if (authLoading || !user || collectState !== "show_stamp" || !stampId) return; const pending = sessionStorage.getItem(PENDING_STAMP_KEY); if (pending === stampId) { doCollect(); } }, [authLoading, user, collectState, stampId, doCollect]); const handleCollect = () => { if (!user) { sessionStorage.setItem(PENDING_STAMP_KEY, stampId!); setCollectState("needs_register"); return; } doCollect(); }; const handleRegisterSuccess = () => { setCollectState("show_stamp"); doCollect(); }; const handleClose = () => { setCollectState("idle"); setStamp(null); navigate("/", { replace: true }); }; const showStampPopup = stamp && (collectState === "show_stamp" || collectState === "collecting"); const showCollectedPopup = stamp && collectState === "collected"; const showAlreadyPopup = stamp && collectState === "already_collected"; const showRegister = collectState === "needs_register"; return (
{/* ═══════════ HERO ═══════════ */}
CityWalk

城市漫步

走过每一条街巷
收集属于你的城市记忆

Stamp
9
Collect
探索
{/* ═══════════ ABOUT ═══════════ */}
About

一场属于你的
城市寻宝之旅

穿行于古桥与老街之间,在园林深处驻足片刻,于茶馆中听一段旧时光。每一个城市坐标都藏着一枚专属图章,等你亲手揭开。

{[ { num: "9", label: "城市坐标" }, { num: "4", label: "限定好礼" }, { num: "∞", label: "重复挑战" }, ].map((item) => (
{item.num}
{item.label}
))}
{/* ═══════════ HOW IT WORKS ═══════════ */}
How it works

三步开启旅程

{STEPS.map((step, i) => (
{step.num}
{i < STEPS.length - 1 &&
}

{step.title}

{step.desc}

))}
{/* ═══════════ Collection Overlays ═══════════ */} {showStampPopup && ( )} {showCollectedPopup && ( )} {showAlreadyPopup && ( )} {showRegister && ( setCollectState("show_stamp")} /> )}
); }