"use client"; import { useEffect, useState } from "react"; import { Button } from "@/components/ui/button"; import { CheckCircle2, XCircle } from "lucide-react"; 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

{error ?
{error}
: null}
    {steps.map((s) => (
  • {s.label}
    {s.detail ? (
    {s.detail}
    ) : null}
  • ))}
{data ? (
Last checked: {new Date(data.timestamp).toLocaleString()}
) : null}
); }