2026-03-29 00:32:24 -04:00

117 lines
3.5 KiB
TypeScript

"use client";
import { useState, useEffect } from "react";
import { useRouter } from "next/navigation";
import {
Card,
CardHeader,
CardTitle,
CardDescription,
CardContent,
} from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
interface Annotator {
id: string;
displayName: string;
}
export default function LoginPage() {
const router = useRouter();
const [annotators, setAnnotators] = useState<Annotator[]>([]);
const [selectedAnnotator, setSelectedAnnotator] = useState<string>("");
const [password, setPassword] = useState("");
const [error, setError] = useState("");
const [loading, setLoading] = useState(false);
useEffect(() => {
fetch("/api/auth")
.then((res) => res.json())
.then((data: Annotator[]) => setAnnotators(data))
.catch(() => setError("Failed to load annotators"));
}, []);
async function handleLogin(e: React.FormEvent) {
e.preventDefault();
setError("");
if (!selectedAnnotator) {
setError("Please select an annotator");
return;
}
setLoading(true);
try {
const res = await fetch("/api/auth", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
annotatorId: selectedAnnotator,
password,
}),
});
if (!res.ok) {
const data = await res.json();
setError(data.error || "Login failed");
return;
}
router.push("/dashboard");
} catch {
setError("Network error");
} finally {
setLoading(false);
}
}
return (
<div className="flex flex-1 items-center justify-center p-4">
<Card className="w-full max-w-sm">
<CardHeader className="text-center">
<CardTitle className="text-2xl">SEC cyBERT</CardTitle>
<CardDescription>Labeling Tool</CardDescription>
</CardHeader>
<form onSubmit={handleLogin}>
<CardContent className="flex flex-col gap-5">
<div className="flex flex-col gap-2">
<Label htmlFor="annotator">Annotator</Label>
<select
id="annotator"
value={selectedAnnotator}
onChange={(e) => setSelectedAnnotator(e.target.value)}
className="flex h-8 w-full items-center rounded-lg border border-input bg-transparent px-2.5 py-2 text-sm outline-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50"
>
<option value="">Select your name</option>
{annotators.map((a) => (
<option key={a.id} value={a.id}>
{a.displayName}
</option>
))}
</select>
</div>
<div className="flex flex-col gap-2">
<Label htmlFor="password">Password</Label>
<Input
id="password"
type="password"
value={password}
onChange={(e) => setPassword(e.target.value)}
placeholder="Enter password"
/>
</div>
{error && (
<p className="text-sm text-destructive">{error}</p>
)}
<Button type="submit" className="w-full" disabled={loading}>
{loading ? "Signing in..." : "Sign In"}
</Button>
</CardContent>
</form>
</Card>
</div>
);
}