import { createFileRoute, useNavigate, Link } from "@tanstack/react-router"; import { useEffect, useState } from "react"; import { supabase } from "@/integrations/supabase/client"; import { useAuth } from "@/lib/auth"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"; import { Loader2, Scale } from "lucide-react"; import { toast } from "sonner"; export const Route = createFileRoute("/setup")({ component: SetupPage, }); function SetupPage() { const navigate = useNavigate(); const { loading, session } = useAuth(); const [checking, setChecking] = useState(true); const [allowed, setAllowed] = useState(false); const [name, setName] = useState(""); const [email, setEmail] = useState(""); const [password, setPassword] = useState(""); const [submitting, setSubmitting] = useState(false); useEffect(() => { // If anyone exists, block access to /setup (async () => { const { count } = await supabase .from("user_roles") .select("*", { count: "exact", head: true }); if ((count ?? 0) === 0) setAllowed(true); setChecking(false); })(); }, []); useEffect(() => { if (!loading && session && !allowed) navigate({ to: "/" }); }, [loading, session, allowed, navigate]); const onSubmit = async (e: React.FormEvent) => { e.preventDefault(); setSubmitting(true); const redirectUrl = `${window.location.origin}/`; const { error } = await supabase.auth.signUp({ email: email.trim(), password, options: { emailRedirectTo: redirectUrl, data: { full_name: name.trim() }, }, }); setSubmitting(false); if (error) { toast.error("Could not create account", { description: error.message }); return; } toast.success("Founding admin account created"); navigate({ to: "/" }); }; if (checking) { return (
); } if (!allowed) { return (
Setup unavailable Firm is already initialized. Use the standard sign-in page.
); } return (
Counsel
Create founding admin This is a one-time setup. The first account becomes the firm administrator and can invite attorneys and staff afterward.
setName(e.target.value)} />
setEmail(e.target.value)} />
setPassword(e.target.value)} />

Minimum 10 characters. Avoid commonly leaked passwords.

); }