"use client"; import Link from "next/link"; import { useCallback, useMemo, useState, type ReactElement } from "react"; import { useTranslation } from "react-i18next"; import { ClipboardList, RefreshCw, Search, Users } from "lucide-react"; import { getAdminDashboard } from "@/api/admin-dashboard"; import { useAsyncEffect } from "@/hooks/use-async-effect"; import { useAdminDateTimeFormatter } from "@/hooks/use-admin-datetime-formatter"; import { useTranslationRef } from "@/hooks/use-translation-ref"; import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert"; import { Button, buttonVariants } from "@/components/ui/button"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { Skeleton } from "@/components/ui/skeleton"; import { AdminNoResourceState } from "@/components/admin/admin-no-resource-state"; import { DashboardKpiCard, DashboardScopeMetric, } from "@/modules/dashboard/dashboard-visuals"; import { cn } from "@/lib/utils"; import { useAdminProfile } from "@/stores/admin-session"; import type { AdminDashboardSiteCsOverview, AdminDashboardWarning, } from "@/types/api/admin-dashboard"; import { LotteryApiBizError } from "@/types/api/errors"; export function SiteCsDashboardConsole(): ReactElement { const { t } = useTranslation(["dashboard", "common"]); const tRef = useTranslationRef(["dashboard", "common"]); const formatDt = useAdminDateTimeFormatter(); const profile = useAdminProfile(); const site = profile?.site ?? null; const [loading, setLoading] = useState(true); const [refreshing, setRefreshing] = useState(false); const [error, setError] = useState(null); const [apiWarnings, setApiWarnings] = useState([]); const [overview, setOverview] = useState(null); const load = useCallback(async (isRefresh = false) => { if (isRefresh) { setRefreshing(true); } else { setLoading(true); } setError(null); try { const d = await getAdminDashboard(); setOverview(d.site_cs_overview); setApiWarnings(d.warnings ?? []); } catch (e) { const msg = e instanceof LotteryApiBizError ? e.message : tRef.current("warnings.loadFailed"); setError(msg); } finally { setLoading(false); setRefreshing(false); } }, [tRef]); useAsyncEffect(() => { void load(false); }, []); const activityHint = useMemo(() => { if (!overview) { return ""; } if (overview.latest_ticket_at) { return t("cs.latestTicketAt", { time: formatDt(overview.latest_ticket_at) }); } return t("cs.noTicketToday"); }, [formatDt, overview, t]); const quickLinks = useMemo( () => [ { href: "/admin/players", label: t("cs.quickLinks.players"), icon: Users }, { href: "/admin/tickets", label: t("cs.quickLinks.tickets"), icon: ClipboardList }, { href: "/admin/wallet/transactions", label: t("cs.quickLinks.wallet"), icon: Search }, ], [t], ); return (

{t("cs.title")}

{site ? t("cs.subtitle", { name: site.name || site.code }) : t("cs.subtitleFallback")}

{error ? ( {t("notice")} {error} ) : null} {!loading && apiWarnings.length > 0 ? ( {t("notice")} {apiWarnings.map((w) => w.message).join(" ")} ) : null} {loading ? (
{Array.from({ length: 3 }).map((_, i) => ( ))}
) : overview ? (
} hint={t("cs.playerCountHint")} /> } hint={activityHint} /> } hint={t("cs.activePlayersHint")} />
{t("cs.workspaceTitle")} {quickLinks.map((link) => { const Icon = link.icon; return ( {link.label} {t("cs.openModule")} ); })} {t("cs.scopeTitle")}
) : ( {t("cs.overviewEmpty")} )}
); }