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