import { Suspense } from "react"; import { ReportsPageClient } from "@/components/reports/ReportsPageClient"; import { aggregateEvents, aggregateReport, parseEventDateParam, parseEventGroupDimension, parseEventSplitDimension, parseEventType, parseGroupDimension, parseIsoDateParam, parseMeasure, parseMode, parseSplitDimension, sumValues, totalForRows, } from "@/lib/reports"; import { loadEventHistory, loadOrgLookups, loadSnapshotEmployees } from "@/lib/reports-data"; import { createClient } from "@/lib/supabase/server"; type SearchParams = { mode?: string; measure?: string; group?: string; split?: string; division?: string; location?: string; status?: string; employment?: string; asOf?: string; eventType?: string; from?: string; to?: string; }; export default async function ReportsPage({ searchParams }: { searchParams: Promise }) { const params = await searchParams; const supabase = await createClient(); const mode = parseMode(params.mode); // Both modes are parsed up front so the data load can start before // anything is awaited. They group by different dimension sets, so the // parsed values stay separate rather than being widened into one type. const asOf = parseIsoDateParam(params.asOf); const eventGroup = parseEventGroupDimension(params.group); const eventSplit = parseEventSplitDimension(params.split); const eventType = parseEventType(params.eventType); const from = parseEventDateParam(params.from); const to = parseEventDateParam(params.to); const measure = parseMeasure(params.measure); const group = parseGroupDimension(params.group); const split = parseSplitDimension(params.split); // The report data depends on neither the org lookups nor on who is signed // in, so all three go out together. Against a hosted database a round trip // costs about as much as the query itself, which made this page's three // sequential waves its dominant cost. const [{ lookups, divisions, locations }, { data: userRes }, events, employees] = await Promise.all([ loadOrgLookups(supabase), supabase.auth.getUser(), mode === "events" ? loadEventHistory(supabase, { eventType: eventType ?? undefined, division: params.division, location: params.location, from, to, }) : Promise.resolve([]), mode === "snapshot" ? loadSnapshotEmployees(supabase, { division: params.division, location: params.location, status: params.status, employment: params.employment, asOf, }) : Promise.resolve([]), ]); const user = userRes.user; // Still a wave of its own: it needs the user id the call above resolves. const { data: savedReports } = user ? await supabase.from("saved_reports").select("id, name, config").eq("created_by", user.id).order("created_at", { ascending: false }) : { data: [] }; if (mode === "events") { const rows = aggregateEvents(events, eventGroup, eventSplit, lookups); return ( ); } const rows = aggregateReport(employees, measure, group, split, lookups, asOf); return ( ); }