Files
lotteryAdmin/src/modules/risk/risk-index-console.tsx

99 lines
3.2 KiB
TypeScript

"use client";
import Link from "next/link";
import { useCallback, useEffect, useState } from "react";
import { getAdminDraws } from "@/api/admin-draws";
import { buttonVariants } from "@/components/ui/button";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
} from "@/components/ui/table";
import { DrawStatusBadge } from "@/modules/draws/draw-status-badge";
import { useAdminDateTimeFormatter } from "@/hooks/use-admin-datetime-formatter";
import { cn } from "@/lib/utils";
import { LotteryApiBizError } from "@/types/api/errors";
import type { AdminDrawListData, AdminDrawListItem } from "@/types/api/admin-draws";
export function RiskIndexConsole() {
const formatDt = useAdminDateTimeFormatter();
const [data, setData] = useState<AdminDrawListData | null>(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
const load = useCallback(async () => {
setLoading(true);
setError(null);
try {
const d = await getAdminDraws({ page: 1, per_page: 50 });
setData(d);
} catch (e) {
const msg =
e instanceof LotteryApiBizError ? e.message : "加载期号列表失败";
setError(msg);
setData(null);
} finally {
setLoading(false);
}
}, []);
useEffect(() => {
queueMicrotask(() => {
void load();
});
}, [load]);
return (
<Card>
<CardHeader>
<CardTitle className="text-lg"></CardTitle>
</CardHeader>
<CardContent className="space-y-4">
{error ? <p className="text-sm text-destructive">{error}</p> : null}
{loading ? (
<p className="text-sm text-muted-foreground"></p>
) : (
<div className="overflow-x-auto rounded-md border">
<Table>
<TableHeader>
<TableRow>
<TableHead></TableHead>
<TableHead></TableHead>
<TableHead></TableHead>
<TableHead className="text-right"></TableHead>
</TableRow>
</TableHeader>
<TableBody>
{(data?.items ?? []).map((row: AdminDrawListItem) => (
<TableRow key={row.id}>
<TableCell className="font-mono font-medium">{row.draw_no}</TableCell>
<TableCell>
<DrawStatusBadge status={row.status} />
</TableCell>
<TableCell className="text-sm text-muted-foreground">
{row.close_time ? formatDt(row.close_time) : "—"}
</TableCell>
<TableCell className="text-right">
<Link
href={`/admin/risk/draws/${row.id}/occupancy`}
className={cn(buttonVariants({ variant: "secondary", size: "sm" }))}
>
</Link>
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</div>
)}
</CardContent>
</Card>
);
}