'use client'; import {useMemo, useState} from 'react'; import Link from 'next/link'; import {ExternalLink} from 'lucide-react'; import {Badge} from '@/components/ui/badge'; import {Checkbox} from '@/components/ui/checkbox'; import {Input} from '@/components/ui/input'; import {cn} from '@/lib/utils'; import type {ZoneDomainItem, ZoneItem} from '@/lib/services/openflare'; export interface ZoneDomainSelectorProps { value: number[]; onChange: (ids: number[]) => void; domains: ZoneDomainItem[]; zones?: ZoneItem[]; /** Current route ID: domains bound to this route remain selectable. */ currentRouteId?: number | null; disabled?: boolean; className?: string; } export function ZoneDomainSelector({ value, onChange, domains, zones = [], currentRouteId = null, disabled = false, className, }: ZoneDomainSelectorProps) { const [keyword, setKeyword] = useState(''); const selected = useMemo(() => new Set(value), [value]); const zoneMap = useMemo( () => new Map(zones.map((zone) => [zone.id, zone.domain])), [zones], ); const filtered = useMemo(() => { const normalized = keyword.trim().toLowerCase(); const list = [...domains].sort((a, b) => a.domain.localeCompare(b.domain)); if (!normalized) { return list; } return list.filter((domain) => { const zoneRoot = zoneMap.get(domain.zone_id) ?? ''; return ( domain.domain.toLowerCase().includes(normalized) || zoneRoot.toLowerCase().includes(normalized) || String(domain.id).includes(normalized) ); }); }, [domains, keyword, zoneMap]); const toggle = (domain: ZoneDomainItem) => { if (disabled) { return; } const boundElsewhere = domain.proxy_route_id != null && domain.proxy_route_id !== currentRouteId; if (boundElsewhere) { return; } if (selected.has(domain.id)) { onChange(value.filter((id) => id !== domain.id)); return; } onChange([...value, domain.id].sort((a, b) => a - b)); }; return (
setKeyword(event.target.value)} placeholder="搜索域名或 Zone…" disabled={disabled} /> {filtered.length === 0 ? (
{domains.length === 0 ? ( <> 暂无可用 Zone 域名。请先在{' '} 网站管理 {' '} 中添加 FQDN。 ) : ( '没有匹配的域名' )}
) : (
{filtered.map((domain) => { const boundElsewhere = domain.proxy_route_id != null && domain.proxy_route_id !== currentRouteId; const checked = selected.has(domain.id); const zoneRoot = zoneMap.get(domain.zone_id); return ( ); })}
)}
); }