"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 }