Files
EvoBGP/apps/web/src/components/patterns/segmented-progress-card.tsx
T
Denozordec a3f3ffd672
CI / changes (push) Successful in 10s
CI / commitlint (push) Has been skipped
CI / openapi (push) Has been skipped
CI / web (push) Successful in 52s
CI / go (push) Has been skipped
CI / bird2 (push) Has been skipped
CI / release (push) Successful in 4m7s
refactor: integrate PanelCard and enhance dashboard components for improved layout
Refactored multiple dashboard components to utilize the new PanelCard for better organization and presentation. Updated the DashboardFramePanel, DashboardQuickLinks, and DashboardOperationsBreakdown components to streamline layouts and enhance user experience. Removed deprecated components and improved loading states in various sections, ensuring a cohesive interface throughout the application.
2026-07-09 21:39:20 +07:00

71 lines
2.4 KiB
TypeScript

import type { ReactNode } from 'react'
import { PanelCard } from '@/components/panel-card'
import { cn } from '@evobgp/ui/lib/utils'
import { Progress } from '@evobgp/ui/components/progress'
export type SegmentStat = {
value: string | number
label: string
percent: number
badge?: ReactNode
}
/** stats-4 pattern: dual metrics + progress + segmented meter (Card surface). */
export function SegmentedProgressCard({
title,
description,
actions,
primary,
secondary,
segments = 30,
footer,
}: {
title: string
description?: string
actions?: ReactNode
primary: SegmentStat
secondary: SegmentStat
segments?: number
footer?: ReactNode
}) {
const filled = Math.round((secondary.percent / 100) * segments)
return (
<PanelCard title={title} description={description} actions={actions} className="h-full">
<div className="flex flex-col gap-4 p-4">
<div className="flex items-stretch gap-x-6">
<div className="flex flex-1 flex-col items-start gap-1">
<div className="mb-1 flex items-center gap-1">
<span className="text-foreground text-2xl font-bold tabular-nums">{primary.value}</span>
{primary.badge}
</div>
<span className="text-muted-foreground text-sm font-medium">{primary.label}</span>
<div className="mt-1 w-full">
<Progress value={primary.percent} className="**:data-[slot=progress-track]:h-2.5" />
</div>
</div>
<div className="border-muted-foreground/10 flex flex-1 flex-col items-start gap-1 border-s ps-6">
<div className="mb-1 flex items-center gap-1">
<span className="text-foreground text-2xl font-bold tabular-nums">{secondary.value}</span>
</div>
<span className="text-muted-foreground text-sm font-medium">{secondary.label}</span>
<div className="mt-1 flex w-full gap-0.5">
{Array.from({ length: segments }).map((_, i) => (
<div
key={i}
className={cn(
'h-2.5 w-0.5 flex-1 rounded-md',
i < filled ? 'bg-success' : 'bg-muted',
)}
/>
))}
</div>
</div>
</div>
{footer ? <div className="text-muted-foreground text-xs">{footer}</div> : null}
</div>
</PanelCard>
)
}