feat(ui): добавить KPI card-35 на domains, groups и services

ReUI PRO card-35 через KpiStatGrid; клик по KPI синхронизирует tabs.

Co-authored-by: Cursor <[email protected]>
This commit is contained in:
Denozordec
2026-07-17 13:44:06 +07:00
co-authored by Cursor
parent af191dcd5b
commit 1e8236298d
7 changed files with 250 additions and 4 deletions
@@ -0,0 +1,61 @@
import { useMemo } from 'react'
import { FolderTreeIcon } from 'lucide-react'
import { KpiStatGrid, type KpiStatCard } from '@/components/reui-kit/kpi-stat-grid'
import type { GroupCatalogRow } from '@/components/columns/groups-columns'
interface GroupKpiCardsProps {
rows: GroupCatalogRow[]
activeTab: string
isLoading?: boolean
onSelectTab: (tabId: string) => void
}
/** KPI strip — ReUI PRO [card-35](https://reui.io/preview/base/card-35) */
export function GroupKpiCards({
rows,
activeTab,
isLoading,
onSelectTab,
}: GroupKpiCardsProps) {
const cards = useMemo<KpiStatCard[]>(() => {
const withDomains = rows.filter((r) => r.domainCount > 0).length
const empty = rows.filter((r) => r.domainCount === 0).length
return [
{
id: 'all',
label: 'Всего',
value: rows.length,
hint: 'Группы доменов',
onSelect: () => onSelectTab('all'),
selected: activeTab === 'all',
},
{
id: 'with_domains',
label: 'С доменами',
value: withDomains,
hint: 'Непустые группы',
onSelect: () => onSelectTab('with_domains'),
selected: activeTab === 'with_domains',
},
{
id: 'empty',
label: 'Пустые',
value: empty,
hint: 'Без доменов',
onSelect: () => onSelectTab('empty'),
selected: activeTab === 'empty',
},
]
}, [rows, activeTab, onSelectTab])
return (
<KpiStatGrid
cards={cards}
isLoading={isLoading}
skeletonCount={3}
emptyIcon={<FolderTreeIcon className="text-muted-foreground size-5" aria-hidden />}
emptyMessage="Нет групп — создайте первую"
/>
)
}