import { useState } from "react"; import { BarChart3, Clock, Film, History, RefreshCw, Users, Zap, type LucideIcon, } from "lucide-react"; import { useTranslation } from "react-i18next"; import { type MyStatus } from "../lib/api"; import { formatEta, formatNumber } from "../lib/format"; import { PopoverSurface } from "./ui/AnchoredPopover"; import { useAnchoredPopover } from "./ui/anchoredPopoverHooks"; import { Button } from "./ui/Button"; import { SURFACE } from "./ui/surfaces"; // The channel-manager catalog stats, collapsed from a crowded inline row into a compact "Stats" chip // that reveals the numbers on hover (reuses the AnchoredPopover hover mode). One row per stat, each // with a leading icon. Kept in the manager's own toolbar (the header's SyncStatus is global; these // are channel-catalog figures). export default function ChannelStatsPopover({ status }: { status: MyStatus }) { const { t, i18n } = useTranslation(); const lang = i18n.language; const [open, setOpen] = useState(false); const pop = useAnchoredPopover({ open, onOpenChange: setOpen, mode: "hover", placement: "bottom-end", offset: 8, }); const { setReference } = pop.refs; // Each row keeps the per-stat explanation the old inline stats carried (as a native `title` on the // row), so hovering a figure still tells the user what it counts — the guidance is not lost. const rows: { icon: LucideIcon; label: string; value: string | number; hint: string }[] = [ { icon: Users, label: t("channels.stats.channels"), value: status.channels_total, hint: t("channels.stats.channelsHint"), }, { icon: RefreshCw, label: t("channels.stats.recentSynced"), value: `${status.channels_recent_synced}/${status.channels_total}`, hint: t("channels.stats.recentSyncedHint"), }, { icon: History, label: t("channels.stats.fullHistory"), value: `${status.channels_deep_done}/${status.channels_deep_requested}`, hint: t("channels.stats.fullHistoryHint"), }, ...(status.deep_pending_count > 0 ? [ { icon: Clock, label: t("channels.stats.left"), value: formatEta(t, status.deep_eta_seconds), hint: t("channels.stats.leftHint", { count: status.deep_pending_count }), }, ] : []), { icon: Film, label: t("channels.stats.myVideos"), value: formatNumber(status.my_videos, lang), hint: t("channels.stats.myVideosHint"), }, { icon: Zap, label: t("channels.stats.quotaLeft"), value: formatNumber(status.quota_remaining_today, lang), hint: t("channels.stats.quotaLeftHint"), }, ]; return ( <> {rows.map((r) => (
))}
); }