feat: global time range context with custom date picker
Lift time range state into a shared React context so the selected
range persists across page navigation and browser refreshes
(localStorage). Add a "Custom" option with a popover date picker
that lets users specify arbitrary start/end dates. All preset end
times now use endOf("day") (23:59:59) instead of the current moment.
This commit is contained in:
@@ -4,7 +4,8 @@ import { useEffect, useState, useCallback } from "react";
|
||||
import { motion } from "motion/react";
|
||||
import { ScrollText, Search, ChevronLeft, ChevronRight, Zap } from "lucide-react";
|
||||
import { TimeRangeSelector } from "@/components/TimeRangeSelector";
|
||||
import { type TimeRange, getTimeRange, buildQuery, formatNumber, formatTokens, formatDate } from "@/lib/utils";
|
||||
import { buildQuery, formatNumber, formatTokens, formatDate } from "@/lib/utils";
|
||||
import { useTimeRange } from "@/lib/time-range-context";
|
||||
import { useI18n } from "@/lib/i18n";
|
||||
|
||||
interface LogEntry {
|
||||
@@ -16,7 +17,7 @@ interface LogEntry {
|
||||
|
||||
export default function LogsPage() {
|
||||
const { t } = useI18n();
|
||||
const [range, setRange] = useState<TimeRange>("7d");
|
||||
const { getEffectiveRange } = useTimeRange();
|
||||
const [page, setPage] = useState(1);
|
||||
const [logs, setLogs] = useState<LogEntry[]>([]);
|
||||
const [total, setTotal] = useState(0);
|
||||
@@ -26,14 +27,14 @@ export default function LogsPage() {
|
||||
|
||||
const fetchData = useCallback(async () => {
|
||||
setLoading(true);
|
||||
const { start, end } = getTimeRange(range);
|
||||
const { start, end } = getEffectiveRange();
|
||||
const res = await fetch(buildQuery("/api/logs", { start, end, page, page_size: pageSize, ...filters }));
|
||||
const data = await res.json();
|
||||
setLogs(data.logs); setTotal(data.total); setLoading(false);
|
||||
}, [range, page, filters]);
|
||||
}, [page, filters, getEffectiveRange]);
|
||||
|
||||
useEffect(() => { fetchData(); }, [fetchData]);
|
||||
useEffect(() => { setPage(1); }, [range, filters]);
|
||||
useEffect(() => { 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"), ""];
|
||||
@@ -45,7 +46,7 @@ export default function LogsPage() {
|
||||
<ScrollText className="h-5 w-5" style={{ color: "var(--accent)", opacity: 0.6 }} />
|
||||
<h1 className="text-2xl font-bold gradient-text">{t("logs.title")}</h1>
|
||||
</motion.div>
|
||||
<TimeRangeSelector value={range} onChange={setRange} />
|
||||
<TimeRangeSelector />
|
||||
</div>
|
||||
|
||||
<motion.div initial={{ opacity: 0, y: 12 }} animate={{ opacity: 1, y: 0 }} className="flex items-center gap-3">
|
||||
|
||||
Reference in New Issue
Block a user