import { useEffect, useState } from "react"; import { formatQuantity, meterDef } from "~/lib/meters"; import type { MeterDef } from "~/lib/meters"; type Day = { day: string; meter: string; quantity: number }; function daysOf(period: string): string[] { const [year, month] = period.split("-").map(Number); const count = new Date(Date.UTC(year, month, 0)).getUTCDate(); return Array.from({ length: count }, (_, index) => `${period}-${String(index + 1).padStart(2, "0")}`); } const LABEL_DAYS = new Set([1, 8, 15, 22]); /** * Daily usage of one meter across the whole billing period: one slot per calendar day, so a single day of usage * is a single bar instead of a full-width block. Includes a legend, a y-axis maximum and day labels. */ export function UsageChart({ days, meter, period }: { days: Day[]; meter: string; period: string }) { const def = meterDef(meter); const unit: MeterDef["unit"] = def?.unit ?? "count"; const byDay = new Map(days.filter((day) => day.meter === meter).map((day) => [day.day, day.quantity])); const slots = daysOf(period).map((day) => ({ day, quantity: byDay.get(day) ?? 0 })); const total = slots.reduce((sum, slot) => sum + slot.quantity, 0); const peak = slots.reduce((best, slot) => (slot.quantity > best.quantity ? slot : best), slots[0]); const max = Math.max(peak?.quantity ?? 0, 0); const [today, setToday] = useState("9999-12-31"); useEffect(() => setToday(new Date().toISOString().slice(0, 10)), []); return (
No usage recorded for this meter in {period}.
) : (