Add logging API routes: logs, vaccinations, growth
This commit is contained in:
parent
797eedaeb3
commit
36becd3dc0
3 changed files with 199 additions and 0 deletions
54
src/app/api/growth/route.ts
Normal file
54
src/app/api/growth/route.ts
Normal file
|
|
@ -0,0 +1,54 @@
|
||||||
|
import { NextResponse } from "next/server";
|
||||||
|
import { sql } from "@/db";
|
||||||
|
|
||||||
|
interface GrowthEntry {
|
||||||
|
childId: string;
|
||||||
|
measuredAt: string;
|
||||||
|
weightKg?: number;
|
||||||
|
heightCm?: number;
|
||||||
|
headCircumferenceCm?: number;
|
||||||
|
notes?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function POST(request: Request) {
|
||||||
|
try {
|
||||||
|
const body: GrowthEntry = await request.json();
|
||||||
|
const { childId, measuredAt, weightKg, heightCm, headCircumferenceCm, notes } = body;
|
||||||
|
|
||||||
|
if (!childId || !measuredAt) {
|
||||||
|
return NextResponse.json({ error: "Missing required fields" }, { status: 400 });
|
||||||
|
}
|
||||||
|
|
||||||
|
await sql.unsafe(
|
||||||
|
`INSERT INTO growth (child_id, measured_at, weight_kg, height_cm, head_circumference_cm, notes)
|
||||||
|
VALUES ($1, $2, $3, $4, $5, $6)`,
|
||||||
|
[childId, new Date(measuredAt), weightKg || null, heightCm || null, headCircumferenceCm || null, notes || null]
|
||||||
|
);
|
||||||
|
|
||||||
|
return NextResponse.json({ success: true });
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
return NextResponse.json({ error: String(error) }, { status: 500 });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function GET(request: Request) {
|
||||||
|
const { searchParams } = new URL(request.url);
|
||||||
|
const childId = searchParams.get("childId");
|
||||||
|
|
||||||
|
if (!childId) {
|
||||||
|
return NextResponse.json({ error: "childId required" }, { status: 400 });
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const growth = await sql.unsafe(
|
||||||
|
`SELECT * FROM growth WHERE child_id = $1 ORDER BY measured_at DESC`,
|
||||||
|
[childId]
|
||||||
|
);
|
||||||
|
|
||||||
|
return NextResponse.json({ growth });
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
return NextResponse.json({ error: String(error) }, { status: 500 });
|
||||||
|
}
|
||||||
|
}
|
||||||
89
src/app/api/logs/route.ts
Normal file
89
src/app/api/logs/route.ts
Normal file
|
|
@ -0,0 +1,89 @@
|
||||||
|
import { NextResponse } from "next/server";
|
||||||
|
import { sql } from "@/db";
|
||||||
|
|
||||||
|
interface LogEntry {
|
||||||
|
type: "feed" | "diaper" | "sleep";
|
||||||
|
childId: string;
|
||||||
|
subType: string;
|
||||||
|
amountMl?: number;
|
||||||
|
notes?: string;
|
||||||
|
startedAt?: string;
|
||||||
|
endedAt?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function POST(request: Request) {
|
||||||
|
try {
|
||||||
|
const body: LogEntry = await request.json();
|
||||||
|
const { type, childId, subType, amountMl, notes, startedAt, endedAt } = body;
|
||||||
|
|
||||||
|
if (!type || !childId || !subType) {
|
||||||
|
return NextResponse.json({ error: "Missing required fields" }, { status: 400 });
|
||||||
|
}
|
||||||
|
|
||||||
|
const now = new Date();
|
||||||
|
|
||||||
|
if (type === "feed") {
|
||||||
|
await sql.unsafe(
|
||||||
|
`INSERT INTO feeds (child_id, type, method, amount_ml, notes, logged_at) VALUES ($1, $2, $3, $4, $5, $6)`,
|
||||||
|
[childId, subType, subType.includes("breast") ? subType : "bottle", amountMl || null, notes || null, now]
|
||||||
|
);
|
||||||
|
} else if (type === "diaper") {
|
||||||
|
await sql.unsafe(
|
||||||
|
`INSERT INTO diapers_logs (child_id, type, notes, logged_at) VALUES ($1, $2, $3, $4)`,
|
||||||
|
[childId, subType, notes || null, now]
|
||||||
|
);
|
||||||
|
} else if (type === "sleep") {
|
||||||
|
const startTime = startedAt ? new Date(startedAt) : now;
|
||||||
|
const endTime = endedAt ? new Date(endedAt) : null;
|
||||||
|
const durationMinutes = endTime
|
||||||
|
? Math.round((endTime.getTime() - startTime.getTime()) / 60000)
|
||||||
|
: null;
|
||||||
|
|
||||||
|
await sql.unsafe(
|
||||||
|
`INSERT INTO sleeps (child_id, type, started_at, ended_at, duration_minutes, notes, logged_at) VALUES ($1, $2, $3, $4, $5, $6, $7)`,
|
||||||
|
[childId, subType, startTime, endTime, durationMinutes, notes || null, now]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NextResponse.json({ success: true });
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
return NextResponse.json({ error: String(error) }, { status: 500 });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function GET(request: Request) {
|
||||||
|
const { searchParams } = new URL(request.url);
|
||||||
|
const childId = searchParams.get("childId");
|
||||||
|
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 });
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
let results: any[] = [];
|
||||||
|
if (type === "feed") {
|
||||||
|
results = await sql.unsafe(
|
||||||
|
`SELECT * FROM feeds WHERE child_id = $1 ORDER BY logged_at DESC LIMIT $2`,
|
||||||
|
[childId, limit]
|
||||||
|
);
|
||||||
|
} else if (type === "diaper") {
|
||||||
|
results = await sql.unsafe(
|
||||||
|
`SELECT * FROM diapers_logs WHERE child_id = $1 ORDER BY logged_at DESC LIMIT $2`,
|
||||||
|
[childId, limit]
|
||||||
|
);
|
||||||
|
} else if (type === "sleep") {
|
||||||
|
results = await sql.unsafe(
|
||||||
|
`SELECT * FROM sleeps WHERE child_id = $1 ORDER BY logged_at DESC LIMIT $2`,
|
||||||
|
[childId, limit]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NextResponse.json({ entries: results || [] });
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
return NextResponse.json({ error: String(error) }, { status: 500 });
|
||||||
|
}
|
||||||
|
}
|
||||||
56
src/app/api/vaccinations/route.ts
Normal file
56
src/app/api/vaccinations/route.ts
Normal file
|
|
@ -0,0 +1,56 @@
|
||||||
|
import { NextResponse } from "next/server";
|
||||||
|
import { sql } from "@/db";
|
||||||
|
|
||||||
|
interface VaccinationEntry {
|
||||||
|
childId: string;
|
||||||
|
vaccineName: string;
|
||||||
|
scheduledDate: string;
|
||||||
|
givenDate?: string;
|
||||||
|
status?: "pending" | "given" | "skipped" | "delayed";
|
||||||
|
provider?: string;
|
||||||
|
lotNumber?: string;
|
||||||
|
notes?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function POST(request: Request) {
|
||||||
|
try {
|
||||||
|
const body: VaccinationEntry = await request.json();
|
||||||
|
const { childId, vaccineName, scheduledDate, givenDate, status, provider, lotNumber, notes } = body;
|
||||||
|
|
||||||
|
if (!childId || !vaccineName || !scheduledDate) {
|
||||||
|
return NextResponse.json({ error: "Missing required fields" }, { status: 400 });
|
||||||
|
}
|
||||||
|
|
||||||
|
await sql.unsafe(
|
||||||
|
`INSERT INTO vaccinations (child_id, vaccine_name, scheduled_date, given_date, status, provider, lot_number, notes)
|
||||||
|
VALUES ($1, $2, $3, $4, $5, $6, $7, $8)`,
|
||||||
|
[childId, vaccineName, scheduledDate, givenDate || null, status || "pending", provider || null, lotNumber || null, notes || null]
|
||||||
|
);
|
||||||
|
|
||||||
|
return NextResponse.json({ success: true });
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
return NextResponse.json({ error: String(error) }, { status: 500 });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function GET(request: Request) {
|
||||||
|
const { searchParams } = new URL(request.url);
|
||||||
|
const childId = searchParams.get("childId");
|
||||||
|
|
||||||
|
if (!childId) {
|
||||||
|
return NextResponse.json({ error: "childId required" }, { status: 400 });
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const vaccinations = await sql.unsafe(
|
||||||
|
`SELECT * FROM vaccinations WHERE child_id = $1 ORDER BY scheduled_date ASC`,
|
||||||
|
[childId]
|
||||||
|
);
|
||||||
|
|
||||||
|
return NextResponse.json({ vaccinations });
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
return NextResponse.json({ error: String(error) }, { status: 500 });
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Reference in a new issue