hku-class/frontend/src/app/login/page.tsx
2026-04-27 09:21:20 +08:00

109 lines
4.4 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"use client";
import { useState } from "react";
import { useRouter } from "next/navigation";
import { useAuth } from "@/hooks/use-auth";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
import { getErrorMessage } from "@/lib/api";
import Link from "next/link";
export default function LoginPage() {
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [error, setError] = useState("");
const [loading, setLoading] = useState(false);
const { login } = useAuth();
const router = useRouter();
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
setError("");
setLoading(true);
try {
await login(email, password);
router.push("/dashboard");
} catch (err: unknown) {
setError(getErrorMessage(err, "登录失败"));
} finally {
setLoading(false);
}
};
return (
<div className="relative min-h-screen overflow-hidden bg-[linear-gradient(180deg,#f7efe2_0%,#f4ebdf_38%,#f9f5ee_100%)] px-4 py-10">
<div className="absolute inset-x-0 top-0 h-72 bg-[radial-gradient(circle_at_top,rgba(115,25,37,0.18),transparent_60%)]" />
<div className="relative mx-auto flex min-h-[calc(100vh-5rem)] max-w-6xl items-center justify-center">
<div className="grid w-full items-center gap-10 lg:grid-cols-[1.1fr_0.9fr]">
<div className="hidden lg:block">
<div className="inline-flex items-center rounded-full border border-[#c9ac82] bg-white/55 px-4 py-1.5 text-[11px] uppercase tracking-[0.28em] text-[#84553c]">
The University of Hong Kong
</div>
<h1 className="mt-6 max-w-2xl text-5xl font-semibold leading-tight text-[#4e1d1a]">
</h1>
<p className="mt-5 max-w-xl text-base leading-8 text-[#775a4a]">
</p>
<div className="mt-8 flex flex-wrap gap-3 text-sm text-[#6d4d3d]">
<span className="rounded-full border border-[#dec8aa] bg-white/60 px-4 py-2"></span>
<span className="rounded-full border border-[#dec8aa] bg-white/60 px-4 py-2"></span>
<span className="rounded-full border border-[#dec8aa] bg-white/60 px-4 py-2"></span>
</div>
</div>
<Card className="mx-auto w-full max-w-md bg-[#fffaf3]">
<CardHeader className="text-center">
<div className="text-[11px] uppercase tracking-[0.24em] text-[#976746]">HKU ICB</div>
<CardTitle className="text-3xl text-[#4e1d1a]"></CardTitle>
<CardDescription className="text-[#7a5e4f]"></CardDescription>
</CardHeader>
<CardContent>
<form onSubmit={handleSubmit} className="space-y-4">
<div className="space-y-2">
<Label htmlFor="email"></Label>
<Input
id="email"
type="email"
placeholder="your@email.com"
value={email}
onChange={(e) => setEmail(e.target.value)}
required
/>
</div>
<div className="space-y-2">
<Label htmlFor="password"></Label>
<Input
id="password"
type="password"
placeholder="请输入密码"
value={password}
onChange={(e) => setPassword(e.target.value)}
required
/>
</div>
{error && (
<p className="rounded-2xl bg-red-50 p-3 text-sm text-red-600">
{error}
</p>
)}
<Button type="submit" className="w-full" disabled={loading}>
{loading ? "登录中..." : "登录"}
</Button>
</form>
<div className="mt-5 text-center text-sm text-[#6f5648]">
{" "}
<Link href="/activate" className="text-[#8a4527] hover:underline">
</Link>
</div>
</CardContent>
</Card>
</div>
</div>
</div>
);
}