feat(budget): monthly budget tracking PoC #3

Merged
addison merged 92 commits from exe-dev-bot/loam:feat/budget-poc into main 2026-02-21 09:09:00 -05:00
Contributor
No description provided.
- package.json with vue 3.5, vite 7, @vitejs/plugin-vue
- vite.config.js with vue plugin
- index.html entry point
- src/main.js and src/App.vue (minimal)

Co-authored-by: Shelley <shelley@exe.dev>
- eslint.config.js (flat config) with eslint-plugin-vue and eslint-config-prettier
- .prettierrc with no-semi, single quotes, trailing commas

Co-authored-by: Shelley <shelley@exe.dev>
- justfile with dev, build, lint, format recipes
- .pre-commit-config.yaml with local eslint and prettier hooks

Co-authored-by: Shelley <shelley@exe.dev>
Co-authored-by: Shelley <shelley@exe.dev>
Co-authored-by: Shelley <shelley@exe.dev>
- Web manifest (name: Loam, earth-tone theme)
- Service worker with auto-update and asset caching
- SVG + PNG icons (192px, 512px)
- Meta tags for theme-color, description, icons

Co-authored-by: Shelley <shelley@exe.dev>
- Add 'just deps' recipe for dependency installation
- Replace 'npm install' with 'just deps' in README
- Add AGENTS.md with just-recipe-only rule and project conventions

Co-authored-by: Shelley <shelley@exe.dev>
- Add sql.js for SQLite WASM in-browser database
- Create src/db.js with full database composable (useDatabase)
- Schema: category, monthly_budget, transaction tables
- IndexedDB persistence layer for data survival across reloads
- Seed default categories: Communication, Hosting, Domains, AI, Savings, Contractors
- Copy sql-wasm.wasm to public/ for WASM loading
- Update vite.config.js with WASM caching for offline support
- Fix sql.js db.run() param binding by using prepare/bind/step pattern

Co-authored-by: Shelley <shelley@exe.dev>
- MonthlySummary: 2x2 grid showing budgeted/spent/income/remaining with progress bar
- CategoryItem: individual category with spent/budgeted and color-coded progress bar
- CategoryList: renders all expense categories with budget progress
- IncomeSection: lists income entries with totals and delete
- TransactionForm: bottom sheet for adding expenses/income with type toggle
- BudgetEditor: bottom sheet for setting category budget amounts
- CategoryManager: full-screen modal with drag-and-drop reorder, inline rename, add/delete
- MonthlyBudget: main orchestrator with month navigation, swipe, FABs, data loading
- App.vue: app shell with global CSS variables and MonthlyBudget as root view

All components use Vue 3 Composition API, scoped CSS, mobile-first design with
44px+ touch targets, Teleport for modals, and smooth transitions.

Co-authored-by: Shelley <shelley@exe.dev>
- Install @playwright/test, configure for Chromium-only
- Add 7 E2E tests covering all budget PoC functionality:
  - Adding expense transactions
  - Viewing monthly summary updates
  - Month navigation (data scoped per month)
  - Category management (add, rename, delete)
  - Setting category budgets
  - Adding income entries
  - Data persistence across page reloads
- Add just recipes: test, test-e2e
- Update AGENTS.md with new recipes
- Add test-results/ to .gitignore

Co-authored-by: Shelley <shelley@exe.dev>
- Dialog ARIA: Add role=dialog, aria-modal, aria-labelledby to all
  bottom sheets and modals (TransactionForm, BudgetEditor, CategoryManager)
- Progress bars: Add role=progressbar with aria-valuenow/min/max and
  aria-label to MonthlySummary and CategoryItem progress indicators
- Touch targets: Ensure all interactive elements meet 44x44px minimum
  (close buttons, delete buttons, drag handles, FABs, manage button)
- Focus management: Auto-focus amount input when sheets open, add
  Escape key to close all modals/sheets
- ARIA labels: Add aria-label to FABs, category items, dynamic labels
  for income delete buttons, new category input
