Updated the KPI components to include a new KpiStatVariant type for better visual differentiation. Refactored the KpiStatCardBody and KpiStatGrid to utilize this variant, allowing for dynamic styling based on the KPI state. Improved the layout of the KpiStatGrid and its associated components for a more cohesive user experience, including adjustments to the Badge footer presentation.
62 lines
1.6 KiB
TypeScript
62 lines
1.6 KiB
TypeScript
import type { ReactElement, ReactNode } from 'react'
|
|
|
|
import { Badge } from '@/components/reui/badge'
|
|
import { KpiStatGrid, type KpiStatItem } from '@/components/kpi-stat-grid'
|
|
|
|
export interface SectionCardItem {
|
|
label: ReactNode
|
|
value: string | number | ReactElement
|
|
hint?: ReactNode
|
|
icon?: ReactNode
|
|
badge?: ReactNode
|
|
variant?: 'default' | 'warning' | 'destructive'
|
|
active?: boolean
|
|
onClick?: () => void
|
|
}
|
|
|
|
const VARIANT_ICON_CLASS: Record<NonNullable<SectionCardItem['variant']>, string> = {
|
|
default: 'text-muted-foreground',
|
|
warning: 'text-warning',
|
|
destructive: 'text-destructive',
|
|
}
|
|
|
|
function hintToFooter(hint: ReactNode) {
|
|
if (typeof hint === 'string') {
|
|
return (
|
|
<Badge variant="outline" size="sm">
|
|
{hint}
|
|
</Badge>
|
|
)
|
|
}
|
|
return hint
|
|
}
|
|
|
|
function toKpiStatItem(item: SectionCardItem, index: number): KpiStatItem {
|
|
const variant = item.variant ?? 'default'
|
|
const footer =
|
|
item.badge ?? (item.hint ? hintToFooter(item.hint) : undefined)
|
|
|
|
return {
|
|
id: typeof item.label === 'string' ? item.label : `section-${index}`,
|
|
icon: item.icon,
|
|
iconClassName: VARIANT_ICON_CLASS[variant],
|
|
value: item.value,
|
|
label: item.label,
|
|
variant,
|
|
footer,
|
|
active: item.active,
|
|
onClick: item.onClick,
|
|
}
|
|
}
|
|
|
|
/** KPI row for route sections — ReUI stats-12 / dashboard PRO pattern. */
|
|
export function SectionCards({ items, className }: { items: SectionCardItem[]; className?: string }) {
|
|
return (
|
|
<KpiStatGrid
|
|
items={items.map(toKpiStatItem)}
|
|
className={className}
|
|
aria-label="Показатели"
|
|
/>
|
|
)
|
|
}
|