import { useT } from "@agent-native/core/client/i18n"; import { IconX, IconCheck, IconLoader2, IconDatabase, IconCloud, IconChevronRight, } from "@tabler/icons-react"; import { useState, useRef, useCallback } from "react"; interface CloudUpgradeProps { title?: string; description?: string; onClose?: () => void; } interface Provider { id: string; name: string; descriptionKey: string; urlPrefix: string; needsAuthToken: boolean; stepKeys: string[]; } const PROVIDERS: Provider[] = [ { id: "turso", name: "Turso", descriptionKey: "cloudUpgrade.providers.turso.description", urlPrefix: "libsql://", needsAuthToken: true, stepKeys: ["step1", "step2", "step3", "step4", "step5"], }, { id: "neon", name: "Neon", descriptionKey: "cloudUpgrade.providers.neon.description", urlPrefix: "postgres://", needsAuthToken: false, stepKeys: ["step1", "step2", "step3", "step4", "step5"], }, { id: "supabase", name: "Supabase", descriptionKey: "cloudUpgrade.providers.supabase.description", urlPrefix: "postgres://", needsAuthToken: false, stepKeys: ["step1", "step2", "step3", "step4", "step5"], }, { id: "d1", name: "Cloudflare D1", // i18n-ignore stable provider name descriptionKey: "cloudUpgrade.providers.d1.description", urlPrefix: "d1://", needsAuthToken: true, stepKeys: ["step1", "step2", "step3", "step4", "step5", "step6"], }, ]; export function CloudUpgrade({ title = "Share Publicly", description = "To share content publicly, connect a cloud database.", onClose, }: CloudUpgradeProps) { const t = useT(); const [selectedProvider, setSelectedProvider] = useState(null); const [dbUrl, setDbUrl] = useState(""); const [authToken, setAuthToken] = useState(""); const [status, setStatus] = useState< "idle" | "saving" | "polling" | "success" | "error" >("idle"); const [errorMsg, setErrorMsg] = useState(""); const connectingRef = useRef(false); const provider = PROVIDERS.find((p) => p.id === selectedProvider); const handleConnect = useCallback(async () => { if (connectingRef.current) return; connectingRef.current = true; if (!dbUrl.trim()) { setErrorMsg( "Database settings are deployment-level. Configure DATABASE_URL with your host and redeploy the app.", ); setStatus("error"); connectingRef.current = false; return; } try { setStatus("error"); setErrorMsg(""); throw new Error( "Database settings are deployment-level. Configure DATABASE_URL and DATABASE_AUTH_TOKEN with your host, redeploy, then check sharing again.", ); } catch (e) { setErrorMsg( e instanceof Error ? e.message : t("cloudUpgrade.connectionFailed"), ); setStatus("error"); } finally { connectingRef.current = false; } }, [dbUrl, authToken, t]); const isConnecting = status === "saving" || status === "polling"; return (
{/* Header */}

{title}

{onClose && ( )}

{description}

{/* Provider selection */}
{PROVIDERS.map((p) => ( ))}
{/* Provider setup steps */} {provider && (

{t("cloudUpgrade.setupSteps")}

    {provider.stepKeys.map((stepKey, i) => (
  1. {t(`cloudUpgrade.providers.${provider.id}.steps.${stepKey}`)}
  2. ))}
)} {/* Credential inputs */}
setDbUrl(e.target.value)} disabled={isConnecting} className="w-full rounded-md border border-zinc-300 bg-white px-3 py-2 text-sm text-zinc-900 placeholder:text-zinc-400 focus:border-blue-500 focus:outline-none focus:ring-1 focus:ring-blue-500 disabled:opacity-50 dark:border-zinc-700 dark:bg-zinc-900 dark:text-zinc-100 dark:placeholder:text-zinc-500" />
{(!provider || provider.needsAuthToken) && (
setAuthToken(e.target.value)} disabled={isConnecting} className="w-full rounded-md border border-zinc-300 bg-white px-3 py-2 text-sm text-zinc-900 placeholder:text-zinc-400 focus:border-blue-500 focus:outline-none focus:ring-1 focus:ring-blue-500 disabled:opacity-50 dark:border-zinc-700 dark:bg-zinc-900 dark:text-zinc-100 dark:placeholder:text-zinc-500" />
)}
{/* Error message */} {status === "error" && errorMsg && (

{errorMsg}

)} {/* Success message */} {status === "success" && (
{t("cloudUpgrade.connectedReloading")}
)} {/* Connect button */}
); }