import { useState } from "react"; import { useAuditLog, type AuditLogRow } from "~/requestHandler/use-admin-hooks"; import { AdminTable, AdminPagination, AdminToolbar, AdminSearch, AdminSelect, AdminPageTitle, StatusBadge, faDate, useDebouncedValue, type Column, } from "~/components/admin/DataTable"; const PAGE_SIZE = 25; const ACTION: Record = { "seller.update": { label: "ویرایش فروشنده", tone: "blue" }, "user.update": { label: "ویرایش کاربر", tone: "blue" }, "product.update": { label: "ویرایش محصول", tone: "blue" }, "payout.complete": { label: "تکمیل تسویه", tone: "green" }, "payout.reject": { label: "رد تسویه", tone: "red" }, "ledger.backfill": { label: "بازسازی دفتر", tone: "gray" }, }; const TARGET_LABEL: Record = { seller: "فروشنده", user: "کاربر", product: "محصول", payout: "تسویه", ledger: "دفتر مالی", }; /** Compact before→after diff of the touched fields. */ function Changes({ before, after }: Pick) { const keys = Array.from( new Set([...Object.keys(before || {}), ...Object.keys(after || {})]) ); const changed = keys.filter( (k) => JSON.stringify(before?.[k]) !== JSON.stringify(after?.[k]) ); if (changed.length === 0) return ; return (
{changed.map((k) => ( {k}: {fmt(before?.[k])} {fmt(after?.[k])} ))}
); } function fmt(v: unknown) { if (v === null || v === undefined) return "∅"; if (typeof v === "boolean") return v ? "true" : "false"; return String(v); } export default function AdminAudit() { const [page, setPage] = useState(1); const [search, setSearch] = useState(""); const [action, setAction] = useState(""); const [targetType, setTargetType] = useState(""); const debouncedSearch = useDebouncedValue(search); const { data, isLoading } = useAuditLog({ page, page_size: PAGE_SIZE, search: debouncedSearch, action, target_type: targetType, }); const reset = (fn: () => void) => { fn(); setPage(1); }; const columns: Column[] = [ { header: "عملیات", render: (r) => { const a = ACTION[r.action] || { label: r.action, tone: "gray" as const }; return ; }, }, { header: "هدف", render: (r) => ( {TARGET_LABEL[r.targetType] || r.targetType} {r.targetId && ( · {r.targetId.slice(0, 8)} )} ), }, { header: "تغییرات", render: (r) => , }, { header: "مدیر", render: (r) => ( {r.actorPhone || "سیستم"} ), }, { header: "تاریخ", render: (r) => {faDate(r.createdAt)}, }, ]; return (
گزارش فعالیت مدیران reset(() => setSearch(v))} placeholder="جستجوی تلفن مدیر / شناسه هدف…" /> reset(() => setAction(v))} options={[ { value: "", label: "همه عملیات‌ها" }, { value: "seller.update", label: "ویرایش فروشنده" }, { value: "user.update", label: "ویرایش کاربر" }, { value: "product.update", label: "ویرایش محصول" }, { value: "payout.complete", label: "تکمیل تسویه" }, { value: "payout.reject", label: "رد تسویه" }, { value: "ledger.backfill", label: "بازسازی دفتر" }, ]} /> reset(() => setTargetType(v))} options={[ { value: "", label: "همه هدف‌ها" }, { value: "seller", label: "فروشنده" }, { value: "user", label: "کاربر" }, { value: "product", label: "محصول" }, { value: "payout", label: "تسویه" }, ]} /> r.id} emptyText="فعالیتی ثبت نشده است" />
); }