/* ===== ABOUT + CONTACT + SIGNUP MODAL ===== */
function AboutPage({ navigate }) {
return (
<>
我們不是
飛輪教室。
是選手基地。
ATTACK FIRST CYCLING 國王單車俱樂部誕生於台中北屯,是一座完全為「公路車競技訓練」打造的室內基地。創辦團隊本身就是長年在山道、爬坡王、隧道計時賽上拚搏的車手與教練 — 我們知道車友需要什麼樣的場地、設備與課表。
場館內配置全套 Magene 智能訓練系統、滾筒台、熱適應教室與 CORE 體溫感測器。包月會員另享 TrainingPeaks Premium 帳號,每一次踩踏、每一段間歇、每一場熱適應訓練都被精準量化。
這裡沒有冷氣轟趴,沒有閃光燈飛輪秀。只有一群把訓練當回事、想在下一場比賽先發制人的人。
// STUDIO SPECS
PRECISION
EQUIPMENT.
{[
{ k: "TRAINER", v: "MAGENE T100", d: "智能直驅訓練台 / 全車隊配置" },
{ k: "POWER METER", v: "MAGENE P325", d: "雙邊功率計,0.5% 精準度" },
{ k: "ROLLER", v: "ELITE NERO", d: "電磁滾筒,車感模擬" },
{ k: "CORE TEMP", v: "CORE SENSOR", d: "核心體溫感測,熱適應監控" },
{ k: "SOFTWARE", v: "TRAININGPEAKS+", d: "Premium 帳號內含" },
{ k: "ENVIRONMENT", v: "HEAT CHAMBER", d: "溫控隔離教室,安全熱訓練" },
].map(s => (
{s.k}
{s.v}
{s.d}
))}
// 5/16 OPENING RIDE
開幕約騎 / 5.16 SAT
詳細活動內容請持續關注 ATTACK FIRST 粉專。一起出發,先發制人。
>
);
}
/* ===== CONTACT ===== */
function ContactPage({ navigate, openSignup }) {
return (
<>
// 報名 & 開課說明
HOW TO
JOIN.
{[
{ n: "01", t: "MESSAGE FB / IG", d: "試營運期間均採訊息報名,請透過 Facebook 或 Instagram 私訊粉專預約報名。" },
{ n: "02", t: "AWAIT REPLY", d: "私訊報名後請靜候粉專回覆報名結果,我們會盡快確認時段。" },
{ n: "03", t: "CLASS STARTS", d: "每時段課程報名達開課人數後才會正式開班,粉專會不定時公告開課進度。" },
{ n: "04", t: "PRIVATE PACK", d: "如有包班需求歡迎洽詢,全天時段皆可預約。" },
].map(s => (
))}
LOCATION
台中 · 北屯
旱溪東路三段 20 號
24.1813° N · 120.7184° E
{/* abstract location plate */}
{/* grid pattern */}
>
);
}
/* ===== SIGNUP MODAL ===== */
function SignupModal({ onClose }) {
const [step, setStep] = useState(1);
const [data, setData] = useState({ plan: "", course: "", slot: "", name: "", phone: "", channel: "" });
const setF = (k, v) => setData(d => ({ ...d, [k]: v }));
const totalSteps = 4;
useEffect(() => {
document.body.style.overflow = "hidden";
const onKey = (e) => { if (e.key === "Escape") onClose(); };
window.addEventListener("keydown", onKey);
return () => { document.body.style.overflow = ""; window.removeEventListener("keydown", onKey); };
}, [onClose]);
const next = () => setStep(s => Math.min(s + 1, totalSteps));
const back = () => setStep(s => Math.max(s - 1, 1));
return (
e.stopPropagation()} style={{ width: "100%", maxWidth: 720, maxHeight: "92vh", background: "var(--canvas)", border: "1px solid var(--hairline)", display: "flex", flexDirection: "column" }}>
{/* header */}
// SIGNUP — 報名預約
{step < totalSteps ? "ATTACK FIRST." : "RECEIVED."}
{/* progress */}
{Array.from({ length: totalSteps }).map((_, i) => (
))}
STEP {step} / {totalSteps}
{["", "PLAN", "PROGRAM", "DETAILS", "DONE"][step]}
{/* body */}
{step === 1 && }
{step === 2 && }
{step === 3 && }
{step === 4 && }
{/* footer */}
{step > 1 && step < totalSteps && (
)}
{step < totalSteps && (
)}
{step === totalSteps && (
)}
);
}
function Step1({ data, setF }) {
const opts = [
{ id: "trial", t: "TRIAL", ch: "首次體驗", d: "350 / 堂 (試營運價,每人限一次)" },
{ id: "single", t: "SINGLE", ch: "單堂報名", d: "團體 500 / 堂 · 熱適應 700 / 堂" },
{ id: "elite", t: "ELITE", ch: "包月 — 精實訓練", d: "$4,500 / 月 · 每月 10 堂" },
{ id: "addict", t: "ADDICT", ch: "包月 — 重度成癮", d: "$6,500 / 月 · 每月 15 堂" },
{ id: "private", t: "PRIVATE", ch: "個人 / 包班", d: "1500/hr 起 · 私訊報價" },
];
return (
{opts.map(o => (
))}
);
}
function Step2({ data, setF }) {
const courses = ["基礎有氧", "VO2 MAX", "閾值訓練", "熱適應訓練", "初階滾筒", "中階滾筒"];
const slots = ["7:00–8:20", "8:40–10:00", "17:20–18:40", "19:00–20:20", "20:40–22:00"];
return (
// 選擇課程類別
{courses.map(c => (
setF("course", c)}>{c}
))}
// 偏好時段
{slots.map(s => (
setF("slot", s)}>{s}
))}
);
}
function Chip({ active, onClick, children }) {
return (
);
}
function Step3({ data, setF }) {
return (
setF("name", v)} placeholder="您怎麼稱呼?" />
setF("phone", v)} placeholder="0912-345-678" />
// 聯絡管道 — CHANNEL
{["Facebook", "Instagram", "電話"].map(c => (
setF("channel", c)}>{c}
))}
);
}
function Step4({ data }) {
return (
RECEIVED.
我們會在 24 小時內透過 {data.channel || "粉專"} 與你聯繫。
歡迎加入國王俱樂部 — Attack First.
{[
["PLAN", data.plan],
["COURSE", data.course],
["SLOT", data.slot],
["NAME", data.name],
["CONTACT", data.phone],
].map(([k, v]) => (
{k}
{v || "—"}
))}
);
}
function Field({ label, value, onChange, placeholder }) {
return (
);
}
window.AboutPage = AboutPage;
window.ContactPage = ContactPage;
window.SignupModal = SignupModal;