From 3d0243304ec877a1113d4b88222f2fc89e914e5c Mon Sep 17 00:00:00 2001 From: Ifeloju Date: Tue, 20 Oct 2026 11:28:59 +0000 Subject: [PATCH] fix(#1038): add live TVL counter card to yield vault page - Fetch total_value_locked from api.yieldStats() on mount - Format value as USD currency string using Intl.NumberFormat - Display as a prominent metric card above the tab bar - Shows loading skeleton and error state gracefully --- dashboard/app/dashboard/yield/page.tsx | 78 ++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) diff --git a/dashboard/app/dashboard/yield/page.tsx b/dashboard/app/dashboard/yield/page.tsx index 82e3546..d92e76c 100644 --- a/dashboard/app/dashboard/yield/page.tsx +++ b/dashboard/app/dashboard/yield/page.tsx @@ -777,6 +777,41 @@ export default function YieldPage() { const hasValidationErrors = Object.keys(formErrors).length > 0; + // ── #1038: TVL Metric Counter ───────────────────────────────────────────────── + const [tvl, setTvl] = useState(null); + const [tvlLoading, setTvlLoading] = useState(true); + const [tvlError, setTvlError] = useState(null); + + useEffect(() => { + let cancelled = false; + setTvlLoading(true); + setTvlError(null); + api + .yieldStats() + .then((res) => { + if (!cancelled) setTvl(res.total_value_locked); + }) + .catch((err) => { + if (!cancelled) + setTvlError(err instanceof Error ? err.message : "Failed to load TVL"); + }) + .finally(() => { + if (!cancelled) setTvlLoading(false); + }); + return () => { + cancelled = true; + }; + }, []); + + /** Format a numeric vault balance as a USD currency string, e.g. $1,234.56 */ + const formatTvl = (value: number): string => + new Intl.NumberFormat("en-US", { + style: "currency", + currency: "USD", + minimumFractionDigits: 2, + maximumFractionDigits: 2, + }).format(value); + return (
@@ -789,6 +824,49 @@ export default function YieldPage() {
+ {/* ── #1038: TVL Metric Counter Card ──────────────────────────────────────── */} +
+
+

+ Total Value Locked (TVL) +

+ {tvlLoading ? ( +
+ ) : tvlError ? ( +

{tvlError}

+ ) : ( +

+ {formatTvl(tvl ?? 0)} +

+ )} +

Live vault balance across all depositors

+
+
+ +
+
+ {/* Tab Bar */}
{(["config", "audit", "apy-history"] as const).map((t) => (