'use client' import {useEffect} from 'react' import {useMutation, useQuery, useQueryClient} from '@tanstack/react-query' import {zodResolver} from '@hookform/resolvers/zod' import {useForm} from 'react-hook-form' import {Loader2} from 'lucide-react' import {toast} from 'sonner' import {z} from 'zod' import {Button} from '@/components/ui/button' import {Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle} from '@/components/ui/dialog' import {Input} from '@/components/ui/input' import {Label} from '@/components/ui/label' import {Select, SelectContent, SelectItem, SelectTrigger, SelectValue} from '@/components/ui/select' import {Textarea} from '@/components/ui/textarea' import {TlsCertificateService, ZoneDomainService, type ZoneDomainItem} from '@/lib/services/openflare' const schema = z.object({domain: z.string().trim().min(1, '请输入完整域名').refine((value) => !value.includes('*.'), 'Zone 域名不支持通配符'), cert_id: z.string(), remark: z.string().max(255)}) type Values = z.infer export function ZoneDomainDialog({open, onOpenChange, zoneId, domain, onSaved}: {open: boolean; onOpenChange(open: boolean): void; zoneId: number; domain?: ZoneDomainItem | null; onSaved(): Promise | void}) { const form = useForm({resolver: zodResolver(schema), defaultValues: {domain: '', cert_id: '', remark: ''}}); const queryClient = useQueryClient() const certificatesQuery = useQuery({queryKey: ['openflare', 'tls-certificates'], queryFn: () => TlsCertificateService.list(), enabled: open}) useEffect(() => { if (open) form.reset({domain: domain?.domain ?? '', cert_id: domain?.cert_id?.toString() ?? '', remark: domain?.remark ?? ''}) }, [domain, form, open]) const mutation = useMutation({mutationFn: (values: Values) => {const payload = {domain: values.domain.toLowerCase(), cert_id: values.cert_id ? Number(values.cert_id) : null, remark: values.remark.trim()}; return domain ? ZoneDomainService.update(zoneId, domain.id, payload) : ZoneDomainService.create(zoneId, payload)}, onSuccess: async () => {toast.success(domain ? '域名已更新' : '域名已添加'); await Promise.all([onSaved(), queryClient.invalidateQueries({queryKey: ['openflare', 'zones']})]); onOpenChange(false)}, onError: (error) => toast.error(error instanceof Error ? error.message : '保存失败')}) return {domain ? '编辑 Zone 域名' : '添加 Zone 域名'}填写明确 FQDN;通配符仅可存在于所选证书的 SAN 中。
mutation.mutate(values))}>
{form.formState.errors.domain &&

{form.formState.errors.domain.message}

}