"use client"; import { useState, useEffect } from "react"; import { useRouter } from "next/navigation"; import { Button, Card, Input, Select } from "@/components/ui"; const IAP_SCHEDULE = [ { name: "BCG", weeks: 0, milestone: "At Birth" }, { name: "OPV-0", weeks: 0, milestone: "At Birth" }, { name: "HepB-1", weeks: 0, milestone: "At Birth" }, { name: "OPV-1", weeks: 6, milestone: "6 Weeks" }, { name: "Pentavalent-1", weeks: 6, milestone: "6 Weeks" }, { name: "PCV-1", weeks: 6, milestone: "6 Weeks" }, { name: "Rota-1", weeks: 6, milestone: "6 Weeks" }, { name: "OPV-2", weeks: 10, milestone: "10 Weeks" }, { name: "Pentavalent-2", weeks: 10, milestone: "10 Weeks" }, { name: "PCV-2", weeks: 10, milestone: "10 Weeks" }, { name: "Rota-2", weeks: 10, milestone: "10 Weeks" }, { name: "OPV-3", weeks: 14, milestone: "14 Weeks" }, { name: "Pentavalent-3", weeks: 14, milestone: "14 Weeks" }, { name: "PCV-3", weeks: 14, milestone: "14 Weeks" }, { name: "Rota-3", weeks: 14, milestone: "14 Weeks" }, { name: "MR-1", weeks: 48, milestone: "9 Months" }, { name: "JE-1", weeks: 48, milestone: "9 Months" }, { name: "Vitamin A-1", weeks: 48, milestone: "9 Months" }, { name: "OPV-4", weeks: 48, milestone: "9 Months" }, { name: "MR-2", weeks: 96, milestone: "18 Months" }, { name: "JE-2", weeks: 96, milestone: "18 Months" }, { name: "DPT-Booster-1", weeks: 96, milestone: "18 Months" }, { name: "Vitamin A-2", weeks: 96, milestone: "18 Months" }, { name: "OPV-5", weeks: 96, milestone: "18 Months" }, { name: "DPT-Booster-2", weeks: 208, milestone: "4 Years" }, { name: "Td", weeks: 208, milestone: "4 Years" }, ]; function dueDate(birthDate: string, weeks: number) { const d = new Date(birthDate); d.setDate(d.getDate() + weeks * 7); return d.toISOString().split("T")[0]; } function weeksSinceBirth(birthDate: string) { return Math.floor((Date.now() - new Date(birthDate).getTime()) / (1000 * 60 * 60 * 24 * 7)); } type VaccState = { given: boolean; date: string; unknown: boolean }; export default function OnboardingPage() { const router = useRouter(); const [step, setStep] = useState(1); const [loading, setLoading] = useState(false); const [saving, setSaving] = useState(false); const [checkingAuth, setCheckingAuth] = useState(true); const [newChildId, setNewChildId] = useState(null); const [form, setForm] = useState({ familyName: "", memberName: "", phone: "", childName: "", birthDate: "", sex: "" as "male" | "female" | "other", }); const [vaccStates, setVaccStates] = useState>({}); useEffect(() => { async function checkAuth() { const res = await fetch("/api/auth/signin"); const data = await res.json(); if (!data.authenticated) { router.push("/login"); } else if (data.familyId) { router.push("/home"); } setCheckingAuth(false); } checkAuth(); }, [router]); const dueVaccines = form.birthDate ? IAP_SCHEDULE.filter(v => v.weeks <= weeksSinceBirth(form.birthDate)) : []; const milestones = [...new Set(dueVaccines.map(v => v.milestone))]; const handleSubmit = async () => { setLoading(true); try { const res = await fetch("/api/onboarding", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(form), }); const data = await res.json(); if (data.success) { setNewChildId(data.childId); // Initialize vaccine states const initial: Record = {}; dueVaccines.forEach(v => { initial[v.name] = { given: false, date: dueDate(form.birthDate, v.weeks), unknown: false }; }); setVaccStates(initial); setStep(3); } } catch (e) { console.error(e); } setLoading(false); }; const handleVaccSave = async () => { setSaving(true); const entries = dueVaccines.map(v => { const s = vaccStates[v.name]; return { vaccineName: v.name, scheduledDate: dueDate(form.birthDate, v.weeks), givenDate: s?.given ? s.date : undefined, status: s?.unknown ? "unknown" : s?.given ? "given" : "pending", }; }); try { await fetch("/api/vaccinations/bulk", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ childId: newChildId, entries }), }); } catch (e) { console.error(e); } setSaving(false); router.push("/home"); }; if (checkingAuth) { return (
Loading...
); } return (
{/* Step indicators */}
{[1, 2, 3].map(s => (
= s ? "bg-rose-400" : "bg-gray-200"}`} /> ))}
{step < 3 && (
👶

Welcome to Tia

Let's set up your family

)} {/* Step 1 — Family info */} {step === 1 && ( <>

Your family

setForm({ ...form, familyName: e.target.value })} placeholder="The Gupta Family" /> setForm({ ...form, memberName: e.target.value })} placeholder="Mama" /> setForm({ ...form, phone: e.target.value })} placeholder="+91 98765 43210" />

For important reminders & updates about your baby

)} {/* Step 2 — Child profile */} {step === 2 && ( <>

Your baby

setForm({ ...form, childName: e.target.value })} placeholder="Tia" /> setForm({ ...form, birthDate: e.target.value })} />
Sex
{(["male", "female", "other"] as const).map((s) => ( ))}
)} {/* Step 3 — Vaccine history */} {step === 3 && ( <>
💉

Vaccine History

{form.childName} is {weeksSinceBirth(form.birthDate)} weeks old. {dueVaccines.length > 0 ? ` Which vaccines have already been given?` : " No vaccines due yet."}

{dueVaccines.length === 0 ? (

All vaccines look up-to-date!

) : (
{milestones.map(milestone => (
{milestone}
{dueVaccines.filter(v => v.milestone === milestone).map(v => { const s = vaccStates[v.name] || { given: false, date: dueDate(form.birthDate, v.weeks), unknown: false }; return (
{v.name}
{s.given && ( setVaccStates(prev => ({ ...prev, [v.name]: { ...s, date: e.target.value } }))} /> )}
); })}
))}
)}
)}
); }