"use client"; import { ArrowRight, Check } from "lucide-react"; import { useRouter } from "next/navigation"; import { useEffect, useRef, useState } from "react"; import { AuthFormCard, FormError } from "@/components/auth/auth-form-card"; import { BrandMark } from "@/components/brand"; import { FullScreenLoader } from "@/components/page-layout"; import { ThemeToggle } from "@/components/theme-toggle"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { api } from "@/lib/api-client"; import { gsap, motionEase, prefersReducedMotion, useGSAP } from "@/lib/motion"; export default function BootstrapPage() { const router = useRouter(); const [loading, setLoading] = useState(false); const [checkingStatus, setCheckingStatus] = useState(true); const [error, setError] = useState(""); const stageRef = useRef(null); useEffect(() => { const checkStatus = async () => { try { const { data } = await api.bootstrap.status.get(); if (data && !data.needsSetup) { router.replace("/login"); } } catch (_err) { } finally { setCheckingStatus(false); } }; checkStatus(); }, [router]); useGSAP( () => { const root = stageRef.current; if (!root || prefersReducedMotion()) return; gsap.fromTo( root, { y: 28, autoAlpha: 0 }, { y: 0, autoAlpha: 1, duration: 0.65, ease: motionEase.out } ); const panelItems = root.querySelectorAll("[data-boot-item]"); gsap.fromTo( panelItems, { y: 16, autoAlpha: 0 }, { y: 0, autoAlpha: 1, duration: 0.5, stagger: 0.07, delay: 0.12, ease: motionEase.out } ); }, { scope: stageRef } ); const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); setLoading(true); setError(""); const formData = new FormData(e.currentTarget); const email = formData.get("email") as string; const password = formData.get("password") as string; const confirmPassword = formData.get("confirmPassword") as string; const name = formData.get("name") as string; if (password !== confirmPassword) { setError("Passwords do not match"); setLoading(false); return; } try { const { data, error: apiError } = await api.bootstrap.setup.post({ email, password, name, }); if (apiError) { const errorMessage = "value" in apiError && typeof apiError.value === "object" && apiError.value && "message" in apiError.value ? String(apiError.value.message) : "Failed to create admin user"; setError(errorMessage); } else if (data?.success) { router.push("/login"); } else { setError("Failed to create admin user"); } } catch (_err) { setError("Failed to connect to server"); } finally { setLoading(false); } }; if (checkingStatus) return ; return (
System bootstrap / 01

Build your command center.

The first account controls users, workloads, routing, and cluster visibility.

Admin authority

Secure session

Ready in one step

); }