# Frontend Refactoring Implementation Guide **Based on:** Frontend Audit Report (2025-11-09) **Priority:** High Priority (Quick Wins) **Estimated Time:** 4 hours **Expected LOC Savings:** ~220 LOC --- ## βœ… Completed (Phase 1) ### New Files Created: 1. **`frontend/src/lib/apiClient.ts`** (170 LOC) - Centralized API client with type-safe methods - Error classification (NETWORK, NOT_FOUND, VALIDATION, SERVER) - Localized error messages - Convenience helpers: `loadContent()`, `loadContentWithError()` 2. **`frontend/src/hooks/useApiData.ts`** (110 LOC) - Custom hook for data fetching - Automatic loading/error state management - Refetch capability - Two variants: `useApiData()` and `useApiDataWithError()` 3. **`frontend/src/state/modules/toast.ts`** (70 LOC) - Zustand store for toast notifications - Queue management - Auto-hide after duration - Convenience methods: `toast.success()`, `toast.error()`, etc. 4. **`frontend/src/components/ToastContainer.tsx`** (30 LOC) - Toast UI component - Supports all toast types (success, error, info, warning) - Click to dismiss 5. **Tests** (3 files, ~250 LOC): - `frontend/tests/apiClient.test.ts` (95 LOC) - `frontend/tests/useApiData.test.ts` (85 LOC) - `frontend/tests/toast.test.ts` (70 LOC) 6. **Styles:** - Added toast CSS to `frontend/src/styles.css` (90 LOC) 7. **i18n:** - Added error messages to `frontend/src/i18n/cs.json` - Added tips translations 8. **Example Refactoring:** - `frontend/src/views/TipsView.refactored.tsx` (69 LOC) - Shows how to use new utilities - 20 LOC saved compared to original **Total Created:** ~550 LOC (utilities) + ~250 LOC (tests) = 800 LOC --- ## πŸš€ Next Steps (Phase 2) ### Step 1: Integrate ToastContainer into App ```typescript // frontend/src/App.tsx import ToastContainer from './components/ToastContainer' function App() { return (
{/* ... rest of app */}
) } ``` ### Step 2: Refactor Views to Use New Utilities **Priority order:** 1. βœ… **TipsView.tsx** (example already created) 2. **ActivitiesView.tsx** (~15 LOC saved) 3. **MeditationsView.tsx** (~18 LOC saved) 4. **SelfReturnView.tsx** (~20 LOC saved) 5. **AttachmentStylesView.tsx** (~12 LOC saved) **Refactoring pattern:** ```typescript // BEFORE: const [data, setData] = useState([]) const [loading, setLoading] = useState(true) const [toast, setToast] = useState(null) useEffect(() => { fetch('/api/content/tips') .then(res => res.json()) .then(data => setData(data.tips || [])) .catch(() => setData([])) .finally(() => setLoading(false)) }, []) useEffect(() => { if (!toast) return const timer = setTimeout(() => setToast(null), 3000) return () => clearTimeout(timer) }, [toast]) // AFTER: const { data: tipsContent, loading } = useApiData({ url: '/api/content/tips', fallback: { tips: [] } }) const tips = tipsContent.tips // Replace setToast() with: import { toast } from '../state/modules/toast' toast.success('Message here') ``` ### Step 3: Refactor ProfileView ProfileView.tsx is the largest file (798 LOC) and needs special attention. **Plan:** 1. Extract `NoContactSection.tsx` (~150 LOC) 2. Extract `MedalsSection.tsx` (~200 LOC) 3. Use `useApiData` for medals loading 4. Use toast store for notifications **Expected result:** ProfileView.tsx: 798 β†’ ~450 LOC ### Step 4: Add Error Boundaries ```typescript // frontend/src/components/ErrorBoundary.tsx export class ErrorBoundary extends React.Component { componentDidCatch(error: Error) { toast.error(t('errors.unknown')) console.error('ErrorBoundary caught:', error) } } ``` ### Step 5: Update Tests Add integration tests for refactored views: ```typescript // frontend/tests/TipsView.integration.test.tsx describe('TipsView integration', () => { it('should load and display tips', async () => { render() await waitFor(() => { expect(screen.getByText('RychlΓ© tipy')).toBeInTheDocument() }) }) }) ``` --- ## πŸ“Š Expected Results ### LOC Changes: ``` Phase 1 (Completed): New utilities created: +550 LOC New tests created: +250 LOC Total created: +800 LOC Phase 2 (To Do): Views refactored: -220 LOC (duplicates eliminated) ProfileView split: -100 LOC (better organization) Total eliminated: -320 LOC Net change: +480 LOC (architectural investment) ``` ### Quality Improvements: - βœ… Consistent error handling - βœ… Type-safe API calls - βœ… Centralized toast management - βœ… Reusable data fetching patterns - βœ… Better testability - βœ… Cleaner component code ### Test Coverage: - βœ… 3 new utility test files - πŸ”„ 5-10 integration tests to add - πŸ”„ Update existing tests for refactored views --- ## πŸ”„ Migration Checklist For each view being refactored: - [ ] Replace `fetch()` with `useApiData()` - [ ] Remove `useState` for loading/error - [ ] Replace local toast logic with `toast.*` functions - [ ] Update imports - [ ] Add/update tests - [ ] Verify functionality in browser - [ ] Check for console errors - [ ] Update documentation --- ## 🎯 Success Criteria Phase 2 is complete when: 1. βœ… All 5 priority views use `useApiData` 2. βœ… All toast notifications use toast store 3. βœ… No duplicated fetch/loading/error patterns 4. βœ… ProfileView split into sub-components 5. βœ… All tests passing (277 backend + 90+ frontend) 6. βœ… No console errors in development 7. βœ… Documentation updated --- ## πŸ“ Notes ### API Client Benefits: - Centralized error handling - Consistent retry logic (future) - Request/response logging (future) - Type safety across app ### useApiData Benefits: - Eliminates 10-15 LOC per view - Consistent loading states - Easy to add features (caching, retries) ### Toast Store Benefits: - Eliminates 8-12 LOC per view - Consistent UX - Queue management - Easy to extend ### Why This Matters: Frontend is already well-structured. These changes: - Remove remaining duplicates - Improve consistency - Make future features easier - Better align with backend patterns --- ## πŸ”— Related Documents - [Frontend Audit Report](./frontend-audit-report.md) - Full analysis - [Backend Audit Report](./backend-audit-report.md) - Comparison - [Lessons Learned](./lessons-learned.md) - Best practices - [ARCHITECTURE.md](./ARCHITECTURE.md) - System architecture --- **Next Action:** Review with team, then start Phase 2 refactoring