import { useEffect, useMemo, useState } from "react"; import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; import { useNavigate, useSearchParams } from "@/lib/router"; import { authApi } from "../api/auth"; import { queryKeys } from "../lib/queryKeys"; import { Button } from "@/components/ui/button"; import { AsciiArtAnimation } from "@/components/AsciiArtAnimation"; import { Sparkles } from "lucide-react"; type AuthMode = "sign_in" | "sign_up"; export function AuthPage() { const queryClient = useQueryClient(); const navigate = useNavigate(); const [searchParams] = useSearchParams(); const [mode, setMode] = useState("sign_in"); const [name, setName] = useState(""); const [email, setEmail] = useState(""); const [password, setPassword] = useState(""); const [error, setError] = useState(null); const nextPath = useMemo(() => searchParams.get("next") || "/", [searchParams]); const { data: session, isLoading: isSessionLoading } = useQuery({ queryKey: queryKeys.auth.session, queryFn: () => authApi.getSession(), retry: false, }); useEffect(() => { if (session) { navigate(nextPath, { replace: true }); } }, [session, navigate, nextPath]); const mutation = useMutation({ mutationFn: async () => { if (mode === "sign_in") { await authApi.signInEmail({ email: email.trim(), password }); return; } await authApi.signUpEmail({ name: name.trim(), email: email.trim(), password, }); }, onSuccess: async () => { setError(null); await queryClient.invalidateQueries({ queryKey: queryKeys.auth.session }); await queryClient.invalidateQueries({ queryKey: queryKeys.companies.all }); navigate(nextPath, { replace: true }); }, onError: (err) => { setError(err instanceof Error ? err.message : "Authentication failed"); }, }); const canSubmit = email.trim().length > 0 && password.trim().length >= 8 && (mode === "sign_in" || name.trim().length > 0); if (isSessionLoading) { return (

Loading…

); } return (
{/* Left half — form */}
Paperclip

{mode === "sign_in" ? "Sign in to Paperclip" : "Create your Paperclip account"}

{mode === "sign_in" ? "Use your email and password to access this instance." : "Create an account for this instance. Email confirmation is not required in v1."}

{ event.preventDefault(); mutation.mutate(); }} > {mode === "sign_up" && (
setName(event.target.value)} autoComplete="name" autoFocus />
)}
setEmail(event.target.value)} autoComplete="email" autoFocus={mode === "sign_in"} />
setPassword(event.target.value)} autoComplete={mode === "sign_in" ? "current-password" : "new-password"} />
{error &&

{error}

}
{mode === "sign_in" ? "Need an account?" : "Already have an account?"}{" "}
{/* Right half — ASCII art animation (hidden on mobile) */}
); }