geocrop-platform./apps/nextgen/.harness/changelogs/2026-07-17-p1-4-finance-par...

82 lines
2.7 KiB
Markdown

# 2026-07-17 — P1-4 modal migration: finance/* (Track A continuation)
Branch: `feat/p1-4-modals-finance`
Worktree: `.worktrees/feat-p1-4-modals-finance`
## Why
P1-4 in the readiness audit calls for migrating every inline modal
to the shared `<Modal>` component Track A introduced (in
`client/src/components/ui/Modal.tsx`). BankingAccounts.tsx already
demonstrates the pattern; this PR applies the same shape across the
`finance/*` slice.
## Changes
### Migrated modals (9 of 22 in `finance/*`)
| File | Modals migrated |
|---|---|
| `client/src/pages/finance/Trips.tsx` | 2 — `TripEditor` (8-field form), `confirmDelete` confirmation |
| `client/src/pages/finance/TripDetail.tsx` | 2 — `Record payment` form, `Assign students` form |
| `client/src/pages/finance/ChartOfAccounts.tsx` | 2 — `confirmDelete` confirmation, `ChartEditor` form |
| `client/src/pages/finance/Discounts.tsx` | 3 — `confirmRevoke`, `DiscountEditor`, `ApplyDiscountModal` |
Each migration follows the Track A pattern:
```tsx
<Modal
open={isOpen}
onClose={onClose}
title="…"
icon={Icon}
maxWidth="max-w-md"
footer={<><button>Cancel</button><button>Save</button></>}
>
<ModalBody>
{/* was the inline form */}
</ModalBody>
</Modal>
```
`<Modal>` already provides the backdrop-blur, click-outside-to-close,
Escape-to-close, scroll-lock, and rounded-2xl premium styling
(see `modals.md` §1). Forms retain `<form id=…>` semantics with the
submit button using `form="…"` so the layout can keep the action row
in the `footer` slot.
### `scripts/lint-no-inline-modals.js` (new)
Tiny Node script that walks `client/src/pages/**`, counts every
`fixed inset-0 … backdrop-blur-sm …` pattern, and exits non-zero if
any remain. Run via `node scripts/lint-no-inline-modals.js`. Used as a
regression net so future PRs that re-introduce an inline modal show
up here.
### Out of scope for this slice
The remaining 13 inline modals in `finance/*` (per lint) live in:
- `Expenses.tsx` (2)
- `FeePlans.tsx` (2)
- `Suppliers.tsx` (2)
- `StudentGroups.tsx` (3)
- `Invoices.tsx` (1 — a right-side detail drawer, not a centered
modal; would change UX if ported as-is)
- `PayrollRuns.tsx` (1)
- `Payslips.tsx` (1)
- `StudentGroupDetail.tsx` (1)
These land in the **next** PR that picks up the `finance/*` slack.
The other 5 file-owner PRs from the original P1-4 list
(`Fees.tsx`, `HRManagement.tsx`, `Inventory.tsx`, `Library.tsx`,
`parent/AcademicProgress.tsx`) land separately.
## Verification
- `node scripts/lint-no-inline-modals.js` → before: 22 in `finance/*`,
after: 13 in `finance/*`. (9 migrated.)
- Manual diff: every inline `<div className="fixed inset-0 …">` in
the 4 migrated files now wraps `<Modal>` + `<ModalBody>`. No
controller-level or store-level changes touched.