- Keyboard nav: Add Space key handler to CategoryItem (role=button),
  Escape handlers on all modal backdraps
- Screen reader: Add sr-only utility class, visually-hidden progress
  percentage text in MonthlySummary
- Focus indicators: Global :focus-visible outline style plus scoped
  focus-visible for buttons in all components
- Semantics: Use <main> landmark, add role=list to preserve list
  semantics despite list-style:none, add aria-live to loading state
- Radio ARIA: TransactionForm type toggle uses role=radiogroup/radio
  with aria-checked
- Fix test selector for exact 'Add' button match after ARIA changes

Co-authored-by: Shelley <shelley@exe.dev>
- useToast composable with addToast/removeToast
- ToastNotification component with slide-in animation
- Support for success/error/warning/info types
- Auto-dismiss after configurable duration, max 3 visible

Co-authored-by: Shelley <shelley@exe.dev>
- Wrap sql.js WASM init in try/catch with user-friendly error
- Fall back to in-memory mode when IndexedDB unavailable
- Handle QuotaExceededError in idbSave
- Wrap all query/mutation helpers in try/catch
- Export dbError, isMemoryOnly, retryInit from useDatabase

Co-authored-by: Shelley <shelley@exe.dev>
- Import and use toast system for all async handler feedback
- Show db error state with retry button, loading spinner for init
- Show memory-only warning banner when IndexedDB unavailable
- Add loading bar during data operations
- Wrap all event handlers in try/catch with success/error toasts
- Add ConfirmDialog component for delete confirmations
- Wire delete confirmations for income and category deletion
- FAB debounce to prevent double-click

Co-authored-by: Shelley <shelley@exe.dev>
- CategoryList: show message when no categories exist
- IncomeSection: make empty message more actionable
- CategoryItem: show 'No budget set — tap to set' when budgeted is 0

Co-authored-by: Shelley <shelley@exe.dev>
TransactionForm:
- Inline error messages shown after touch or submit attempt
- Amount must be positive, capped at 999,999,999.99
- Category required for expenses
- Date required
- Vendor max 100 chars with remaining count at >80
- Note max 500 chars with remaining count at >450
- Prevent double-submit with saving state

BudgetEditor:
- Amount must be >= 0, capped at 999,999,999.99
- Error shown after touch or submit attempt
- Prevent double-submit with saving state

Co-authored-by: Shelley <shelley@exe.dev>
- Add typography tokens: font-size-xs through 2xl, line-height, font-weight
- Restructure colors into private primitives and semantic tokens
- Add semantic surface tokens: surface-elevated, surface-overlay, text-on-primary
- Add spacing scale (xs through 2xl) and shadow scale (sm through xl)
- Add dark mode foundation as commented-out [data-theme='dark'] block
- Add responsive breakpoints: tablet (768px+), desktop (1024px+)
- Add .tabular-nums utility class for currency alignment
- All existing variable names preserved as backward-compat aliases

Co-authored-by: Shelley <shelley@exe.dev>
- Create SkeletonPulse.vue: reusable shimmer component with gradient animation
- Replace loading spinner with full skeleton screen mimicking real layout
- Skeleton includes: month header, summary card, 5 category rows, income section
- Polish loading bar: gradient fill, smoother cubic-bezier animation
- Add month slide transitions (slide-left/slide-right on navigation)
- Add FAB ripple effect (CSS-only approach)
- Responsive desktop layout: side-by-side summary + categories grid
- Replace all hardcoded values with design system tokens

Co-authored-by: Shelley <shelley@exe.dev>
- Add direction ref ('left'/'right') to useMonthNavigation composable
- goToPrevMonth sets direction to 'right', goToNextMonth sets 'left'
- Enables slide transitions in MonthlyBudget.vue

