Files
smalltown/app/owner/page.tsx

183 lines
5.6 KiB
TypeScript
Raw Permalink Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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, useEffect } from "react";
import Link from "next/link";
import { useRouter } from "next/navigation";
export default function OwnerPage() {
const router = useRouter();
const [isLogin, setIsLogin] = useState(true);
const [username, setUsername] = useState("");
const [password, setPassword] = useState("");
const [error, setError] = useState("");
const [loading, setLoading] = useState(false);
const [checking, setChecking] = useState(true);
const [ready, setReady] = useState(false);
useEffect(() => {
let cancelled = false;
async function checkAuth() {
try {
const res = await fetch("/api/auth/me");
const data = await res.json();
if (!cancelled && data.user) {
router.replace("/owner/dashboard");
return;
}
} catch (error) {
console.error("检查登录状态失败", error);
}
if (!cancelled) {
setChecking(false);
setReady(true);
}
}
checkAuth();
return () => {
cancelled = true;
};
}, [router]);
if (!ready) {
return (
<div className="min-h-screen flex items-center justify-center bg-gray-50">
<div className="text-center">
<div className="text-4xl mb-2 animate-bounce">🏗</div>
<p className="text-gray-500">...</p>
</div>
</div>
);
}
async function handleSubmit(e: React.FormEvent) {
e.preventDefault();
setError("");
setLoading(true);
try {
const endpoint = isLogin ? "/api/auth/login" : "/api/auth/register";
const res = await fetch(endpoint, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ username, password }),
});
const data = await res.json();
if (!res.ok) {
setError(data.error || "操作失败");
return;
}
router.push("/owner/dashboard");
} catch (error) {
setError("网络错误,请重试");
} finally {
setLoading(false);
}
}
return (
<div className="min-h-screen bg-gray-50">
<header className="bg-white px-4 py-3 flex items-center gap-4 shadow-sm">
<Link href="/" className="text-2xl text-gray-600">
</Link>
<h1 className="font-semibold text-gray-900"></h1>
</header>
<main className="px-4 py-8">
<div className="text-center mb-8">
<div className="text-6xl mb-4">🏗</div>
<h2 className="text-2xl font-bold text-gray-900">
{isLogin ? "房东登录" : "房东注册"}
</h2>
<p className="text-gray-500 mt-2">
{isLogin ? "登录后管理您的房源" : "注册后发布和管理房源"}
</p>
</div>
<form onSubmit={handleSubmit} className="bg-white rounded-2xl p-6 shadow-sm">
{error && (
<div className="bg-red-50 text-red-600 text-sm p-3 rounded-lg mb-4">
{error}
</div>
)}
<div className="mb-4">
<label className="block text-sm font-medium text-gray-700 mb-2">
</label>
<input
type="text"
value={username}
onChange={(e) => setUsername(e.target.value)}
placeholder="请输入用户名至少3位"
className="w-full px-4 py-3 rounded-xl border border-gray-200 focus:border-orange-500 focus:ring-2 focus:ring-orange-200 outline-none transition"
required
minLength={3}
/>
</div>
<div className="mb-6">
<label className="block text-sm font-medium text-gray-700 mb-2">
</label>
<input
type="password"
value={password}
onChange={(e) => setPassword(e.target.value)}
placeholder="请输入密码至少6位"
className="w-full px-4 py-3 rounded-xl border border-gray-200 focus:border-orange-500 focus:ring-2 focus:ring-orange-200 outline-none transition"
required
minLength={6}
/>
</div>
<button
type="submit"
disabled={loading}
className="w-full py-4 bg-gradient-to-r from-orange-500 to-orange-600 text-white font-semibold rounded-xl shadow-lg hover:shadow-xl transition disabled:opacity-50"
>
{loading ? "处理中..." : (isLogin ? "登录" : "注册")}
</button>
<div className="mt-4 text-center text-sm">
{isLogin ? (
<p className="text-gray-500">
{" "}
<button
type="button"
onClick={() => setIsLogin(false)}
className="text-orange-500 font-medium"
>
</button>
</p>
) : (
<p className="text-gray-500">
{" "}
<button
type="button"
onClick={() => setIsLogin(true)}
className="text-orange-500 font-medium"
>
</button>
</p>
)}
</div>
</form>
<p className="text-center text-gray-400 text-sm mt-8">
<Link href="/" className="text-orange-500">
</Link>
</p>
</main>
</div>
);
}