MCPcopy Create free account
hub / github.com/dev-lou/voting-system / OverviewPanel

Function OverviewPanel

src/components/admin/OverviewPanel.tsx:12–179  ·  view source on GitHub ↗
()

Source from the content-addressed store, hash-verified

10interface Stats {
11 totalVoters: number;
12 votesCast: number;
13 activeSections: number;
14 activeElection: Election | null;
15}
16
17interface SectionTurnout {
18 year_section: string;
19 total_voters: number;
20 votes_cast: number;
21}
22
23export function OverviewPanel({ onGoToAudit }: { onGoToAudit?: () => void }) {
24 const [stats, setStats] = useState<Stats | null>(null);
25 const [sections, setSections] = useState<SectionTurnout[]>([]);
26 const [loading, setLoading] = useState(true);
27 const [auditLog, setAuditLog] = useState<AuditEntry[]>([]);
28 const adminEmail = sessionStorage.getItem(ADMIN_SESSION_KEY) ?? "";
29
30 const [isDark, setIsDark] = useState(false);
31
32 useEffect(() => {
33 const checkDark = () => setIsDark(document.documentElement.classList.contains("dark"));
34 checkDark();
35 const observer = new MutationObserver(checkDark);
36 observer.observe(document.documentElement, { attributes: true, attributeFilter: ["class"] });
37 return () => observer.disconnect();
38 }, []);
39
40 async function load() {
41 setLoading(true);
42 try {
43 const [statsRes, sectionRes, electionRes] = await Promise.all([
44 supabase.rpc("admin_get_stats", { p_admin_email: adminEmail }),
45 supabase.rpc("admin_get_section_turnout", { p_admin_email: adminEmail }),
46 supabase.from("elections").select("*").eq("is_active", true).maybeSingle(),
47 ]);
48
49 const statsArray = statsRes.data as Array<{ total_voters: number; votes_cast: number; active_sections: number }> | null;
50 const statsData = statsArray?.[0] ?? null;
51
52 setStats({
53 totalVoters: statsData?.total_voters ?? 0,
54 votesCast: statsData?.votes_cast ?? 0,
55 activeSections: statsData?.active_sections ?? 0,
56 activeElection: electionRes.data as Election | null,
57 });
58
59 setSections((sectionRes.data as SectionTurnout[] | null) ?? []);
60 } catch (err) {
61 console.error("Failed to load stats:", err);
62 } finally {
63 setLoading(false);
64 }
65 }
66
67 useEffect(() => {
68 load();
69 setAuditLog(getAuditLog());

Callers

nothing calls this directly

Calls 3

getAuditLogFunction · 0.90
clearAuditLogFunction · 0.90
loadFunction · 0.70

Tested by

no test coverage detected