'use client'; import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'; import { useTranslations } from 'next-intl'; import { ArrowLeft, Cloud, Save, ShieldCheck, Trash2 } from 'lucide-react'; import Link from 'next/link'; import { useEffect, useMemo, useState } from 'react'; import { toast } from 'sonner'; import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert'; import { Button } from '@/components/ui/button'; import { Card, CardContent, CardDescription, CardHeader, CardTitle, } from '@/components/ui/card'; import { Field, FieldDescription, FieldGroup, FieldLabel, } from '@/components/ui/field'; import { Input } from '@/components/ui/input'; import { Select, SelectContent, SelectGroup, SelectItem, SelectTrigger, SelectValue, } from '@/components/ui/select'; import { ErrorInline } from '@/components/layout/error'; import { CloudflareService, cloudflareQueryKey, DnsAccountService, type CloudflareConnectionSource, } from '@/lib/services/openflare'; import { getErrorMessage } from '../../websites/components/website-utils'; const dnsAccountsQueryKey = ['openflare', 'dns-accounts'] as const; export default function CloudflareSettingsPage() { const t = useTranslations('cloudflare.settings'); const queryClient = useQueryClient(); const [source, setSource] = useState('dns_account'); const [dnsAccountID, setDNSAccountID] = useState(''); const [apiToken, setAPIToken] = useState(''); const connectionQuery = useQuery({ queryKey: [...cloudflareQueryKey, 'connection'], queryFn: () => CloudflareService.getConnection(), }); const accountsQuery = useQuery({ queryKey: dnsAccountsQueryKey, queryFn: () => DnsAccountService.list(), }); const cloudflareAccounts = useMemo( () => (accountsQuery.data ?? []).filter( (account) => account.type === 'cloudflare', ), [accountsQuery.data], ); useEffect(() => { const connection = connectionQuery.data; if (!connection?.configured) return; if (connection.source) setSource(connection.source); if (connection.dns_account_id) setDNSAccountID(String(connection.dns_account_id)); }, [connectionQuery.data]); const refresh = async () => { await queryClient.invalidateQueries({ queryKey: cloudflareQueryKey }); }; const saveMutation = useMutation({ mutationFn: () => CloudflareService.saveConnection({ source, dns_account_id: source === 'dns_account' ? Number(dnsAccountID) : 0, api_token: source === 'standalone' ? apiToken : '', }), onSuccess: async () => { toast.success(t('saved')); setAPIToken(''); await refresh(); }, onError: (error) => toast.error(getErrorMessage(error)), }); const verifyMutation = useMutation({ mutationFn: () => CloudflareService.verifyConnection(), onSuccess: async () => { toast.success(t('verified')); await refresh(); }, onError: (error) => toast.error(getErrorMessage(error)), }); const clearMutation = useMutation({ mutationFn: () => CloudflareService.clearConnection(), onSuccess: async () => { toast.success(t('cleared')); setDNSAccountID(''); setAPIToken(''); await refresh(); }, onError: (error) => toast.error(getErrorMessage(error)), }); return (

{t('title')}

{connectionQuery.isError ? ( void connectionQuery.refetch()} /> ) : null} {t('sourceTitle')} {t('sourceDesc')} {t('source')} {source === 'dns_account' ? ( {t('dnsAccount')} {t('dnsHint')}{' '} {t('dnsLink')} {t('dnsHintAfter')} ) : ( API Token setAPIToken(event.target.value)} placeholder={ connectionQuery.data?.configured ? t('tokenKeep') : t('tokenEnter') } /> )}
{t('statusTitle')} {connectionQuery.data?.ready ? t('ready') : t('notReady')}
); }