diff --git a/.planning/phases/07-quick-add-library/07-01-PLAN.md b/.planning/phases/07-quick-add-library/07-01-PLAN.md index 2d6bda3..34e45e5 100644 --- a/.planning/phases/07-quick-add-library/07-01-PLAN.md +++ b/.planning/phases/07-quick-add-library/07-01-PLAN.md @@ -15,7 +15,7 @@ requirements: [QADD-01, QADD-03] must_haves: truths: - - "A quick_add_items table exists with user_id, name, icon, and sort_order columns" + - "The API accepts and returns quick-add items with name, icon, and sort_order in all CRUD responses" - "API returns a list of quick-add items for the authenticated user" - "API can create, update, and delete quick-add items" - "Quick-add items are user-scoped — one user cannot see another's items" diff --git a/.planning/phases/07-quick-add-library/07-02-PLAN.md b/.planning/phases/07-quick-add-library/07-02-PLAN.md index 3513415..a4d3c72 100644 --- a/.planning/phases/07-quick-add-library/07-02-PLAN.md +++ b/.planning/phases/07-quick-add-library/07-02-PLAN.md @@ -80,6 +80,7 @@ Output: QuickAddPage, QuickAddPicker component, useQuickAdd hook, API client add @frontend/src/pages/TemplatePage.tsx @frontend/src/pages/DashboardPage.tsx @frontend/src/components/AppLayout.tsx +@frontend/src/components/EmptyState.tsx @frontend/src/App.tsx @frontend/src/i18n/en.json @frontend/src/i18n/de.json @@ -187,7 +188,7 @@ const navItems = [ - Table with columns: Name, Icon, Actions (Edit pencil button, Delete trash button) - Edit mode: clicking edit turns row into inline inputs, Save/Cancel buttons - Delete: immediate delete (no confirmation needed for library items — they are presets, not budget data) - - Empty state: use EmptyState component with Zap icon, heading "No saved items", subtext "Save your frequently-used one-off categories here for quick access." + - Empty state: use the project's existing `EmptyState` component (`frontend/src/components/EmptyState.tsx`) with Zap icon, heading "No saved items", subtext "Save your frequently-used one-off categories here for quick access." 4. **Sidebar nav** (`frontend/src/components/AppLayout.tsx`): Add nav item after template: `{ path: '/quick-add', label: t('nav.quickAdd'), icon: Zap }` @@ -256,9 +257,11 @@ const navItems = [ - On mount, fetch quick-add items via `quickAdd.list()` (direct API call, not hook — this is a lightweight picker, not a full CRUD page) - Render a Popover (from shadcn/ui) with trigger button: icon `Zap` + text "Quick Add" (from i18n `quickAdd.addOneOff`) - Inside popover: list of quick-add items, each as a clickable row showing icon + name - - On click: create a budget item via `budgetItems.create(budgetId, { category_id: null, item_tier: 'one_off', notes: item.name })` — Since quick-add items are independent presets (not linked to categories), the picker creates a one-off budget item. The backend CreateBudgetItem handler must accept this. **However**, looking at the existing BudgetItem model, category_id is required (UUID NOT NULL in DB). So instead: - - The picker should first check if a category with the same name exists for the user. If not, create one via `categories.create({ name: item.name, type: 'variable_expense', icon: item.icon })`, then create the budget item with that category_id and `item_tier: 'one_off'`. - - Alternatively (simpler): show the quick-add library items, and on click, find or create a matching category, then call `budgetItems.create(budgetId, { category_id, item_tier: 'one_off' })`. + - On click, resolve the category_id then create the budget item. Since category_id is NOT NULL in the DB, the picker must find or create a matching category: + 1. Fetch the user's categories via `categories.list()` + 2. Find a category whose name matches `item.name` (case-insensitive) + 3. If no match, create one via `categories.create({ name: item.name, type: 'variable_expense', icon: item.icon })` + 4. Call `budgetItems.create(budgetId, { category_id: resolvedCategoryId, item_tier: 'one_off' })` with the resolved category_id - After creation: call `onItemAdded()` to refresh, close popover - If quick-add library is empty: show a small message "No saved items" with a link to /quick-add - Add loading spinner on the clicked item while creating