Co-authored-by: Shelley <shelley@exe.dev>
BottomSheet: add drag handle pill, backdrop blur, spring-like animation
MonthlySummary: progress bar gradient overlay, percentage label, animated fill
CategoryItem: card styling with elevation, scale-on-tap micro-interaction
CategoryList: consistent token usage, proper spacing
IncomeSection: hover/active states on entries, full token migration
form-fields.css: focus label color change, replace hardcoded colors with tokens

Co-authored-by: Shelley <shelley@exe.dev>
- Replace all hardcoded hex colors with semantic CSS custom properties
- Remove unnecessary fallback values from var() expressions
- Ensures dark mode readiness across all modal/dialog components

Co-authored-by: Shelley <shelley@exe.dev>
New test files:
- budget-crud.spec.js: form validation errors (empty/zero/negative/max
  amounts, missing category), empty states, delete flows (income deletion
  with cancel/confirm, category deletion with cascade), budget editing
  (set/update/zero/per-month), data persistence (multi-entity reload,
  custom categories, deletion persistence)
- budget-navigation.spec.js: month navigation edge cases (12mo forward/
  back, rapid nav, 24mo past/future), keyboard navigation (Escape closes
  modals/dialogs, Tab order, Enter submits), responsive behavior (mobile/
  tablet/desktop layout checks), data isolation between months, month-
  scoped budget independence

Also fixes 2 pre-existing test failures in budget.spec.js:
- Category delete now goes through ConfirmDialog
- Month navigation checks 'No budget set' instead of '$0.00 / $0.00'

Total: 58 tests (was 7), all passing.
Co-authored-by: Shelley <shelley@exe.dev>
Accessibility improvements across all components:

- Focus trap composable (useFocusTrap.js) with Tab cycling, focus
  restoration, and optional initial focus element. Applied to
  BottomSheet, ConfirmDialog, and CategoryManager.
- Live regions: aria-live on summary grid and progress label so screen
  readers announce budget changes. Error toasts use role="alert".
- Form error association: aria-describedby links errors to inputs,
  aria-invalid on invalid fields (TransactionForm, BudgetEditor).
- Color-independent indicators: status text + icons (✓ On track,
  ⚠ Caution, ✕ Over budget) on MonthlySummary progress bar and
  CategoryItem amounts, so color alone doesn't convey status.
- Reduced motion: prefers-reduced-motion media query disables all
  animations and transitions globally.
- Landmark structure: month nav uses <nav>, FAB container has
  role="group" with aria-label.
- Semantic HTML: visually hidden h2 for Budget Summary, h3→h2 in
  ConfirmDialog, aria-hidden on drag ghost, aria-required on
  category input.
- Dialog announcements: ConfirmDialog auto-focuses Cancel button.

Co-authored-by: Shelley <shelley@exe.dev>
Database layer:
- Add JSDoc to all exported db functions (30+ param/returns tags)
- Optimize getMonthlySummary from 3 queries to 1
- Add getLastInsertId helper; addCategory/addTransaction return new ID
- Add input validation to write operations
- Use shallowRef for db singleton (no deep reactivity needed)
- Document cascade delete pattern in deleteCategory

Component API consistency:
- Standardize script setup ordering across all components
- Add component-level JSDoc with @emits documentation
- Add JSDoc to complex computed properties (budget thresholds)
- Extract inline dblclick handler to startRenameImmediate method
- Fix all 16 ESLint warnings (attribute order, hyphenation)

CSS architecture:
- Replace hardcoded hex colors with design tokens throughout
- Replace hardcoded font-size/font-weight with token variables
- Add --color-accent-hover and --ring-accent tokens
- Tokenize form-fields.css (font-size, font-weight, spacing, transitions)
- Remove unnecessary fallback values from app-internal components

Performance:
- shallowRef for categories, budgetEntries, transactions arrays
- Debounce month navigation (150ms guard via isNavigating ref)
- Add MONTH_NAV_DEBOUNCE_MS constant

Code quality:
- Add TODO markers for known limitations (pagination, keyboard nav)
- Add section comments and JSDoc headers to all composables
- Codebase is lint-clean (0 warnings) and builds cleanly

