# UI Architecture
This document describes the user interface architecture and how the frontend integrates with the backend API.
## Overview
The UI is built with React and TypeScript, using Material-UI for components. The frontend communicates with the FastAPI backend through REST API endpoints and WebSocket connections for real-time updates.
## Architecture
```
React Frontend → REST API / WebSocket → FastAPI Backend → Python Services → Database
```
## Frontend Structure
```
frontend/src/
├── pages/ # Page components (Trading, Portfolio, Strategies, etc.)
├── components/ # Reusable UI components
├── api/ # API client functions
├── hooks/ # Custom React hooks
└── types/ # TypeScript type definitions
```
## Page Components
### DashboardPage
- Overview of trading activity
- Key metrics and charts
- Quick actions
### TradingPage
- Order placement form
- Positions table
- Order history
- Real-time price updates
### PortfolioPage
- Portfolio summary
- Holdings table
- Risk metrics
- Performance charts
### StrategiesPage
- Strategy list and management
- Strategy configuration
- Start/stop controls
- Performance metrics
### BacktestPage
- Backtest configuration
- Results display
- Export functionality
### SettingsPage
- Exchange management
- Configuration settings
- API key management
## Real-Time Updates
### WebSocket Connection
The frontend connects to the backend WebSocket endpoint (`/ws/`) for real-time updates:
- Price updates
- Order status changes
- Position updates
- Strategy status changes
### Implementation
```typescript
// Using WebSocket hook
import { useWebSocket } from '@/hooks/useWebSocket';
function TradingPage() {
const { data, connected } = useWebSocket('/ws/');
// Handle real-time price updates
useEffect(() => {
if (data?.type === 'price_update') {
// Update UI with new price
}
}, [data]);
}
```
## API Integration
### API Client
All API calls go through the API client which handles:
- Request/response serialization
- Error handling
- Authentication (if added)
```typescript
// Example API call
import { tradingApi } from '@/api/trading';
const placeOrder = async () => {
const order = await tradingApi.placeOrder({
exchangeId: 1,
symbol: 'BTC/USD',
side: 'buy',
type: 'market',
quantity: 0.1,
paperTrading: true
});
};
```
### React Query
The frontend uses React Query for:
- Data fetching
- Caching
- Automatic refetching
- Optimistic updates
```typescript
import { useQuery, useMutation } from '@tanstack/react-query';
import { portfolioApi } from '@/api/portfolio';
function PortfolioPage() {
const { data, isLoading } = useQuery({
queryKey: ['portfolio'],
queryFn: () => portfolioApi.getCurrent()
});
const updateMutation = useMutation({
mutationFn: portfolioApi.update,
onSuccess: () => {
// Invalidate and refetch
queryClient.invalidateQueries({ queryKey: ['portfolio'] });
}
});
}
```
## State Management
### Component State
- Local component state with `useState`
- Form state management
- UI-only state (modals, tabs, etc.)
### Server State
- React Query for server state
- Automatic caching and synchronization
- Optimistic updates
### Global State
- Context API for theme, auth (if needed)
- Minimal global state - prefer server state
## Component Patterns
### Container/Presentational Pattern
```typescript
// Container component (handles data fetching)
function TradingPageContainer() {
const { data } = useQuery({ queryKey: ['orders'], queryFn: fetchOrders });
return ;
}
// Presentational component (pure UI)
function TradingPage({ orders }) {
return (
);
}
```
### Custom Hooks
Extract reusable logic into custom hooks:
```typescript
function useOrders() {
const { data, isLoading, error } = useQuery({
queryKey: ['orders'],
queryFn: () => tradingApi.getOrders()
});
const placeOrder = useMutation({
mutationFn: tradingApi.placeOrder
});
return { orders: data, isLoading, error, placeOrder };
}
```
## Error Handling
### API Errors
```typescript
try {
await tradingApi.placeOrder(order);
} catch (error) {
if (error.response?.status === 400) {
// Handle validation error
} else if (error.response?.status === 500) {
// Handle server error
}
}
```
### Error Boundaries
Use React Error Boundaries to catch and display errors gracefully:
```typescript
}>
```
## Performance Optimization
### Code Splitting
Use React.lazy for code splitting:
```typescript
const TradingPage = lazy(() => import('@/pages/TradingPage'));
}>
```
### Memoization
Use React.memo, useMemo, and useCallback to prevent unnecessary re-renders:
```typescript
const MemoizedTable = React.memo(OrdersTable);
const filteredData = useMemo(() => {
return data.filter(/* ... */);
}, [data, filter]);
```
## Testing
See [Testing Guide](../developer/testing.md) for frontend testing strategies.
## Styling
- Material-UI components and theming
- Consistent design system
- Dark/light theme support
- Responsive design
## Accessibility
- Semantic HTML
- ARIA labels where needed
- Keyboard navigation
- Screen reader support