Skip to content

Commit b93d794

Browse files
Merge branch 'let-s-use-rechart-for-usage-monitoring-in-the-the-monitoring-view-r9mo'
2 parents 140d15a + f7c6f7b commit b93d794

1 file changed

Lines changed: 99 additions & 84 deletions

File tree

src/routes/monitoring/index.tsx

Lines changed: 99 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { Select, SelectTrigger, SelectValue, SelectContent, SelectItem } from '@
88
import { Switch } from '@/components/ui/switch'
99
import { Label } from '@/components/ui/label'
1010
import { ChartContainer, ChartTooltip, ChartTooltipContent, type ChartConfig } from '@/components/ui/chart'
11-
import { Area, AreaChart, XAxis, YAxis, CartesianGrid } from 'recharts'
11+
import { Area, AreaChart, XAxis, YAxis, CartesianGrid, RadialBarChart, RadialBar, PolarAngleAxis } from 'recharts'
1212
import { HugeiconsIcon } from '@hugeicons/react'
1313
import { Cancel01Icon, Loading03Icon } from '@hugeicons/core-free-icons'
1414
import {
@@ -632,13 +632,6 @@ function ViboraInstancesTab() {
632632
)
633633
}
634634

635-
// Helper to get color class based on usage percentage
636-
function getUsageColor(percent: number): string {
637-
if (percent >= 90) return 'bg-red-500'
638-
if (percent >= 70) return 'bg-yellow-500'
639-
return 'bg-green-500'
640-
}
641-
642635
// Helper to get text color class based on usage percentage
643636
function getUsageTextColor(percent: number): string {
644637
if (percent >= 90) return 'text-red-500'
@@ -671,10 +664,75 @@ function formatResetDate(resetAt: string): string {
671664
return date.toLocaleDateString([], { month: 'short', day: 'numeric', hour: '2-digit', minute: '2-digit' })
672665
}
673666

667+
// Radial gauge component for usage visualization
668+
function UsageGauge({
669+
percent,
670+
label,
671+
subtitle,
672+
color,
673+
}: {
674+
percent: number
675+
label: string
676+
subtitle: string
677+
color: string
678+
}) {
679+
const data = [{ value: Math.min(percent, 100), fill: color }]
680+
681+
return (
682+
<Card className="p-4">
683+
<div className="flex items-center gap-4">
684+
<div className="relative size-24 shrink-0">
685+
<RadialBarChart
686+
width={96}
687+
height={96}
688+
cx={48}
689+
cy={48}
690+
innerRadius={32}
691+
outerRadius={44}
692+
barSize={10}
693+
data={data}
694+
startAngle={90}
695+
endAngle={-270}
696+
>
697+
<PolarAngleAxis
698+
type="number"
699+
domain={[0, 100]}
700+
angleAxisId={0}
701+
tick={false}
702+
/>
703+
<RadialBar
704+
background={{ fill: 'hsl(var(--muted))' }}
705+
dataKey="value"
706+
cornerRadius={5}
707+
angleAxisId={0}
708+
/>
709+
</RadialBarChart>
710+
<div className="absolute inset-0 flex items-center justify-center">
711+
<span className={`text-lg font-semibold tabular-nums ${getUsageTextColor(percent)}`}>
712+
{percent.toFixed(0)}%
713+
</span>
714+
</div>
715+
</div>
716+
<div className="flex-1 min-w-0">
717+
<h3 className="text-sm font-medium truncate">{label}</h3>
718+
<p className="text-xs text-muted-foreground mt-1">{subtitle}</p>
719+
</div>
720+
</div>
721+
</Card>
722+
)
723+
}
724+
674725
function ClaudeUsageLimitsTab() {
675726
const { t } = useTranslation('monitoring')
676727
const { data: usage, isLoading, error } = useClaudeUsage()
677728

729+
// Get color based on usage level
730+
const getGaugeColor = (percent: number): string => {
731+
if (percent >= 90) return '#ef4444' // red-500
732+
if (percent >= 70) return '#eab308' // yellow-500
733+
return '#22c55e' // green-500
734+
}
735+
678736
return (
679737
<div className="space-y-4">
680738
{isLoading && (
@@ -697,91 +755,48 @@ function ClaudeUsageLimitsTab() {
697755

698756
{usage && usage.available && (
699757
<div className="space-y-3">
700-
{/* 5-Hour Block */}
701-
{usage.fiveHour && (
702-
<Card className="p-4">
703-
<div className="flex items-center justify-between mb-2">
704-
<h3 className="text-sm font-medium">{t('usage.fiveHourBlock')}</h3>
705-
<span className={`text-sm font-medium tabular-nums ${getUsageTextColor(usage.fiveHour.percentUsed)}`}>
706-
{usage.fiveHour.percentUsed.toFixed(1)}%
707-
</span>
708-
</div>
709-
<div className="h-2 w-full overflow-hidden rounded-full bg-muted">
710-
<div
711-
className={`h-full transition-all ${getUsageColor(usage.fiveHour.percentUsed)}`}
712-
style={{ width: `${Math.min(usage.fiveHour.percentUsed, 100)}%` }}
713-
/>
714-
</div>
715-
<p className="mt-2 text-xs text-muted-foreground">
716-
{t('usage.resetsIn', { time: formatTimeRemaining(usage.fiveHour.timeRemainingMinutes) })}
717-
</p>
718-
</Card>
719-
)}
758+
{/* Main usage gauges */}
759+
<div className="grid gap-3 sm:grid-cols-2">
760+
{/* 5-Hour Block */}
761+
{usage.fiveHour && (
762+
<UsageGauge
763+
percent={usage.fiveHour.percentUsed}
764+
label={t('usage.fiveHourBlock')}
765+
subtitle={t('usage.resetsIn', { time: formatTimeRemaining(usage.fiveHour.timeRemainingMinutes) })}
766+
color={getGaugeColor(usage.fiveHour.percentUsed)}
767+
/>
768+
)}
720769

721-
{/* 7-Day Rolling */}
722-
{usage.sevenDay && (
723-
<Card className="p-4">
724-
<div className="flex items-center justify-between mb-2">
725-
<h3 className="text-sm font-medium">{t('usage.sevenDayRolling')}</h3>
726-
<span className={`text-sm font-medium tabular-nums ${getUsageTextColor(usage.sevenDay.percentUsed)}`}>
727-
{usage.sevenDay.percentUsed.toFixed(1)}%
728-
</span>
729-
</div>
730-
<div className="h-2 w-full overflow-hidden rounded-full bg-muted">
731-
<div
732-
className={`h-full transition-all ${getUsageColor(usage.sevenDay.percentUsed)}`}
733-
style={{ width: `${Math.min(usage.sevenDay.percentUsed, 100)}%` }}
734-
/>
735-
</div>
736-
<p className="mt-2 text-xs text-muted-foreground">
737-
{t('usage.resetsAt', { time: formatResetDate(usage.sevenDay.resetAt) })}
738-
{' · '}
739-
{t('usage.weekProgress', { percent: usage.sevenDay.weekProgressPercent })}
740-
</p>
741-
</Card>
742-
)}
770+
{/* 7-Day Rolling */}
771+
{usage.sevenDay && (
772+
<UsageGauge
773+
percent={usage.sevenDay.percentUsed}
774+
label={t('usage.sevenDayRolling')}
775+
subtitle={`${t('usage.resetsAt', { time: formatResetDate(usage.sevenDay.resetAt) })} · ${t('usage.weekProgress', { percent: usage.sevenDay.weekProgressPercent })}`}
776+
color={getGaugeColor(usage.sevenDay.percentUsed)}
777+
/>
778+
)}
779+
</div>
743780

744781
{/* Model-specific limits (Opus/Sonnet) */}
745782
{(usage.sevenDayOpus || usage.sevenDaySonnet) && (
746783
<div className="grid gap-3 sm:grid-cols-2">
747784
{usage.sevenDayOpus && (
748-
<Card className="p-4">
749-
<div className="flex items-center justify-between mb-2">
750-
<h3 className="text-sm font-medium">{t('usage.opusWeekly')}</h3>
751-
<span className={`text-sm font-medium tabular-nums ${getUsageTextColor(usage.sevenDayOpus.percentUsed)}`}>
752-
{usage.sevenDayOpus.percentUsed.toFixed(1)}%
753-
</span>
754-
</div>
755-
<div className="h-2 w-full overflow-hidden rounded-full bg-muted">
756-
<div
757-
className={`h-full transition-all ${getUsageColor(usage.sevenDayOpus.percentUsed)}`}
758-
style={{ width: `${Math.min(usage.sevenDayOpus.percentUsed, 100)}%` }}
759-
/>
760-
</div>
761-
<p className="mt-2 text-xs text-muted-foreground">
762-
{t('usage.resetsAt', { time: formatResetDate(usage.sevenDayOpus.resetAt) })}
763-
</p>
764-
</Card>
785+
<UsageGauge
786+
percent={usage.sevenDayOpus.percentUsed}
787+
label={t('usage.opusWeekly')}
788+
subtitle={t('usage.resetsAt', { time: formatResetDate(usage.sevenDayOpus.resetAt) })}
789+
color={getGaugeColor(usage.sevenDayOpus.percentUsed)}
790+
/>
765791
)}
766792

767793
{usage.sevenDaySonnet && (
768-
<Card className="p-4">
769-
<div className="flex items-center justify-between mb-2">
770-
<h3 className="text-sm font-medium">{t('usage.sonnetWeekly')}</h3>
771-
<span className={`text-sm font-medium tabular-nums ${getUsageTextColor(usage.sevenDaySonnet.percentUsed)}`}>
772-
{usage.sevenDaySonnet.percentUsed.toFixed(1)}%
773-
</span>
774-
</div>
775-
<div className="h-2 w-full overflow-hidden rounded-full bg-muted">
776-
<div
777-
className={`h-full transition-all ${getUsageColor(usage.sevenDaySonnet.percentUsed)}`}
778-
style={{ width: `${Math.min(usage.sevenDaySonnet.percentUsed, 100)}%` }}
779-
/>
780-
</div>
781-
<p className="mt-2 text-xs text-muted-foreground">
782-
{t('usage.resetsAt', { time: formatResetDate(usage.sevenDaySonnet.resetAt) })}
783-
</p>
784-
</Card>
794+
<UsageGauge
795+
percent={usage.sevenDaySonnet.percentUsed}
796+
label={t('usage.sonnetWeekly')}
797+
subtitle={t('usage.resetsAt', { time: formatResetDate(usage.sevenDaySonnet.resetAt) })}
798+
color={getGaugeColor(usage.sevenDaySonnet.percentUsed)}
799+
/>
785800
)}
786801
</div>
787802
)}

0 commit comments

Comments
 (0)