Frontend Guide
Framework
React 18 with TypeScript, built with Vite.
Key libraries:
- •
@mui/material(v7) - Component library with custom amber/gold theme - •
@tanstack/react-query(v5) - Server state management with caching - •
react-router-dom(v7) - Client-side routing - •
axios- HTTP client - •
recharts- Charting - •
react-day-picker- Date selection - •
react-dropzone- File uploads - •
date-fns- Date utilities
Component Structure
code
bank-statements-web/src/ ├── api/ # API clients and context │ ├── ApiClient.ts # Client interface aggregating domain clients │ ├── ApiContext.tsx # React context for API access │ ├── *Client.ts # Domain-specific API clients (TransactionClient, CategoryClient, etc.) │ └── AuthClient.ts # Authentication API ├── auth/ # Authentication │ ├── AuthContext.tsx # Auth state + token refresh │ └── ProtectedRoute.tsx # Route guard ├── components/ # Reusable UI components │ ├── layout/ # AppLayout, AppNavigation, UserMenu │ ├── upload/ # File upload components │ ├── DatePeriodNavigator/# Date navigation with own CSS │ └── *.tsx # Feature components (TransactionTable, CategorySelector, etc.) ├── pages/ # Route page components │ └── *.tsx # One per route (Transactions, Categories, Charts, etc.) ├── services/hooks/ # Custom data hooks │ └── use*.ts # useTransactions, useCategories, useAccounts, etc. ├── theme/ # Theme configuration │ └── ThemeContext.tsx # MUI theme + light/dark mode ├── types/ # TypeScript types │ └── *.ts # Transaction, EnhancementRule, Auth, etc. ├── utils/ # Utility functions │ ├── format.ts # Currency/date formatting │ └── categoryColors.ts # Category colour utilities ├── App.tsx # Router configuration └── main.tsx # App entry point with providers
State Management
Three-tier approach:
- •
Server State - TanStack Query
- •5-minute stale time by default
- •Manual cache invalidation via
queryClient.invalidateQueries() - •Query keys defined per-hook (e.g.
TRANSACTION_QUERY_KEYS)
- •
Global UI State - React Context
- •
AuthContext- User session, login/logout, token refresh - •
ThemeContext- Light/dark/system mode with localStorage persistence - •
ApiContext- Provides API client to components
- •
- •
Local State - useState/useCallback
- •Filter state with URL sync via
useSearchParams - •Modal open/close states
- •Debounced input values
- •Filter state with URL sync via
Data Hooks Pattern:
tsx
// Services layer wraps API calls with caching and mutation logic
const { transactions, loading, fetchTransactions, categorizeTransaction } = useTransactions()
Routing
React Router v7 with nested routes:
- •
/login,/register,/auth/callback- Public routes - •
/- Protected route wrapper withAppLayout- •
/transactions(index) - •
/categories - •
/accounts - •
/charts - •
/recurring - •
/enhancement-rules - •
/categorizations - •
/statements - •
/upload - •
/settings
- •
Route guards via ProtectedRoute component checking AuthContext.
Styling
Hybrid approach:
- •
CSS Variables (
index.css)- •Design tokens:
--bg-primary,--text-accent,--button-primary, etc. - •Dark mode via
[data-theme='dark']selector - •Typography: Sora (display), DM Sans (body), JetBrains Mono (numbers)
- •Design tokens:
- •
MUI Theme (
ThemeContext.tsx)- •Extends CSS variables into MUI components
- •Component overrides for Drawer, AppBar, TableCell, etc.
- •Amber/gold accent colour scheme
- •
Component CSS (co-located
*.cssfiles)- •Page-specific styles:
TransactionsPage.css,CategoriesPage.css - •Component-specific:
Pagination.css,CategorySelector.css
- •Page-specific styles:
- •
MUI Overrides (in
index.css)- •Global button, input, dialog styling
- •Icon button states and colours
Creating Components
Page Components:
- •Create
src/pages/MyPage.tsx - •Add corresponding
src/pages/MyPage.cssif needed - •Register route in
App.tsx - •Add navigation entry in
components/layout/AppNavigation.tsx
Feature Components:
- •Create in
src/components/MyComponent.tsx - •Use MUI components + CSS variables for styling
- •Accept data/callbacks as props, avoid internal API calls
Data Hooks:
- •Create in
src/services/hooks/useMyData.ts - •Use
useApi()for API access - •Define query keys for cache management
- •Wrap mutations with error handling
API Clients:
- •Create
src/api/MyClient.tswith typed methods - •Add to
ApiClientinterface - •Instantiate in
createApiClient.ts
Key Patterns
- •URL Filter Sync: Pages sync filter state to URL params for shareable links
- •Debounced Inputs: Text/amount filters use local state + debounce before API call
- •Optimistic Updates: Mutations update local state immediately, then invalidate cache
- •Responsive Layout:
AppLayoutswitches between permanent/temporary drawer based on screen size and touch detection - •Modal Pattern: State managed in parent page, data passed as props