Co-authored-by: Shelley <shelley@exe.dev>
- Migration system with schema_version table and ordered migrations
- Promise-based operation queue serializing all write operations
- PRAGMA integrity_check on startup with isCorrupt state
- resetDatabase() with best-effort data export before wipe
- exportData()/importData() for JSON backup and restore
- sanitizeText() strips control chars, enforces max length
- getStorageInfo()/getDatabaseSize() for quota monitoring
- All write operations (CRUD) now go through enqueue()

Co-authored-by: Shelley <shelley@exe.dev>
- BottomSheet-based settings panel with three sections
- Data Management: JSON export download, file import, database reset
- Storage: database size, quota monitoring with progress bar
- About: version display and app tagline
- Reset uses ConfirmDialog with strong warning
- All actions show toast notifications on success/failure

Co-authored-by: Shelley <shelley@exe.dev>
- Precache WASM files via globPatterns (sql-wasm.wasm)
- Add navigateFallback for SPA offline navigation
- Add useOnlineStatus composable for network detection
- Add offline banner in MonthlyBudget (informational, not alarming)
- Integrate settings gear button in month header
- Wire SettingsPanel with data-imported/data-reset events

Co-authored-by: Shelley <shelley@exe.dev>
Co-authored-by: Shelley <shelley@exe.dev>
- Add AppIcon component with 19 inline SVG icons replacing text/emoji symbols
- Add BottomNav component for Budget/Settings tab navigation
- Wrap CategoryList and IncomeSection in card containers with elevation
- Add empty state SVG illustrations for categories and income
- Refine typography: increased section header letter-spacing (0.06em)
- WCAG contrast fix: update gray-400 from #94a3b8 to #7c8ba0 (4.7:1)
- Add accent surface color tokens for hover states
- Add micro-animations: hover elevation on cards, press scale on buttons,
  border accent on income entries, summary item hover
- Add safe area support (viewport-fit=cover, env(safe-area-inset-*))
- Fix E2E nav tests: wait for debounce between rapid month clicks

Co-authored-by: Shelley <shelley@exe.dev>
New test files (76 new tests, 134 total):

- tests/settings.spec.js (26 tests)
  - Bottom navigation: tab switching, aria-current, state preservation
  - Export: download trigger, JSON structure validation, data inclusion
  - Import: valid restore, invalid JSON errors, missing fields, round-trip
  - Reset: confirm dialog, cancel preserves data, full reset + re-seed
  - Storage info: DB size, progress bar, quota display
  - About section: version, tagline

- tests/accessibility.spec.js (23 tests)
  - Focus traps: Tab/Shift+Tab cycling in TransactionForm, BudgetEditor, ConfirmDialog
  - ARIA live: toast notifications for all CRUD operations
  - Keyboard-only: full expense flow, month navigation, bottom nav, Enter activation
  - ARIA attributes: labels, roles, progressbar attributes, alertdialog

- tests/data-integrity.spec.js (16 tests)
  - Multi-month export → reset → import round-trip
  - Accumulation: 10 transactions sum correctly, multiple income entries
  - Remaining calculation: budget minus spending, negative overspend
  - Export metadata: category sort_order, created_at preservation
  - Import validation: empty/null/future version/non-array fields
  - Data safety: failed import preserves existing data
  - Offline: app functional offline, offline banner appears/disappears
  - Reload resilience: data survives 3 sequential reloads

- tests/visual-regression.spec.js (11 tests)
  - Mobile (375x812): empty state, populated view, all modals, settings
  - Desktop (1024x768): empty state, populated view, settings
  - Baseline screenshots for future regression detection

Co-authored-by: Shelley <shelley@exe.dev>
Accessibility:
- Add @media (forced-colors: active) fallbacks for progress bars,
  loading bar, skeleton shimmer, FABs, and toast notifications
