'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 { getCertificateStatus } from '../../components/website-utils'; export function ZoneCertificatesPanel({ domains, certificates, }: { domains: ZoneDomainItem[]; certificates: TlsCertificateItem[]; }) { 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 (
本 Zone 使用的证书 证书在全局证书库管理;此处仅展示已绑定到本 Zone 域名的证书。
{unboundCount > 0 ? (

还有 {unboundCount} 个域名未绑定证书,可在「域名」Tab 中选择证书。

) : null} {boundCertificates.length === 0 ? ( ) : (
证书 状态 覆盖域名 到期时间 {boundCertificates.map( ({ certificate, domains: boundDomains }) => { const status = getCertificateStatus(certificate); return ( {certificate.name}

{certificate.primary_domain || `证书 #${certificate.id}`}

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