110 lines
3.1 KiB
TypeScript
110 lines
3.1 KiB
TypeScript
"use client";
|
|
|
|
import { Alert, Box, Button, Card, CardContent, Chip, Stack, TextField, Typography } from "@mui/material";
|
|
import { signIn } from "next-auth/react";
|
|
import { useRouter } from "next/navigation";
|
|
import type { FormEvent } from "react";
|
|
import { useState } from "react";
|
|
|
|
const demoAccounts = [
|
|
{ label: "Vorstand A", username: "vorstand-a" },
|
|
{ label: "Vorstand B", username: "vorstand-b" },
|
|
{ label: "Finanz-AG", username: "finanzen" },
|
|
{ label: "Deko Mitglied", username: "deko" }
|
|
];
|
|
|
|
export function LoginForm() {
|
|
const router = useRouter();
|
|
const [identifier, setIdentifier] = useState("vorstand-a");
|
|
const [password, setPassword] = useState("demo123!");
|
|
const [error, setError] = useState<string | null>(null);
|
|
const [isLoading, setIsLoading] = useState(false);
|
|
|
|
async function handleSubmit(event: FormEvent<HTMLFormElement>) {
|
|
event.preventDefault();
|
|
setError(null);
|
|
setIsLoading(true);
|
|
|
|
const result = await signIn("credentials", {
|
|
identifier,
|
|
password,
|
|
redirect: false
|
|
});
|
|
|
|
setIsLoading(false);
|
|
|
|
if (result?.error) {
|
|
setError("Anmeldung fehlgeschlagen. Bitte Zugangsdaten pr\u00fcfen.");
|
|
return;
|
|
}
|
|
|
|
router.push("/");
|
|
router.refresh();
|
|
}
|
|
|
|
return (
|
|
<Card
|
|
sx={{
|
|
maxWidth: 520,
|
|
width: "100%",
|
|
mx: "auto",
|
|
overflow: "visible"
|
|
}}
|
|
>
|
|
<CardContent sx={{ p: { xs: 3, md: 4 } }}>
|
|
<Stack spacing={3}>
|
|
<Box>
|
|
<Typography variant="h2" gutterBottom>
|
|
Anmeldung
|
|
</Typography>
|
|
<Typography color="text.secondary">
|
|
Melde dich mit deinem Login-Namen und Passwort an.
|
|
</Typography>
|
|
</Box>
|
|
|
|
<Stack direction="row" useFlexGap flexWrap="wrap" gap={1}>
|
|
{demoAccounts.map((account) => (
|
|
<Chip
|
|
key={account.username}
|
|
label={account.label}
|
|
onClick={() => {
|
|
setIdentifier(account.username);
|
|
setPassword("demo123!");
|
|
}}
|
|
variant="outlined"
|
|
/>
|
|
))}
|
|
</Stack>
|
|
|
|
<Alert severity="info">{"Demo-Passwort f\u00fcr alle Konten: demo123!"}</Alert>
|
|
|
|
{error ? <Alert severity="error">{error}</Alert> : null}
|
|
|
|
<Box component="form" onSubmit={handleSubmit}>
|
|
<Stack spacing={2}>
|
|
<TextField
|
|
label="Login-Name"
|
|
value={identifier}
|
|
onChange={(event) => setIdentifier(event.target.value)}
|
|
fullWidth
|
|
required
|
|
/>
|
|
<TextField
|
|
label="Passwort"
|
|
type="password"
|
|
value={password}
|
|
onChange={(event) => setPassword(event.target.value)}
|
|
fullWidth
|
|
required
|
|
/>
|
|
<Button type="submit" size="large" variant="contained" disabled={isLoading}>
|
|
{isLoading ? "Anmeldung l\u00e4uft..." : "Einloggen"}
|
|
</Button>
|
|
</Stack>
|
|
</Box>
|
|
</Stack>
|
|
</CardContent>
|
|
</Card>
|
|
);
|
|
}
|