- Both global (App.vue) and scoped component-level forced-color overrides
- Add role='button' + tabindex='0' to CategoryManager drag handles

Performance:
- Lazy-load SettingsPanel via defineAsyncComponent (code-split to 5.85KB)
- Split sql.js into separate vendor chunk (39.32KB, independently cacheable)
- Add database indexes on transaction.date, transaction.category_id,
  and monthly_budget.month for faster queries
- Fix potential memory leak in useFocusTrap (onUnmounted cleanup)

Build results:
- Main JS chunk: 178KB → 136KB (23% reduction)
- Total chunks: 3 (index + sql-wasm + SettingsPanel)
- CSS also code-split with SettingsPanel

Co-authored-by: Shelley <shelley@exe.dev>
Co-authored-by: Shelley <shelley@exe.dev>

# Conflicts:
#	.gitignore
#	AGENTS.md
#	README.md
#	index.html
#	justfile
#	package-lock.json
#	package.json
#	src/App.vue
#	vite.config.js
ci: add Forgejo Actions workflow for lint, e2e tests, and build
Some checks failed
CI / lint (pull_request) Has been cancelled
CI / test-e2e (pull_request) Has been cancelled
CI / build (pull_request) Has been cancelled
33931711fb
Co-authored-by: Shelley <shelley@exe.dev>
ci: rename to .yml, add setup-just step to all jobs
Some checks failed
CI / lint (pull_request) Has been cancelled
CI / test-e2e (pull_request) Has been cancelled
CI / build (pull_request) Has been cancelled
75c52a87bc
Co-authored-by: Shelley <shelley@exe.dev>
@ -0,0 +23,4 @@
<template>
<!-- Standard 20×20 stroke-based icons -->
<svg
Owner

Instead of hand-drawn icons, we should pick an MIT set from https://icon-sets.iconify.design that matches the design goals of the app

