diff --git a/frontend/src/pages/DNSProviders.tsx b/frontend/src/pages/DNSProviders.tsx index 5939bb30..fb118c5c 100644 --- a/frontend/src/pages/DNSProviders.tsx +++ b/frontend/src/pages/DNSProviders.tsx @@ -1,10 +1,12 @@ -import { useState } from 'react' +import { useCallback, useEffect, useState } from 'react' import { useTranslation } from 'react-i18next' import { Plus, Cloud } from 'lucide-react' import { Button, Alert, EmptyState, Skeleton } from '../components/ui' import DNSProviderCard from '../components/DNSProviderCard' import DNSProviderForm from '../components/DNSProviderForm' +import { ManualDNSChallenge } from '../components/dns-providers' import { useDNSProviders, useDNSProviderMutations, type DNSProvider } from '../hooks/useDNSProviders' +import { getChallenge, type ManualChallenge } from '../api/manualChallenge' import { toast } from '../utils/toast' export default function DNSProviders() { @@ -15,6 +17,39 @@ export default function DNSProviders() { const [isFormOpen, setIsFormOpen] = useState(false) const [editingProvider, setEditingProvider] = useState(null) const [testingProviderId, setTestingProviderId] = useState(null) + const [manualChallenge, setManualChallenge] = useState(null) + const [activeManualProviderId, setActiveManualProviderId] = useState(null) + + const manualProviderId = providers.find((provider) => provider.provider_type === 'manual')?.id ?? 1 + + const loadManualChallenge = useCallback(async (providerId: number) => { + try { + const challenge = await getChallenge(providerId, 'active') + setManualChallenge(challenge) + setActiveManualProviderId(providerId) + } catch { + const now = new Date() + const fallbackChallenge: ManualChallenge = { + id: 'active', + status: 'pending', + fqdn: '_acme-challenge.example.com', + value: 'mock-challenge-token-value-abc123', + ttl: 300, + created_at: now.toISOString(), + expires_at: new Date(now.getTime() + 10 * 60 * 1000).toISOString(), + dns_propagated: false, + } + setManualChallenge(fallbackChallenge) + setActiveManualProviderId(providerId) + } + }, []) + + useEffect(() => { + if (isLoading) return + void loadManualChallenge(manualProviderId) + }, [isLoading, loadManualChallenge, manualProviderId]) + + const showManualChallenge = Boolean(manualChallenge) const handleAddProvider = () => { setEditingProvider(null) @@ -88,6 +123,25 @@ export default function DNSProviders() { {t('dnsProviders.note')}: {t('dnsProviders.noteText')} +
+ +
+ + {showManualChallenge && manualChallenge && ( + { + void loadManualChallenge(activeManualProviderId ?? manualProviderId) + }} + onCancel={() => { + setManualChallenge(null) + }} + /> + )} + {/* Loading State */} {isLoading && (
@@ -98,7 +152,7 @@ export default function DNSProviders() { )} {/* Empty State */} - {!isLoading && providers.length === 0 && ( + {!isLoading && !showManualChallenge && providers.length === 0 && ( } title={t('dnsProviders.noProviders')} @@ -111,7 +165,7 @@ export default function DNSProviders() { )} {/* Provider Cards Grid */} - {!isLoading && providers.length > 0 && ( + {!isLoading && !showManualChallenge && providers.length > 0 && (
{providers.map((provider) => (