Skip to content

Stack the add/edit expense screen so back pops it like Cancel - #22

Merged
srjn45 merged 2 commits into
mainfrom
feat/entry-stacked-screen
Jul 20, 2026
Merged

Stack the add/edit expense screen so back pops it like Cancel#22
srjn45 merged 2 commits into
mainfrom
feat/entry-stacked-screen

Conversation

@srjn45

@srjn45 srjn45 commented Jul 20, 2026

Copy link
Copy Markdown
Owner

Problem

The add/edit expense form was rendered inline inside LedgerManager (a view.mode state swap), not as a navigation route. So the phone's hardware/nav back button (and the iOS back-swipe / browser back) didn't return to the list — it would exit the app or navigate away. The only way back was the on-screen Cancel button.

Fix

Extract the form into its own stacked route so back / swipe pops it, exactly like Cancel:

  • app/entry.tsx — new route. No params = add; ?id=<entryId> = edit.
  • EntryManager (pure, DB-injected) — owns create / update / soft-delete and the "last used currency" default (§7.3); renders a ‹ Back button whose action equals Cancel.
  • EntryScreen (route wrapper) — resolves the entry + picker categories, owns navigation (router.back() on save / cancel / delete), and pops back to a since-deleted entry gracefully.
  • LedgerManager now just navigates (onAddEntry / onEditEntry); duplicate and row delete + Undo stay inline as before.
  • toastStore (tiny Zustand singleton) carries the confirming snackbar — crucially the delete Undo (data safety, §6.7) — from the popping entry screen back to the ledger, drained on its next render. The ledger re-reads on focus, so the new/updated/removed row is live on return (web included).

Tests

  • Form flows (create debit/credit, edit, tag chip space/comma, tag upsert, delete-from-form, cancel) moved to entryManager.test.tsx, driven against real in-memory SQLite.
  • ledgerManager.test.tsx keeps list / delete+Undo / duplicate / per-day totals / empty-state, and now asserts the navigation wiring (FAB + empty CTA → onAddEntry; row tap → onEditEntry(entry)).
  • 228 pass; lint / typecheck / format all clean.

No version bump here — a release of this would be a separate 1.1.4.

🤖 Generated with Claude Code

srjn45 and others added 2 commits July 20, 2026 15:39
The add/edit form was an inline `view.mode` swap inside LedgerManager, so
the native/hardware back button and back-swipe gesture couldn't pop it —
they'd exit the app or navigate away instead of returning to the ledger.

Extract the form into its own stacked route (`/entry`, `?id=` to edit):
- EntryManager (pure, DB-injected): create / update / soft-delete + the
  "last used currency" default; renders a Back button that mirrors Cancel.
- EntryScreen (route wrapper): resolves the entry + categories, owns
  navigation (router.back on save/cancel/delete).
- LedgerManager now navigates via onAddEntry / onEditEntry; duplicate and
  row-delete stay inline. A tiny toastStore carries the confirming
  snackbar — including the delete Undo (data safety, §6.7) — back to the
  ledger across the pop, drained on its next render.

Tests: form flows (create/edit/tags/delete/cancel) move to
entryManager.test.tsx; ledgerManager.test.tsx keeps list/delete/duplicate
and asserts the new navigation wiring. 228 pass; lint/typecheck/format clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@srjn45
srjn45 merged commit 0aedece into main Jul 20, 2026
2 checks passed
@srjn45
srjn45 deleted the feat/entry-stacked-screen branch July 20, 2026 13:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant