"use client"; import type React from "react"; import { useCallback, useEffect, useState } from "react"; import { useTranslation } from "react-i18next"; import { getAdminJackpotContributions, getAdminJackpotPayoutLogs } from "@/api/admin-jackpot"; import { AdminListPaginationFooter } from "@/components/admin/admin-list-pagination-footer"; import { AdminTableExportButton } from "@/components/admin/admin-table-export-button"; import { ModuleScaffold } from "@/components/admin/module-scaffold"; import { Button } from "@/components/ui/button"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from "@/components/ui/table"; import { useAdminDateTimeFormatter } from "@/hooks/use-admin-datetime-formatter"; import { useExportLabels } from "@/hooks/use-export-labels"; import { formatAdminMinorUnits } from "@/lib/money"; import { LotteryApiBizError } from "@/types/api/errors"; import type { AdminJackpotContributionsData, AdminJackpotPayoutLogsData, } from "@/types/api/admin-jackpot"; type JackpotRecordsConsoleProps = { embedded?: boolean; }; /** 表格在 admin-table-shell 内时去掉 Table 组件自带的第二层边框 */ const TABLE_IN_SHELL_CLASS = "[&_[data-slot=table-container]]:rounded-none [&_[data-slot=table-container]]:border-0 [&_[data-slot=table-container]]:bg-transparent [&_[data-slot=table-container]]:shadow-none"; function JackpotRecordTableSection({ title, tableId, exportFilename, exportSheetName, loading, hasData, children, footer, }: { title: string; tableId: string; exportFilename: string; exportSheetName: string; loading: boolean; hasData: boolean; children: React.ReactNode; footer: React.ReactNode; }) { const { t } = useTranslation("common"); return (

{title}

{loading && !hasData ? (

{t("states.loading")}

) : (
{children}
)} {footer ?
{footer}
: null}
); } export function JackpotRecordsConsole({ embedded = false }: JackpotRecordsConsoleProps) { const { t } = useTranslation(["jackpot", "common"]); const payoutExport = useExportLabels("jackpotPayouts"); const contributionExport = useExportLabels("jackpotContributions"); const formatDt = useAdminDateTimeFormatter(); const [drawNo, setDrawNo] = useState(""); const [appliedDrawNo, setAppliedDrawNo] = useState(""); const [payouts, setPayouts] = useState(null); const [pPage, setPPage] = useState(1); const [pPer, setPPer] = useState(10); const [contribs, setContribs] = useState(null); const [cPage, setCPage] = useState(1); const [cPer, setCPer] = useState(10); const [loadingP, setLoadingP] = useState(true); const [loadingC, setLoadingC] = useState(true); const [err, setErr] = useState(null); const loadPayouts = useCallback(async () => { setLoadingP(true); try { const d = await getAdminJackpotPayoutLogs({ page: pPage, per_page: pPer, draw_no: appliedDrawNo.trim() || undefined, }); setPayouts(d); } catch (e) { setErr(e instanceof LotteryApiBizError ? e.message : t("payoutLoadFailed")); } finally { setLoadingP(false); } }, [pPage, pPer, appliedDrawNo, t]); const loadContribs = useCallback(async () => { setLoadingC(true); try { const d = await getAdminJackpotContributions({ page: cPage, per_page: cPer, draw_no: appliedDrawNo.trim() || undefined, }); setContribs(d); } catch (e) { setErr(e instanceof LotteryApiBizError ? e.message : t("contributionLoadFailed")); } finally { setLoadingC(false); } }, [cPage, cPer, appliedDrawNo, t]); useEffect(() => { queueMicrotask(() => { void loadPayouts(); }); }, [loadPayouts]); useEffect(() => { queueMicrotask(() => { void loadContribs(); }); }, [loadContribs]); const applyDraw = () => { setAppliedDrawNo(drawNo); setPPage(1); setCPage(1); }; const triggerTypeText = (value: string) => { const key = `triggerTypes.${value}`; const translated = t(key); return translated === key ? value : translated; }; const filterBlock = embedded ? (
setDrawNo(e.target.value)} placeholder={t("optional")} />
) : ( {t("filter")}
setDrawNo(e.target.value)} placeholder={t("optional")} />
); const payoutFooter = payouts ? ( { setPPer(n); setPPage(1); }} onPageChange={setPPage} /> ) : null; const contributionFooter = contribs ? ( { setCPer(n); setCPage(1); }} onPageChange={setCPage} /> ) : null; const payoutTable = ( {t("table.id", { ns: "common" })} {t("drawNo")} {t("trigger")} {t("payoutAmount")} {t("winnerCount")} {t("time")} {(payouts?.items ?? []).length === 0 ? ( {t("states.noData", { ns: "common" })} ) : ( (payouts?.items ?? []).map((r) => ( {r.id} {r.draw_no ?? "—"} {triggerTypeText(r.trigger_type)} {formatAdminMinorUnits(r.total_payout_amount, r.currency_code ?? "NPR")} {r.winner_count} {formatDt(r.created_at)} )) )}
); const contributionTable = ( {t("table.id", { ns: "common" })} {t("drawNo")} {t("ticketNo")} {t("player")} {t("contributionAmount")} {t("time")} {(contribs?.items ?? []).length === 0 ? ( {t("states.noData", { ns: "common" })} ) : ( (contribs?.items ?? []).map((r) => ( {r.id} {r.draw_no ?? "—"} {r.ticket_no ?? "—"} {r.player_username ?? "—"} {formatAdminMinorUnits(r.contribution_amount, r.currency_code ?? "NPR")} {formatDt(r.created_at)} )) )}
); const content = ( <> {filterBlock} {err ?

{err}

: null} {embedded ? (
{payoutTable} {contributionTable}
) : (
{payoutTable} {contributionTable}
)} ); if (embedded) { return content; } return {content}; }