"use client" import { useMemo, type ReactNode } from "react" import { type ColumnDef, getCoreRowModel, getExpandedRowModel, getSortedRowModel, useReactTable, } from "@tanstack/react-table" import type { CertStatus, Server } from "@/lib/data" import type { CertificateDto } from "@mmapp/contracts/certificates" import { Flag } from "@/components/flag" import { cn } from "@/lib/utils" import { DataGridShell } from "@/components/data-grids/shared/data-grid-shell" import { DATA_GRID_CELL_PAD, DATA_GRID_CELL_PAD_FIRST, DATA_GRID_CELL_PAD_LAST, } from "@/components/data-grids/shared/data-grid-layout" import { DataGridSortHeader } from "@/components/data-grids/shared/data-grid-sort-header" import { CertificateExpandedDetail, daysLeftBar, } from "@/components/data-grids/certificate-expanded-detail" import { EmptyState } from "@/components/empty-state" import { BadgeCheckIcon, ChevronDownIcon, ChevronRightIcon, ServerIcon, ShieldAlertIcon, ShieldCheckIcon, ShieldOffIcon, } from "lucide-react" const STATUS_CONFIG: Record< CertStatus, { label: string; icon: ReactNode; badge: string; row: string } > = { valid: { label: "Действителен", icon: , badge: "bg-emerald-500/10 text-emerald-600 dark:text-emerald-400 border-emerald-500/20", row: "", }, expired: { label: "Истёк", icon: , badge: "bg-red-500/10 text-red-600 dark:text-red-400 border-red-500/20", row: "bg-red-500/5", }, revoked: { label: "Отозван", icon: , badge: "bg-amber-500/10 text-amber-600 dark:text-amber-400 border-amber-500/20", row: "bg-amber-500/5", }, } function daysLeftColor(days: number): string { if (days < 0) return "text-red-500" if (days <= 7) return "text-red-500" if (days <= 30) return "text-amber-500" return "text-emerald-600 dark:text-emerald-400" } function CertDaysCell({ cert }: { cert: CertificateDto }) { const pct = daysLeftBar(cert.daysLeft) return ( <>
{cert.daysLeft < 0 ? `Истёк ${-cert.daysLeft}д назад` : `${cert.daysLeft}д осталось`} {cert.validUntil}
) } interface CertificatesDataGridProps { certificates: CertificateDto[] serverMap: Map isLoading?: boolean } function CertificatesDataGrid({ certificates, serverMap, isLoading }: CertificatesDataGridProps) { const columns = useMemo[]>( () => [ { id: "name", accessorKey: "name", header: ({ column }) => ( ), cell: ({ row }) => { const cert = row.original const cfg = STATUS_CONFIG[cert.status] const expanded = row.getIsExpanded() return (
{expanded ? ( ) : ( )}
{cfg.icon} {cert.name}

{cert.commonName}

) }, meta: { headerTitle: "Сертификат", headerClassName: DATA_GRID_CELL_PAD_FIRST, cellClassName: DATA_GRID_CELL_PAD_FIRST, expandedContent: (row: CertificateDto) => , }, }, { id: "server", accessorKey: "serverId", header: ({ column }) => , cell: ({ row }) => { const cert = row.original const server = serverMap.get(cert.serverId) return server ? (
{server.name}
) : (
{cert.serverName ?? cert.serverId}
) }, meta: { headerTitle: "Сервер", headerClassName: DATA_GRID_CELL_PAD, cellClassName: DATA_GRID_CELL_PAD, }, }, { id: "issuedBy", accessorKey: "issuedBy", header: ({ column }) => , cell: ({ row }) => (

{row.original.issuedBy}

), meta: { headerTitle: "Издатель", headerClassName: DATA_GRID_CELL_PAD, cellClassName: DATA_GRID_CELL_PAD, }, }, { id: "daysLeft", accessorKey: "daysLeft", header: ({ column }) => , cell: ({ row }) => (
), meta: { headerTitle: "Срок", headerClassName: DATA_GRID_CELL_PAD, cellClassName: DATA_GRID_CELL_PAD, }, }, { id: "usage", accessorKey: "usage", header: () => Использование, enableSorting: false, cell: ({ row }) => (
{row.original.usage.map((u) => ( {u} ))}
), meta: { headerTitle: "Использование", headerClassName: DATA_GRID_CELL_PAD, cellClassName: DATA_GRID_CELL_PAD, }, }, { id: "status", accessorKey: "status", header: ({ column }) => , cell: ({ row }) => { const cfg = STATUS_CONFIG[row.original.status] return ( {cfg.label} ) }, meta: { headerTitle: "Статус", headerClassName: DATA_GRID_CELL_PAD_LAST, cellClassName: DATA_GRID_CELL_PAD_LAST, }, }, ], [serverMap], ) const table = useReactTable({ data: certificates, columns, getCoreRowModel: getCoreRowModel(), getSortedRowModel: getSortedRowModel(), getExpandedRowModel: getExpandedRowModel(), getRowId: (row) => row.id, getRowCanExpand: () => true, }) if (!isLoading && certificates.length === 0) { return ( } title="Нет сертификатов" description="Выпустите или импортируйте сертификат" className="border-0 py-12" /> ) } return ( table.getRow(row.id).toggleExpanded()} /> ) } export { CertificatesDataGrid, STATUS_CONFIG, type CertificatesDataGridProps }