Files
gitlab-instance-0a899031_salon/app/page.tsx
2026-03-15 22:57:54 -05:00

168 lines
8.8 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.
"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 } 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">
{/* 信任标签 + 新成员 */}
<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>👥 </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 className="flex items-center gap-1.5 sm:gap-2 text-stone-500 dark:text-stone-400 text-xs sm:text-sm shrink-0">
<span className="font-semibold text-amber-600 dark:text-amber-400">50+</span>
<span></span>
</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-20 sm:h-20 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, 80px" 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">
{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 mb-1.5">
</span>
)}
<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="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>
<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: "不需要,填表即可。", 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">{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>
</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>
);
}