Files
mylinspirer/frontend/src/components/Login.tsx
2025-12-06 22:32:01 +08:00

84 lines
2.4 KiB
TypeScript

import { Component, createSignal } from "solid-js";
import { Button } from "./ui/Button";
import { Card } from "./ui/Card";
import { Input } from "./ui/Input";
interface LoginProps {
onLoginSuccess: (token: string) => void;
}
const Login: Component<LoginProps> = (props) => {
const [password, setPassword] = createSignal("");
const [error, setError] = createSignal("");
const [isLoading, setIsLoading] = createSignal(false);
const handleSubmit = async (e: Event) => {
e.preventDefault();
setError("");
setIsLoading(true);
try {
const response = await fetch("/admin/api/login", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ password: password() }),
});
if (!response.ok) {
const errorData = await response.json().catch(() => ({ error: "Login failed" }));
throw new Error(errorData.error || "Invalid password");
}
const data = await response.json();
props.onLoginSuccess(data.token);
} catch (err) {
setError(err instanceof Error ? err.message : "Login failed");
} finally {
setIsLoading(false);
}
};
return (
<div class="min-h-screen bg-gray-100 flex items-center justify-center">
<Card class="p-8 w-96">
<h1 class="text-2xl font-bold text-gray-900 mb-6 text-center">My Linspirer Admin Login</h1>
<form onSubmit={handleSubmit}>
<div class="mb-4">
<label class="block text-gray-700 text-sm font-medium mb-2" for="password">
Password
</label>
<Input
id="password"
type="password"
value={password()}
onInput={(e) => setPassword(e.currentTarget.value)}
placeholder="Enter admin password"
disabled={isLoading()}
required
/>
</div>
{error() && (
<div class="mb-4 p-3 bg-red-50 border border-red-200 rounded-md">
<p class="text-sm text-red-600">{error()}</p>
</div>
)}
<Button type="submit" size="lg" disabled={isLoading()}>
{isLoading() ? "Logging in..." : "Login"}
</Button>
</form>
<div class="mt-4 text-center text-sm text-gray-500">
<p>Default password: admin123</p>
</div>
</Card>
</div>
);
};
export default Login;