page.tsx
Ricky/Cat Project Final/fp_fixed /src/app/login/page.tsx
"use client";
import React, { useState, FormEvent } from "react";
import { useRouter } from "next/navigation";
import { apiUrl } from "@/lib/publicUrl";
import "./login.css";
export default function LoginPage() {
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [loading, setLoading] = useState(false);
const router = useRouter();
const handleSubmit = async (e: FormEvent) => {
e.preventDefault();
// ⚙️ 暫時關閉 email 驗證 (測試模式)
// 原本這段驗證可以暫時註解掉,之後再開回
// if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) {
// alert("Please enter a valid email");
// return;
// }
try {
setLoading(true);
if (!email || !password) {
alert("Please enter email and password.");
return;
}
if (password.length < 8) {
alert("Password must be at least 8 characters.");
return;
}
const res = await fetch(apiUrl("/api/auth/login"), {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ email, password }),
});
const json = await res.json().catch(() => ({}));
if (!res.ok) {
alert(json?.message || "Login failed.");
return;
}
localStorage.setItem("auth_token", json.token);
localStorage.setItem("owner_email", email);
router.push("/match-result");
} catch (err) {
console.error("❌ Submit failed:", err);
alert("Something went wrong.");
} finally {
setLoading(false);
}
};
return (
<main className="login-container">
<section className="login-card">
<div className="left">
<h1>Ethical Feline Registry</h1>
<p className="subtitle">Connecting Whiskers with Kindness</p>
<form onSubmit={handleSubmit}>
<label>Email Address (Optional for Testing)</label>
<input
type="email"
placeholder="you@example.com"
value={email}
onChange={(e) => setEmail(e.target.value)}
disabled={loading}
/>
<label>Password</label>
<input
type="password"
placeholder="At least 8 characters"
value={password}
onChange={(e) => setPassword(e.target.value)}
disabled={loading}
/>
<button type="submit" disabled={loading}>
{loading ? "Loading..." : "Log In"}
</button>
<p style={{ marginTop: 12, fontSize: 13 }}>
No account yet? <a href="/cat-questionnaire" style={{ textDecoration: "underline" }}>Register your cat</a>
</p>
</form>
</div>
<div className="right">
<img
src="/image/sleepingcat.jpg"
alt="Cute orange cat sleeping"
className="cat-image"
width={600}
/>
</div>
</section>
</main>
);
}
Bài viết liên quan
__init__.py
__init__.py — python source code from the Ricky learning materials (Ricky/Cat Project Final/back_web-4/app/__init__.py).
Đọc bài viết →auth.py
auth.py — python source code from the Ricky learning materials (Ricky/Cat Project Final/back_web-4/app/admin/auth.py).
Đọc bài viết →routes.py
routes.py — python source code from the Ricky learning materials (Ricky/Cat Project Final/back_web-4/app/admin/routes.py).
Đọc bài viết →config.py
config.py — python source code from the Ricky learning materials (Ricky/Cat Project Final/back_web-4/app/config.py).
Đọc bài viết →admin_ingest.py
admin_ingest.py — python source code from the Ricky learning materials (Ricky/Cat Project Final/back_web-4/app/routes/admin_ingest.py).
Đọc bài viết →admin_stats.py
admin_stats.py — python source code from the Ricky learning materials (Ricky/Cat Project Final/back_web-4/app/routes/admin_stats.py).
Đọc bài viết →