diff --git a/CHANGELOG.md b/CHANGELOG.md index 3da3e1d..d4ea0d6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,11 @@ All notable changes to Epicure are documented here. This file is mirrored in-app at `/changelog` (and in the admin dashboard) via `apps/web/lib/changelog.ts` — update both together. +## 0.55.3 — 2026-07-19 19:00 + +### Fixed +- Admin Insights page's actual crash, found from server logs: the page (a server component) was passing plain formatter functions as props into its chart components (client components) — React can't serialize functions across that boundary. Replaced with a plain string prop ("day" vs "month") formatted inside the client component instead. + ## 0.55.2 — 2026-07-19 18:20 ### Fixed diff --git a/apps/web/app/admin/insights/page.tsx b/apps/web/app/admin/insights/page.tsx index b1aaddc..394fb24 100644 --- a/apps/web/app/admin/insights/page.tsx +++ b/apps/web/app/admin/insights/page.tsx @@ -34,11 +34,6 @@ function lastNMonths(n: number): string[] { return out; } -function formatMonth(m: string) { - const [y, mo] = m.split("-"); - return new Date(Number(y), Number(mo) - 1, 1).toLocaleDateString(undefined, { month: "short", year: "2-digit" }); -} - export default async function AdminInsightsPage() { const since = new Date(); since.setDate(since.getDate() - DAYS); @@ -128,7 +123,7 @@ export default async function AdminInsightsPage() { Daily, last {DAYS} days - + @@ -168,7 +163,7 @@ export default async function AdminInsightsPage() { Monthly total across all users, last 6 months - + diff --git a/apps/web/components/admin/charts/time-series-chart.tsx b/apps/web/components/admin/charts/time-series-chart.tsx index 3e99ea2..ccc870e 100644 --- a/apps/web/components/admin/charts/time-series-chart.tsx +++ b/apps/web/components/admin/charts/time-series-chart.tsx @@ -5,22 +5,36 @@ import { cn } from "@/lib/utils"; export type TimeSeriesPoint = { date: string; value: number }; +/** "day" expects "YYYY-MM-DD", "month" expects "YYYY-MM" — kept as a plain + * string enum rather than a formatter function prop, since this chart is + * a "use client" component and functions passed from a server component + * parent aren't serializable across that boundary (React throws: "Functions + * cannot be passed directly to Client Components"). */ +function formatPoint(date: string, kind: "day" | "month"): string { + if (kind === "month") { + const [y, m] = date.split("-"); + return new Date(Number(y), Number(m) - 1, 1).toLocaleDateString(undefined, { month: "short", year: "2-digit" }); + } + return new Date(`${date}T00:00:00Z`).toLocaleDateString(undefined, { month: "short", day: "numeric", timeZone: "UTC" }); +} + /** Single-series area/line chart with a hover crosshair+tooltip and a * table-view fallback — hand-rolled SVG, no charting lib. */ export function TimeSeriesChart({ data, formatValue = (n) => String(n), - formatDate = (d) => d, + dateFormat = "day", height = 200, }: { data: TimeSeriesPoint[]; formatValue?: (n: number) => string; - formatDate?: (d: string) => string; + dateFormat?: "day" | "month"; height?: number; }) { const [hovered, setHovered] = useState(null); const [showTable, setShowTable] = useState(false); const svgRef = useRef(null); + const formatDate = (d: string) => formatPoint(d, dateFormat); const width = 600; const paddingBottom = 24; diff --git a/apps/web/lib/changelog.ts b/apps/web/lib/changelog.ts index e389612..fe941dd 100644 --- a/apps/web/lib/changelog.ts +++ b/apps/web/lib/changelog.ts @@ -1,5 +1,5 @@ // Mirrors CHANGELOG.md at the repo root — update both together. -export const APP_VERSION = "0.55.2"; +export const APP_VERSION = "0.55.3"; export type ChangelogEntry = { version: string; @@ -11,6 +11,13 @@ export type ChangelogEntry = { }; export const CHANGELOG: ChangelogEntry[] = [ + { + version: "0.55.3", + date: "2026-07-19 19:00", + fixed: [ + "Admin Insights page's actual crash, found from server logs: the page (a server component) was passing plain formatter functions as props into its chart components (client components) — React can't serialize functions across that boundary. Replaced with a plain string prop (\"day\" vs \"month\") formatted inside the client component instead.", + ], + }, { version: "0.55.2", date: "2026-07-19 18:20", diff --git a/apps/web/package.json b/apps/web/package.json index f085295..b563544 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -1,6 +1,6 @@ { "name": "@epicure/web", - "version": "0.55.2", + "version": "0.55.3", "private": true, "scripts": { "dev": "next dev", diff --git a/package.json b/package.json index fbe58df..9147aa6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "epicure", - "version": "0.55.2", + "version": "0.55.3", "private": true, "scripts": { "dev": "pnpm --filter web dev",