📋 Description
app/dashboard/goals/page.tsx renders a grid of SavingsGoalCard from a static goalsData array (Children's Education, Emergency Medical Fund, Family Home...). There is no way to add or edit a goal, even though validation already exists in lib/validation/savings-goals.ts (with a test at tests/unit/validation/savings-goals.test.ts) and a contract layer at lib/contracts/savings-goals.ts.
This issue adds an Add/Edit Savings Goal modal form and lifts the goals list into state.
Why this matters: savings goals are where remitted money becomes a plan. A read-only sample grid can't let families actually create the goals the product is built around.
🎯 Requirements & Context
Functional requirements
Context & constraints
- Follow the modal/focus-trap conventions established across the app.
- Submit can stay client-side state for this issue; wiring to
/api/goals may be a follow-up.
🛠️ Suggested Execution
git checkout -b feat/savings-goal-add-edit
- Build the modal, validate, manage state, recompute derived fields, add TSDoc.
- Extend the existing validation test for any new rules.
npm run lint
npx tsc --noEmit
npm run test:coverage
npm run build
- Edge cases: target date in the past (overdue), target less than current, decimal amounts, very long titles (truncation), reduced motion, mobile
320px.
- a11y: modal focus trap, ESC to close, labelled inputs.
- i18n: externalize labels.
Example commit message
feat(goals): add/edit savings goal modal wired to live state
Adds a validated Add/Edit form, lifts goalsData into state, and
recomputes daysLeft/isOverdue from the target date.
✅ Acceptance Criteria & Guidelines
| Requirement |
Target |
| Add + edit goal flows |
Required |
| Validation via savings-goals validator |
Required |
| Derived fields recomputed |
Required |
| Validation test coverage |
≥ 90% |
| Modal a11y (focus trap, ESC) |
Required |
| Responsive + i18n |
Required |
| Lint + typecheck + build clean |
Required |
| Timeframe |
96 hours from assignment |
💬 Community & Support
Join the RemitWise contributor community on Discord: https://discord.gg/CtQuPZFMA
Comment to claim before starting. 🚀
📋 Description
app/dashboard/goals/page.tsxrenders a grid ofSavingsGoalCardfrom a staticgoalsDataarray (Children's Education, Emergency Medical Fund, Family Home...). There is no way to add or edit a goal, even though validation already exists inlib/validation/savings-goals.ts(with a test attests/unit/validation/savings-goals.test.ts) and a contract layer atlib/contracts/savings-goals.ts.This issue adds an Add/Edit Savings Goal modal form and lifts the goals list into state.
🎯 Requirements & Context
Functional requirements
PageHeaderCTA that opens a modal form (title, description, target amount, target date, icon).lib/validation/savings-goals.ts.SavingsGoalCard.goalsDatainto component state; new/edited goals update the grid and the stats inSavingsGoalsStatsCards.daysLeft/isOverduefrom the target date rather than storing them statically.Context & constraints
/api/goalsmay be a follow-up.🛠️ Suggested Execution
320px.Example commit message
✅ Acceptance Criteria & Guidelines
💬 Community & Support
Join the RemitWise contributor community on Discord: https://discord.gg/CtQuPZFMA
Comment to claim before starting. 🚀