import { useState } from "react"; import { useNavigate } from "react-router"; import { motion } from "motion/react"; import { ChevronUp, ChevronDown, Loader2 } from "lucide-react"; import { Input } from "../components/ui/input"; import { useUser, calcPregnancyWeek, calcDueDate } from "../context/UserContext"; import { submitOnboarding } from "../services/api"; type DateMode = "due_date" | "last_period"; type MultiplePregnancy = "单胎" | "双胎" | "三胎+"; type PregnancyCount = 1 | 2 | 3; const MEDICAL_CONDITIONS = [ "糖尿病 / 妊娠糖尿病史", "高血压 / 妊娠高血压史", "甲状腺疾病", ]; export function OnboardingPage() { const navigate = useNavigate(); const { updateUser } = useUser(); const [isSubmitting, setIsSubmitting] = useState(false); const [error, setError] = useState(""); // 基本信息 const [dateMode, setDateMode] = useState("due_date"); const [dueDate, setDueDate] = useState(""); const [lastPeriodDate, setLastPeriodDate] = useState(""); // 特殊情况 const [showSpecial, setShowSpecial] = useState(false); const [age, setAge] = useState(""); const [multiplePregnancy, setMultiplePregnancy] = useState("单胎"); const [medicalHistory, setMedicalHistory] = useState([]); const [noMedicalHistory, setNoMedicalHistory] = useState(false); // 补充信息 const [showExtra, setShowExtra] = useState(false); const [preWeight, setPreWeight] = useState(""); const [height, setHeight] = useState(""); const [pregnancyCount, setPregnancyCount] = useState(1); // 计算孕周和预产期(用于显示) const computedInfo = (() => { if (dateMode === "last_period" && lastPeriodDate) { const { weeks, days } = calcPregnancyWeek(lastPeriodDate); const due = calcDueDate(lastPeriodDate); if (weeks >= 0 && weeks <= 42) { return { weeks, days, dueDate: due, valid: true }; } } if (dateMode === "due_date" && dueDate) { // 从预产期反推末次月经:预产期 - 280天 const dueDateObj = new Date(dueDate); const lmpDate = new Date(dueDateObj.getTime() - 280 * 24 * 60 * 60 * 1000); const lmpStr = lmpDate.toISOString().split("T")[0]; const { weeks, days } = calcPregnancyWeek(lmpStr); if (weeks >= 0 && weeks <= 42) { return { weeks, days, dueDate, lmpDate: lmpStr, valid: true }; } } return { weeks: 0, days: 0, dueDate: "", valid: false }; })(); const canSubmit = dateMode === "due_date" ? !!dueDate : !!lastPeriodDate; const toggleMedicalCondition = (condition: string) => { setNoMedicalHistory(false); setMedicalHistory((prev) => prev.includes(condition) ? prev.filter((c) => c !== condition) : [...prev, condition] ); }; const toggleNoMedicalHistory = () => { setNoMedicalHistory(!noMedicalHistory); if (!noMedicalHistory) { setMedicalHistory([]); } }; const handleSubmit = async () => { setError(""); setIsSubmitting(true); try { // 确定末次月经日期 let lmpDate = lastPeriodDate; let dueDateStr = dueDate; if (dateMode === "due_date" && dueDate) { const dueDateObj = new Date(dueDate); lmpDate = new Date(dueDateObj.getTime() - 280 * 24 * 60 * 60 * 1000).toISOString().split("T")[0]; dueDateStr = dueDate; } else if (dateMode === "last_period" && lastPeriodDate) { dueDateStr = calcDueDate(lastPeriodDate); lmpDate = lastPeriodDate; } const { weeks, days } = calcPregnancyWeek(lmpDate); const payload: Record = { last_period_date: lmpDate, due_date: dueDateStr, pregnancy_week: weeks, pregnancy_day: days, multiple_pregnancy: multiplePregnancy, pregnancy_count: pregnancyCount, }; if (age) payload.age = parseInt(age); if (medicalHistory.length > 0) payload.medical_history = medicalHistory; if (preWeight) payload.pre_pregnancy_weight = parseFloat(preWeight); if (height) payload.height = parseFloat(height); await submitOnboarding(payload as Parameters[0]); updateUser({ lastPeriodDate: lmpDate, dueDate: dueDateStr, currentWeek: weeks, currentDay: days, age: age ? parseInt(age) : null, prePregnancyWeight: preWeight ? parseFloat(preWeight) : null, height: height ? parseFloat(height) : null, medicalHistory, isOnboarded: true, }); navigate("/home"); } catch (err: unknown) { const message = err instanceof Error ? err.message : "保存失败,请重试"; setError(message); } finally { setIsSubmitting(false); } }; return (
{/* 页面标题 */}

完善孕期信息

帮助我们更准确地解读您的报告

{/* 基本信息 */}

基本信息 *

{/* 日期方式切换 */}

请选择一种方式

{/* 日期输入 */} {dateMode === "due_date" ? (

预产期

setDueDate(e.target.value)} className="h-12 rounded-xl border-2 border-gray-200 focus:border-morandi-200 bg-white" />
) : (

末次月经日期

setLastPeriodDate(e.target.value)} className="h-12 rounded-xl border-2 border-gray-200 focus:border-morandi-200 bg-white" />
)} {/* 孕周计算结果 */} {computedInfo.valid && (

当前孕 {computedInfo.weeks} 周{" "} {computedInfo.days} 天 {dateMode === "last_period" && computedInfo.dueDate && ( · 预产期 {new Date(computedInfo.dueDate).toLocaleDateString("zh-CN")} )}

)}
{/* 特殊情况(选填) */}
{showSpecial && ( {/* 年龄 */}

年龄

setAge(e.target.value)} className="h-12 rounded-xl border-2 border-gray-200 focus:border-morandi-200 bg-white" />

💡 35岁以上属于高龄孕妇,某些指标的风险评估会不同

{/* 多胎妊娠 */}

是否多胎妊娠?

{(["单胎", "双胎", "三胎+"] as MultiplePregnancy[]).map((opt) => ( ))}
{/* 疾病史 */}

是否有以下疾病史?(可多选)

{MEDICAL_CONDITIONS.map((condition) => ( ))}
)}
{/* 补充信息(选填) */}
{showExtra && ( {/* 孕前体重 */}

孕前体重 (kg)

setPreWeight(e.target.value)} className="h-12 rounded-xl border-2 border-gray-200 focus:border-morandi-200 bg-white" />
{/* 身高 */}

身高 (cm)

setHeight(e.target.value)} className="h-12 rounded-xl border-2 border-gray-200 focus:border-morandi-200 bg-white" />
{/* 第几次怀孕 */}

第几次怀孕

{([1, 2, 3] as PregnancyCount[]).map((count) => ( ))}
)}
{/* 错误提示 */} {error && (

{error}

)} {/* 底部按钮 */}
); }