44 lines
1.7 KiB
TypeScript
44 lines
1.7 KiB
TypeScript
import React from 'react';
|
|
import { login } from '../api';
|
|
import { useNavigate } from 'react-router-dom';
|
|
import { Input } from '@/components/ui/input';
|
|
import { Button } from '@/components/ui/button';
|
|
import AppearanceToggleDropdown from '@/components/appearance-dropdown';
|
|
|
|
export default function LoginPage() {
|
|
const nav = useNavigate();
|
|
const [email, setEmail] = React.useState('');
|
|
const [password, setPassword] = React.useState('');
|
|
const [error, setError] = React.useState<string | null>(null);
|
|
const [loading, setLoading] = React.useState(false);
|
|
|
|
async function submit(e: React.FormEvent) {
|
|
e.preventDefault();
|
|
setError(null);
|
|
setLoading(true);
|
|
try {
|
|
const { token } = await login(email, password);
|
|
localStorage.setItem('ta_token', token);
|
|
nav('/admin', { replace: true });
|
|
} catch (err: any) {
|
|
setError('Login fehlgeschlagen');
|
|
} finally { setLoading(false); }
|
|
}
|
|
|
|
return (
|
|
<div className="mx-auto max-w-sm p-6">
|
|
<div className="mb-4 flex items-center justify-between">
|
|
<h1 className="text-lg font-semibold">Tenant Admin</h1>
|
|
<AppearanceToggleDropdown />
|
|
</div>
|
|
<form onSubmit={submit} className="space-y-3">
|
|
{error && <div className="rounded border border-red-300 bg-red-50 p-2 text-sm text-red-700">{error}</div>}
|
|
<Input placeholder="E-Mail" type="email" value={email} onChange={(e) => setEmail(e.target.value)} />
|
|
<Input placeholder="Passwort" type="password" value={password} onChange={(e) => setPassword(e.target.value)} />
|
|
<Button type="submit" disabled={loading || !email || !password} className="w-full">{loading ? 'Bitte warten…' : 'Anmelden'}</Button>
|
|
</form>
|
|
</div>
|
|
);
|
|
}
|
|
|