From d0aa91aa51341f33a99da8b7e40d16cd90034f87 Mon Sep 17 00:00:00 2001 From: Shroominic Date: Sun, 23 Nov 2025 13:11:11 -0800 Subject: [PATCH] feat(ui): enhance dashboard visualizations - Replace usage metrics line charts with gradient area charts - Redesign summary cards with improved styling and icons - Add revenue share progress bar to models table - Format numbers in tables for better readability --- ui/components/revenue-by-model-table.tsx | 55 +++++++++++++--------- ui/components/usage-metrics-chart.tsx | 59 +++++++++++++++++++----- ui/components/usage-summary-cards.tsx | 12 +++-- 3 files changed, 88 insertions(+), 38 deletions(-) diff --git a/ui/components/revenue-by-model-table.tsx b/ui/components/revenue-by-model-table.tsx index 9cea3eb5..867d911b 100644 --- a/ui/components/revenue-by-model-table.tsx +++ b/ui/components/revenue-by-model-table.tsx @@ -9,6 +9,7 @@ import { TableRow, } from '@/components/ui/table'; import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'; +import { Progress } from '@/components/ui/progress'; import { ModelRevenueData } from '@/lib/api/services/admin'; interface RevenueByModelTableProps { @@ -25,7 +26,7 @@ export function RevenueByModelTable({ Revenue by Model

- Total Revenue: {totalRevenue.toLocaleString(undefined, { maximumFractionDigits: 2 })} sats + Total Revenue: {totalRevenue.toLocaleString(undefined, { maximumFractionDigits: 2 })} sats

@@ -37,6 +38,7 @@ export function RevenueByModelTable({ Successful Failed Revenue (sats) + Share Refunds (sats) Net Revenue (sats) Avg/Request @@ -45,31 +47,40 @@ export function RevenueByModelTable({ {models.length === 0 ? ( - + No model data available ) : ( - models.map((model) => ( - - {model.model} - {model.requests} - {model.successful} - {model.failed} - - {model.revenue_sats.toLocaleString(undefined, { maximumFractionDigits: 2 })} - - - {model.refunds_sats.toLocaleString(undefined, { maximumFractionDigits: 2 })} - - - {model.net_revenue_sats.toLocaleString(undefined, { maximumFractionDigits: 2 })} - - - {model.avg_revenue_per_request.toLocaleString(undefined, { maximumFractionDigits: 3 })} - - - )) + models.map((model) => { + const share = totalRevenue > 0 ? (model.revenue_sats / totalRevenue) * 100 : 0; + return ( + + {model.model} + {model.requests} + {model.successful} + {model.failed} + + {model.revenue_sats.toLocaleString(undefined, { maximumFractionDigits: 2 })} + + +
+ + {share.toFixed(0)}% +
+
+ + {model.refunds_sats.toLocaleString(undefined, { maximumFractionDigits: 2 })} + + + {model.net_revenue_sats.toLocaleString(undefined, { maximumFractionDigits: 2 })} + + + {model.avg_revenue_per_request.toLocaleString(undefined, { maximumFractionDigits: 3 })} + +
+ ); + }) )}
diff --git a/ui/components/usage-metrics-chart.tsx b/ui/components/usage-metrics-chart.tsx index 294d5e56..588371e0 100644 --- a/ui/components/usage-metrics-chart.tsx +++ b/ui/components/usage-metrics-chart.tsx @@ -2,8 +2,8 @@ import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'; import { - Line, - LineChart, + Area, + AreaChart, ResponsiveContainer, Tooltip, XAxis, @@ -42,34 +42,71 @@ export function UsageMetricsChart({ - - + + + {dataKeys.map((dataKey) => ( + + + + + ))} + + + - - + {dataKeys.map((dataKey) => ( - ))} - + diff --git a/ui/components/usage-summary-cards.tsx b/ui/components/usage-summary-cards.tsx index 4c8dc63a..2ca842ae 100644 --- a/ui/components/usage-summary-cards.tsx +++ b/ui/components/usage-summary-cards.tsx @@ -102,15 +102,17 @@ export function UsageSummaryCards({ summary }: UsageSummaryCardsProps) { ]; return ( -
+
{cards.map((card) => ( - + - {card.title} - + {card.title} +
+ +
-
{card.value}
+
{card.value}
))}