"use client"; import { useEffect, useState } from "react"; import { Button } from "@/components/ui/button"; type DiagnosticsResponse = { timestamp: string; env: { POSTGRES_URL: boolean; BETTER_AUTH_SECRET: boolean; GOOGLE_CLIENT_ID: boolean; GOOGLE_CLIENT_SECRET: boolean; OPENAI_API_KEY: boolean; NEXT_PUBLIC_APP_URL: boolean; }; database: { connected: boolean; schemaApplied: boolean; error?: string; }; auth: { configured: boolean; routeResponding: boolean | null; }; ai: { configured: boolean; }; overallStatus: "ok" | "warn" | "error"; }; function StatusIcon({ ok }: { ok: boolean }) { return ok ? ( ✅ ) : ( ❌ ); } export function SetupChecklist() { const [data, setData] = useState(null); const [loading, setLoading] = useState(false); const [error, setError] = useState(null); async function load() { setLoading(true); setError(null); try { const res = await fetch("/api/diagnostics", { cache: "no-store" }); if (!res.ok) throw new Error(`HTTP ${res.status}`); const json = (await res.json()) as DiagnosticsResponse; setData(json); } catch (e) { setError(e instanceof Error ? e.message : "Failed to load diagnostics"); } finally { setLoading(false); } } useEffect(() => { load(); }, []); const steps = [ { key: "env", label: "Environment variables", ok: !!data?.env.POSTGRES_URL && !!data?.env.BETTER_AUTH_SECRET && !!data?.env.GOOGLE_CLIENT_ID && !!data?.env.GOOGLE_CLIENT_SECRET, detail: "Requires POSTGRES_URL, BETTER_AUTH_SECRET, GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET", }, { key: "db", label: "Database connected & schema", ok: !!data?.database.connected && !!data?.database.schemaApplied, detail: data?.database.error ? `Error: ${data.database.error}` : undefined, }, { key: "auth", label: "Auth configured", ok: !!data?.auth.configured, detail: data?.auth.routeResponding === false ? "Auth route not responding" : undefined, }, { key: "ai", label: "AI integration (optional)", ok: !!data?.ai.configured, detail: !data?.ai.configured ? "Set OPENAI_API_KEY for AI chat" : undefined, }, ] as const; const completed = steps.filter((s) => s.ok).length; return ( Setup checklist {completed}/{steps.length} completed {loading ? "Checking..." : "Re-check"} {error ? {error} : null} {steps.map((s) => ( {s.label} {s.detail ? ( {s.detail} ) : null} ))} {data ? ( Last checked: {new Date(data.timestamp).toLocaleString()} ) : null} ); }
{completed}/{steps.length} completed