"use client"; import { useEffect, useState, useCallback } from "react"; import { Permission } from "../auth-context"; import { api } from "../api"; import { layoutStyles, cardStyles, tableStyles, paginationStyles } from "../styles/shared"; import { Header } from "../components/Header"; import { useRequireAuth } from "../hooks/useRequireAuth"; import { components } from "../generated/api"; // Use generated types from OpenAPI schema type _CounterRecord = components["schemas"]["CounterRecordResponse"]; type _SumRecord = components["schemas"]["SumRecordResponse"]; type PaginatedCounterRecords = components["schemas"]["PaginatedResponse_CounterRecordResponse_"]; type PaginatedSumRecords = components["schemas"]["PaginatedResponse_SumRecordResponse_"]; export default function AuditPage() { const [counterData, setCounterData] = useState(null); const [sumData, setSumData] = useState(null); const [counterError, setCounterError] = useState(null); const [sumError, setSumError] = useState(null); const [counterPage, setCounterPage] = useState(1); const [sumPage, setSumPage] = useState(1); const { user, isLoading, isAuthorized } = useRequireAuth({ requiredPermission: Permission.VIEW_AUDIT, fallbackRedirect: "/", }); const fetchCounterRecords = useCallback(async (page: number) => { setCounterError(null); try { const data = await api.get( `/api/audit/counter?page=${page}&per_page=10` ); setCounterData(data); } catch (err) { setCounterData(null); setCounterError(err instanceof Error ? err.message : "Failed to load counter records"); } }, []); const fetchSumRecords = useCallback(async (page: number) => { setSumError(null); try { const data = await api.get(`/api/audit/sum?page=${page}&per_page=10`); setSumData(data); } catch (err) { setSumData(null); setSumError(err instanceof Error ? err.message : "Failed to load sum records"); } }, []); useEffect(() => { if (user && isAuthorized) { fetchCounterRecords(counterPage); } }, [user, counterPage, isAuthorized, fetchCounterRecords]); useEffect(() => { if (user && isAuthorized) { fetchSumRecords(sumPage); } }, [user, sumPage, isAuthorized, fetchSumRecords]); const formatDate = (dateStr: string) => { return new Date(dateStr).toLocaleString(); }; if (isLoading) { return (
Loading...
); } if (!user || !isAuthorized) { return null; } return (
{/* Counter Records Table */}

Counter Activity

{counterData?.total ?? 0} records
{counterError && ( )} {!counterError && counterData?.records.map((record) => ( ))} {!counterError && (!counterData || counterData.records.length === 0) && ( )}
User Before After Date
{counterError}
{record.user_email} {record.value_before} {record.value_after} {formatDate(record.created_at)}
No records yet
{counterData && counterData.total_pages > 1 && (
{counterPage} / {counterData.total_pages}
)}
{/* Sum Records Table */}

Sum Activity

{sumData?.total ?? 0} records
{sumError && ( )} {!sumError && sumData?.records.map((record) => ( ))} {!sumError && (!sumData || sumData.records.length === 0) && ( )}
User A B Result Date
{sumError}
{record.user_email} {record.a} {record.b} {record.result} {formatDate(record.created_at)}
No records yet
{sumData && sumData.total_pages > 1 && (
{sumPage} / {sumData.total_pages}
)}
); } // Page-specific styles only const styles: Record = { tablesContainer: { display: "flex", flexDirection: "column", gap: "2rem", maxWidth: "1200px", margin: "0 auto", }, tdResult: { padding: "0.875rem 1rem", fontSize: "0.875rem", color: "#a78bfa", fontWeight: 600, fontFamily: "'DM Sans', monospace", }, };