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>
This commit was merged in pull request #13.
This commit is contained in:
2026-05-26 06:21:33 +00:00
committed by reid
parent b91b7c364e
commit 5b6f628380
32 changed files with 2092 additions and 34 deletions
+50
View File
@@ -0,0 +1,50 @@
import { useState, useEffect, useCallback } from "react";
import type { DashboardData, JobUpdate, DashboardMetrics } from "../types/index.ts";
interface UseDashboardDataResult {
data: DashboardData | null;
loading: boolean;
error: string | null;
refetch: () => void;
}
const API_BASE = "/api";
async function fetchJson<T>(url: string): Promise<T> {
const response = await fetch(url);
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
return response.json() as Promise<T>;
}
export function useDashboardData(): UseDashboardDataResult {
const [data, setData] = useState<DashboardData | null>(null);
const [loading, setLoading] = useState<boolean>(true);
const [error, setError] = useState<string | null>(null);
const fetchData = useCallback(async () => {
setLoading(true);
setError(null);
try {
const [updates, metrics] = await Promise.all([
fetchJson<JobUpdate[]>(`${API_BASE}/updates/latest/`),
fetchJson<DashboardMetrics>(`${API_BASE}/updates/metrics/`),
]);
setData({ updates, metrics });
} catch (err: unknown) {
const message =
err instanceof Error ? err.message : "An unknown error occurred";
setError(message);
} finally {
setLoading(false);
}
}, []);
useEffect(() => {
fetchData();
}, [fetchData]);
return { data, loading, error, refetch: fetchData };
}