"use client"; import { useState, useEffect } from "react"; import { useFamily } from "../FamilyProvider"; interface Medicine { id: string; name: string; dose: string; notes: string; reminderTime?: string; } interface Allergy { id: string; name: string; severity: string; notes: string; } interface Visit { id: string; doctorName: string; reason: string; date: string; notes: string; } interface Illness { id: string; name: string; startDate: string; endDate?: string; notes: string; } // IAP Vaccination Schedule (India) const IAP_SCHEDULE = [ { name: "BCG", weeks: 0 }, { name: "OPV-0", weeks: 0 }, { name: "HepB-1", weeks: 0 }, { name: "OPV-1", weeks: 6 }, { name: "Pentavalent-1", weeks: 6 }, { name: "PCV-1", weeks: 6 }, { name: "Rota-1", weeks: 6 }, { name: "OPV-2", weeks: 10 }, { name: "Pentavalent-2", weeks: 10 }, { name: "PCV-2", weeks: 10 }, { name: "Rota-2", weeks: 10 }, { name: "OPV-3", weeks: 14 }, { name: "Pentavalent-3", weeks: 14 }, { name: "PCV-3", weeks: 14 }, { name: "Rota-3", weeks: 14 }, { name: "MR-1", weeks: 48 }, // 9 months { name: "JE-1", weeks: 48 }, { name: "Vitamin A-1", weeks: 48 }, { name: "OPV-4", weeks: 48 }, { name: "MR-2", weeks: 96 }, // 18 months { name: "JE-2", weeks: 96 }, { name: "DPT-Booster-1", weeks: 96 }, { name: "Vitamin A-2", weeks: 96 }, { name: "OPV-5", weeks: 96 }, { name: "DPT-Booster-2", weeks: 208 }, // 4 years { name: "Tetanus and adult diphtheria (Td)", weeks: 208 }, ]; function calculateDueDate(birthDate: string, weeks: number): string { const birth = new Date(birthDate); birth.setDate(birth.getDate() + weeks * 7); return birth.toISOString().split("T")[0]; } export default function MedicalPage() { const [vaccinations, setVaccinations] = useState([]); const [loading, setLoading] = useState(true); const { childId: sessionChildId, child, loading: loadingChild } = useFamily(); const [tab, setTab] = useState<"vaccinations" | "medicine" | "allergies" | "visits" | "illness">("vaccinations"); const [vaccineTab, setVaccineTab] = useState<"upcoming" | "completed" | "overdue">("upcoming"); const [showAddDate, setShowAddDate] = useState(null); const [givenDate, setGivenDate] = useState(""); // CRUD state for medicine, allergies, visits, illness const [medicines, setMedicines] = useState([]); const [allergies, setAllergies] = useState([]); const [visits, setVisits] = useState([]); const [illnesses, setIllnesses] = useState([]); // Add/Edit mode const [editingMed, setEditingMed] = useState(null); const [editingAllergy, setEditingAllergy] = useState(null); const [editingVisit, setEditingVisit] = useState(null); const [editingIllness, setEditingIllness] = useState(null); const [showAddMed, setShowAddMed] = useState(false); const [showAddAllergy, setShowAddAllergy] = useState(false); const [showAddVisit, setShowAddVisit] = useState(false); const [showAddIllness, setShowAddIllness] = useState(false); // Form state for new items const [newMedName, setNewMedName] = useState(""); const [newMedDose, setNewMedDose] = useState(""); const [newMedNotes, setNewMedNotes] = useState(""); const [newAllergyName, setNewAllergyName] = useState(""); const [newAllergySeverity, setNewAllergySeverity] = useState("mild"); const [newAllergyNotes, setNewAllergyNotes] = useState(""); const [newVisitDoctor, setNewVisitDoctor] = useState(""); const [newVisitReason, setNewVisitReason] = useState(""); const [newVisitDate, setNewVisitDate] = useState(""); const [newVisitNotes, setNewVisitNotes] = useState(""); const [newIllnessName, setNewIllnessName] = useState(""); const [newIllnessStart, setNewIllnessStart] = useState(""); const [newIllnessEnd, setNewIllnessEnd] = useState(""); const [newIllnessNotes, setNewIllnessNotes] = useState(""); // Load data from database on mount useEffect(() => { fetchMedicines(); fetchAllergies(); fetchVisits(); fetchIllnesses(); }, []); const fetchMedicines = async () => { try { const res = await fetch(`/api/medicines?childId=${childId}`); const data = await res.json(); setMedicines(data.medicines || []); } catch (err) { console.error("Failed to fetch medicines:", err); } }; const fetchAllergies = async () => { try { const res = await fetch(`/api/allergies?childId=${childId}`); const data = await res.json(); setAllergies(data.allergies || []); } catch (err) { console.error("Failed to fetch allergies:", err); } }; const fetchVisits = async () => { try { const res = await fetch(`/api/visits?childId=${childId}`); const data = await res.json(); setVisits(data.visits || []); } catch (err) { console.error("Failed to fetch visits:", err); } }; const fetchIllnesses = async () => { try { const res = await fetch(`/api/illnesses?childId=${childId}`); const data = await res.json(); setIllnesses(data.illnesses || []); } catch (err) { console.error("Failed to fetch illnesses:", err); } }; // Medicine CRUD - now using database const saveMedicine = async () => { if (!newMedName) return; try { if (editingMed) { await fetch(`/api/medicines`, { method: "PATCH", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ id: editingMed.id, name: newMedName, dose: newMedDose, notes: newMedNotes }), }); } else { await fetch("/api/medicines", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ childId, name: newMedName, dose: newMedDose, notes: newMedNotes }), }); } fetchMedicines(); } catch (err) { console.error("Failed to save:", err); } resetMedForm(); }; const deleteMedicine = async (id: string) => { try { await fetch(`/api/medicines?id=${id}`, { method: "DELETE" }); fetchMedicines(); } catch (err) { console.error("Failed to delete:", err); } }; const editMedicine = (med: Medicine) => { setEditingMed(med); setNewMedName(med.name); setNewMedDose(med.dose); setNewMedNotes(med.notes); setShowAddMed(true); }; const resetMedForm = () => { setEditingMed(null); setNewMedName(""); setNewMedDose(""); setNewMedNotes(""); setShowAddMed(false); }; // Allergy CRUD - now using database const saveAllergy = async () => { if (!newAllergyName) return; try { if (editingAllergy) { await fetch(`/api/allergies`, { method: "PATCH", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ id: editingAllergy.id, name: newAllergyName, severity: newAllergySeverity, notes: newAllergyNotes }), }); } else { await fetch("/api/allergies", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ childId, name: newAllergyName, severity: newAllergySeverity, notes: newAllergyNotes }), }); } fetchAllergies(); } catch (err) { console.error("Failed to save:", err); } resetAllergyForm(); }; const deleteAllergy = async (id: string) => { try { await fetch(`/api/allergies?id=${id}`, { method: "DELETE" }); fetchAllergies(); } catch (err) { console.error("Failed to delete:", err); } }; const editAllergy = (allergy: Allergy) => { setEditingAllergy(allergy); setNewAllergyName(allergy.name); setNewAllergySeverity(allergy.severity); setNewAllergyNotes(allergy.notes); setShowAddAllergy(true); }; const resetAllergyForm = () => { setEditingAllergy(null); setNewAllergyName(""); setNewAllergySeverity("mild"); setNewAllergyNotes(""); setShowAddAllergy(false); }; // Visit CRUD - now using database const saveVisit = async () => { if (!newVisitDoctor) return; try { if (editingVisit) { await fetch(`/api/visits`, { method: "PATCH", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ id: editingVisit.id, doctorName: newVisitDoctor, reason: newVisitReason, date: newVisitDate, notes: newVisitNotes }), }); } else { await fetch("/api/visits", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ childId, doctorName: newVisitDoctor, reason: newVisitReason, date: newVisitDate, notes: newVisitNotes }), }); } fetchVisits(); } catch (err) { console.error("Failed to save:", err); } resetVisitForm(); }; const deleteVisit = async (id: string) => { try { await fetch(`/api/visits?id=${id}`, { method: "DELETE" }); fetchVisits(); } catch (err) { console.error("Failed to delete:", err); } }; const editVisit = (visit: Visit) => { setEditingVisit(visit); setNewVisitDoctor(visit.doctorName); setNewVisitReason(visit.reason); setNewVisitDate(visit.date); setNewVisitNotes(visit.notes); setShowAddVisit(true); }; const resetVisitForm = () => { setEditingVisit(null); setNewVisitDoctor(""); setNewVisitReason(""); setNewVisitDate(""); setNewVisitNotes(""); setShowAddVisit(false); }; // Illness CRUD - now using database const saveIllness = async () => { if (!newIllnessName) return; try { if (editingIllness) { await fetch(`/api/illnesses`, { method: "PATCH", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ id: editingIllness.id, name: newIllnessName, startDate: newIllnessStart, endDate: newIllnessEnd, notes: newIllnessNotes }), }); } else { await fetch("/api/illnesses", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ childId, name: newIllnessName, startDate: newIllnessStart, endDate: newIllnessEnd, notes: newIllnessNotes }), }); } fetchIllnesses(); } catch (err) { console.error("Failed to save:", err); } resetIllnessForm(); }; const deleteIllness = async (id: string) => { try { await fetch(`/api/illnesses?id=${id}`, { method: "DELETE" }); fetchIllnesses(); } catch (err) { console.error("Failed to delete:", err); } }; const editIllness = (illness: Illness) => { setEditingIllness(illness); setNewIllnessName(illness.name); setNewIllnessStart(illness.startDate); setNewIllnessEnd(illness.endDate || ""); setNewIllnessNotes(illness.notes); setShowAddIllness(true); }; const resetIllnessForm = () => { setEditingIllness(null); setNewIllnessName(""); setNewIllnessStart(""); setNewIllnessEnd(""); setNewIllnessNotes(""); setShowAddIllness(false); }; const childId = sessionChildId; const birthDate = child?.birthDate || "2024-01-15"; // Common supplements for babies const SUPPLEMENTS = [ { name: "Vitamin D3", dose: "400 IU daily", notes: "For bone health" }, { name: "Iron", dose: "1 mg/kg daily", notes: "As prescribed" }, { name: "Calcium", dose: "500 mg daily", notes: "With food" }, { name: "Zinc", dose: "5 mg daily", notes: "Immune support" }, { name: "Omega-3", dose: "DHA 100mg", notes: "Brain development" }, { name: "Probiotics", dose: "1 shot daily", notes: "Gut health" }, { name: "Multivitamin", dose: "As directed", notes: "Daily vitamin" }, ]; useEffect(() => { fetch(`/api/vaccinations?childId=${childId}`) .then((res) => res.json()) .then((data) => { setVaccinations(data.vaccinations || []); setLoading(false); }) .catch(() => setLoading(false)); }, [childId]); const handleMarkGiven = async (vaccineName: string) => { const dueDate = calculateDueDate(birthDate, IAP_SCHEDULE.find((v) => v.name === vaccineName)?.weeks || 0); const dateToSave = givenDate || new Date().toISOString().split("T")[0]; await fetch("/api/vaccinations", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ childId, vaccineName, scheduledDate: dueDate, givenDate: dateToSave, status: "given", }), }); setVaccinations((prev) => [...prev, { vaccine_name: vaccineName, given_date: dateToSave, status: "given" }]); setShowAddDate(null); setGivenDate(""); }; const isGiven = (name: string) => vaccinations.some((v) => v.vaccine_name === name && v.status === "given"); const getGivenDate = (name: string) => vaccinations.find((v) => v.vaccine_name === name && v.status === "given")?.given_date; const isPending = (name: string) => !isGiven(name); // Get vaccines by status const getVaccinesByStatus = (status: "upcoming" | "completed" | "overdue") => { const today = new Date(); const todayStr = today.toISOString().split("T")[0]; return IAP_SCHEDULE.filter((v) => { const dueDate = calculateDueDate(birthDate, v.weeks); const given = isGiven(v.name); if (status === "completed") return given; if (status === "overdue") return !given && dueDate < todayStr; if (status === "upcoming") return !given && dueDate >= todayStr; return false; }).sort((a, b) => a.weeks - b.weeks); }; const getVaccineStatus = (name: string) => { const dueDate = calculateDueDate(birthDate, IAP_SCHEDULE.find((v) => v.name === name)?.weeks || 0); const today = new Date(); const todayStr = today.toISOString().split("T")[0]; const given = isGiven(name); if (given) return "completed"; if (dueDate < todayStr) return "overdue"; return "upcoming"; }; return (

