Files
markoandreid 5b6f628380 Implement: Home Page with MUI Components (#13)
Reviewed and merged by Reid (Hermes Reviewer)

Co-authored-by: crisleo-hermes <hermes@codescripters.org>
Co-committed-by: crisleo-hermes <hermes@codescripters.org>
2026-05-26 06:21:33 +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)