Files
LMS/frontend/src/app/login/page.tsx
T

80 lines
2.6 KiB
TypeScript

"use client";
import { useState } from "react";
import { useRouter } from "next/navigation";
import Link from "next/link";
import { api } from "@/lib/api";
export default function LoginPage() {
const router = useRouter();
const [form, setForm] = useState({ username: "", password: "" });
const [error, setError] = useState("");
const [loading, setLoading] = useState(false);
async function handleSubmit(e: React.FormEvent) {
e.preventDefault();
setError("");
setLoading(true);
try {
await api.login(form);
router.push("/dashboard");
} catch (err: unknown) {
setError(err instanceof Error ? err.message : "Login failed.");
} finally {
setLoading(false);
}
}
return (
<div className="min-h-screen flex items-center justify-center px-4">
<div className="w-full max-w-sm bg-white rounded-2xl shadow-md p-8">
<h1 className="text-2xl font-bold mb-6 text-center">Sign in</h1>
{error && (
<p className="mb-4 text-sm text-red-600 bg-red-50 border border-red-200 rounded-lg px-3 py-2">
{error}
</p>
)}
<form onSubmit={handleSubmit} className="space-y-4">
<div>
<label className="block text-sm font-medium mb-1">Username</label>
<input
className="w-full border rounded-lg px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-blue-500"
value={form.username}
onChange={(e) => setForm({ ...form, username: e.target.value })}
required
autoComplete="username"
/>
</div>
<div>
<label className="block text-sm font-medium mb-1">Password</label>
<input
type="password"
className="w-full border rounded-lg px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-blue-500"
value={form.password}
onChange={(e) => setForm({ ...form, password: e.target.value })}
required
autoComplete="current-password"
/>
</div>
<button
type="submit"
disabled={loading}
className="w-full bg-blue-600 hover:bg-blue-700 disabled:opacity-60 text-white font-semibold rounded-lg py-2 text-sm transition"
>
{loading ? "Signing in…" : "Sign in"}
</button>
</form>
<p className="mt-6 text-center text-sm text-gray-500">
No account?{" "}
<Link href="/register" className="text-blue-600 hover:underline">
Register
</Link>
</p>
</div>
</div>
);
}