"use client"; import { useEffect, useState } from "react"; import Link from "next/link"; import HeroSection from "./HeroSection"; import MyRegistrationStatus from "./MyRegistrationStatus"; import SessionCard from "./SessionCard"; import HostLink from "./HostLink"; import Footer from "./Footer"; import Header from "./Header"; import { getSessionsWithDates, HOSTS } from "@/config/home.config"; const WECHAT_STORAGE_KEY = "salon_join_wechat"; interface HomeContentProps { initialVolunteer: { nickname: string; avatar?: string; xiaohongshu_url?: string } | null; } const VOLUNTEER_BIO = "签到、茶歇准备、拍照摄像。"; function getPendingOrderId(): string | null { if (typeof window === "undefined") return null; try { const cookie = document.cookie.split(";").find((c) => c.trim().startsWith("join_pay_order=")); const raw = cookie?.split("=")[1]?.trim(); const decoded = raw ? decodeURIComponent(raw) : ""; const fromStorage = localStorage.getItem("join_pay_order") || ""; const value = decoded || fromStorage; const orderId = value.split("|")[0]?.trim() || ""; return orderId || null; } catch { return null; } } function clearPendingOrder(): void { try { localStorage.removeItem("join_pay_order"); document.cookie = "join_pay_order=; path=/; max-age=0"; } catch {} } export default function HomeContent({ initialVolunteer }: HomeContentProps) { const [volunteer, setVolunteer] = useState(initialVolunteer); useEffect(() => { fetch("/api/join/volunteers") .then((r) => r.json()) .then((d) => d?.volunteer && setVolunteer(d.volunteer)) .catch(() => {}); }, []); // 支付完成后再次打开首页:后台完成订单并刷新用户信息(手机浏览器唤醒微信支付后,用户可能直接回首页,notify 可能未到,需轮询) useEffect(() => { const orderId = getPendingOrderId(); if (!orderId) return; let cancelled = false; const tryComplete = async (): Promise => { const r = await fetch("/api/salon/complete-order", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ order_id: orderId }), credentials: "include", }); const d = await r.json(); if (!d?.ok) return false; if (d?.token && d?.record) { fetch("/api/auth/sync-session", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ token: d.token, record: d.record }), credentials: "include", }).catch(() => {}); import("@/app/lib/pocketbase").then(({ pbSaveAuth }) => pbSaveAuth(d.token, d.record)); if (d.record?.wechatId) { try { localStorage.setItem(WECHAT_STORAGE_KEY, d.record.wechatId); } catch {} } } clearPendingOrder(); window.dispatchEvent(new CustomEvent("auth:updated")); window.dispatchEvent(new CustomEvent("vip:updated")); return true; }; const run = async () => { const retryDelays = [1500, 2500, 3500, 4500, 5500]; for (let i = 0; i <= retryDelays.length; i++) { if (cancelled) return; if (await tryComplete()) return; if (i < retryDelays.length && !cancelled) { await new Promise((r) => setTimeout(r, retryDelays[i])); } } }; void run(); return () => { cancelled = true; }; }, []); return (
{/* 是什么 / 不是什么 - 小红书风格 */}

是什么 · 适合谁

  • · 周末同城轻社交,loft民宿见~
  • · 4–8 人小圈子,聊得来就多聊
  • · 第一次来也完全 OK

不是什么 · 不适合谁

  • · 不是相亲局、卖课、强制破冰
  • · 只想线上聊、想加所有人微信的 pass
  • · 想销售引流、不尊重边界的 pass
{/* 报名流程 */}

📋 怎么参加

1

填表

2

审核

3

通过后联系你确认

{/* 信任标签 */}
📍 公开场地 👥 4–8 人 ✍️ 填表申请 ☕ 茶歇
{/* 本周场次 */}

📅 本周活动

{getSessionsWithDates().map((s, i) => ( ))}
{/* 活动亮点 */}

💡 活动亮点

{[ { icon: "😌", title: "氛围轻松", desc: "loft民宿里的小聚,不用尬聊,聊得来就多聊~" }, { icon: "🛡️", title: "安全靠谱", desc: "公开场地,地址提前说。尊重边界,不追问隐私。" }, { icon: "👍", title: "第一次也 OK", desc: "很多人都是第一次来,小圈子人数可控~" }, { icon: "✍️", title: "填表就行", desc: "不用注册、不用先付,填个表就好。" }, ].map((item) => (
{item.icon}

{item.title}

{item.desc}

))}
{/* 发起人 + 志愿者(有志愿者时替换 host-2 卡片) */}

👤 发起人

{HOSTS.map((host) => { const isHost2 = host.id === "host-2"; const displayHost = isHost2 && volunteer ? { ...host, name: volunteer.nickname, avatar: volunteer.avatar || host.avatar, bio: VOLUNTEER_BIO, link: volunteer.xiaohongshu_url || host.link, } : host; return ( ); })}
{/* FAQ */}

常见问题

{[ { q: "提交后多久会收到确认?", a: "活动前 1–2 天会联系,微信/短信确认。不匹配不会反复打扰~", icon: "⏱️" }, { q: "第一次参加可以吗?", a: "可以呀!很多人都是第一次来。4–8 人小圈子、公开场地,聊得来就多聊~", icon: "✨" }, { q: "临时有事怎么办?", a: "随时可以退出,提前说一声就行~", icon: "🔄" }, ].map((faq) => (
{faq.icon}

{faq.q}

{faq.a}

))}
{/* CTA - 移动端隐藏,只保留底部悬浮去报名 */}
立即报名

先填表,我们会根据场次联系你~

{/* 移动端悬浮 CTA */}
去报名
); }