"use client"; import { useState, useRef, type FormEvent, type ChangeEvent } from "react"; const genderOptions = ["男", "女"]; const singleOptions = ["单身", "恋爱中", "已婚"]; const educationOptions = ["高中及以下", "大专", "本科", "硕士", "博士"]; const graduationYears = Array.from({ length: 41 }, (_, i) => String(2026 - i)); interface FormData { nickname: string; gender: string; single: string; profession: string; intro: string; wechat: string; education: string; graduationYear: string; phone: string; } interface MediaInfo { preview: string; url: string; type: "image" | "video"; } export default function JoinPage() { const [form, setForm] = useState({ nickname: "", gender: "", single: "", profession: "", intro: "", wechat: "", education: "", graduationYear: "", phone: "", }); const [media, setMedia] = useState(null); const [uploading, setUploading] = useState(false); const fileRef = useRef(null); const [submitted, setSubmitted] = useState(false); const [submitting, setSubmitting] = useState(false); const [error, setError] = useState(null); const set = (key: keyof FormData, value: string) => setForm((prev) => ({ ...prev, [key]: value })); const handleSubmit = async (e: FormEvent) => { e.preventDefault(); setError(null); setSubmitting(true); try { const res = await fetch("/api/join", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ ...form, media: media?.url }), }); const data = await res.json(); if (!res.ok || !data?.ok) { throw new Error(data?.error || "提交失败,请稍后重试"); } setSubmitted(true); } catch (err) { setError(err instanceof Error ? err.message : "网络错误,请重试"); } finally { setSubmitting(false); } }; if (submitted) { return (

申请已提交

我们会尽快审核你的信息
审核通过后将通过微信邀请你入群

← 返回首页
); } return (
{/* ── PC: center column / H5: full width ── */}
{/* ── Banner ── */}
{/* Hero image area */}
🌍
Digital Nomad Community
{/* Decorative blobs */}
{/* Title block */}

🌍 数字游民社区报名

{"💼 结识志同道合的伙伴\n📍 线下聚会 + 线上分享\n🤝 互助成长,资源共享"}

{/* ── Form card ── */}
{/* ---- Row group: nickname + gender (PC side-by-side) ---- */}
set("nickname", e.target.value)} required className="form-input" />
{/* ---- Row group: single + profession ---- */}
set("profession", e.target.value)} required className="form-input" />
{/* ---- wechat + phone ---- */}
set("wechat", e.target.value)} required className="form-input" /> { const v = e.target.value.replace(/\D/g, "").slice(0, 11); set("phone", v); }} className="form-input" />
{/* ---- Intro (full width) ---- */}