docs: complete project research
This commit is contained in:
@@ -1,234 +1,277 @@
|
||||
# Stack Research
|
||||
|
||||
**Domain:** Personal finance dashboard UI overhaul — React SPA
|
||||
**Researched:** 2026-03-16
|
||||
**Domain:** Personal finance dashboard — v2.0 wizard setup, auto-budget creation, sharp pastel design system
|
||||
**Researched:** 2026-04-02
|
||||
**Confidence:** HIGH
|
||||
|
||||
---
|
||||
|
||||
## Context: What Already Exists
|
||||
## Context: What Already Exists (Do Not Re-Research)
|
||||
|
||||
This is a subsequent-milestone research document. The stack is **locked**. The project uses:
|
||||
Actual installed versions from `package.json` (not the prior research document, which had aspirational versions):
|
||||
|
||||
| Package | Installed Version | Status |
|
||||
|---------|------------------|--------|
|
||||
| React | 19.2.4 | Locked |
|
||||
| Vite | 8.0.0 | Locked |
|
||||
| Package | Actual Installed Version | Notes |
|
||||
|---------|-------------------------|-------|
|
||||
| React | ^19.2.4 | Locked |
|
||||
| Vite | ^8.0.0 | Locked |
|
||||
| TypeScript | ~5.9.3 | Locked |
|
||||
| Tailwind CSS | 4.2.1 | Locked |
|
||||
| Recharts | **3.8.0** | Locked — already on latest |
|
||||
| Radix UI (via `radix-ui`) | 1.4.3 | Locked |
|
||||
| Lucide React | 0.577.0 | Locked |
|
||||
| next-themes | 0.4.6 | Locked |
|
||||
| TanStack Query | 5.90.21 | Locked |
|
||||
| Tailwind CSS | ^4.2.1 | Locked |
|
||||
| Recharts | **2.15.4** | Locked — NOT 3.x (prior research was wrong) |
|
||||
| radix-ui | ^1.4.3 | Unified post-June 2025 package |
|
||||
| lucide-react | ^0.577.0 | Locked |
|
||||
| next-themes | ^0.4.6 | Locked |
|
||||
| TanStack Query | ^5.90.21 | Locked |
|
||||
| react-router-dom | ^7.13.1 | Locked |
|
||||
| sonner | ^2.0.7 | Locked |
|
||||
| @supabase/supabase-js | ^2.99.1 | Backend is Supabase, not custom Go |
|
||||
| i18next + react-i18next | ^25.8.18 / ^16.5.8 | Locked |
|
||||
|
||||
The `index.css` already defines a complete OKLCH `@theme inline` color system with category-specific colors (`--color-income`, `--color-bill`, etc.) and chart colors (`--color-chart-1` through `--color-chart-5`). The project uses the `radix-ui` unified package (post-June 2025 migration).
|
||||
**Backend reality check:** Despite the milestone context referencing "Go 1.25 backend", the project is a Supabase-backed React SPA. There is no Go source code. All backend work happens via Supabase migrations (SQL) and the `@supabase/supabase-js` client. This is authoritative — verified from `package.json` and `supabase/migrations/`.
|
||||
|
||||
**No new frameworks or backend dependencies.** This research covers only what to add or lean into for the UI overhaul.
|
||||
**Form handling reality check:** Current forms (login, register, template items) use vanilla `useState` + `React.FormEvent`. No react-hook-form or zod are installed.
|
||||
|
||||
**Design token reality check:** `--radius: 0.625rem` is applied globally and is the source of the "clunky rounded" look. Sharp redesign requires overriding this token.
|
||||
|
||||
---
|
||||
|
||||
## Recommended Stack: Additions and Patterns
|
||||
## New Dependencies Required
|
||||
|
||||
### shadcn/ui Components to Add
|
||||
### 1. react-hook-form + zod — Wizard Form Validation
|
||||
|
||||
The project has shadcn/ui components already (card, button, input, etc.) but is missing two critical primitives for the redesign.
|
||||
The wizard-style template setup requires multi-step form state that persists across steps, per-step validation before advancing, and type-safe schema enforcement. Vanilla `useState` breaks down across 4+ wizard steps with interdependent validation.
|
||||
|
||||
| Component | Install Command | Purpose | Why |
|
||||
|-----------|----------------|---------|-----|
|
||||
| `chart` | `npx shadcn@latest add chart` | `ChartContainer` + `ChartTooltipContent` wrappers | Provides theme-aware chart wrappers that read from CSS variables. Eliminates boilerplate for consistent chart theming across all chart types. Copy-paste into `src/components/ui/chart.tsx`. |
|
||||
| `accordion` | `npx shadcn@latest add accordion` | Collapsible category sections on dashboard | Built on Radix UI Accordion primitive. WAI-ARIA compliant, keyboard navigable, supports `type="multiple"` to keep multiple groups open. |
|
||||
| `collapsible` | `npx shadcn@latest add collapsible` | Single collapsible toggle pattern | Alternative to Accordion when only one independent section needs to expand/collapse (simpler than full Accordion). |
|
||||
**Use react-hook-form 7.72.0 + zod 4.3.6 + @hookform/resolvers 5.2.2.**
|
||||
|
||||
**CRITICAL: Recharts v3 + shadcn chart.tsx compatibility.** The project is on Recharts 3.8.0. The official shadcn/ui chart PR (#8486) for Recharts v3 support is not yet merged (as of March 2026). After running `npx shadcn@latest add chart`, the generated `chart.tsx` may need manual fixes:
|
||||
| Package | Version | Purpose | Why |
|
||||
|---------|---------|---------|-----|
|
||||
| `react-hook-form` | 7.72.0 | Multi-step form state, per-field validation | Industry standard for React forms; tiny bundle (9.3kb); uncontrolled inputs avoid re-render storms across wizard steps |
|
||||
| `zod` | 4.3.6 | Schema validation with TypeScript inference | Zod 4 is stable (released 2025, latest 4.3.6); 14x faster than v3; subpath exports `zod/v4` enable coexistence if needed |
|
||||
| `@hookform/resolvers` | 5.2.2 | Bridge between zod schemas and react-hook-form | v5.2.2 supports both Zod v3 and v4 with automatic runtime detection |
|
||||
|
||||
1. The `ChartContainer` may log `"width(-1) and height(-1) of chart should be greater than 0"` warnings — fix by adding `initialDimension={{ width: 320, height: 200 }}` to the `ResponsiveContainer` inside `chart.tsx`.
|
||||
2. If TypeScript errors appear on `TooltipProps`, update the import to use `TooltipProps` from `recharts` directly.
|
||||
3. Community-verified workaround exists in shadcn-ui/ui issue #9892.
|
||||
**Zod v4 import note:** Use `import { z } from "zod"` (root export maps to v4) unless you need v3 compatibility, then use `import { z } from "zod/v4"` explicitly. The `zodResolver` from `@hookform/resolvers/zod` handles both transparently.
|
||||
|
||||
**Confidence: HIGH** — PR #8486 and issue #9892 are the authoritative sources; the fix is a small patch to one file.
|
||||
**Known issue:** @hookform/resolvers 5.2.1+ has reported edge-case type errors with specific Zod v4 configurations (GitHub issue #813). Use `5.2.2` (published ~February 2026) which addresses this. If type errors appear, verify the import path is `@hookform/resolvers/zod` not a sub-subpath.
|
||||
|
||||
**Confidence: HIGH** — Versions verified via npm search results (react-hook-form 7.72.0 published April 2026; zod 4.3.6; @hookform/resolvers 5.2.2). Integration pattern is the standard shadcn/ui documented approach.
|
||||
|
||||
---
|
||||
|
||||
### Core Charting Patterns (Recharts 3.8.0)
|
||||
### 2. Wizard/Stepper UI — Custom Component (No External Library)
|
||||
|
||||
No new charting libraries are needed. Recharts 3.8.0 is the current stable release and supports all required chart types natively. Three chart types are needed for the dashboard redesign:
|
||||
shadcn/ui does not include a stepper or wizard component in its official core library. The discussion thread #1422 requesting it has been open for years. However, shadcn/ui's blocks library now includes stepper patterns (as of March 2026 update) built purely with shadcn/ui `Button`, `Badge`, and Tailwind — **no external npm package needed**.
|
||||
|
||||
**1. Donut Chart (expense category breakdown)**
|
||||
**Recommendation: Build a custom `<WizardStepper>` component from shadcn/ui primitives.**
|
||||
|
||||
This approach:
|
||||
- Requires zero new npm packages
|
||||
- Matches the existing design system exactly (token-driven styling)
|
||||
- Is 50–80 lines of TypeScript — not complex
|
||||
- Avoids third-party stepper library churn (none are dominant; most are abandoned within 1-2 years)
|
||||
|
||||
Pattern:
|
||||
|
||||
```tsx
|
||||
// Already in use. Enrich by:
|
||||
// - Increasing innerRadius to ~60, outerRadius to ~100 for visual weight
|
||||
// - Adding paddingAngle={3} for visible segment separation
|
||||
// - Using stroke="none" (replaces removed blendStroke in v3)
|
||||
// - Rendering a center label via custom activeShape or absolute-positioned div
|
||||
<PieChart>
|
||||
<Pie
|
||||
data={pieData}
|
||||
dataKey="value"
|
||||
cx="50%"
|
||||
cy="50%"
|
||||
innerRadius={60}
|
||||
outerRadius={100}
|
||||
paddingAngle={3}
|
||||
stroke="none"
|
||||
>
|
||||
{pieData.map((entry) => (
|
||||
<Cell key={entry.type} fill={categoryColors[entry.type]} />
|
||||
))}
|
||||
</Pie>
|
||||
<Tooltip content={<ChartTooltipContent />} />
|
||||
</PieChart>
|
||||
```
|
||||
// src/components/shared/WizardStepper.tsx
|
||||
// Steps indicator: array of step objects → renders numbered circles + connecting lines
|
||||
// Active step gets primary color; completed steps get checkmark icon
|
||||
// Controlled via `currentStep: number` prop passed down from wizard page
|
||||
|
||||
Note: In Recharts v3, `Cell` is deprecated in favor of the `shape` prop and `activeShape`/`inactiveShape` are deprecated in favor of `shape`. Existing `Cell` usage still works; migration is not required for this milestone.
|
||||
interface Step {
|
||||
id: string
|
||||
label: string
|
||||
}
|
||||
|
||||
**2. Vertical Bar Chart (income budget vs actual)**
|
||||
|
||||
```tsx
|
||||
<BarChart data={incomeData}>
|
||||
<CartesianGrid vertical={false} strokeDasharray="3 3" />
|
||||
<XAxis dataKey="name" />
|
||||
<YAxis />
|
||||
<Bar dataKey="budgeted" radius={[4, 4, 0, 0]} fill="var(--color-muted)" />
|
||||
<Bar dataKey="actual" radius={[4, 4, 0, 0]} fill="var(--color-income)" />
|
||||
<Tooltip content={<ChartTooltipContent />} />
|
||||
</BarChart>
|
||||
```
|
||||
|
||||
**3. Horizontal Bar Chart (spend by category type)**
|
||||
|
||||
```tsx
|
||||
// layout="vertical" turns BarChart into a horizontal bar chart
|
||||
<BarChart data={categoryData} layout="vertical">
|
||||
<XAxis type="number" hide />
|
||||
<YAxis type="category" dataKey="name" width={130} />
|
||||
<Bar dataKey="budgeted" radius={[0, 4, 4, 0]} fill="var(--color-muted)" />
|
||||
<Bar dataKey="actual" radius={[0, 4, 4, 0]} fill="var(--color-primary)" />
|
||||
<Tooltip content={<ChartTooltipContent />} />
|
||||
</BarChart>
|
||||
```
|
||||
|
||||
**Confidence: HIGH** — All three patterns verified against Recharts official examples and docs.
|
||||
|
||||
---
|
||||
|
||||
### Tailwind CSS 4 Color System Patterns
|
||||
|
||||
The existing `index.css` is already correctly structured with `@theme inline`. The overhaul needs to extend it with:
|
||||
|
||||
**1. Richer category colors (more vibrant for charts)**
|
||||
|
||||
The current category colors are defined but conservative. For the rich visual style target, increase chroma:
|
||||
|
||||
```css
|
||||
/* Recommended: bump chroma from ~0.14 to ~0.18+ for visual richness */
|
||||
--color-income: oklch(0.68 0.19 145); /* vivid green */
|
||||
--color-bill: oklch(0.65 0.19 25); /* vivid orange-red */
|
||||
--color-variable-expense: oklch(0.70 0.18 55); /* vivid amber */
|
||||
--color-debt: oklch(0.62 0.20 355); /* vivid rose */
|
||||
--color-saving: oklch(0.68 0.18 220); /* vivid blue */
|
||||
--color-investment: oklch(0.65 0.18 285); /* vivid purple */
|
||||
```
|
||||
|
||||
**2. Semantic status tokens for budget comparison**
|
||||
|
||||
```css
|
||||
--color-over-budget: oklch(0.62 0.20 25); /* red-orange for overspend */
|
||||
--color-on-budget: oklch(0.68 0.19 145); /* green for on-track */
|
||||
--color-budget-bar-bg: oklch(0.92 0.01 260); /* neutral track for progress bars */
|
||||
```
|
||||
|
||||
**3. Dark theme token set**
|
||||
|
||||
The current CSS has no dark mode overrides. With `next-themes` v0.4.6 already installed, dark mode works by toggling `.dark` on `<html>`. Add a dark block:
|
||||
|
||||
```css
|
||||
.dark {
|
||||
@theme inline {
|
||||
--color-background: oklch(0.13 0.02 260);
|
||||
--color-foreground: oklch(0.95 0.005 260);
|
||||
--color-card: oklch(0.18 0.02 260);
|
||||
/* ...etc — mirror the light tokens with dark values */
|
||||
}
|
||||
interface WizardStepperProps {
|
||||
steps: Step[]
|
||||
currentStep: number // 0-based index
|
||||
}
|
||||
```
|
||||
|
||||
This is optional for the current milestone (desktop-first, dark mode not listed as a goal), but the token structure is already set up for it.
|
||||
State management: hold `currentStep` in the wizard page component with `useState`. Each step's validation runs via `react-hook-form`'s `trigger(fieldNames)` before `setCurrentStep(n + 1)`.
|
||||
|
||||
**Confidence: HIGH** — Tailwind CSS 4 `@theme inline` pattern verified against official Tailwind v4 docs.
|
||||
**Confidence: HIGH** — shadcn/ui blocks page confirms stepper patterns are available as copy-paste blocks with no external dependencies (verified March 2026). Zero external library is the correct choice.
|
||||
|
||||
---
|
||||
|
||||
### Typography Patterns
|
||||
### 3. shadcn/ui Components to Add
|
||||
|
||||
Already uses Inter via `--font-sans`. No new font installations needed. Apply these patterns consistently:
|
||||
The wizard needs two additional shadcn/ui components not currently installed:
|
||||
|
||||
| Pattern | CSS / Tailwind | Where to Use |
|
||||
|---------|---------------|--------------|
|
||||
| Tabular numbers | `tabular-nums` (already used in DashboardPage) | All currency amounts, percentages |
|
||||
| Monospace amounts | `font-mono` | Dense data tables where column alignment matters |
|
||||
| Numeric font features | `font-feature-settings: "tnum" 1` | When `tabular-nums` alone is insufficient |
|
||||
| Large metric emphasis | `text-3xl font-bold tracking-tight` | Summary card primary values |
|
||||
| Muted labels | `text-sm text-muted-foreground` | Section headers, stat labels |
|
||||
| Component | Install Command | Purpose | Notes |
|
||||
|-----------|----------------|---------|-------|
|
||||
| `progress` | `npx shadcn@latest add progress` | Optional step progress bar within wizard header | Built on Radix UI Progress; already themed via CSS vars. Use if linear progress indicator preferred over dot/circle steps. |
|
||||
| `checkbox` | `npx shadcn@latest add checkbox` | Select/deselect template items in wizard step | Built on Radix UI Checkbox; WAI-ARIA compliant. |
|
||||
| `scroll-area` | `npx shadcn@latest add scroll-area` | Scrollable category library panel in budget view | Built on Radix UI ScrollArea; consistent cross-browser scrollbar styling. |
|
||||
|
||||
The codebase already uses `tabular-nums` on currency values — this is correct and should be applied everywhere financial numbers appear.
|
||||
The existing `dialog.tsx`, `input.tsx`, `button.tsx`, `select.tsx`, `badge.tsx`, and `skeleton.tsx` are already present and sufficient for the wizard steps and inline library picker.
|
||||
|
||||
**Confidence: HIGH** — Pattern matches current codebase and Shopify Polaris / Datawrapper typography standards.
|
||||
**Confidence: HIGH** — Verified against current component list in `src/components/ui/`.
|
||||
|
||||
---
|
||||
|
||||
### Layout Patterns
|
||||
## Design Token Changes — Sharp Minimal Pastel System
|
||||
|
||||
**Summary card grid:**
|
||||
No new packages are needed. All changes are CSS variable overrides in `src/index.css`.
|
||||
|
||||
```tsx
|
||||
// 4 cards on desktop, 2x2 on tablet, stacked on mobile
|
||||
<div className="grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4">
|
||||
### Border Radius — The Core Change
|
||||
|
||||
The v1.0 design feels "clunky and rounded" because `--radius: 0.625rem` (10px) is applied everywhere. The v2.0 "sharp minimal" direction requires:
|
||||
|
||||
```css
|
||||
/* Sharp edges — change ONE token, affects all shadcn/ui components */
|
||||
--radius: 0.125rem; /* 2px — sharp but not perfectly square */
|
||||
/* Alternative: 0rem for fully square (more aggressive) */
|
||||
```
|
||||
|
||||
**Chart row:**
|
||||
This single change propagates through every shadcn/ui component because they all use `rounded-[var(--radius)]` or similar. No individual component changes needed.
|
||||
|
||||
```tsx
|
||||
// Charts side-by-side on desktop, stacked on mobile
|
||||
<div className="grid grid-cols-1 gap-6 lg:grid-cols-2">
|
||||
### Pastel Color Recalibration
|
||||
|
||||
The current category colors use L~0.55 (text-weight, too dark for fills and backgrounds). "Clear pastels" in a sharp minimal design system need a two-tier system:
|
||||
|
||||
- **Surface pastel** (card backgrounds, highlights): L~0.93-0.96, C~0.04-0.06
|
||||
- **Accent pastel** (borders, tags, icons): L~0.75-0.80, C~0.10-0.12
|
||||
- **Text** (labels, amounts): L~0.40-0.50, C~0.15-0.18 (existing values are correct for this)
|
||||
|
||||
```css
|
||||
/* New: pastel surface colors for wizard step indicators, category cards */
|
||||
--color-income-surface: oklch(0.95 0.04 155);
|
||||
--color-bill-surface: oklch(0.95 0.04 25);
|
||||
--color-variable-expense-surface: oklch(0.95 0.04 50);
|
||||
--color-debt-surface: oklch(0.95 0.05 355);
|
||||
--color-saving-surface: oklch(0.95 0.04 220);
|
||||
--color-investment-surface: oklch(0.95 0.04 285);
|
||||
|
||||
/* New: accent pastel (for badges, step indicators, borders) */
|
||||
--color-income-accent: oklch(0.80 0.10 155);
|
||||
--color-bill-accent: oklch(0.80 0.10 25);
|
||||
--color-variable-expense-accent: oklch(0.80 0.10 50);
|
||||
--color-debt-accent: oklch(0.80 0.11 355);
|
||||
--color-saving-accent: oklch(0.80 0.10 220);
|
||||
--color-investment-accent: oklch(0.80 0.10 285);
|
||||
```
|
||||
|
||||
**Collapsible category section:**
|
||||
The existing text-weight category colors (`--color-income`, etc.) remain unchanged — they're already correct for text/icon usage and pass WCAG 4.5:1.
|
||||
|
||||
```tsx
|
||||
// Using shadcn Accordion — one group per CategoryType
|
||||
<Accordion type="multiple" defaultValue={["income", "bill"]}>
|
||||
<AccordionItem value="income">
|
||||
<AccordionTrigger>
|
||||
{/* Summary row: label + budgeted + actual + delta */}
|
||||
</AccordionTrigger>
|
||||
<AccordionContent>
|
||||
{/* Line item rows */}
|
||||
</AccordionContent>
|
||||
</AccordionItem>
|
||||
</Accordion>
|
||||
### Minimal Layout Tokens
|
||||
|
||||
```css
|
||||
/* Reduce visual weight for card borders — sharp design reads better with subtle borders */
|
||||
--color-border: oklch(0.90 0.008 260); /* slightly lighter than current 0.88 */
|
||||
|
||||
/* Tighter card padding via CSS custom property (used in PageShell / StatCard) */
|
||||
/* No token needed — use Tailwind p-4 consistently instead of p-6 */
|
||||
```
|
||||
|
||||
Use `type="multiple"` so users can expand multiple sections simultaneously. Default expand income and variable_expense as the most-checked categories.
|
||||
|
||||
**Confidence: HIGH** — Standard shadcn/ui pattern, verified against official docs.
|
||||
**Confidence: HIGH** — Based on OKLCH perceptual uniformity properties; the lightness/chroma values follow the Evil Martians OKLCH guide for pastel palette design.
|
||||
|
||||
---
|
||||
|
||||
## What NOT to Use
|
||||
## Backend Changes — Supabase (Auto-Budget Creation + Template Seeding)
|
||||
|
||||
### Auto-Budget Creation
|
||||
|
||||
The feature "auto-create monthly budgets from template on first visit" requires:
|
||||
|
||||
1. **A Supabase RPC function** (PostgreSQL function called via `.rpc()`) to atomically create a budget + copy template items in a single round-trip. Application-layer logic (JavaScript calling multiple inserts) is fragile across network failures.
|
||||
|
||||
```sql
|
||||
-- New migration: create_budget_from_template(user_id, month_date)
|
||||
-- Returns the new budget_id
|
||||
-- Idempotent: if budget for that month already exists, returns existing id
|
||||
create or replace function create_budget_from_template(
|
||||
p_user_id uuid,
|
||||
p_month date -- first day of the target month
|
||||
)
|
||||
returns uuid
|
||||
language plpgsql
|
||||
security definer -- needed to bypass RLS for the INSERT
|
||||
as $$
|
||||
declare
|
||||
v_template_id uuid;
|
||||
v_budget_id uuid;
|
||||
begin
|
||||
-- Get user's template
|
||||
select id into v_template_id from templates where user_id = p_user_id limit 1;
|
||||
if v_template_id is null then return null; end if;
|
||||
|
||||
-- Idempotency: return existing budget for this month
|
||||
select id into v_budget_id
|
||||
from budgets
|
||||
where user_id = p_user_id
|
||||
and start_date = date_trunc('month', p_month)::date
|
||||
limit 1;
|
||||
if v_budget_id is not null then return v_budget_id; end if;
|
||||
|
||||
-- Create new budget
|
||||
insert into budgets (user_id, start_date, end_date, currency)
|
||||
values (
|
||||
p_user_id,
|
||||
date_trunc('month', p_month)::date,
|
||||
(date_trunc('month', p_month) + interval '1 month' - interval '1 day')::date,
|
||||
(select currency from profiles where id = p_user_id limit 1)
|
||||
)
|
||||
returning id into v_budget_id;
|
||||
|
||||
-- Copy template items to budget items
|
||||
insert into budget_items (budget_id, category_id, budgeted_amount, item_tier)
|
||||
select v_budget_id, ti.category_id, ti.budgeted_amount, ti.item_tier
|
||||
from template_items ti
|
||||
where ti.template_id = v_template_id;
|
||||
|
||||
return v_budget_id;
|
||||
end;
|
||||
$$;
|
||||
```
|
||||
|
||||
Frontend call:
|
||||
```typescript
|
||||
const { data: budgetId } = await supabase.rpc('create_budget_from_template', {
|
||||
p_user_id: user.id,
|
||||
p_month: `${year}-${month}-01`
|
||||
})
|
||||
```
|
||||
|
||||
**Why RPC not application layer:** A single RPC is atomic (no partial state if network drops mid-sequence), runs in 1 round-trip instead of 3-4, and the idempotency guard prevents duplicate budgets from double-calls (React StrictMode double-invocation, fast navigation, etc.).
|
||||
|
||||
### Template Seeding (Wizard First-Run)
|
||||
|
||||
The wizard "pre-filled common items" require a static list seeded client-side — no backend change needed. The wizard presents checkboxes for ~15 common items (Rent, Salary, Car Insurance, Groceries, etc.) with pre-populated amounts. On wizard completion, one batch `insert` creates the template + template_items. The existing `templates` and `template_items` tables support this without schema changes.
|
||||
|
||||
**Categories pre-seeding:** Categories (income, bill, variable_expense, etc.) are per-user, not system-wide. The wizard must also insert default categories before template items can reference them. Order: insert default categories → insert template → insert template_items.
|
||||
|
||||
This can also be an RPC (`setup_user_template`) or application-layer batch — the wizard runs once, so network failure risk is acceptable at client-side orchestration.
|
||||
|
||||
### Category Library (Inline Add-from-Library)
|
||||
|
||||
The `quick_add_items` table stores name + icon only — no amount or category_type. For the inline category library in budget view (replacing the QuickAdd page), the library needs category_type to know which budget section to add to.
|
||||
|
||||
**Schema addition needed:**
|
||||
|
||||
```sql
|
||||
-- New migration: add category_type to quick_add_items
|
||||
alter table quick_add_items
|
||||
add column category_type category_type, -- existing enum
|
||||
add column default_amount numeric(12,2) default 0;
|
||||
```
|
||||
|
||||
This enables the library to show items grouped by type and pre-fill amounts when adding to a budget.
|
||||
|
||||
**Confidence: MEDIUM** — RPC pattern is well-established in Supabase. Schema addition is straightforward. The exact RPC SQL above is a starting point and may need adjustment based on profiles table structure (currency field). Flag for verification in planning phase.
|
||||
|
||||
---
|
||||
|
||||
## What NOT to Add
|
||||
|
||||
| Avoid | Why | Use Instead |
|
||||
|-------|-----|-------------|
|
||||
| Nivo | Adds a large bundle, different component API, requires adapting all existing chart code | Recharts 3.8.0 — already installed, sufficient |
|
||||
| ApexCharts / ECharts | New library dependency, no benefit over Recharts for this scope | Recharts 3.8.0 |
|
||||
| react-financial-charts | Designed for candlestick / OHLC trading charts, not budget dashboards | Recharts 3.8.0 |
|
||||
| Recharts 2.x | Project is already on v3.8.0 — never downgrade | Stay on 3.8.0 |
|
||||
| shadcn `npx shadcn@latest add` for chart without reading the output | The generated chart.tsx requires a manual Recharts v3 patch | Run the add command, then apply the `initialDimension` fix to `ChartContainer` |
|
||||
| CSS-in-JS for theming | Tailwind v4 `@theme inline` already handles all theming via CSS variables | Extend `index.css` `@theme inline` block |
|
||||
| Custom progress bar libraries | Raw Tailwind divs with `style={{ width: X% }}` are already used and are sufficient | Keep existing progress bar pattern, improve styling only |
|
||||
| Framer Motion | Adds bundle weight; CSS transitions via `transition-all duration-200` cover needed animations | Tailwind transition utilities |
|
||||
| React Grid Layout | Drag/resize dashboards are out of scope for this milestone | Standard CSS Grid |
|
||||
| External stepper library (react-use-wizard, react-step-wizard, stepperize) | None is dominant; all add bundle weight for what is 50 lines of custom code; APIs change | Custom `<WizardStepper>` using shadcn/ui Button + Badge + Tailwind |
|
||||
| Zod v3 (avoid if installing fresh) | v4 is stable and 14x faster; no reason to use v3 for new code | `zod@4.3.6` |
|
||||
| Framer Motion for wizard step transitions | 28kb gzip; CSS `transition-opacity duration-200` is sufficient for step fade | Tailwind transition utilities |
|
||||
| Recharts upgrade to 3.x in this milestone | 2.15.4 is working; v3 migration guide lists breaking changes that would require updating all existing charts; out of scope | Stay on 2.15.4 for v2.0 milestone; plan upgrade separately |
|
||||
| CSS-in-JS for new design tokens | Tailwind v4 `@theme inline` in `index.css` already handles all theming | Extend `index.css` `@theme inline` block |
|
||||
| Zustand for wizard state | TanStack Query + useState is already the state pattern in this app; wizard state is local and short-lived | `useState` in wizard page component |
|
||||
| Supabase Edge Functions for auto-budget | PostgreSQL function (RPC) runs in the same DB transaction; simpler, no Deno runtime | Supabase RPC (pg function) |
|
||||
|
||||
---
|
||||
|
||||
@@ -236,10 +279,26 @@ Use `type="multiple"` so users can expand multiple sections simultaneously. Defa
|
||||
|
||||
| Recommended | Alternative | When to Use Alternative |
|
||||
|-------------|-------------|-------------------------|
|
||||
| Recharts 3.8.0 (stay) | Nivo | If you needed animated, visually opinionated charts with server-side rendering — not applicable here |
|
||||
| shadcn Accordion | KendoReact PanelBar | If the project used KendoReact's broader component suite — it doesn't |
|
||||
| Tailwind `tabular-nums` | Geist Mono font | Use Geist Mono only if building a dense trading-style table where column alignment is a core feature, not a budget dashboard |
|
||||
| shadcn chart.tsx (copy-paste) | Direct Recharts usage | Acceptable — the project's existing dashboard already uses Recharts directly. shadcn wrappers add theme-aware tooltips and config-based colors but are not mandatory |
|
||||
| Custom WizardStepper | `react-use-wizard` (npm) | If wizard logic were complex (branching paths, async steps with external dependencies) — this wizard is linear with simple validation |
|
||||
| Zod 4 | Valibot | If bundle size were critical (Valibot is ~1kb vs Zod's ~14kb) — not a concern here |
|
||||
| Supabase RPC for auto-budget | Application-layer multi-insert | Acceptable if you tolerate partial failure risk and handle retry logic — RPC is cleaner |
|
||||
| Two-tier OKLCH pastel tokens | Single token set | If the design only needed chart colors — the wizard and library UI need surface pastels that the existing single-tier system doesn't provide |
|
||||
|
||||
---
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
# Wizard form validation (new packages)
|
||||
bun add react-hook-form@7.72.0 zod@4.3.6 @hookform/resolvers@5.2.2
|
||||
|
||||
# New shadcn/ui components
|
||||
npx shadcn@latest add progress
|
||||
npx shadcn@latest add checkbox
|
||||
npx shadcn@latest add scroll-area
|
||||
```
|
||||
|
||||
No other npm/bun installs needed. All other new functionality (wizard stepper UI, design token changes, Supabase RPC, schema migration) is implemented via local code and SQL.
|
||||
|
||||
---
|
||||
|
||||
@@ -247,43 +306,59 @@ Use `type="multiple"` so users can expand multiple sections simultaneously. Defa
|
||||
|
||||
| Package | Version | Compatible With | Notes |
|
||||
|---------|---------|-----------------|-------|
|
||||
| Recharts | 3.8.0 | React 19 | Requires `react-is` peer dependency override for React 19 |
|
||||
| shadcn chart.tsx | CLI generated | Recharts 3.8.0 | Apply `initialDimension` fix to `ChartContainer` after generation |
|
||||
| Tailwind CSS | 4.2.1 | `@theme inline` | Use `@theme inline` (not bare `@theme`) when referencing other CSS vars |
|
||||
| next-themes | 0.4.6 | React 19 | Compatible; dark mode toggled via `.dark` class on `<html>` |
|
||||
| radix-ui | 1.4.3 | Post-June 2025 migration | shadcn CLI add commands now generate imports from `radix-ui`, not `@radix-ui/react-*` |
|
||||
| react-hook-form | 7.72.0 | React 19 | Fully compatible; hooks-based, no legacy API |
|
||||
| zod | 4.3.6 | TypeScript ~5.9.3 | Requires TypeScript 4.5+; project is on 5.9.3 — fine |
|
||||
| @hookform/resolvers | 5.2.2 | react-hook-form 7.x + zod 4.x | Automatic v3/v4 Zod detection |
|
||||
| Recharts | 2.15.4 | React 19 | Stays on v2; DO NOT upgrade in this milestone |
|
||||
| Tailwind CSS | 4.2.1 | `@theme inline` | Sharp radius via `--radius: 0.125rem` in `@theme inline` block |
|
||||
| radix-ui | 1.4.3 | shadcn new-york style | New shadcn add commands generate `radix-ui` imports (unified package), not `@radix-ui/*` |
|
||||
|
||||
---
|
||||
|
||||
## Installation
|
||||
## Integration Points
|
||||
|
||||
```bash
|
||||
# Add shadcn chart primitives (then apply Recharts v3 fix to chart.tsx)
|
||||
npx shadcn@latest add chart
|
||||
### Wizard → Template → Budget Flow
|
||||
|
||||
# Add Accordion for collapsible dashboard sections
|
||||
npx shadcn@latest add accordion
|
||||
```
|
||||
WizardPage (new route: /setup)
|
||||
└─ react-hook-form (FormProvider wrapping all steps)
|
||||
└─ WizardStepper component (step indicator)
|
||||
└─ Step 1: Pick categories (checkbox + default amounts)
|
||||
└─ Step 2: Adjust fixed items (input fields, pre-filled)
|
||||
└─ Step 3: Adjust variable items
|
||||
└─ Step 4: Review + confirm
|
||||
└─ onSubmit → batch insert categories + template + template_items
|
||||
└─ redirect to /dashboard
|
||||
|
||||
# Add Collapsible if single-section toggles are needed
|
||||
npx shadcn@latest add collapsible
|
||||
DashboardPage (existing)
|
||||
└─ on mount: check if budget exists for current month
|
||||
└─ if not: call supabase.rpc('create_budget_from_template', { month })
|
||||
└─ render budget data (existing pattern, improved display)
|
||||
|
||||
BudgetDetailPage (existing, enhanced)
|
||||
└─ inline category library panel (uses scroll-area + checkbox/button)
|
||||
└─ add one-off items directly from library
|
||||
```
|
||||
|
||||
No npm/bun package installs needed — Recharts 3.8.0 is already installed and sufficient.
|
||||
### Design Token Change Impact
|
||||
|
||||
The `--radius` change in `index.css` requires no component-level changes — all shadcn/ui components use the token automatically. The new surface/accent OKLCH tokens need to be applied explicitly in new components (wizard steps, category library cards); existing components are unaffected.
|
||||
|
||||
---
|
||||
|
||||
## Sources
|
||||
|
||||
- [Recharts GitHub Releases](https://github.com/recharts/recharts/releases) — version 3.8.0 confirmed latest stable (March 2025)
|
||||
- [Recharts 3.0 Migration Guide](https://github.com/recharts/recharts/wiki/3.0-migration-guide) — breaking changes from v2 to v3
|
||||
- [shadcn/ui Chart Docs](https://ui.shadcn.com/docs/components/chart) — ChartContainer, ChartConfig, ChartTooltip patterns
|
||||
- [shadcn-ui/ui PR #8486](https://github.com/shadcn-ui/ui/pull/8486) — Recharts v3 chart.tsx upgrade (open as of March 2026)
|
||||
- [shadcn-ui/ui Issue #9892](https://github.com/shadcn-ui/ui/issues/9892) — Community-verified Recharts v3 chart.tsx fix
|
||||
- [shadcn/ui Accordion Docs](https://ui.shadcn.com/docs/components/radix/accordion) — component API verified
|
||||
- [Tailwind CSS v4 Theme Docs](https://tailwindcss.com/docs/theme) — `@theme inline`, CSS variables, OKLCH palette
|
||||
- [npm recharts](https://www.npmjs.com/package/recharts) — 3.8.0 current, 7M weekly downloads, healthy maintenance
|
||||
- npm search results (April 2026) — react-hook-form 7.72.0, zod 4.3.6, @hookform/resolvers 5.2.2
|
||||
- [zod.dev/v4](https://zod.dev/v4) — Zod 4 stable release notes, versioning strategy
|
||||
- [shadcn/ui blocks page](https://ui.shadcn.com/blocks) — Confirmed no native stepper component; patterns available as copy-paste blocks (no npm dep)
|
||||
- [shadcn-ui/ui Discussion #1422](https://github.com/shadcn-ui/ui/discussions/1422) — Feature request for stepper (still open as of April 2026)
|
||||
- [react-hook-form/resolvers GitHub](https://github.com/react-hook-form/resolvers/releases) — v5.2.2 Zod v4 support
|
||||
- [github.com/recharts/recharts/wiki/3.0-migration-guide](https://github.com/recharts/recharts/wiki/3.0-migration-guide) — v3 breaking changes confirming upgrade is out of scope for this milestone
|
||||
- [evilmartians.com — Better dynamic themes with OKLCH](https://evilmartians.com/chronicles/better-dynamic-themes-in-tailwind-with-oklch-color-magic) — OKLCH lightness/chroma guidance for pastel systems
|
||||
- `package.json` in project root — authoritative source for actual installed versions (Recharts 2.15.4, not 3.x as prior research stated)
|
||||
- `supabase/migrations/` — authoritative source confirming Supabase backend, existing schema
|
||||
|
||||
---
|
||||
|
||||
*Stack research for: SimpleFinanceDash UI Overhaul*
|
||||
*Researched: 2026-03-16*
|
||||
*Stack research for: SimpleFinanceDash v2.0 — Wizard Setup, Auto-Budget, Sharp Pastel Design*
|
||||
*Researched: 2026-04-02*
|
||||
|
||||
Reference in New Issue
Block a user