'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('zoneCertsTitle')} {t('zoneCertsDesc')}
{unboundCount > 0 ? (

{t('unboundCertHint', { count: unboundCount })}

) : null} {boundCertificates.length === 0 ? ( ) : (
{t('certificate')} {t('status')} {t('coverage')} {t('expiresAt')} {boundCertificates.map( ({ certificate, domains: boundDomains }) => { const status = getCertificateStatus(certificate, tc); return ( {certificate.name}

{certificate.primary_domain || t('certNumber', { id: certificate.id })}

{status.label} {boundDomains .map((domain) => domain.domain) .join(' ยท ')} {formatDateTime(certificate.not_after)}
); }, )}
)}
); }