'use client'; import Link from 'next/link'; import { useMemo } from 'react'; import { ExternalLink, FileKey } from 'lucide-react'; import { EmptyStateWithBorder } from '@/components/layout/empty'; import { Badge } from '@/components/ui/badge'; import { Button } from '@/components/ui/button'; import { Card, CardContent, CardDescription, CardHeader, CardTitle, } from '@/components/ui/card'; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from '@/components/ui/table'; import type { TlsCertificateItem, ZoneDomainItem, } from '@/lib/services/openflare'; import { formatDateTime } from '@/lib/utils'; import { useTranslations } from 'next-intl'; import { getCertificateStatus } from '../../components/website-utils'; export function ZoneCertificatesPanel({ domains, certificates, }: { domains: ZoneDomainItem[]; certificates: TlsCertificateItem[]; }) { const t = useTranslations('websites'); const tc = useTranslations('certificates'); const certificateMap = useMemo( () => new Map(certificates.map((certificate) => [certificate.id, certificate])), [certificates], ); const boundCertificates = useMemo(() => { const rows = new Map< number, { certificate: TlsCertificateItem; domains: ZoneDomainItem[] } >(); for (const domain of domains) { if (domain.cert_id == null) { continue; } const certificate = certificateMap.get(domain.cert_id); if (!certificate) { continue; } const existing = rows.get(certificate.id); if (existing) { existing.domains.push(domain); } else { rows.set(certificate.id, { certificate, domains: [domain] }); } } return Array.from(rows.values()).sort((left, right) => left.certificate.name.localeCompare(right.certificate.name), ); }, [certificateMap, domains]); const unboundCount = domains.filter( (domain) => domain.cert_id == null, ).length; return (
{t('unboundCertHint', { count: unboundCount })}
) : null} {boundCertificates.length === 0 ? (