"use client"; import { FormEvent, useState } from "react"; import Link from "next/link"; import { useRouter } from "next/navigation"; import { storeAuthToken } from "@/hooks/use-optional-auth"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; const API_BASE = process.env.NEXT_PUBLIC_API_URL ?? ""; export default function SignInPage() { const router = useRouter(); const [email, setEmail] = useState(""); const [password, setPassword] = useState(""); const [error, setError] = useState(null); const [busy, setBusy] = useState(false); async function onSubmit(e: FormEvent) { e.preventDefault(); setBusy(true); setError(null); try { const res = await fetch(`${API_BASE}/api/auth/login`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ email, password }), }); const data = await res.json().catch(() => ({})); if (!res.ok) { throw new Error(data.detail || "Sign in failed"); } storeAuthToken(data.token); router.replace("/"); router.refresh(); } catch (err) { setError(err instanceof Error ? err.message : "Sign in failed"); } finally { setBusy(false); } } return (

Sign in

Periscope account for this server. Invite collaborators from a project once they have an account.

setEmail(e.target.value)} />
setPassword(e.target.value)} />
{error &&

{error}

}

No account?{" "} Create one

); }