Files
gitlab-instance-0a899031_salon/app/page.tsx
2026-03-15 23:19:43 -05:00

260 lines
16 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"use client";
import Link from "next/link";
import HeroSection from "./components/HeroSection";
import SessionCoverImage from "./components/SessionCoverImage";
import Footer from "./components/Footer";
import Header from "./components/Header";
import AvatarStack from "./components/AvatarStack";
import { SESSIONS, ACTIVITY_TYPES, SESSION_TAGS } from "@/config/home.config";
export default function Home() {
return (
<div className="min-h-screen bg-[#faf8f5] dark:bg-stone-950 pb-20 sm:pb-12">
<Header />
<HeroSection />
<main className="max-w-[900px] mx-auto px-4 sm:px-6 md:px-8 py-8 sm:py-12 md:py-14 space-y-10 sm:space-y-14">
{/* 这是什么 / 不是什么 */}
<section>
<div className="grid sm:grid-cols-2 gap-4 sm:gap-6">
<div className="rounded-xl sm:rounded-2xl bg-white dark:bg-stone-900/80 border border-stone-200/80 dark:border-stone-700/80 p-4 sm:p-6">
<h3 className="text-base sm:text-lg font-semibold text-stone-800 dark:text-stone-100 mb-3 sm:mb-4 flex items-center gap-2">
<span className="text-amber-600 dark:text-amber-400"></span>
</h3>
<ul className="space-y-2 text-sm sm:text-base text-stone-600 dark:text-stone-400">
<li>· </li>
<li>· </li>
<li>· 68 </li>
<li>· </li>
</ul>
</div>
<div className="rounded-xl sm:rounded-2xl bg-white dark:bg-stone-900/80 border border-stone-200/80 dark:border-stone-700/80 p-4 sm:p-6">
<h3 className="text-base sm:text-lg font-semibold text-stone-800 dark:text-stone-100 mb-3 sm:mb-4 flex items-center gap-2">
<span className="text-stone-400 dark:text-stone-500"></span>
</h3>
<ul className="space-y-2 text-sm sm:text-base text-stone-600 dark:text-stone-400">
<li>· </li>
<li>· </li>
<li>· </li>
<li>· 便</li>
</ul>
</div>
</div>
</section>
{/* 报名后会发生什么 - 3 步流程 */}
<section>
<h2 className="text-lg sm:text-xl font-semibold text-stone-800 dark:text-stone-100 mb-4 sm:mb-5 flex items-center gap-2">
<span>📋</span>
</h2>
<div className="rounded-xl sm:rounded-2xl bg-white dark:bg-stone-900/80 border border-stone-200/80 dark:border-stone-700/80 p-4 sm:p-6 md:p-8">
<div className="grid sm:grid-cols-3 gap-6 sm:gap-8">
<div className="flex flex-col items-center text-center">
<div className="w-10 h-10 rounded-full bg-amber-100 dark:bg-amber-900/30 text-amber-700 dark:text-amber-300 font-bold text-lg flex items-center justify-center mb-3">1</div>
<h4 className="font-semibold text-stone-800 dark:text-stone-100 text-sm sm:text-base"></h4>
<p className="mt-1 text-xs sm:text-sm text-stone-500 dark:text-stone-400"></p>
</div>
<div className="flex flex-col items-center text-center">
<div className="w-10 h-10 rounded-full bg-amber-100 dark:bg-amber-900/30 text-amber-700 dark:text-amber-300 font-bold text-lg flex items-center justify-center mb-3">2</div>
<h4 className="font-semibold text-stone-800 dark:text-stone-100 text-sm sm:text-base"></h4>
<p className="mt-1 text-xs sm:text-sm text-stone-500 dark:text-stone-400"></p>
</div>
<div className="flex flex-col items-center text-center">
<div className="w-10 h-10 rounded-full bg-amber-100 dark:bg-amber-900/30 text-amber-700 dark:text-amber-300 font-bold text-lg flex items-center justify-center mb-3">3</div>
<h4 className="font-semibold text-stone-800 dark:text-stone-100 text-sm sm:text-base">/</h4>
<p className="mt-1 text-xs sm:text-sm text-stone-500 dark:text-stone-400"></p>
</div>
</div>
<p className="mt-6 pt-6 border-t border-stone-100 dark:border-stone-700 text-xs sm:text-sm text-stone-500 dark:text-stone-400 text-center">
</p>
</div>
</section>
{/* 信任标签 + 最近报名意向 */}
<div className="flex flex-col gap-4 sm:gap-6">
<div className="flex flex-wrap justify-center gap-x-6 gap-y-1.5 sm:gap-x-8 text-xs sm:text-sm text-stone-600 dark:text-stone-400">
<span>📍 </span>
<span>👥 68 </span>
<span> </span>
<span>🆓 </span>
</div>
<div className="rounded-xl sm:rounded-2xl bg-white dark:bg-stone-900/80 border border-stone-200/80 dark:border-stone-700/80 p-4 sm:p-6">
<div className="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-3 sm:gap-4">
<div className="min-w-0">
<p className="text-[10px] sm:text-xs font-medium text-amber-600 dark:text-amber-400/90 uppercase tracking-wider mb-1.5 sm:mb-2">
👋
</p>
<AvatarStack />
</div>
</div>
</div>
</div>
{/* 本周场次 */}
<section>
<h2 className="text-lg sm:text-xl font-semibold text-stone-800 dark:text-stone-100 mb-4 sm:mb-5 flex items-center gap-2">
<span>📅</span>
</h2>
<div className="grid gap-3 sm:gap-4 sm:grid-cols-2">
{SESSIONS.map((s, i) => (
<Link
key={s.id}
href={`/join?session=${encodeURIComponent(s.id)}`}
className="group flex flex-col sm:flex-row gap-3 sm:gap-4 p-4 sm:p-5 rounded-xl sm:rounded-2xl bg-white dark:bg-stone-900/80 border border-stone-200/80 dark:border-stone-700/80 hover:border-amber-200 dark:hover:border-amber-900/50 hover:shadow-lg hover:shadow-amber-900/5 transition-all"
>
<div className="relative w-full sm:w-24 sm:h-24 shrink-0 aspect-[16/10] sm:aspect-square rounded-lg sm:rounded-xl overflow-hidden bg-stone-100 dark:bg-stone-800">
{s.coverImage ? (
<SessionCoverImage src={s.coverImage} alt={s.title} type={s.type} fill sizes="(max-width: 640px) 100vw, 96px" className="object-cover" />
) : (
<div className="absolute inset-0 flex items-center justify-center text-2xl">
{s.type === "skill-exchange" ? "🔄" : "☕"}
</div>
)}
</div>
<div className="min-w-0 flex-1">
<div className="flex flex-wrap gap-1 mb-1.5">
{s.tags?.map((tag) => (
<span key={tag} className="inline-block text-[9px] sm:text-[10px] font-medium text-amber-600 dark:text-amber-400/90 bg-amber-50 dark:bg-amber-900/20 px-1.5 py-0.5 rounded">
{SESSION_TAGS[tag]}
</span>
))}
{i === 0 && (
<span className="inline-block text-[9px] sm:text-[10px] font-medium text-amber-600 dark:text-amber-400 bg-amber-50 dark:bg-amber-900/20 px-1.5 py-0.5 rounded">
</span>
)}
</div>
<span className="text-[10px] sm:text-xs text-amber-600 dark:text-amber-400/90">
{ACTIVITY_TYPES[s.type]} · {s.city}
</span>
<h3 className="font-semibold text-stone-800 dark:text-stone-100 text-sm sm:text-base group-hover:text-amber-700 dark:group-hover:text-amber-400 mt-0.5">
{s.title}
</h3>
<p className="text-xs sm:text-sm text-stone-500 dark:text-stone-400 mt-0.5">
{s.date} {s.time} · {s.place}
</p>
<span className="inline-flex items-center gap-1 mt-2 sm:mt-3 text-amber-600 dark:text-amber-400 text-xs sm:text-sm font-medium">
</span>
</div>
</Link>
))}
</div>
</section>
{/* 适合谁 / 不适合谁 */}
<section>
<h2 className="text-lg sm:text-xl font-semibold text-stone-800 dark:text-stone-100 mb-4 sm:mb-5 flex items-center gap-2">
<span>🎯</span> /
</h2>
<div className="grid sm:grid-cols-2 gap-4 sm:gap-6">
<div className="rounded-xl sm:rounded-2xl bg-white dark:bg-stone-900/80 border border-stone-200/80 dark:border-stone-700/80 p-4 sm:p-6">
<h3 className="text-base sm:text-lg font-semibold text-stone-800 dark:text-stone-100 mb-3 sm:mb-4"></h3>
<ul className="space-y-2 text-sm sm:text-base text-stone-600 dark:text-stone-400">
<li>· </li>
<li>· </li>
<li>· </li>
<li>· </li>
</ul>
</div>
<div className="rounded-xl sm:rounded-2xl bg-white dark:bg-stone-900/80 border border-stone-200/80 dark:border-stone-700/80 p-4 sm:p-6">
<h3 className="text-base sm:text-lg font-semibold text-stone-800 dark:text-stone-100 mb-3 sm:mb-4"></h3>
<ul className="space-y-2 text-sm sm:text-base text-stone-600 dark:text-stone-400">
<li>· 线</li>
<li>· </li>
<li>· </li>
<li>· </li>
</ul>
</div>
</div>
</section>
{/* 为什么来 */}
<section>
<h2 className="text-lg sm:text-xl font-semibold text-stone-800 dark:text-stone-100 mb-4 sm:mb-5 flex items-center gap-2">
<span>💡</span>
</h2>
<div className="rounded-xl sm:rounded-2xl bg-white dark:bg-stone-900/80 border border-stone-200/80 dark:border-stone-700/80 p-4 sm:p-6 md:p-8">
<div className="grid sm:grid-cols-2 gap-4 sm:gap-6">
{[
{ icon: "😌", title: "氛围轻松", desc: "咖啡馆、书店里的线下小聚,不用尬聊,聊得来就多聊几句。" },
{ icon: "🛡️", title: "安全靠谱", desc: "公开场地,地址提前告知。尊重边界,不追问隐私。" },
{ icon: "👍", title: "第一次来也 OK", desc: "很多人都是第一次参加,小组活动人数可控,不会尴尬。" },
{ icon: "✍️", title: "填表就行", desc: "无需注册登录,不用先付款,填个表单即可。" },
].map((item) => (
<div key={item.title} className="flex gap-2.5 sm:gap-3">
<span className="text-xl sm:text-2xl shrink-0">{item.icon}</span>
<div>
<p className="font-medium text-stone-800 dark:text-stone-100 text-sm sm:text-base">{item.title}</p>
<p className="text-xs sm:text-sm text-stone-500 dark:text-stone-400 mt-0.5 leading-relaxed">{item.desc}</p>
</div>
</div>
))}
</div>
</div>
</section>
{/* FAQ */}
<section id="faq">
<h2 className="text-lg sm:text-xl font-semibold text-stone-800 dark:text-stone-100 mb-4 sm:mb-5 flex items-center gap-2">
<span></span>
</h2>
<div className="space-y-2 sm:space-y-3">
{[
{ q: "提交后多久会收到确认?", a: "我们会在活动前 12 天根据场次与匹配度联系合适报名者,通过微信或短信确认。若当前场次不匹配,不会反复打扰。", icon: "⏱️" },
{ q: "联系方式会公开给其他人吗?", a: "不会。联系方式仅用于活动确认,不会公开给其他报名者。", icon: "🔒" },
{ q: "第一次参加会不会尴尬?", a: "不会。很多人都是第一次来68 人小组人数可控,公开场地氛围轻松,聊得来就多聊几句。", icon: "✨" },
{ q: "如果临时有事不去了怎么办?", a: "随时可以退出,提前告知即可。我们尊重每个人的选择。", icon: "🔄" },
{ q: "活动地点为什么不是先公开具体地址?", a: "我们会根据报名情况确定具体场地,确认后会通过微信/短信告知。均为公开场地(咖啡馆、书店等),地址提前通知。", icon: "📍" },
{ q: "会不会有人骚扰、硬加联系方式?", a: "我们强调边界感,不强制交换联系方式。公开场地、小组形式也有助于降低此类情况。如有不适可随时离开。", icon: "🛡️" },
].map((faq) => (
<details
key={faq.q}
className="group rounded-lg sm:rounded-xl bg-white dark:bg-stone-900/80 border border-stone-200/80 dark:border-stone-700/80 overflow-hidden"
>
<summary className="flex items-center gap-2.5 sm:gap-3 p-3 sm:p-4 cursor-pointer list-none [&::-webkit-details-marker]:hidden select-none">
<span className="text-base sm:text-lg shrink-0">{faq.icon}</span>
<p className="font-medium text-stone-800 dark:text-stone-100 text-xs sm:text-sm flex-1">{faq.q}</p>
<span className="shrink-0 text-stone-400 text-xs transition-transform duration-200 group-open:rotate-180"></span>
</summary>
<div className="px-3 pb-3 sm:px-4 sm:pb-4 pt-0 flex gap-2.5 sm:gap-3">
<span className="w-[1.25rem] sm:w-[1.5rem] shrink-0" aria-hidden />
<p className="text-xs sm:text-sm text-stone-500 dark:text-stone-400 leading-relaxed">{faq.a}</p>
</div>
</details>
))}
</div>
</section>
{/* CTA */}
<section className="pt-2 sm:pt-4">
<Link
href="/join"
className="block w-full bg-amber-600 hover:bg-amber-700 text-white text-center py-3.5 sm:py-4 rounded-xl font-semibold text-sm sm:text-base shadow-lg shadow-amber-900/20 transition-all"
>
</Link>
<p className="mt-3 text-center text-xs sm:text-sm text-stone-500 dark:text-stone-400">
·
</p>
</section>
</main>
{/* 移动端悬浮 CTA */}
<div className="fixed bottom-0 left-0 right-0 p-3 sm:p-4 bg-white/95 dark:bg-stone-900/95 backdrop-blur border-t border-stone-200 dark:border-stone-800 sm:hidden z-50 safe-area-pb">
<Link
href="/join"
className="block w-full bg-amber-600 hover:bg-amber-700 text-white text-center py-3 rounded-xl font-medium text-sm"
>
</Link>
</div>
<Footer />
</div>
);
}