diff --git a/src/lib/dtoParsers.ts b/src/lib/dtoParsers.ts index 21cacda..29254de 100644 --- a/src/lib/dtoParsers.ts +++ b/src/lib/dtoParsers.ts @@ -39,8 +39,8 @@ export function computeChamberMetrics(chambers: ChamberDto[]) { return sum + acm; }, 0); // Governors can be members of multiple chambers; use the largest chamber roster - // as a stable approximation of global active governors for the summary tile. - const activeGovernors = chambers.reduce((max, chamber) => { + // as a stable approximation of global governors for the summary tile. + const governors = chambers.reduce((max, chamber) => { const { governors } = getChamberNumericStats(chamber); return Math.max(max, governors); }, 0); @@ -50,7 +50,7 @@ export function computeChamberMetrics(chambers: ChamberDto[]) { ); return { totalChambers: chambers.length, - activeGovernors, + governors, totalAcm, liveProposals, }; diff --git a/src/pages/chambers/Chambers.tsx b/src/pages/chambers/Chambers.tsx index be199e9..fa64e6f 100644 --- a/src/pages/chambers/Chambers.tsx +++ b/src/pages/chambers/Chambers.tsx @@ -12,12 +12,13 @@ import { Button } from "@/components/primitives/button"; import { Link } from "react-router"; import { InlineHelp } from "@/components/InlineHelp"; import { NoDataYetBar } from "@/components/NoDataYetBar"; -import { apiChambers } from "@/lib/apiClient"; +import { apiChambers, apiClock } from "@/lib/apiClient"; import { computeChamberMetrics, getChamberNumericStats, } from "@/lib/dtoParsers"; import type { ChamberDto } from "@/types/api"; +import type { GetClockResponse } from "@/types/api"; import { Surface } from "@/components/Surface"; type Metric = { @@ -34,6 +35,7 @@ const metricCards: Metric[] = [ const Chambers: React.FC = () => { const [chambers, setChambers] = useState(null); + const [clock, setClock] = useState(null); const [loadError, setLoadError] = useState(null); const [search, setSearch] = useState(""); const [filters, setFilters] = useState<{ @@ -47,12 +49,15 @@ const Chambers: React.FC = () => { (async () => { try { const res = await apiChambers(); + const clockRes = await apiClock().catch(() => null); if (!active) return; setChambers(res.items); + setClock(clockRes); setLoadError(null); } catch (error) { if (!active) return; setChambers([]); + setClock(null); setLoadError((error as Error).message); } })(); @@ -90,9 +95,12 @@ const Chambers: React.FC = () => { const computedMetrics = useMemo((): Metric[] => { if (!chambers) return metricCards; - const { activeGovernors, totalAcm, liveProposals } = + const { governors, totalAcm, liveProposals } = computeChamberMetrics(chambers); - const governors = activeGovernors; + const activeGovernors = Math.min( + governors, + Math.max(0, Math.floor(clock?.activeGovernors ?? governors)), + ); return [ { label: "Total chambers", value: String(chambers.length) }, { @@ -102,7 +110,7 @@ const Chambers: React.FC = () => { { label: "Total ACM", value: totalAcm.toLocaleString() }, { label: "Live proposals", value: String(liveProposals) }, ]; - }, [chambers]); + }, [chambers, clock]); return (