checkpoint: goals feature, wallet balance, and goals/wallet detail UI

- Add goals feature (models, migrations, API, web pages)
- Add reserved/centralized wallet balance service
- Add wallet detail page and overview components
- Add new UI components (progress, multi-select, FAB)
- Remove stray empty -H/-d files from working tree
This commit is contained in:
Dwindi Ramadhana
2026-06-17 20:40:00 +07:00
parent 35e93b826a
commit 6a6e74562c
401 changed files with 9517 additions and 397 deletions

223
GOALS_STANDARDS_UPDATE.md Executable file
View File

@@ -0,0 +1,223 @@
# ✅ Goals Feature - Standards Compliance Update
**Date:** October 22, 2025
**Status:** In Progress
---
## 🎯 **Issues to Fix:**
### **1. Thousand Separators for Assets** ✅
**Problem:** Asset amounts showing without thousand separators
```
Before: 80 gram ≈ Rp 165840000 ❌
After: 80 gram ≈ Rp 165.840.000 ✅
```
**Solution:** Updated `formatCurrency` in `/constants/currencies.ts` to use `toLocaleString` for non-currency codes (units).
---
### **2. Multilingual Support** ⏳
**Problem:** Goals feature has hardcoded English text
**Required Changes:**
#### **Add to `/locales/en.ts` and `/locales/id.ts`:**
```typescript
goals: {
title: 'Goals' / 'Tujuan',
pageDescription: 'Track your savings goals and progress' / 'Lacak tujuan tabungan dan progres Anda',
newGoal: 'New Goal' / 'Tujuan Baru',
// ... (see full list in en.ts)
}
```
#### **Update Components to Use Translations:**
- `Goals.tsx` - Main page
- `GoalDetail.tsx` - Detail page
- `CreateGoalDialog.tsx` - Create dialog
- `AddMoneyDialog.tsx` - Add money dialog
---
### **3. Mobile Optimization** ⏳
**Problem:** Goals dialogs not following mobile standards
**Required Changes:**
#### **Button Sizing:**
```tsx
// Before
<Button>New Goal</Button>
// After
<Button className="h-11 md:h-9 px-6 md:px-4 text-base md:text-sm">
{t.goals.newGoal}
</Button>
```
#### **Input Sizing:**
```tsx
// Before
<Input placeholder="Goal name" />
// After
<Input
className="h-11 md:h-9 text-base md:text-sm"
placeholder={t.goals.goalNamePlaceholder}
/>
```
#### **Label Sizing:**
```tsx
// Before
<Label>Goal Name</Label>
// After
<Label className="text-base md:text-sm">
{t.goals.goalName}
</Label>
```
#### **Spacing:**
```tsx
// Before
<div className="grid gap-4">
// After
<div className="grid gap-3 md:gap-2">
```
#### **Use ResponsiveDialog:**
```tsx
// Before
import { Dialog } from '@/components/ui/dialog';
// After
import { ResponsiveDialog } from '@/components/ui/responsive-dialog';
```
---
## 📋 **Implementation Checklist:**
### ✅ **Completed:**
- [x] Add thousand separators to asset amounts
- [x] Update `formatCurrency` function
- [x] Add English translations to `en.ts`
- [x] Add Indonesian translations to `id.ts`
- [x] Update `AddMoneyDialog.tsx` to use translations
- [x] Add mobile-responsive classes to `AddMoneyDialog.tsx`
### ⏳ **In Progress:**
- [ ] Update `Goals.tsx` to use translations
- [ ] Update `GoalDetail.tsx` to use translations
- [ ] Update `CreateGoalDialog.tsx` to use translations
### ⏳ **Pending:**
- [ ] Add mobile-optimized button sizing
- [ ] Add mobile-optimized input sizing
- [ ] Add mobile-optimized label sizing
- [ ] Add mobile-optimized spacing
- [ ] Replace Dialog with ResponsiveDialog
- [ ] Test on mobile viewport
- [ ] Verify touch targets (44px minimum)
---
## 🔧 **Quick Fixes Needed:**
### **1. formatCurrency Already Fixed** ✅
```typescript
// Now handles assets with thousand separators
formatCurrency(80, 'gram') "80 gram"
formatCurrency(165840000, 'IDR') "Rp 165.840.000"
```
### **2. Add Indonesian Translations**
Copy the `goals` section from `en.ts` and translate to Indonesian in `id.ts`.
### **3. Update All Goal Components**
Replace all hardcoded text with `t.goals.key` pattern.
### **4. Mobile Optimization**
Apply responsive classes to all buttons, inputs, labels, and spacing.
---
## 📊 **Example Transformations:**
### **Before (Non-Compliant):**
```tsx
<Button onClick={() => setCreateDialogOpen(true)}>
<Plus className="h-4 w-4" />
New Goal
</Button>
<Input
placeholder="e.g., Vacation to Bali"
value={formData.name}
/>
<Label>Goal Name *</Label>
```
### **After (Compliant):**
```tsx
<Button
onClick={() => setCreateDialogOpen(true)}
className="h-11 md:h-9 px-6 md:px-4 text-base md:text-sm gap-2"
>
<Plus className="h-4 w-4" />
{t.goals.newGoal}
</Button>
<Input
className="h-11 md:h-9 text-base md:text-sm"
placeholder={t.goals.goalNamePlaceholder}
value={formData.name}
/>
<Label className="text-base md:text-sm">
{t.goals.goalName} *
</Label>
```
---
## 🎯 **Priority Order:**
1. **High Priority:**
- ✅ Thousand separators (DONE)
- ⏳ Indonesian translations
- ⏳ Update Goals.tsx with translations
2. **Medium Priority:**
- ⏳ Update dialogs with translations
- ⏳ Mobile button/input sizing
3. **Low Priority:**
- ⏳ ResponsiveDialog implementation
- ⏳ Final mobile testing
---
## 📝 **Notes:**
- **Thousand Separators:** Now working for all asset types
- **Translation Keys:** Added to `en.ts`, need to add to `id.ts`
- **Mobile Standards:** Follow existing patterns from Transactions/Wallets pages
- **ResponsiveDialog:** Can be implemented last as Dialog works on mobile (just not optimal)
---
**Next Steps:**
1. Add Indonesian translations
2. Update Goals components to use `t.goals.*`
3. Apply mobile-responsive classes
4. Test on mobile viewport
---
**Status:** Thousand separators ✅ | Translations ⏳ | Mobile ⏳