Files
job-tracker/docs/frontend/home-page-mui.md
T
Marko (Hermes Implementer) 811045daca feat: home page with MUI components
- 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
2026-05-26 04:38:49 +00:00

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 AppBar with Toolbar, Typography ("Job Tracker")
  • Wraps child content via Outlet from React Router

UpdateCard

  • MUI CardCardContent
  • Displays: company name, position title, status change (from_statusto_status), created date, metrics summary
  • Props: JobUpdate

MetricsPanel

  • MUI Grid container with metric Card items
  • Each metric: total applications, interviews count, offers count, rejection rate
  • Props: DashboardMetrics

LoadingSkeleton

  • MUI Skeleton components 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: /apihttp://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)