import React, { useCallback, useEffect, useMemo, useState } from "react"; import { Box, Button, Chip, Paper, Table, TableBody, TableCell, TableContainer, TableHead, TableRow, Typography, } from "@mui/material"; import { api } from "../api"; import { useToast } from "../toast"; import { useI18n } from "../i18n/I18nProvider"; type AuditItem = { id: number; type: string; oldValue?: string | null; newValue?: string | null; note?: string | null; at: string; jobApplicationId: number; jobTitle?: string | null; companyName?: string | null; ownerUserId?: string | null; ownerEmail?: string | null; ownerUserName?: string | null; }; function canUndo(type: string) { return ["StatusChanged", "FollowUpSet", "ResponseUpdated", "Deleted", "Restored"].includes(type); } export default function AdminAuditPage() { const { toast } = useToast(); const { t } = useI18n(); const [items, setItems] = useState([]); const [loading, setLoading] = useState(false); const [busyId, setBusyId] = useState(null); const load = useCallback(async () => { setLoading(true); try { const r = await api.get("/admin/audit?take=200"); setItems(r.data ?? []); } catch { setItems([]); } finally { setLoading(false); } }, []); useEffect(() => { void load(); }, [load]); const undo = async (e: AuditItem) => { if (!canUndo(e.type)) return; setBusyId(e.id); try { const res = await api.post<{ ok: boolean; message: string }>(`/admin/audit/${e.id}/undo`, {}); toast(res.data?.message || "Undone.", "success"); await load(); } catch (err: any) { const msg = err?.response?.data?.message || err?.response?.data || err?.message || "Undo failed."; toast(String(msg), "error"); } finally { setBusyId(null); } }; const restore = async (e: AuditItem) => { setBusyId(e.id); try { await api.post(`/jobapplications/${e.jobApplicationId}/restore`, {}); toast(t("adminAuditRestored"), "success"); await load(); } catch (err: any) { const msg = err?.response?.data || err?.message || "Restore failed."; toast(String(msg), "error"); } finally { setBusyId(null); } }; const rows = useMemo(() => items, [items]); return ( {t("adminAuditTitle")} {t("adminAuditSubtitle")} {t("adminAuditAt")} {t("adminAuditType")} {t("adminAuditJob")} {t("adminAuditUser")} {t("adminAuditDetails")} {t("adminAuditActions")} {loading ? ( {t("loading")} ) : rows.length === 0 ? ( {t("adminAuditNoEvents")} ) : ( rows.map((e) => { const jobLabel = e.jobTitle || `Job #${e.jobApplicationId}`; const ownerLabel = e.ownerEmail || e.ownerUserName || e.ownerUserId || "-"; const details = e.oldValue || e.newValue ? `${e.oldValue ?? ""} -> ${e.newValue ?? ""}` : ""; const disabled = busyId === e.id; const showRestore = e.type === "Deleted"; return ( {e.at ? new Date(e.at).toLocaleString() : ""} {e.companyName ? `${e.companyName} - ` : ""} {jobLabel} jobId={e.jobApplicationId} {ownerLabel} {details} {e.note ? `${details ? "\n" : ""}${e.note}` : ""} {canUndo(e.type) ? ( ) : null} {showRestore ? ( ) : null} ); }) )}
); }