'use client'; import { zodResolver } from '@hookform/resolvers/zod'; import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'; import { useEffect, useState } from 'react'; import { useForm } from 'react-hook-form'; import { ChevronDown, Loader2 } from 'lucide-react'; import { Button } from '@/components/ui/button'; import { Dialog, DialogContent, DialogDescription, 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 { Switch } from '@/components/ui/switch'; import { Textarea } from '@/components/ui/textarea'; import type { TlsCertificateItem } from '@/lib/services/openflare'; import { DnsAccountService, TlsCertificateService, } from '@/lib/services/openflare'; import { useTranslations } from 'next-intl'; import { type AcmeApplyFormValues, createAcmeApplySchema, defaultAcmeApplyValues, } from './schemas'; import { getErrorMessage } from './website-utils'; const certificatesQueryKey = ['openflare', 'tls-certificates']; type CertificateApplyMode = 'create' | 'edit-acme' | 'convert-upload'; interface CertificateApplyDialogProps { open: boolean; onOpenChange: (open: boolean) => void; onApplied?: (certificate: TlsCertificateItem) => void; mode?: CertificateApplyMode; certificate?: TlsCertificateItem | null; } export function CertificateApplyDialog({ open, onOpenChange, onApplied, mode = 'create', certificate, }: CertificateApplyDialogProps) { const t = useTranslations('certificates'); const queryClient = useQueryClient(); const [error, setError] = useState(''); const [showAdvanced, setShowAdvanced] = useState(false); const dnsAccountsQuery = useQuery({ queryKey: ['openflare', 'dns-accounts'], queryFn: () => DnsAccountService.list(), enabled: open, }); const defaultAcmeAccountQuery = useQuery({ queryKey: ['openflare', 'acme-accounts', 'default'], queryFn: () => TlsCertificateService.getDefaultAcmeAccount(), enabled: open, }); const form = useForm({ resolver: zodResolver(createAcmeApplySchema(t)), defaultValues: defaultAcmeApplyValues, }); useEffect(() => { if (!open) return; setError(''); setShowAdvanced(false); if (certificate) { form.reset({ name: certificate.name, primary_domain: mode === 'convert-upload' ? '' : certificate.primary_domain || '', other_domains: mode === 'convert-upload' ? '' : certificate.other_domains || '', remark: certificate.remark || '', acme_account_id: mode === 'convert-upload' ? 0 : certificate.acme_account_id, dns_account_id: mode === 'convert-upload' ? 0 : certificate.dns_account_id, key_algorithm: certificate.key_algorithm || 'EC256', auto_renew: mode === 'convert-upload' ? true : certificate.auto_renew, dns1: mode === 'convert-upload' ? '' : certificate.dns1 || '', dns2: mode === 'convert-upload' ? '' : certificate.dns2 || '', disable_cname: mode === 'convert-upload' ? false : certificate.disable_cname, skip_dns: mode === 'convert-upload' ? false : certificate.skip_dns, }); if ( mode !== 'convert-upload' && (certificate.dns1 || certificate.dns2 || certificate.disable_cname || certificate.skip_dns) ) { setShowAdvanced(true); } } else { form.reset(defaultAcmeApplyValues); } }, [certificate, form, mode, open]); useEffect(() => { if ( defaultAcmeAccountQuery.data && form.getValues('acme_account_id') === 0 ) { form.setValue('acme_account_id', defaultAcmeAccountQuery.data.id); } }, [defaultAcmeAccountQuery.data, form, open]); const applyMutation = useMutation({ mutationFn: (values: AcmeApplyFormValues) => { if (mode === 'edit-acme' && certificate) { return TlsCertificateService.updateAcme(certificate.id, values); } if (mode === 'convert-upload' && certificate) { return TlsCertificateService.convertToAcme(certificate.id, values); } return TlsCertificateService.apply(values); }, onSuccess: async (result) => { await queryClient.invalidateQueries({ queryKey: certificatesQueryKey }); onApplied?.(result); onOpenChange(false); }, onError: (err) => setError(getErrorMessage(err, t('requestFailed'))), }); const title = mode === 'edit-acme' ? t('applyEditTitle') : mode === 'convert-upload' ? t('applyConvertTitle') : t('applyTitle'); const description = mode === 'edit-acme' ? t('applyEditDesc') : mode === 'convert-upload' ? t('applyConvertDesc') : t('applyDesc'); return ( {title} {description}
{ setError(''); applyMutation.mutate(values); })} > {error ?

{error}

: null}