import { ArrowRight, LockKeyhole } from "lucide-react"; import { type FormEvent, type ReactNode, useState } from "react"; import { Button } from "#/components/ui/button"; import { Input } from "#/components/ui/input"; import { Label } from "#/components/ui/label"; import { authRequest } from "./auth-client"; import { safeReturnTo } from "./return-to"; export function AuthFrame({ children }: { children: ReactNode }) { return (
{children}
); } export function LoginPage() { return ; } export function SetupPage() { return ; } function formText(data: FormData, name: string) { const value = data.get(name); return typeof value === "string" ? value : ""; } function CredentialsForm({ setup }: { setup: boolean }) { const [pending, setPending] = useState(false); const [error, setError] = useState(""); async function submit(event: FormEvent) { event.preventDefault(); if (pending) return; const data = new FormData(event.currentTarget); const email = formText(data, "email").trim(); const password = formText(data, "password"); if (setup && password !== data.get("confirmPassword")) { setError("Passwords do not match."); return; } setPending(true); setError(""); try { const state = await authRequest( setup ? { action: "setup", email, password, name: formText(data, "name").trim(), setupToken: formText(data, "setupToken").trim(), } : { action: "login", email, password }, ); if (!state.owner?.onboardingCompletedAt) { window.location.assign("/onboarding"); return; } const returnTo = new URLSearchParams(window.location.search).get("returnTo"); window.location.assign(safeReturnTo(returnTo)); } catch (cause) { setError(cause instanceof Error ? cause.message : "Unable to sign in. Please try again."); setPending(false); } } return (

{setup ? "Make yourself at home." : "Welcome back."}

{setup ? "Create the owner account for your personal workspace." : "Sign in to your personal workspace."}

{setup && (
)}
{setup && (

Use 15–128 characters. A few memorable words work well.

)}
{setup && ( <>

Use the setup code provided by your server administrator.

)} {error && (

{error}

)}

{setup ? "This workspace has one owner. Connections can be added later." : "A private workspace. Access is limited to its owner."}

); }