import { Execution, ID, Query } from 'appwrite' import { FormEvent, useEffect, useState } from 'react' import { appwriteDatabaseId, databases, functions } from '../lib/appwrite' const badgeClass = (status: string) => status === 'active' ? 'rounded-full bg-emerald-500/20 px-2 py-1 text-xs text-emerald-200' : 'rounded-full bg-amber-500/20 px-2 py-1 text-xs text-amber-200' type Zone = { id: string name: string status: string paused?: boolean } type Worker = { name: string modifiedOn?: string active?: boolean } export default function Cloudflare() { const [label, setLabel] = useState('') const [apiKey, setApiKey] = useState('') const [accountId, setAccountId] = useState('') const [cloudflareAccountId, setCloudflareAccountId] = useState('') const [credentials, setCredentials] = useState<{ $id: string; label: string }[]>([]) const [zones, setZones] = useState([]) const [workers, setWorkers] = useState([]) const [execution, setExecution] = useState(null) const [error, setError] = useState(null) const [modalOpen, setModalOpen] = useState(false) const [newZone, setNewZone] = useState('') useEffect(() => { const loadCredentials = async () => { if (!appwriteDatabaseId) return try { const response = await databases.listDocuments(appwriteDatabaseId, 'cloud_accounts', [ Query.equal('provider', 'cloudflare'), ]) const docs = response.documents.map((doc) => ({ $id: doc.$id, label: (doc as { label?: string }).label || doc.$id })) setCredentials(docs) } catch (err) { console.error(err) setError('Falha ao carregar credenciais Cloudflare.') } } loadCredentials() }, []) const handleSaveKey = async (event: FormEvent) => { event.preventDefault() setError(null) if (!appwriteDatabaseId) { setError('Configure VITE_APPWRITE_DATABASE_ID para salvar a chave de API.') return } try { const document = await databases.createDocument(appwriteDatabaseId, 'cloud_accounts', ID.unique(), { provider: 'cloudflare', apiKey, label, }) setCredentials((prev) => [...prev, { $id: document.$id, label: label || document.$id }]) setLabel('') setApiKey('') } catch (err) { console.error(err) setError('Não foi possível salvar a API Key.') } } const handleStatus = async () => { setError(null) const selectedAccount = accountId || credentials[0]?.$id if (!selectedAccount) { setError('Selecione ou cadastre uma credencial Cloudflare antes de consultar o status.') return } try { const executionResult = await functions.createExecution( 'check-cloudflare-status', JSON.stringify({ accountId: selectedAccount, cloudflareAccountId }), ) setExecution(executionResult) const payload = executionResult.responseBody ? JSON.parse(executionResult.responseBody) : {} setZones((payload.zones as Zone[]) || []) setWorkers((payload.workers as Worker[]) || []) } catch (err) { console.error(err) setError('Não foi possível checar o status do Cloudflare.') } } const handleAddZone = () => { if (!newZone.trim()) return setZones((prev) => [{ id: crypto.randomUUID(), name: newZone, status: 'pending' }, ...prev]) setNewZone('') setModalOpen(false) } const online = zones.some((zone) => zone.status === 'active' && !zone.paused) return (

Cloudflare

Integração e Status

Salve a API Key criptografada no Appwrite e consulte a função check-cloudflare-status.

Salvar credencial

Armazene a chave com criptografia gerenciada pelo Appwrite.

setLabel(e.target.value)} className="mt-1 w-full rounded-lg border border-slate-800 bg-slate-950 px-3 py-2 text-sm text-slate-100 outline-none focus:border-cyan-400" />
setApiKey(e.target.value)} required className="mt-1 w-full rounded-lg border border-slate-800 bg-slate-950 px-3 py-2 text-sm text-slate-100 outline-none focus:border-cyan-400" />
{error ?

{error}

: null}

Status das zonas

Selecione a credencial e consulte o status em tempo real.

setCloudflareAccountId(e.target.value)} className="mt-1 w-full rounded-lg border border-slate-800 bg-slate-950 px-3 py-2 text-sm text-slate-100 outline-none focus:border-cyan-400" />
{execution ? (
Execução #{execution.$id} • Status {execution.status}
) : null}

Zonas DNS

{online ? 'Online' : 'Aguardando verificação'}
    {zones.length === 0 ?
  • Nenhuma zona carregada.
  • : null} {zones.map((zone) => (
  • {zone.name}

    ID: {zone.id}

    {zone.status}
  • ))}

Workers

    {workers.length === 0 ?
  • Nenhum worker listado.
  • : null} {workers.map((worker) => (
  • {worker.name}

    {worker.modifiedOn}

    {worker.active ? 'Ativo' : 'Inativo'}
  • ))}
{modalOpen ? (

Adicionar Nova Zona

Inclua uma entrada manual enquanto a função sincroniza zonas.

setNewZone(e.target.value)} placeholder="example.com" className="mt-3 w-full rounded-lg border border-slate-800 bg-slate-900 px-3 py-2 text-sm text-slate-100 outline-none focus:border-cyan-400" />
) : null}
) }