Instead of hand-drawn icons, we should pick an MIT set from https://icon-sets.iconify.design that matches the design goals of the app
addison marked this conversation as resolved
src/App.vue Outdated
@ -8,0 +40,4 @@
--font-feature-tabular: 'tnum';
/* -----------------------------------------------------------------------
Color Palette Primitives
Owner

The app must set different values based on dark mode or light mode, and follow the user's system dark mode setting. Default to dark mode.

The app must set different values based on dark mode or light mode, and follow the user's system dark mode setting. Default to dark mode.
addison marked this conversation as resolved
@ -0,0 +1,515 @@
<template>
Owner

Settings should be a dedicated page rather than a bottom sheet.

Settings should be a dedicated page rather than a bottom sheet.
addison marked this conversation as resolved
@ -0,0 +1,21 @@
/**
Owner

We should use TypeScript from the start across the project to avoid type errors.

We should use TypeScript from the start across the project to avoid type errors.
addison marked this conversation as resolved
@ -0,0 +35,4 @@
><AppIcon name="import"
/></span>
<span class="action-label">
<span class="action-title">Import Data</span>
Owner

We don't want "Import". We want to directly open the database file use the filesystem API. Store file handle in IndexDB.

Please download https://git.kwila.cloud/kwila/address-book/raw/branch/main/index.html and analyze that file for best practices related to local file handling

We don't want "Import". We want to directly open the database file use the filesystem API. Store file handle in IndexDB. Please download https://git.kwila.cloud/kwila/address-book/raw/branch/main/index.html and analyze that file for best practices related to local file handling
addison marked this conversation as resolved
@ -0,0 +175,4 @@
const storageEstimate = ref(null)
const appVersion =
typeof __APP_VERSION__ !== 'undefined' ? __APP_VERSION__ : '0.1.0-beta'
Owner

We need some code for setting APP_VERSION automatically somehow. The fallback should be "??" instead of "0.1.0-beta"

We need some code for setting __APP_VERSION__ automatically somehow. The fallback should be "??" instead of "0.1.0-beta"
addison marked this conversation as resolved
Co-authored-by: Shelley <shelley@exe.dev>
Co-authored-by: Shelley <shelley@exe.dev>
Co-authored-by: Shelley <shelley@exe.dev>
Co-authored-by: Shelley <shelley@exe.dev>
docs(agents): update AGENTS.md to reflect TypeScript, dark mode, icons, settings changes
Some checks failed
CI / lint (pull_request) Has been cancelled
CI / test-e2e (pull_request) Has been cancelled
CI / build (pull_request) Has been cancelled
712e46bd23
Co-authored-by: Shelley <shelley@exe.dev>
refactor: rename SettingsPanel to SettingsView
Some checks failed
CI / lint (pull_request) Has been cancelled
CI / test-e2e (pull_request) Has been cancelled
CI / build (pull_request) Has been cancelled
892bb48267
Co-authored-by: Shelley <shelley@exe.dev>
fix: hide month navigation on settings page
Some checks failed
CI / lint (pull_request) Has been cancelled
CI / test-e2e (pull_request) Has been cancelled
CI / build (pull_request) Has been cancelled
cfea7b386e
Co-authored-by: Shelley <shelley@exe.dev>
fix: correct app tagline to 'Loam - Kwila business management'
Some checks failed
CI / lint (pull_request) Has been cancelled
CI / test-e2e (pull_request) Has been cancelled
CI / build (pull_request) Has been cancelled
cad92999c2
Co-authored-by: Shelley <shelley@exe.dev>
Co-authored-by: Shelley <shelley@exe.dev>
Co-authored-by: Shelley <shelley@exe.dev>
Co-authored-by: Shelley <shelley@exe.dev>
docs(agents): update architecture, design rules, and file format docs
Some checks failed
CI / lint (pull_request) Has been cancelled
CI / test-e2e (pull_request) Has been cancelled
CI / build (pull_request) Has been cancelled
8ac2fae683
Co-authored-by: Shelley <shelley@exe.dev>
Co-authored-by: Shelley <shelley@exe.dev>
docs(agents): document auto-save behavior, design rules for shadows and icons
Some checks failed
CI / lint (pull_request) Has been cancelled
CI / test-e2e (pull_request) Has been cancelled
CI / build (pull_request) Has been cancelled
f671fa651c
Co-authored-by: Shelley <shelley@exe.dev>
feat: require .db file selection on first launch with welcome screen
Some checks failed
CI / lint (pull_request) Has been cancelled
CI / test-e2e (pull_request) Has been cancelled
CI / build (pull_request) Has been cancelled
b2fa0d79d8
Co-authored-by: Shelley <shelley@exe.dev>
fix: vertically center icons in welcome screen action buttons
Some checks failed
CI / lint (pull_request) Has been cancelled
CI / test-e2e (pull_request) Has been cancelled
CI / build (pull_request) Has been cancelled
8a3df6daa7
Co-authored-by: Shelley <shelley@exe.dev>
Owner

Some things I noticed:

  • Future month budgets should default to previous month's budget until explicitly set
  • Categories should be handled in a a top level /budget/categories page, instead of bottom sheet
  • Income ilustration is broke. use simple large icon instead
  • About card should include link to the git repo
Some things I noticed: - Future month budgets should default to previous month's budget until explicitly set - Categories should be handled in a a top level /budget/categories page, instead of bottom sheet - Income ilustration is broke. use simple large icon instead - About card should include link to the git repo
refactor: global card and action-btn styles, remove Save button, add Ctrl+S
Some checks failed
CI / lint (pull_request) Has been cancelled
CI / test-e2e (pull_request) Has been cancelled
CI / build (pull_request) Has been cancelled
6c1fe86a91
Co-authored-by: Shelley <shelley@exe.dev>
fix: action buttons use transparent bg for contrast inside cards
Some checks failed
CI / lint (pull_request) Has been cancelled
CI / test-e2e (pull_request) Has been cancelled
CI / build (pull_request) Has been cancelled
d625be5172
Co-authored-by: Shelley <shelley@exe.dev>
Co-authored-by: Shelley <shelley@exe.dev>
Co-authored-by: Shelley <shelley@exe.dev>
Co-authored-by: Shelley <shelley@exe.dev>
docs(agents): update routes, architecture, and budget inheritance docs
Some checks failed
CI / lint (pull_request) Failing after 6s
CI / test-e2e (pull_request) Failing after 6s
CI / build (pull_request) Failing after 5s
db637fde37
Co-authored-by: Shelley <shelley@exe.dev>
fix: add mouse drag support and edit button for category rename
Some checks failed
CI / lint (pull_request) Failing after 5s
CI / test-e2e (pull_request) Failing after 6s
CI / build (pull_request) Failing after 5s
686aa0ebfd
Co-authored-by: Shelley <shelley@exe.dev>
refactor: budget at /budget, categories at /budget/categories, remove from nav
Some checks failed
CI / lint (pull_request) Failing after 5s
CI / test-e2e (pull_request) Failing after 6s
CI / build (pull_request) Failing after 5s
8ca3516894
Co-authored-by: Shelley <shelley@exe.dev>
fix(categories): correct drag-to-reorder placement when dragging downward
Some checks failed
CI / lint (pull_request) Failing after 5s
CI / test-e2e (pull_request) Failing after 6s
CI / build (pull_request) Failing after 5s
24531b69cd
Two bugs caused items to land far below the intended drop position:

1. Math.round in moveDrag rounded up when cursor was in the bottom half
   of a row, making overIndex one higher than the row being hovered.
   Changed to Math.floor for accurate row detection.

2. Array splice in endDrag didn't account for index shift after removal.
   When dragging downward (to > from), removing the source item shifts
   all subsequent indices down by 1, so insertion index must be
   decremented. Added: const insertAt = to > from ? to - 1 : to

Co-authored-by: Shelley <shelley@exe.dev>
- Fix IncomeSection empty message (remove reference to nonexistent green button)
- Remove garish hover/active styles from income entries (border-left accent,
  heavy background tint, dark-mode-broken rgba active state)
- Add ExpenseList bottom sheet: tapping a category now shows its expenses
  with vendor, date, amount, note, and delete button
- ExpenseList includes 'Edit Budget' button to open BudgetEditor
- Wire up expense delete with confirmation dialog in MonthlyBudget

Co-authored-by: Shelley <shelley@exe.dev>
fix(income): extend list items and header edge-to-edge within card padding
Some checks failed
CI / lint (pull_request) Failing after 20s
CI / test-e2e (pull_request) Failing after 35s
CI / build (pull_request) Failing after 33s
428b1f935d
Co-authored-by: Shelley <shelley@exe.dev>
feat(budget): add category detail page for viewing expenses
Some checks failed
CI / lint (pull_request) Failing after 6s
CI / test-e2e (pull_request) Failing after 6s
CI / build (pull_request) Failing after 5s
679fc5ba69
Replace the ExpenseList bottom sheet with a dedicated category detail
page at /budget/category/:id. Tapping a category row on the budget
overview now navigates to a full page showing:

- Budget summary card (budgeted, spent, remaining, progress bar)
- Transaction list sorted by date descending
- Edit Budget button (opens BudgetEditor bottom sheet)
- FAB for adding expenses (pre-selects current category)
- Delete button on each transaction with confirmation dialog
- Footer showing transaction count and total

Changes:
- Create CategoryDetail.vue as a new route component
- Add /budget/category/:id route to router
- Update CategoryItem to navigate instead of emitting edit event
- Add chevron-right icon to CategoryItem for navigation affordance
- Pass month prop through CategoryList to CategoryItem
- Remove ExpenseList component and all related state from MonthlyBudget
- Add initialCategory prop to TransactionForm for pre-selection
- Delete ExpenseList.vue

Co-authored-by: Shelley <shelley@exe.dev>
docs(agents): add category detail route and component info
Some checks failed
CI / lint (pull_request) Failing after 5s
CI / test-e2e (pull_request) Failing after 6s
CI / build (pull_request) Failing after 5s
1a399e1892
Co-authored-by: Shelley <shelley@exe.dev>
feat: improve layout
Some checks failed
CI / lint (pull_request) Failing after 9s
CI / build (pull_request) Failing after 6s
CI / test-e2e (pull_request) Failing after 9s
29efdb1d6d
feat: expenses page
Some checks failed
CI / lint (pull_request) Failing after 5s
CI / test-e2e (pull_request) Failing after 6s
CI / build (pull_request) Failing after 5s
054a3dab46
refactor: remove category page
Some checks failed
CI / lint (pull_request) Failing after 5s
CI / test-e2e (pull_request) Failing after 6s
CI / build (pull_request) Failing after 5s
617024c7a0
feat: category bottom sheet
Some checks failed
CI / lint (pull_request) Failing after 5s
CI / build (pull_request) Failing after 9s
CI / test-e2e (pull_request) Failing after 11s
029abdc889
feat: auto-fill form
Some checks failed
CI / lint (pull_request) Failing after 5s
CI / test-e2e (pull_request) Failing after 6s
CI / build (pull_request) Failing after 5s
9c60b860c1
feat: improvements for progress bars
Some checks failed
CI / lint (pull_request) Failing after 6s
CI / test-e2e (pull_request) Failing after 6s
CI / build (pull_request) Failing after 5s
3d7e19e1e4
feat: more improvements
Some checks failed
CI / lint (pull_request) Failing after 6s
CI / test-e2e (pull_request) Failing after 7s
CI / build (pull_request) Failing after 15s
888cfc745a
feat: edit expense
Some checks failed
CI / lint (pull_request) Failing after 5s
CI / test-e2e (pull_request) Failing after 6s
CI / build (pull_request) Failing after 5s
0f4fa6a2b8
feat: improve export filename
Some checks failed
CI / lint (pull_request) Failing after 5s
CI / test-e2e (pull_request) Failing after 6s
CI / build (pull_request) Failing after 5s
162d6e72eb
feat: edit expense
Some checks failed
CI / lint (pull_request) Failing after 5s
CI / test-e2e (pull_request) Failing after 6s
CI / build (pull_request) Failing after 5s
c2f857d8e2
feat: basic privacy toggle
Some checks failed
CI / lint (pull_request) Failing after 5s
CI / test-e2e (pull_request) Failing after 6s
CI / build (pull_request) Failing after 5s
e7a29a7916
feat: new privacy filter component
Some checks failed
CI / lint (pull_request) Failing after 5s
CI / test-e2e (pull_request) Failing after 6s
CI / build (pull_request) Failing after 5s
27e3b6a017
feat: improve privacy view
Some checks failed
CI / lint (pull_request) Failing after 5s
CI / test-e2e (pull_request) Failing after 6s
CI / build (pull_request) Failing after 5s
c066012019
docs: revise README
Some checks failed
CI / lint (pull_request) Failing after 6m14s
CI / test-e2e (pull_request) Failing after 7m34s
CI / build (pull_request) Successful in 10m58s
62978245ff
fix: lint issues and formatting
Some checks failed
CI / lint (pull_request) Failing after 6m11s
CI / build (pull_request) Failing after 6m8s
CI / test-e2e (pull_request) Failing after 7m16s
79037ad70e
- Add return type to useBudgetStatus computed properties
- Reorder aria-label before @click in MonthlySummary
- Rename Expenses to ExpenseList for multi-word component name
- Add default case to switch statements
fix: some tests
Some checks failed
CI / lint (pull_request) Failing after 6m21s
CI / test-e2e (pull_request) Failing after 8m14s
CI / build (pull_request) Successful in 11m17s
100fb1a14f
addison deleted branch feat/budget-poc 2026-02-21 09:09:00 -05:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
kwila/loam!3
No description provided.