From 515e93aae1e82e09c5209ea0e32a29afc9d1a21b Mon Sep 17 00:00:00 2001 From: Mannu Date: Mon, 18 May 2026 10:49:00 +0530 Subject: [PATCH] =?UTF-8?q?fix(activity):=20repair=20full=20log=20flow=20?= =?UTF-8?q?=E2=80=94=20quick=20log=20=E2=86=92=20activity=20page?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Three bugs fixed: 1. GET /api/logs required a `type` param; activity page calls without one, always receiving {error} → empty list. Fixed: when type is omitted, merge feeds + diapers_logs + sleeps, sort by time, return camelCase fields (loggedAt, subType, amount) matching the activity page interface. 2. Type-specific queries (used by homepage) still return raw snake_case rows unchanged so the homepage "Recent Activity" section is unaffected. 3. LogModal initialised subType as "breast_milk" regardless of log type. Adding a useEffect to reset it (breast_milk / wet / nap) when type changes prevents bad enum values from being sent for diaper/sleep logs. Co-Authored-By: Claude Sonnet 4.6 --- src/app/api/logs/route.ts | 24 ++++++++++++++++++++++-- src/app/page.tsx | 8 ++++++++ 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/src/app/api/logs/route.ts b/src/app/api/logs/route.ts index 33a9cc6..a5bae77 100644 --- a/src/app/api/logs/route.ts +++ b/src/app/api/logs/route.ts @@ -76,8 +76,8 @@ export async function GET(request: Request) { const type = searchParams.get("type"); const limit = parseInt(searchParams.get("limit") || "20"); - if (!childId || !type) { - return NextResponse.json({ error: "childId and type required" }, { status: 400 }); + if (!childId) { + return NextResponse.json({ error: "childId required" }, { status: 400 }); } // Verify child belongs to user's family @@ -87,6 +87,26 @@ export async function GET(request: Request) { } try { + // No type → return all log types merged, camelCase (used by activity page) + if (!type) { + const [feeds, diapers, sleeps] = await Promise.all([ + sql.unsafe(`SELECT id, type as sub_type, amount_ml, notes, logged_at FROM feeds WHERE child_id = $1 ORDER BY logged_at DESC LIMIT $2`, [childId, limit]), + sql.unsafe(`SELECT id, type as sub_type, notes, logged_at FROM diapers_logs WHERE child_id = $1 ORDER BY logged_at DESC LIMIT $2`, [childId, limit]), + sql.unsafe(`SELECT id, type as sub_type, notes, logged_at FROM sleeps WHERE child_id = $1 ORDER BY logged_at DESC LIMIT $2`, [childId, limit]), + ]); + + const all = [ + ...(feeds as any[]).map(r => ({ id: r.id, type: "feed", subType: r.sub_type, amount: r.amount_ml ?? null, notes: r.notes, loggedAt: r.logged_at })), + ...(diapers as any[]).map(r => ({ id: r.id, type: "diaper", subType: r.sub_type, amount: null, notes: r.notes, loggedAt: r.logged_at })), + ...(sleeps as any[]).map(r => ({ id: r.id, type: "sleep", subType: r.sub_type, amount: null, notes: r.notes, loggedAt: r.logged_at })), + ] + .sort((a, b) => new Date(b.loggedAt).getTime() - new Date(a.loggedAt).getTime()) + .slice(0, limit); + + return NextResponse.json({ entries: all }); + } + + // Type-specific queries — return raw snake_case rows (used by homepage) let results: any[] = []; if (type === "feed") { results = await sql.unsafe( diff --git a/src/app/page.tsx b/src/app/page.tsx index 9fee7b1..271853d 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -82,6 +82,14 @@ function LogModal({ type, childId, onClose }: { type: "feed" | "diaper" | "sleep const [subType, setSubType] = useState("breast_milk"); const [amountMl, setAmountMl] = useState(""); const [notes, setNotes] = useState(""); + + // Reset subType default whenever the log type changes + useEffect(() => { + if (type === "feed") setSubType("breast_milk"); + else if (type === "diaper") setSubType("wet"); + else if (type === "sleep") setSubType("nap"); + }, [type]); + if (!type) return null; const handleSubmit = async () => {