fix(reports): charts rendered one colour — RSC client/server boundary bug #120
No reviewers
Labels
No labels
bug
claude-failed
claude-pr
claude-queue
claude-working
epic
feature
interactive
portal
triaged
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: shad0w/pelagia-portal#120
Loading…
Add table
Reference in a new issue
No description provided.
Delete branch "fix/reports-series-colors"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Fixes the real cause of "Reports charts show one colour" (the earlier #118 was the right idea but couldn't take effect because of this bug).
Symptom
Every line / bar series in the comparison charts rendered in recharts' default colour (
#3182bd), and the detail-page breakdown swatches had no colour.Root cause — a React Server Components boundary bug
SERIES_COLORSwas defined incomponents/reports/charts.tsx, which is a"use client"module. The report pages are server components and imported the palette from it. A plain value imported from a client module into a server component is a client-reference proxy, not the real array — soSERIES_COLORS[i % SERIES_COLORS.length]evaluated toSERIES_COLORS[NaN] → undefined, every<Line stroke={undefined}>fell back to the recharts default.strokeWidth={2}(a literal inside the client chart) still applied — which is why only the colour was wrong. And it passed the jsdom unit tests because those import the array directly, not across the RSC boundary.Fix
Move the palette into a dependency-free shared module
lib/report-colors.ts(no"use client", no server-only imports) so it resolves to the real array in both the server and client graphs.charts.tsxand all four report pages now import it from there. (It can't live inlib/reports.ts— that imports Prismadb, which must not enter the client bundle.)Verification
Confirmed in a real browser against seeded data: the line strokes now cycle the 10-colour palette (
#2563eb, #16a34a, #9333ea, …) instead of a uniform#3182bd.tscclean.🤖 Generated with Claude Code
The comparison charts (and detail-page breakdown swatches) rendered every series in recharts' default colour instead of the per-item palette. Root cause: `SERIES_COLORS` was defined in `components/reports/charts.tsx`, which is a "use client" module. The report **pages are server components** and imported the palette from it. A plain value imported from a client module into a server component is a client-reference proxy, not the real array — so `SERIES_COLORS[i % SERIES_COLORS.length]` was `SERIES_COLORS[NaN]` → undefined, every line got `stroke={undefined}`, and recharts fell back to #3182bd. (The literal `strokeWidth={2}` still applied, which is why only the colour was wrong. It passed jsdom tests because those import the array directly, not across the RSC boundary.) Fix: move the palette to a dependency-free shared module `lib/report-colors.ts` (no "use client", no server-only imports) that resolves to the real array in both server and client graphs. `charts.tsx` and all four report pages import it from there. It can't live in `lib/reports.ts` (that imports Prisma `db`, which must not enter the client bundle). Verified in a real browser: line strokes now cycle the 10-colour palette (#2563eb, #16a34a, …) instead of a uniform #3182bd. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>