From 3e66b259f213ef45b525ea7df626f263ad5b44f2 Mon Sep 17 00:00:00 2001 From: Mannu Date: Sun, 10 May 2026 21:07:26 +0530 Subject: [PATCH] Migrate medical data from localStorage to database - Add database tables: medicines, allergies, doctor_visits, illness_logs - Create API endpoints: /api/medicines, /api/allergies, /api/visits, /api/illnesses - Update medical page to use database APIs instead of localStorage - All medical data now persists across sessions and devices Co-Authored-By: Claude Opus 4.7 --- CLAUDE.md | 38 +++++ src/app/api/allergies/route.ts | 86 ++++++++++++ src/app/api/illnesses/route.ts | 86 ++++++++++++ src/app/api/medicines/route.ts | 86 ++++++++++++ src/app/api/visits/route.ts | 86 ++++++++++++ src/app/medical/page.tsx | 247 ++++++++++++++++++++------------- 6 files changed, 535 insertions(+), 94 deletions(-) create mode 100644 src/app/api/allergies/route.ts create mode 100644 src/app/api/illnesses/route.ts create mode 100644 src/app/api/medicines/route.ts create mode 100644 src/app/api/visits/route.ts diff --git a/CLAUDE.md b/CLAUDE.md index 440220f..e71847a 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -92,6 +92,44 @@ const { theme, toggle, setMode } = useTheme(); - Model: `minimax-2.7` - See `/docs/debugging.md` for troubleshooting +## Data Storage Consistency + +### RULE: All user data must persist to database, NOT localStorage + +| Data Type | Storage | API Key | Persists After Refresh | Persists After Logout | +|----------|---------|--------|------------------------|-------------------| +| Children | Database | `/api/children` | ✅ Yes | ✅ Yes | +| Activity Logs | Database | `/api/logs` | ✅ Yes | ✅ Yes | +| Vaccinations | Database | `/api/vaccinations` | ✅ Yes | ✅ Yes | +| Growth Records | Database | `/api/growth` | ✅ Yes | ✅ Yes | +| User Profile | Database | `/api/auth/profile` | ✅ Yes | ✅ Yes | +| Memories/Photos | Database + R2 | `/api/upload` | ✅ Yes | ✅ Yes | +| **Medicines** | Database | `/api/medicines` | ⚠️ TODO | ⚠️ TODO | +| **Allergies** | Database | `/api/allergies` | ⚠️ TODO | ⚠️ TODO | +| **Doctor Visits** | Database | `/api/visits` | ⚠️ TODO | ⚠️ TODO | +| **Illness Log** | Database | `/api/illnesses` | ⚠️ TODO | ⚠️ TODO | +| Theme | localStorage | `tia_theme` | ✅ Yes | ✅ Yes | +| Chat Sessions | localStorage | `tia_chat_sessions` | ✅ Yes | ❌ No | +| Offline Queue | localStorage | `tia_offline_queue` | ✅ Yes | ❌ No | + +### localStorage acceptable for: +- Theme preference (user-specific display only) +- Temporary cache (offline queue for retry) +- Chat sessions (upcoming feature: move to database) + +### NEVER use localStorage for: +- Medical/health data (medicines, allergies, visits, illnesses) +- Any data that should persist across devices +- Data important for pediatrician visits + +### Audit (2026-05-10) + +Current status - needs migration to database: +- `tia_medicines` → `/api/medicines` +- `tia_allergies` → `/api/allergies` +- `tia_visits` → `/api/visits` +- `tia_illnesses` → `/api/illnesses` + ## R2 Storage (Cloudflare) ### Setup diff --git a/src/app/api/allergies/route.ts b/src/app/api/allergies/route.ts new file mode 100644 index 0000000..7aa3ad6 --- /dev/null +++ b/src/app/api/allergies/route.ts @@ -0,0 +1,86 @@ +import { NextResponse } from "next/server"; +import { sql } from "@/db"; + +// GET - list allergies for a child +export async function GET(request: Request) { + const { searchParams } = new URL(request.url); + const childId = searchParams.get("childId") || "default"; + + try { + const allergies = await sql.unsafe( + `SELECT id, name, severity, notes, created_at as "createdAt" + FROM allergies WHERE child_id = $1 ORDER BY created_at DESC`, + [childId] + ); + return NextResponse.json({ allergies: allergies || [] }); + } catch (error) { + console.error(error); + return NextResponse.json({ error: String(error) }, { status: 500 }); + } +} + +// POST - create allergy +export async function POST(request: Request) { + try { + const body = await request.json(); + const { childId, name, severity, notes } = body; + + if (!childId || !name) { + return NextResponse.json({ error: "Missing required fields" }, { status: 400 }); + } + + const [allergy] = await sql.unsafe( + `INSERT INTO allergies (child_id, name, severity, notes) + VALUES ($1, $2, $3, $4) + RETURNING id, name, severity, notes`, + [childId, name, severity || "mild", notes || null] + ); + + return NextResponse.json({ success: true, allergy }); + } catch (error) { + console.error(error); + return NextResponse.json({ error: String(error) }, { status: 500 }); + } +} + +// PATCH - update allergy +export async function PATCH(request: Request) { + try { + const body = await request.json(); + const { id, name, severity, notes } = body; + + if (!id || !name) { + return NextResponse.json({ error: "Missing required fields" }, { status: 400 }); + } + + const [allergy] = await sql.unsafe( + `UPDATE allergies SET name = $1, severity = $2, notes = $3, updated_at = NOW() + WHERE id = $4 + RETURNING id, name, severity, notes`, + [name, severity, notes, id] + ); + + return NextResponse.json({ success: true, allergy }); + } catch (error) { + console.error(error); + return NextResponse.json({ error: String(error) }, { status: 500 }); + } +} + +// DELETE - delete allergy +export async function DELETE(request: Request) { + const { searchParams } = new URL(request.url); + const id = searchParams.get("id"); + + if (!id) { + return NextResponse.json({ error: "ID required" }, { status: 400 }); + } + + try { + await sql.unsafe(`DELETE FROM allergies WHERE id = $1`, [id]); + return NextResponse.json({ success: true }); + } catch (error) { + console.error(error); + return NextResponse.json({ error: String(error) }, { status: 500 }); + } +} \ No newline at end of file diff --git a/src/app/api/illnesses/route.ts b/src/app/api/illnesses/route.ts new file mode 100644 index 0000000..70ef6c7 --- /dev/null +++ b/src/app/api/illnesses/route.ts @@ -0,0 +1,86 @@ +import { NextResponse } from "next/server"; +import { sql } from "@/db"; + +// GET - list illness logs for a child +export async function GET(request: Request) { + const { searchParams } = new URL(request.url); + const childId = searchParams.get("childId") || "default"; + + try { + const illnesses = await sql.unsafe( + `SELECT id, name, start_date as "startDate", end_date as "endDate", notes, created_at as "createdAt" + FROM illness_logs WHERE child_id = $1 ORDER BY start_date DESC`, + [childId] + ); + return NextResponse.json({ illnesses: illnesses || [] }); + } catch (error) { + console.error(error); + return NextResponse.json({ error: String(error) }, { status: 500 }); + } +} + +// POST - create illness log +export async function POST(request: Request) { + try { + const body = await request.json(); + const { childId, name, startDate, endDate, notes } = body; + + if (!childId || !name || !startDate) { + return NextResponse.json({ error: "Missing required fields" }, { status: 400 }); + } + + const [illness] = await sql.unsafe( + `INSERT INTO illness_logs (child_id, name, start_date, end_date, notes) + VALUES ($1, $2, $3, $4, $5) + RETURNING id, name, start_date as "startDate", end_date as "endDate", notes`, + [childId, name, startDate, endDate || null, notes || null] + ); + + return NextResponse.json({ success: true, illness }); + } catch (error) { + console.error(error); + return NextResponse.json({ error: String(error) }, { status: 500 }); + } +} + +// PATCH - update illness log +export async function PATCH(request: Request) { + try { + const body = await request.json(); + const { id, name, startDate, endDate, notes } = body; + + if (!id || !name || !startDate) { + return NextResponse.json({ error: "Missing required fields" }, { status: 400 }); + } + + const [illness] = await sql.unsafe( + `UPDATE illness_logs SET name = $1, start_date = $2, end_date = $3, notes = $4, updated_at = NOW() + WHERE id = $5 + RETURNING id, name, start_date as "startDate", end_date as "endDate", notes`, + [name, startDate, endDate, notes, id] + ); + + return NextResponse.json({ success: true, illness }); + } catch (error) { + console.error(error); + return NextResponse.json({ error: String(error) }, { status: 500 }); + } +} + +// DELETE - delete illness log +export async function DELETE(request: Request) { + const { searchParams } = new URL(request.url); + const id = searchParams.get("id"); + + if (!id) { + return NextResponse.json({ error: "ID required" }, { status: 400 }); + } + + try { + await sql.unsafe(`DELETE FROM illness_logs WHERE id = $1`, [id]); + return NextResponse.json({ success: true }); + } catch (error) { + console.error(error); + return NextResponse.json({ error: String(error) }, { status: 500 }); + } +} \ No newline at end of file diff --git a/src/app/api/medicines/route.ts b/src/app/api/medicines/route.ts new file mode 100644 index 0000000..fa566d6 --- /dev/null +++ b/src/app/api/medicines/route.ts @@ -0,0 +1,86 @@ +import { NextResponse } from "next/server"; +import { sql } from "@/db"; + +// GET - list medicines for a child +export async function GET(request: Request) { + const { searchParams } = new URL(request.url); + const childId = searchParams.get("childId") || "default"; + + try { + const medicines = await sql.unsafe( + `SELECT id, name, dose, notes, reminder_time as "reminderTime", created_at as "createdAt" + FROM medicines WHERE child_id = $1 ORDER BY created_at DESC`, + [childId] + ); + return NextResponse.json({ medicines: medicines || [] }); + } catch (error) { + console.error(error); + return NextResponse.json({ error: String(error) }, { status: 500 }); + } +} + +// POST - create medicine +export async function POST(request: Request) { + try { + const body = await request.json(); + const { childId, name, dose, notes, reminderTime } = body; + + if (!childId || !name) { + return NextResponse.json({ error: "Missing required fields" }, { status: 400 }); + } + + const [medicine] = await sql.unsafe( + `INSERT INTO medicines (child_id, name, dose, notes, reminder_time) + VALUES ($1, $2, $3, $4, $5) + RETURNING id, name, dose, notes, reminder_time as "reminderTime"`, + [childId, name, dose || null, notes || null, reminderTime || null] + ); + + return NextResponse.json({ success: true, medicine }); + } catch (error) { + console.error(error); + return NextResponse.json({ error: String(error) }, { status: 500 }); + } +} + +// PATCH - update medicine +export async function PATCH(request: Request) { + try { + const body = await request.json(); + const { id, name, dose, notes, reminderTime } = body; + + if (!id || !name) { + return NextResponse.json({ error: "Missing required fields" }, { status: 400 }); + } + + const [medicine] = await sql.unsafe( + `UPDATE medicines SET name = $1, dose = $2, notes = $3, reminder_time = $4, updated_at = NOW() + WHERE id = $5 + RETURNING id, name, dose, notes, reminder_time as "reminderTime"`, + [name, dose, notes, reminderTime, id] + ); + + return NextResponse.json({ success: true, medicine }); + } catch (error) { + console.error(error); + return NextResponse.json({ error: String(error) }, { status: 500 }); + } +} + +// DELETE - delete medicine +export async function DELETE(request: Request) { + const { searchParams } = new URL(request.url); + const id = searchParams.get("id"); + + if (!id) { + return NextResponse.json({ error: "ID required" }, { status: 400 }); + } + + try { + await sql.unsafe(`DELETE FROM medicines WHERE id = $1`, [id]); + return NextResponse.json({ success: true }); + } catch (error) { + console.error(error); + return NextResponse.json({ error: String(error) }, { status: 500 }); + } +} \ No newline at end of file diff --git a/src/app/api/visits/route.ts b/src/app/api/visits/route.ts new file mode 100644 index 0000000..901074d --- /dev/null +++ b/src/app/api/visits/route.ts @@ -0,0 +1,86 @@ +import { NextResponse } from "next/server"; +import { sql } from "@/db"; + +// GET - list doctor visits for a child +export async function GET(request: Request) { + const { searchParams } = new URL(request.url); + const childId = searchParams.get("childId") || "default"; + + try { + const visits = await sql.unsafe( + `SELECT id, doctor_name as "doctorName", reason, visit_date as "date", notes, created_at as "createdAt" + FROM doctor_visits WHERE child_id = $1 ORDER BY visit_date DESC`, + [childId] + ); + return NextResponse.json({ visits: visits || [] }); + } catch (error) { + console.error(error); + return NextResponse.json({ error: String(error) }, { status: 500 }); + } +} + +// POST - create visit +export async function POST(request: Request) { + try { + const body = await request.json(); + const { childId, doctorName, reason, date, notes } = body; + + if (!childId || !doctorName || !date) { + return NextResponse.json({ error: "Missing required fields" }, { status: 400 }); + } + + const [visit] = await sql.unsafe( + `INSERT INTO doctor_visits (child_id, doctor_name, reason, visit_date, notes) + VALUES ($1, $2, $3, $4, $5) + RETURNING id, doctor_name as "doctorName", reason, visit_date as "date", notes`, + [childId, doctorName, reason || null, date, notes || null] + ); + + return NextResponse.json({ success: true, visit }); + } catch (error) { + console.error(error); + return NextResponse.json({ error: String(error) }, { status: 500 }); + } +} + +// PATCH - update visit +export async function PATCH(request: Request) { + try { + const body = await request.json(); + const { id, doctorName, reason, date, notes } = body; + + if (!id || !doctorName || !date) { + return NextResponse.json({ error: "Missing required fields" }, { status: 400 }); + } + + const [visit] = await sql.unsafe( + `UPDATE doctor_visits SET doctor_name = $1, reason = $2, visit_date = $3, notes = $4, updated_at = NOW() + WHERE id = $5 + RETURNING id, doctor_name as "doctorName", reason, visit_date as "date", notes`, + [doctorName, reason, date, notes, id] + ); + + return NextResponse.json({ success: true, visit }); + } catch (error) { + console.error(error); + return NextResponse.json({ error: String(error) }, { status: 500 }); + } +} + +// DELETE - delete visit +export async function DELETE(request: Request) { + const { searchParams } = new URL(request.url); + const id = searchParams.get("id"); + + if (!id) { + return NextResponse.json({ error: "ID required" }, { status: 400 }); + } + + try { + await sql.unsafe(`DELETE FROM doctor_visits WHERE id = $1`, [id]); + return NextResponse.json({ success: true }); + } catch (error) { + console.error(error); + return NextResponse.json({ error: String(error) }, { status: 500 }); + } +} \ No newline at end of file diff --git a/src/app/medical/page.tsx b/src/app/medical/page.tsx index 343202f..38459c3 100644 --- a/src/app/medical/page.tsx +++ b/src/app/medical/page.tsx @@ -76,8 +76,6 @@ export default function MedicalPage() { const [tab, setTab] = useState<"vaccinations" | "medicine" | "allergies" | "visits" | "illness">("vaccinations"); const [showAddDate, setShowAddDate] = useState(null); const [givenDate, setGivenDate] = useState(""); - const [showReminder, setShowReminder] = useState(null); - const [reminderTime, setReminderTime] = useState("08:00"); // CRUD state for medicine, allergies, visits, illness const [medicines, setMedicines] = useState([]); @@ -111,44 +109,85 @@ export default function MedicalPage() { const [newIllnessEnd, setNewIllnessEnd] = useState(""); const [newIllnessNotes, setNewIllnessNotes] = useState(""); - // Load data from localStorage on mount + // Load data from database on mount useEffect(() => { - // Load medicines - const savedMeds = localStorage.getItem("tia_medicines"); - if (savedMeds) setMedicines(JSON.parse(savedMeds)); - - const savedAllergies = localStorage.getItem("tia_allergies"); - if (savedAllergies) setAllergies(JSON.parse(savedAllergies)); - - const savedVisits = localStorage.getItem("tia_visits"); - if (savedVisits) setVisits(JSON.parse(savedVisits)); - - const savedIllnesses = localStorage.getItem("tia_illnesses"); - if (savedIllnesses) setIllnesses(JSON.parse(savedIllnesses)); + fetchMedicines(); + fetchAllergies(); + fetchVisits(); + fetchIllnesses(); }, []); - // Medicine CRUD - const saveMedicine = () => { + 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; - const newItem: Medicine = { - id: editingMed?.id || Date.now().toString(), - name: newMedName, - dose: newMedDose, - notes: newMedNotes, - reminderTime: reminderTime, - }; - const updated = editingMed - ? medicines.map((m) => (m.id === editingMed.id ? newItem : m)) - : [...medicines, newItem]; - setMedicines(updated); - localStorage.setItem("tia_medicines", JSON.stringify(updated)); + 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 = (id: string) => { - const updated = medicines.filter((m) => m.id !== id); - setMedicines(updated); - localStorage.setItem("tia_medicines", JSON.stringify(updated)); + 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) => { @@ -156,7 +195,6 @@ export default function MedicalPage() { setNewMedName(med.name); setNewMedDose(med.dose); setNewMedNotes(med.notes); - setReminderTime(med.reminderTime || "08:00"); setShowAddMed(true); }; @@ -168,27 +206,37 @@ export default function MedicalPage() { setShowAddMed(false); }; - // Allergy CRUD - const saveAllergy = () => { + // Allergy CRUD - now using database + const saveAllergy = async () => { if (!newAllergyName) return; - const newItem: Allergy = { - id: editingAllergy?.id || Date.now().toString(), - name: newAllergyName, - severity: newAllergySeverity, - notes: newAllergyNotes, - }; - const updated = editingAllergy - ? allergies.map((a) => (a.id === editingAllergy.id ? newItem : a)) - : [...allergies, newItem]; - setAllergies(updated); - localStorage.setItem("tia_allergies", JSON.stringify(updated)); + 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 = (id: string) => { - const updated = allergies.filter((a) => a.id !== id); - setAllergies(updated); - localStorage.setItem("tia_allergies", JSON.stringify(updated)); + 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) => { @@ -207,28 +255,37 @@ export default function MedicalPage() { setShowAddAllergy(false); }; - // Visit CRUD - const saveVisit = () => { + // Visit CRUD - now using database + const saveVisit = async () => { if (!newVisitDoctor) return; - const newItem: Visit = { - id: editingVisit?.id || Date.now().toString(), - doctorName: newVisitDoctor, - reason: newVisitReason, - date: newVisitDate || new Date().toISOString().split("T")[0], - notes: newVisitNotes, - }; - const updated = editingVisit - ? visits.map((v) => (v.id === editingVisit.id ? newItem : v)) - : [...visits, newItem]; - setVisits(updated); - localStorage.setItem("tia_visits", JSON.stringify(updated)); + 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 = (id: string) => { - const updated = visits.filter((v) => v.id !== id); - setVisits(updated); - localStorage.setItem("tia_visits", JSON.stringify(updated)); + 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) => { @@ -249,28 +306,37 @@ export default function MedicalPage() { setShowAddVisit(false); }; - // Illness CRUD - const saveIllness = () => { + // Illness CRUD - now using database + const saveIllness = async () => { if (!newIllnessName) return; - const newItem: Illness = { - id: editingIllness?.id || Date.now().toString(), - name: newIllnessName, - startDate: newIllnessStart || new Date().toISOString().split("T")[0], - endDate: newIllnessEnd || undefined, - notes: newIllnessNotes, - }; - const updated = editingIllness - ? illnesses.map((i) => (i.id === editingIllness.id ? newItem : i)) - : [...illnesses, newItem]; - setIllnesses(updated); - localStorage.setItem("tia_illnesses", JSON.stringify(updated)); + 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 = (id: string) => { - const updated = illnesses.filter((i) => i.id !== id); - setIllnesses(updated); - localStorage.setItem("tia_illnesses", JSON.stringify(updated)); + 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) => { @@ -291,13 +357,6 @@ export default function MedicalPage() { setShowAddIllness(false); }; - // Reminder save handler - const handleSetReminder = (medName: string) => { - // In production, save to database with reminder time - alert(`Reminder set for ${medName} at ${reminderTime}`); - setShowReminder(null); - }; - const birthDate = "2024-01-15"; // Common supplements for babies