- Rewrote frontend from JSX to TypeScript (TSX) - AppLayout with MUI AppBar, ThemeProvider, CssBaseline - HomePage at / with dashboard metrics and recent updates - MetricsPanel with 4 metric cards (total, interviews, offers, rejection rate) - UpdateCard for each job update with status chip - LoadingSkeleton during data fetch - Error Alert on API failure - Create New Job Application button navigating to /applications/new - Vite proxy for /api → backend on :8000 - useDashboardData custom hook with concurrent fetch Closes #2
3.2 KiB
3.2 KiB
Spec: Home Page with MUI Components
Ticket
Gitea: crisleo-hermes/job-tracker#2 Kanban: t_e6936299
Overview
Build a home page at route / using Material-UI (MUI) components that displays the last three job updates and dashboard metrics, with a button to create a new job application.
Pages
HomePage (/)
- AppBar with title "Job Tracker"
- Dashboard metrics cards row (total applications, interviews, offers, rejection rate)
- Last 3 job updates displayed as cards
- "Create New Job Application" button (navigates to creation flow)
- Loading skeleton while data fetches
- Error snackbar on API failure
- Responsive Grid layout
API Endpoints Consumed
| Method | Path | Description |
|---|---|---|
| GET | /api/updates/latest/ |
3 most recent JobUpdates with nested job info |
| GET | /api/updates/metrics/ |
Dashboard metrics (total, status breakdown, interviews, offers, rejection rate) |
Response Shapes
GET /api/updates/latest/
[
{
"id": 1,
"job_id": 1,
"company_name": "Acme Corp",
"position_title": "Software Engineer",
"from_status": "APPLIED",
"to_status": "INTERVIEW",
"notes": "Moving to next round",
"created_at": "2025-01-15T10:00:00Z",
"metrics": {"response_time_days": 5}
}
]
GET /api/updates/metrics/
{
"total_applications": 12,
"status_breakdown": {"APPLIED": 5, "INTERVIEW": 4, "OFFER": 2, "REJECTED": 1},
"interviews_count": 6,
"offers_count": 2,
"rejection_rate": 8.3
}
Components
AppLayout
- MUI
AppBarwithToolbar,Typography("Job Tracker") - Wraps child content via
Outletfrom React Router
UpdateCard
- MUI
Card→CardContent - Displays: company name, position title, status change (
from_status→to_status), created date, metrics summary - Props:
JobUpdate
MetricsPanel
- MUI
Gridcontainer with metricCarditems - Each metric: total applications, interviews count, offers count, rejection rate
- Props:
DashboardMetrics
LoadingSkeleton
- MUI
Skeletoncomponents mimicking the home page layout
Data Fetching
Custom hook useDashboardData using React's useEffect + useState:
- Fetches from
/api/updates/latest/and/api/updates/metrics/concurrently (Promise.all) - Vite proxy:
/api→http://localhost:8000/api - States: loading, error (with error message), data
TypeScript Types
interface JobUpdate {
id: number;
job_id: number;
company_name: string;
position_title: string;
from_status: string | null;
to_status: string;
notes: string;
created_at: string;
metrics: Record<string, unknown>;
}
interface DashboardMetrics {
total_applications: number;
status_breakdown: Record<string, number>;
interviews_count: number;
offers_count: number;
rejection_rate: number;
}
Acceptance Criteria
- Home page at route
/ - MUI components exclusively (AppBar, Typography, Card, Grid, Button, Skeleton, Snackbar)
- Last 3 job updates: job ID, status, creation date, metrics
- "Create New Job Application" button navigates to
/applications/new - Loading indicators while fetching data (Skeleton components)
- Graceful error handling (Snackbar with error message)
- Responsive layout (Grid breakpoints)