import { useState } from "react"; import { useQuery, useQueryClient } from "@tanstack/react-query"; import { Shield, CheckCircle, ChevronDown, ChevronUp, Loader2 } from "lucide-react"; import { Button } from "@/components/ui/button"; import { Textarea } from "@/components/ui/textarea"; import { useAuth } from "@/contexts/AuthContext"; import { useLang } from "@/contexts/LanguageContext"; import { useToast } from "@/hooks/use-toast"; const BASE = import.meta.env.BASE_URL.replace(/\/$/, ""); const API_BASE = `${BASE}/api`; const BASE_URL = import.meta.env.BASE_URL.replace(/\/$/, ""); async function fetchSetupStatus(): Promise<{ refreshTokenConfigured: boolean }> { const r = await fetch(`${API_BASE}/admin/setup-status`, { credentials: "include" }); if (!r.ok) return { refreshTokenConfigured: true }; return r.json(); } export function SetupWizard() { const { isAdmin, isLoaded } = useAuth(); const { t } = useLang(); const { toast } = useToast(); const qc = useQueryClient(); const [token, setToken] = useState(""); const [saving, setSaving] = useState(false); const [stepsOpen, setStepsOpen] = useState(true); const { data, isLoading } = useQuery({ queryKey: ["setupStatus"], queryFn: fetchSetupStatus, enabled: isLoaded && isAdmin, staleTime: 0, }); if (!isLoaded || !isAdmin || isLoading || data?.refreshTokenConfigured) return null; const handleSave = async () => { if (!token.trim()) return; setSaving(true); try { const r = await fetch(`${API_BASE}/admin/setup`, { method: "POST", credentials: "include", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ refreshToken: token.trim() }), }); const data = await r.json(); if (!r.ok) throw new Error(data.error || "Failed"); await qc.invalidateQueries({ queryKey: ["setupStatus"] }); toast({ description: t.setupSuccess }); } catch (e: any) { toast({ variant: "destructive", description: e.message || t.setupError }); } setSaving(false); }; return (

{t.setupTitle}

{t.setupSubtitle}

{stepsOpen && (
    {(t.adminGuideSteps as string[]).map((step, i) => (
  1. {i + 1}
  2. ))}
Token guide screenshot
)}