Add comprehensive project documentation including changelog, QA tracker, code quality audit, implementation guide, K6 load testing guide, frontend exploration notes, and file mapping reference. Co-Authored-By: Paperclip <noreply@paperclip.ing>
307 lines
8.8 KiB
Markdown
307 lines
8.8 KiB
Markdown
# GoodGo Frontend: i18n + A11y Implementation Quick Reference
|
|
|
|
## 🎯 Key Findings at a Glance
|
|
|
|
### Current State
|
|
- ✅ **Next.js 14** with App Router (well-structured)
|
|
- ✅ **React 18** + TypeScript (type-safe)
|
|
- ✅ **Tailwind CSS** with dark mode support (HSL-based theme)
|
|
- ✅ **Good component library** (~35 components)
|
|
- ✅ **Some A11y basics** in place (semantic HTML, ARIA labels, skip link)
|
|
- ❌ **NO i18n setup** (everything hardcoded Vietnamese)
|
|
- ❌ **A11y gaps** (focus management, some ARIA missing, color contrast TBD)
|
|
|
|
### Strategic Entry Points for Implementation
|
|
|
|
#### 1. **i18n Entry Points** (Priority 1)
|
|
```
|
|
Files to modify for i18n:
|
|
├── app/layout.tsx → Add i18n provider
|
|
├── middleware.ts → Add locale routing
|
|
├── app/(public)/layout.tsx → Navigation text
|
|
├── app/(auth)/login/page.tsx → Form labels + errors
|
|
├── app/(auth)/register/page.tsx → Form labels + errors
|
|
├── components/listings/listing-form-steps.tsx → Multi-step form labels
|
|
├── components/search/filter-bar.tsx → Filter options + city names
|
|
├── lib/validations/*.ts → Zod error messages
|
|
└── [All other components with text]
|
|
|
|
Total files to update: ~25-30 files with hardcoded strings
|
|
```
|
|
|
|
#### 2. **A11y Critical Fixes** (Priority 1.5)
|
|
```
|
|
Components needing A11y updates:
|
|
├── components/ui/dialog.tsx → Focus trapping + focus restoration
|
|
├── components/listings/image-gallery.tsx → Keyboard nav + ARIA
|
|
├── components/search/filter-bar.tsx → Proper labeling + ARIA
|
|
├── app/(dashboard)/layout.tsx → Tab focus management
|
|
└── Across all forms → Error message association
|
|
|
|
Tasks:
|
|
- Add focus trapping in modals
|
|
- Verify color contrast (WCAG AA)
|
|
- Add aria-busy to loading states
|
|
- Add proper aria-label to icon buttons
|
|
- Link form errors to inputs with aria-describedby
|
|
```
|
|
|
|
#### 3. **Message File Structure for i18n**
|
|
```
|
|
public/locales/
|
|
├── en.json
|
|
│ ├── common: { home, search, dashboard, logout, ... }
|
|
│ ├── auth: { login, register, email, password, ... }
|
|
│ ├── property: { apartment, house, villa, ... }
|
|
│ ├── transaction: { sale, rent, ... }
|
|
│ ├── directions: { north, south, east, ... }
|
|
│ ├── status: { draft, active, sold, ... }
|
|
│ ├── validation: { required, min_length, ... }
|
|
│ └── errors: { oauth_failed, access_denied, ... }
|
|
└── vi.json
|
|
└── [Same structure]
|
|
```
|
|
|
|
---
|
|
|
|
## 📋 Implementation Checklist
|
|
|
|
### Phase 1: Setup (2-3 hours)
|
|
- [ ] Install `next-intl` package
|
|
- [ ] Create message files (en.json, vi.json)
|
|
- [ ] Update next.config.js for i18n routing
|
|
- [ ] Create i18n config (config.ts)
|
|
- [ ] Update middleware.ts for locale detection
|
|
- [ ] Wrap root layout with i18n provider
|
|
|
|
### Phase 2: Core Refactoring (6-8 hours)
|
|
- [ ] Update root layout & metadata
|
|
- [ ] Refactor all validations (Zod) to use messages
|
|
- [ ] Extract component strings to useTranslations()
|
|
- [ ] Update all enums (TRANSACTION_TYPES, PROPERTY_TYPES, etc.) to use i18n
|
|
- [ ] Update page layouts (public, auth, dashboard)
|
|
- [ ] Update all page content
|
|
|
|
### Phase 3: Component Updates (4-6 hours)
|
|
- [ ] Update all UI components
|
|
- [ ] Update form components
|
|
- [ ] Update navigation components
|
|
- [ ] Update search/filter components
|
|
- [ ] Update listing form
|
|
|
|
### Phase 4: A11y Fixes (4-6 hours)
|
|
- [ ] Fix focus management in dialogs
|
|
- [ ] Add focus trapping
|
|
- [ ] Update form error linking (aria-describedby)
|
|
- [ ] Add aria-busy to loading states
|
|
- [ ] Add aria-labels to icon buttons
|
|
- [ ] Verify color contrast
|
|
- [ ] Update test setup for i18n
|
|
|
|
### Phase 5: Testing & QA (3-4 hours)
|
|
- [ ] Test both locales on all pages
|
|
- [ ] Run axe DevTools accessibility audit
|
|
- [ ] Test keyboard navigation
|
|
- [ ] Test screen reader compatibility
|
|
- [ ] Update unit tests for i18n
|
|
|
|
---
|
|
|
|
## 🗣️ Text Content Inventory
|
|
|
|
### Navigation & Layout (~15 items)
|
|
| Location | Text | Status |
|
|
|----------|------|--------|
|
|
| Public header | Trang chủ, Tìm kiếm, Đăng nhập, Đăng ký | ❌ Hardcoded |
|
|
| Dashboard nav | 8 nav items | ❌ Hardcoded |
|
|
| Footer | 4 sections | ❌ Hardcoded |
|
|
|
|
### Forms & Validation (~40+ items)
|
|
| Location | Type | Count | Status |
|
|
|----------|------|-------|--------|
|
|
| Login form | Labels + errors | 8 | ❌ Hardcoded |
|
|
| Register form | Labels + errors | 10 | ❌ Hardcoded |
|
|
| Listing form | Multi-step labels | 25+ | ❌ Hardcoded |
|
|
| Search filters | Option labels | 30+ | ❌ Hardcoded |
|
|
| Zod validation | Error messages | 20+ | ❌ Hardcoded |
|
|
|
|
### Enums & Constants (~50+ items)
|
|
| File | Items | Status |
|
|
|------|-------|--------|
|
|
| TRANSACTION_TYPES | 2 labels | ❌ Hardcoded |
|
|
| PROPERTY_TYPES | 6 labels | ❌ Hardcoded |
|
|
| LISTING_STATUSES | 8 labels | ❌ Hardcoded |
|
|
| DIRECTIONS | 8 labels | ❌ Hardcoded |
|
|
| CITIES | 13 names | ❌ Hardcoded |
|
|
| PRICE_RANGES | 6 ranges | ❌ Hardcoded |
|
|
|
|
### Page Content (~30 items)
|
|
| Page | Sections | Status |
|
|
|------|----------|--------|
|
|
| Landing page | Hero, search, stats, CTA | ❌ Hardcoded |
|
|
| Search results | No results, loading, headers | ❌ Hardcoded |
|
|
| Dashboard | Section titles, empty states | ❌ Hardcoded |
|
|
|
|
---
|
|
|
|
## 🔑 Critical Files for i18n
|
|
|
|
### Must-Update Files (Blockers)
|
|
1. **middleware.ts** — Locale routing
|
|
2. **app/layout.tsx** — i18n provider setup
|
|
3. **lib/validations/*.ts** — Message integration
|
|
4. **lib/*.ts** — Any API error message handling
|
|
|
|
### High-Priority Files
|
|
1. **app/(public)/layout.tsx** — Navigation
|
|
2. **app/(auth)/login/page.tsx** — Auth forms
|
|
3. **components/listings/listing-form-steps.tsx** — Forms
|
|
4. **components/search/filter-bar.tsx** — Filters
|
|
|
|
### Medium-Priority Files
|
|
1. All page components
|
|
2. All UI components with text
|
|
3. Error boundary components
|
|
|
|
---
|
|
|
|
## ♿ A11y Implementation Priority
|
|
|
|
### WCAG 2.1 AA Critical Fixes
|
|
1. **Focus Management** (Level A)
|
|
- Add focus trap in `dialog.tsx`
|
|
- Restore focus on dialog close
|
|
- Visible focus indicator on all buttons
|
|
|
|
2. **Color Contrast** (Level AA)
|
|
- Run axe DevTools audit
|
|
- Fix any < 4.5:1 ratio text
|
|
- Fix < 3:1 ratio graphics
|
|
|
|
3. **Form Accessibility** (Level A)
|
|
- Link all error messages with aria-describedby
|
|
- Proper labeling with htmlFor
|
|
- Fieldset grouping for complex forms
|
|
|
|
4. **Loading States** (Level A)
|
|
- Add aria-busy to spinners
|
|
- Add aria-label with context
|
|
|
|
5. **Icon Buttons** (Level A)
|
|
- All icon-only buttons need aria-label
|
|
- Theme toggle button already has label ✓
|
|
|
|
### Nice-to-Have A11y Enhancements
|
|
- Skip link already present ✓
|
|
- Semantic HTML already used ✓
|
|
- Role="alert" on errors ✓
|
|
- aria-invalid on form fields ✓
|
|
|
|
---
|
|
|
|
## 📦 Dependencies to Add
|
|
|
|
```bash
|
|
npm install next-intl
|
|
|
|
# No new devDependencies needed if using next-intl
|
|
# Testing with mocked i18n available
|
|
```
|
|
|
|
**Total installation footprint:** ~500KB minified
|
|
|
|
---
|
|
|
|
## 🧪 Testing Strategy
|
|
|
|
### Unit Tests
|
|
```typescript
|
|
// vitest.setup.ts - Mock i18n
|
|
vi.mock('next-intl', () => ({
|
|
useTranslations: () => (key) => mockMessages[key]
|
|
}));
|
|
```
|
|
|
|
### Component Tests
|
|
```typescript
|
|
// Test both locales
|
|
describe('LoginForm', () => {
|
|
it('renders Vietnamese labels', () => { ... });
|
|
it('renders English labels', () => { ... });
|
|
});
|
|
```
|
|
|
|
### E2E Tests
|
|
```typescript
|
|
// Test locale switching
|
|
- /en/login → English
|
|
- /vi/login → Vietnamese
|
|
- /en/dashboard → English dashboard
|
|
```
|
|
|
|
---
|
|
|
|
## 📊 Estimated Timeline
|
|
|
|
| Phase | Duration | Effort |
|
|
|-------|----------|--------|
|
|
| Setup | 2-3h | Low |
|
|
| Core Refactoring | 6-8h | Medium |
|
|
| Components | 4-6h | Medium |
|
|
| A11y Fixes | 4-6h | Low-Medium |
|
|
| Testing | 3-4h | Medium |
|
|
| **Total** | **19-27h** | **~3-4 days** |
|
|
|
|
---
|
|
|
|
## 🚀 Implementation Order (Recommended)
|
|
|
|
1. **Setup i18n infrastructure** (creates foundation)
|
|
2. **Update middleware + root layout** (enables routing)
|
|
3. **Extract & centralize all text** (main work)
|
|
4. **Fix A11y issues** (parallelize with #3)
|
|
5. **Test thoroughly** (final verification)
|
|
|
|
---
|
|
|
|
## 💡 Quick Win Opportunities
|
|
|
|
These can be done immediately:
|
|
1. Create message file structure (30 min)
|
|
2. Add focus trap to dialog (30 min)
|
|
3. Add aria-busy to spinners (20 min)
|
|
4. Color contrast audit (1 hour)
|
|
5. Icon button aria-labels (30 min)
|
|
|
|
---
|
|
|
|
## 📝 Notes for Implementation
|
|
|
|
### Locale Detection (middleware)
|
|
```typescript
|
|
// Check in order: URL > cookie > header > default
|
|
function getLocale(request) {
|
|
// 1. URL pathname: /en/* or /vi/*
|
|
// 2. Cookie: goodgo_locale
|
|
// 3. Header: Accept-Language
|
|
// 4. Default: vi
|
|
}
|
|
```
|
|
|
|
### Message Fallback Strategy
|
|
```typescript
|
|
// If translation missing, use English as fallback
|
|
// Otherwise fallback to Vietnamese (primary)
|
|
```
|
|
|
|
### Performance Considerations
|
|
- Keep message files < 100KB each
|
|
- Lazy load per-page messages if needed
|
|
- Static generation for SEO-critical pages
|
|
|
|
---
|
|
|
|
**Last Updated:** April 9, 2026
|
|
**Version:** 1.0 - Pre-Implementation
|
|
**Confidence:** High
|