Medical

{tab === "vaccinations" && (

IAP Schedule

{loading ? (

Loading...

) : ( getVaccinesByStatus(vaccineTab).map((vaccine) => { const given = isGiven(vaccine.name); const actualDate = getGivenDate(vaccine.name); const dueDate = calculateDueDate(birthDate, vaccine.weeks); const status = getVaccineStatus(vaccine.name); const daysOverdue = status === "overdue" ? Math.floor((new Date().getTime() - new Date(dueDate).getTime()) / (1000 * 60 * 60 * 24)) : 0; return (
{vaccine.name}
Due: {new Date(dueDate).toLocaleDateString()} {actualDate && ` · Given: ${new Date(actualDate).toLocaleDateString()}`}
{status === "overdue" && (
{daysOverdue} days overdue
)}
{given ? ( ) : showAddDate === vaccine.name ? (
setGivenDate(e.target.value)} className="p-1 text-sm border dark:border-gray-600 rounded dark:bg-gray-700 dark:text-white" placeholder="Date given" />
) : ( )}
); }) )}
)} {tab === "medicine" && (

Medicine & Supplements

{/* Add Form */} {showAddMed && (
setNewMedName(e.target.value)} placeholder="Medicine name" className="w-full p-2 border dark:border-gray-600 rounded-lg dark:bg-gray-700 dark:text-white dark:placeholder-gray-400" /> setNewMedDose(e.target.value)} placeholder="Dose (e.g., 5ml, 1 tablet)" className="w-full p-2 border dark:border-gray-600 rounded-lg dark:bg-gray-700 dark:text-white dark:placeholder-gray-400" /> setNewMedNotes(e.target.value)} placeholder="Notes" className="w-full p-2 border dark:border-gray-600 rounded-lg dark:bg-gray-700 dark:text-white dark:placeholder-gray-400" />
)} {medicines.length === 0 && !showAddMed ? (

No medicines added

) : ( medicines.map((med) => (
{med.name}
{med.dose} {med.notes && `· ${med.notes}`} {med.reminderTime && ` · ⏰ ${med.reminderTime}`}
)) )} {!showAddMed && ( )}
)} {tab === "allergies" && (

Known Allergies

{showAddAllergy && (
setNewAllergyName(e.target.value)} placeholder="Allergy name (e.g., Peanut, Milk)" className="w-full p-2 border dark:border-gray-600 rounded-lg dark:bg-gray-700 dark:text-white dark:placeholder-gray-400" /> setNewAllergyNotes(e.target.value)} placeholder="Notes" className="w-full p-2 border dark:border-gray-600 rounded-lg dark:bg-gray-700 dark:text-white dark:placeholder-gray-400" />
)} {allergies.length === 0 && !showAddAllergy ? (

No allergies recorded

) : ( allergies.map((allergy) => (
{allergy.name}
{allergy.severity.toUpperCase()} {allergy.notes && ` · ${allergy.notes}`}
)) )} {!showAddAllergy && ( )}
)} {tab === "visits" && (

Doctor Visits

{showAddVisit && (
setNewVisitDoctor(e.target.value)} placeholder="Doctor name" className="w-full p-2 border dark:border-gray-600 rounded-lg dark:bg-gray-700 dark:text-white dark:placeholder-gray-400" /> setNewVisitReason(e.target.value)} placeholder="Reason (e.g., Checkup, Fever)" className="w-full p-2 border dark:border-gray-600 rounded-lg dark:bg-gray-700 dark:text-white dark:placeholder-gray-400" /> setNewVisitDate(e.target.value)} className="w-full p-2 border dark:border-gray-600 rounded-lg dark:bg-gray-700 dark:text-white" /> setNewVisitNotes(e.target.value)} placeholder="Notes" className="w-full p-2 border dark:border-gray-600 rounded-lg dark:bg-gray-700 dark:text-white dark:placeholder-gray-400" />
)} {visits.length === 0 && !showAddVisit ? (

No visits recorded

) : ( visits.map((visit) => (
{visit.doctorName}
{new Date(visit.date).toLocaleDateString()} {visit.reason && ` · ${visit.reason}`} {visit.notes && ` · ${visit.notes}`}
)) )} {!showAddVisit && ( )}
)} {tab === "illness" && (

Illness Log

{showAddIllness && (
setNewIllnessName(e.target.value)} placeholder="Illness (e.g., Cold, Fever, Flu)" className="w-full p-2 border dark:border-gray-600 rounded-lg dark:bg-gray-700 dark:text-white dark:placeholder-gray-400" />
setNewIllnessStart(e.target.value)} placeholder="Start date" className="w-full p-2 border dark:border-gray-600 rounded-lg dark:bg-gray-700 dark:text-white" /> setNewIllnessEnd(e.target.value)} placeholder="End date" className="w-full p-2 border dark:border-gray-600 rounded-lg dark:bg-gray-700 dark:text-white" />
setNewIllnessNotes(e.target.value)} placeholder="Notes" className="w-full p-2 border dark:border-gray-600 rounded-lg dark:bg-gray-700 dark:text-white dark:placeholder-gray-400" />
)} {illnesses.length === 0 && !showAddIllness ? (

No illnesses recorded

) : ( illnesses.map((illness) => (
{illness.name}
{new Date(illness.startDate).toLocaleDateString()} {illness.endDate && ` - ${new Date(illness.endDate).toLocaleDateString()}`} {illness.notes && ` · ${illness.notes}`}
)) )} {!showAddIllness && ( )}
)}
); }