"use client"; import { useEffect, useState, useCallback, startTransition } from "react"; import { motion } from "motion/react"; import { ScrollText, Search, ChevronLeft, ChevronRight, Zap } from "lucide-react"; import { TimeRangeSelector } from "@/components/TimeRangeSelector"; import { buildQuery, formatNumber, formatDate } from "@/lib/utils"; import { useTimeRange } from "@/lib/time-range-context"; import { useI18n } from "@/lib/i18n"; interface LogEntry { id: number; created_at: string; display_name: string; real_model: string; channel_name: string; prompt_tokens: number; completion_tokens: number; total_tokens: number; use_time: number; is_stream: boolean; } export default function LogsPage() { const { t } = useI18n(); const { getEffectiveRange } = useTimeRange(); const [page, setPage] = useState(1); const [logs, setLogs] = useState([]); const [total, setTotal] = useState(0); const [loading, setLoading] = useState(true); const [filters, setFilters] = useState({ username: "", model: "", token_name: "" }); const pageSize = 100; const fetchData = useCallback(async () => { startTransition(() => setLoading(true)); const { start, end } = getEffectiveRange(); const res = await fetch(buildQuery("/api/logs", { start, end, page, page_size: pageSize, ...filters })); const data = await res.json(); startTransition(() => { setLogs(data.logs); setTotal(data.total); setLoading(false); }); }, [page, filters, getEffectiveRange]); useEffect(() => { fetchData(); }, [fetchData]); useEffect(() => { startTransition(() => setPage(1)); }, [getEffectiveRange, filters]); const totalPages = Math.ceil(total / pageSize); const headers = [t("th.time"), t("th.user"), t("th.realModel"), t("th.channel"), t("th.input"), t("th.output"), t("th.totalToken"), t("th.latency"), ""]; return (

{t("logs.title")}

setFilters({ ...filters, username: e.target.value })} className="input-glass rounded-lg pl-9 pr-3 py-2 text-sm w-36" />
setFilters({ ...filters, model: e.target.value })} className="input-glass rounded-lg px-3 py-2 text-sm w-36" /> setFilters({ ...filters, token_name: e.target.value })} className="input-glass rounded-lg px-3 py-2 text-sm w-36" /> {formatNumber(total)} {t("common.records")}
{headers.map((h, i) => ( ))} {loading ? ( ) : logs.map((log) => ( ))}
= 4 ? "text-right" : "text-left"}`} style={{ color: "var(--text-muted)" }}>{h}
{formatDate(log.created_at)} {log.display_name} {log.real_model} {log.channel_name} {formatNumber(log.prompt_tokens)} {formatNumber(log.completion_tokens)} {formatNumber(log.total_tokens)} {log.use_time}ms {log.is_stream ? : ""}
{totalPages > 1 && (
{page} / {totalPages}
)}
); }