'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)}
); })}
)}
); }