"use client"; import Image from "next/image"; import { ArrowRight, Eye, EyeOff, Lock, UserRound, } from "@/components/icons/platform-icons"; import { useRouter } from "next/navigation"; import { type FormEvent, useEffect, useRef, useState } from "react"; type WizardStep = "welcome" | "account" | "setup" | "done"; const WIZARD_STEPS: WizardStep[] = ["welcome", "account", "setup", "done"]; const setupSteps = [ { title: "Creating your account", description: "Saving credentials and creating the first session.", }, { title: "Preparing storage", description: "Creating required folders and workspace paths.", }, { title: "Setting up the App Store", description: "Downloading and indexing the default catalog.", }, ] as const; export function RegisterForm() { const router = useRouter(); const [step, setStep] = useState("welcome"); const [username, setUsername] = useState(""); const [password, setPassword] = useState(""); const [confirmPassword, setConfirmPassword] = useState(""); const [error, setError] = useState(null); const [setupStage, setSetupStage] = useState(0); const [isPasswordVisible, setIsPasswordVisible] = useState(false); const [isConfirmPasswordVisible, setIsConfirmPasswordVisible] = useState(false); // Frozen at submit time so the setup effect doesn't need state deps const credentials = useRef({ username: "", password: "", confirmPassword: "" }); useEffect(() => { if (step !== "setup") return; const data = credentials.current; let cancelled = false; setSetupStage(0); const t1 = window.setTimeout(() => { if (!cancelled) setSetupStage(1); }, 1200); const t2 = window.setTimeout(() => { if (!cancelled) setSetupStage(2); }, 3200); const register = fetch("/api/auth/register", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(data), }).then(async (res) => { if (!res.ok) { const json = await res.json().catch(() => ({})) as { error?: string }; throw new Error(json.error ?? "Registration failed"); } }); const minWait = new Promise((resolve) => setTimeout(resolve, 4400)); Promise.all([register, minWait]) .then(() => { if (!cancelled) setStep("done"); }) .catch((err: unknown) => { if (!cancelled) { setError(err instanceof Error ? err.message : "Registration failed"); setStep("account"); } }); return () => { cancelled = true; window.clearTimeout(t1); window.clearTimeout(t2); }; }, [step]); // credentials are frozen in a ref at submit time function handleAccountSubmit(e: FormEvent) { e.preventDefault(); if (password !== confirmPassword) { setError("Passwords do not match"); return; } setError(null); credentials.current = { username, password, confirmPassword }; setStep("setup"); } const currentSetupStep = setupSteps[setupStage]; const stepIndex = WIZARD_STEPS.indexOf(step); return (
{/* Step indicator — hidden during setup which has its own internal progress */} {step !== "setup" && (
{WIZARD_STEPS.map((s, i) => ( ))}
)} {step === "welcome" && (
Homeio
Home server

Welcome to your
Home Server

Set up your private home server in minutes. All your files, apps, and settings — in one place.

)} {step === "account" && (
Homeio
Home server

Create admin account

Configure local access

setUsername(e.target.value)} placeholder="Admin username" className="h-10 w-full border-0 bg-transparent px-1 text-[15px] text-foreground outline-none placeholder:text-muted-foreground/52" required autoFocus />
setPassword(e.target.value)} placeholder="New password" className="h-10 w-full border-0 bg-transparent px-1 text-[15px] text-foreground outline-none placeholder:text-muted-foreground/52" required />
setConfirmPassword(e.target.value)} placeholder="Confirm new password" className="h-10 w-full border-0 bg-transparent px-1 text-[15px] text-foreground outline-none placeholder:text-muted-foreground/52" required />
{error ? (

{error}

) : null}
)} {step === "setup" && (
Homeio
Home server

{currentSetupStep?.title}

Setup in progress

{setupSteps.map((s, i) => ( ))}

{currentSetupStep?.description}

First launch may take longer while background services finish initialization.

Working
)} {step === "done" && (
Homeio
Home server

You're all set

Your home server is ready. Sign in to access your dashboard.

)}
); }