--- phase: 04-chart-polish-and-bug-fixes plan: 02 type: execute wave: 2 depends_on: - "04-01" files_modified: - frontend/src/pages/DashboardPage.tsx - frontend/src/components/ExpenseBreakdown.tsx - frontend/src/components/AvailableBalance.tsx autonomous: true requirements: - IXTN-04 must_haves: truths: - "Hovering over an ExpenseBreakdown pie slice shows a tooltip with the category name and currency-formatted value" - "Hovering over an AvailableBalance donut slice shows a tooltip with the segment name and currency-formatted value" - "Chart tooltip values use the budget's currency code (not hardcoded EUR)" - "Chart tooltip values use the user's preferred_locale for number formatting" - "AvailableBalance center text also receives the user's locale for formatting" artifacts: - path: "frontend/src/components/ExpenseBreakdown.tsx" provides: "Custom Recharts Tooltip with formatted currency" contains: "formatCurrency" - path: "frontend/src/components/AvailableBalance.tsx" provides: "Custom Recharts Tooltip on donut chart + locale-aware center text" contains: "Tooltip" - path: "frontend/src/pages/DashboardPage.tsx" provides: "Locale threading from useAuth to chart components" contains: "useAuth" key_links: - from: "frontend/src/pages/DashboardPage.tsx" to: "frontend/src/hooks/useAuth.ts" via: "useAuth() hook call to get user.preferred_locale" pattern: "useAuth\\(\\)" - from: "frontend/src/pages/DashboardPage.tsx" to: "frontend/src/components/ExpenseBreakdown.tsx" via: "locale prop passed to ExpenseBreakdown" pattern: "locale=.*userLocale" - from: "frontend/src/pages/DashboardPage.tsx" to: "frontend/src/components/AvailableBalance.tsx" via: "locale prop passed to AvailableBalance" pattern: "locale=.*userLocale" - from: "frontend/src/components/ExpenseBreakdown.tsx" to: "frontend/src/lib/format.ts" via: "formatCurrency called inside Tooltip content renderer" pattern: "formatCurrency.*budget\\.currency.*locale" - from: "frontend/src/components/AvailableBalance.tsx" to: "frontend/src/lib/format.ts" via: "formatCurrency called inside Tooltip content renderer and center text" pattern: "formatCurrency.*budget\\.currency.*locale" --- Wire custom currency-formatted tooltips into both chart components and thread the user's locale preference from `useAuth` through `DashboardPage` to the charts. After this plan, hovering over any chart segment shows a properly formatted currency value. Purpose: IXTN-04 — chart tooltips currently show raw numbers without currency formatting Output: Both charts have styled tooltips, locale flows from user settings to chart display @/home/jean-luc-makiola/.claude/get-shit-done/workflows/execute-plan.md @/home/jean-luc-makiola/.claude/get-shit-done/templates/summary.md @.planning/PROJECT.md @.planning/ROADMAP.md @.planning/phases/04-chart-polish-and-bug-fixes/04-RESEARCH.md @.planning/phases/04-chart-polish-and-bug-fixes/04-01-SUMMARY.md From frontend/src/lib/format.ts (after Plan 01): ```typescript export function formatCurrency(amount: number, currency?: string, locale?: string): string ``` From frontend/src/lib/api.ts: ```typescript export interface User { // ... preferred_locale: string // ... } export interface BudgetDetail { id: string name: string currency: string // ... totals: BudgetTotals items: BudgetItem[] } ``` From frontend/src/hooks/useAuth.ts: ```typescript export function useAuth(): { user: User | null loading: boolean login: (email: string, password: string) => Promise // ... } ``` From frontend/src/components/ExpenseBreakdown.tsx (current): ```typescript interface Props { budget: BudgetDetail } // Needs locale prop added ``` From frontend/src/components/AvailableBalance.tsx (current): ```typescript interface Props { budget: BudgetDetail } // Needs locale prop added, also needs Tooltip import added ``` From frontend/src/lib/palette.ts: ```typescript export type CategoryType = 'income' | 'bill' | 'variable_expense' | 'debt' | 'saving' | 'investment' | 'carryover' export const palette: Record ``` Task 1: Add locale prop and custom Tooltip to both chart components frontend/src/components/ExpenseBreakdown.tsx, frontend/src/components/AvailableBalance.tsx **ExpenseBreakdown.tsx:** 1. Add `locale?: string` to the `Props` interface 2. Import `formatCurrency` from `@/lib/format` 3. Replace bare `` with a custom `content` renderer: ```tsx { if (!active || !payload?.length) return null const item = payload[0] return (

{item.name}

{formatCurrency(Number(item.value), budget.currency, locale)}

) }} /> ``` 4. Destructure `locale = 'en'` from props with default **AvailableBalance.tsx:** 1. Add `locale?: string` to the `Props` interface 2. Import `Tooltip` from `recharts` (add to existing import) 3. Add `` with identical custom `content` renderer pattern inside the `` after the `` element 4. Update the center text `formatCurrency(available, budget.currency)` call to include locale: `formatCurrency(available, budget.currency, locale)` 5. Destructure `locale = 'en'` from props with default **Do NOT** use `ChartContainer` or `ChartTooltipContent` from shadcn — these charts use raw Recharts primitives and the project rule forbids editing shadcn ui source files. **Tooltip styling** must match shadcn design system: `rounded-lg border border-border/50 bg-background px-2.5 py-1.5 text-xs shadow-xl` — this replicates the ChartTooltipContent styling without importing it.
cd /home/jean-luc-makiola/Development/projects/SimpleFinanceDash/frontend && bun vitest run Both chart components accept an optional locale prop, render custom tooltips with formatCurrency, and AvailableBalance center text passes locale to formatCurrency
Task 2: Thread user locale from useAuth through DashboardPage to chart components frontend/src/pages/DashboardPage.tsx 1. Add `useAuth` import: `import { useAuth } from '@/hooks/useAuth'` 2. Inside `DashboardPage` function body, call: `const { user } = useAuth()` 3. Derive locale with defensive fallback: `const userLocale = user?.preferred_locale || 'en'` 4. Pass `locale={userLocale}` prop to both chart component instances: - `` - `` 5. Do NOT pass locale to other components (BillsTracker, VariableExpenses, DebtTracker, FinancialOverview) — those components use formatCurrency with the new 'en' default which is correct. A full locale-threading pass across all table components is out of scope for this phase. The `useAuth()` hook is idempotent — it reads from the same React state already initialized by `App.tsx`, so there is no double-fetch concern. cd /home/jean-luc-makiola/Development/projects/SimpleFinanceDash/frontend && bun vitest run DashboardPage calls useAuth(), derives userLocale, and passes it to both ExpenseBreakdown and AvailableBalance as a locale prop
1. `cd frontend && bun vitest run` — full test suite passes 2. `cd frontend && bun run build` — production build succeeds with no TypeScript errors 3. Manual: hover over ExpenseBreakdown pie slices — tooltip shows category name + formatted currency 4. Manual: hover over AvailableBalance donut slices — tooltip shows segment name + formatted currency 5. Manual: AvailableBalance center text formats using user's locale preference - ExpenseBreakdown shows formatted currency tooltip on hover (not raw numbers) - AvailableBalance shows formatted currency tooltip on hover (previously had no tooltip) - AvailableBalance center text uses the user's locale for formatting - DashboardPage reads user.preferred_locale via useAuth and threads it to both chart components - Full test suite and build pass with no errors After completion, create `.planning/phases/04-chart-polish-and-bug-fixes/04-02-SUMMARY.md`