proj/Frontend/components/auth/register-form.tsx
2026-01-21 09:52:33 +01:00

245 lines
9.2 KiB
TypeScript

"use client"
import React, { useState } from "react"
import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from "@/components/ui/card"
import { Checkbox } from "@/components/ui/checkbox"
import { useAuth } from "@/lib/auth-context"
import { type UserRole } from "@/lib/types"
import { Mail, Lock, User, UserPlus, AlertCircle, Building2 } from "lucide-react"
interface RegisterFormProps {
onSwitchToLogin: () => void
}
export function RegisterForm({ onSwitchToLogin }: RegisterFormProps) {
const { register, rooms } = useAuth()
const [firstname, setFirstname] = useState("")
const [lastname, setLastname] = useState("")
const [email, setEmail] = useState("")
const [password, setPassword] = useState("")
const [role, setRole] = useState<UserRole>("LEHRKRAFT")
const [selectedRoomIds, setSelectedRoomIds] = useState<number[]>([])
const [error, setError] = useState("")
const [isLoading, setIsLoading] = useState(false)
const handleRoomToggle = (roomId: number) => {
setSelectedRoomIds((prev) => (prev.includes(roomId) ? prev.filter((r) => r !== roomId) : [...prev, roomId]))
}
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault()
setError("")
if (role === "RAUMBETREUER" && selectedRoomIds.length === 0) {
setError("Bitte wählen Sie mindestens einen Raum aus")
return
}
setIsLoading(true)
const success = await register(
{
firstname,
lastname,
email,
role,
roomIds: role === "RAUMBETREUER" ? selectedRoomIds : undefined,
password
}
)
if (!success) {
setError("Registrierung fehlgeschlagen")
}
// API logic redirects or we stay here. If success, we probably want to call onSwitchToLogin if strictly following "register then login" flow,
// but AuthContext comments implied auto-login or just handled.
// Actually AuthContext returns true if success.
if (success) {
onSwitchToLogin()
}
setIsLoading(false)
}
return (
<Card className="w-full max-w-md border-border/60 shadow-lg">
<CardHeader className="space-y-1 pb-6">
<CardTitle className="text-2xl font-semibold tracking-tight">Konto erstellen</CardTitle>
<CardDescription className="text-muted-foreground">Geben Sie Ihre Daten ein</CardDescription>
</CardHeader>
<form onSubmit={handleSubmit}>
<CardContent className="space-y-4">
{error && (
<div className="flex items-center gap-2 rounded-lg bg-destructive/10 p-3 text-sm text-destructive">
<AlertCircle className="h-4 w-4" />
{error}
</div>
)}
<div className="grid grid-cols-2 gap-4">
<div className="space-y-2">
<Label htmlFor="firstname" className="text-sm font-medium">
Vorname
</Label>
<div className="relative">
<User className="absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" />
<Input
id="firstname"
type="text"
placeholder="Max"
value={firstname}
onChange={(e) => setFirstname(e.target.value)}
className="pl-10"
required
/>
</div>
</div>
<div className="space-y-2">
<Label htmlFor="lastname" className="text-sm font-medium">
Nachname
</Label>
<div className="relative">
<User className="absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" />
<Input
id="lastname"
type="text"
placeholder="Mustermann"
value={lastname}
onChange={(e) => setLastname(e.target.value)}
className="pl-10"
required
/>
</div>
</div>
</div>
<div className="space-y-2">
<Label htmlFor="reg-email" className="text-sm font-medium">
E-Mail
</Label>
<div className="relative">
<Mail className="absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" />
<Input
id="reg-email"
type="email"
placeholder="name@schule.de"
value={email}
onChange={(e) => setEmail(e.target.value)}
className="pl-10"
required
/>
</div>
</div>
<div className="space-y-2">
<Label htmlFor="reg-password" className="text-sm font-medium">
Kennwort
</Label>
<div className="relative">
<Lock className="absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" />
<Input
id="reg-password"
type="password"
placeholder="Kennwort erstellen"
value={password}
onChange={(e) => setPassword(e.target.value)}
className="pl-10"
required
minLength={4}
/>
</div>
</div>
<div className="space-y-3">
<Label className="text-sm font-medium">Rolle</Label>
<div className="grid grid-cols-2 gap-3">
<button
type="button"
onClick={() => setRole("LEHRKRAFT")}
className={`flex flex-col items-center gap-2 rounded-lg border-2 p-4 transition-all ${role === "LEHRKRAFT"
? "border-primary bg-primary/5"
: "border-border hover:border-primary/50 hover:bg-muted/50"
}`}
>
<User className={`h-5 w-5 ${role === "LEHRKRAFT" ? "text-primary" : "text-muted-foreground"}`} />
<span className={`text-sm font-medium ${role === "LEHRKRAFT" ? "text-primary" : "text-foreground"}`}>
Lehrkraft
</span>
</button>
<button
type="button"
onClick={() => setRole("RAUMBETREUER")}
className={`flex flex-col items-center gap-2 rounded-lg border-2 p-4 transition-all ${role === "RAUMBETREUER"
? "border-primary bg-primary/5"
: "border-border hover:border-primary/50 hover:bg-muted/50"
}`}
>
<Building2
className={`h-5 w-5 ${role === "RAUMBETREUER" ? "text-primary" : "text-muted-foreground"}`}
/>
<span className={`text-sm font-medium ${role === "RAUMBETREUER" ? "text-primary" : "text-foreground"}`}>
Raumbetreuer
</span>
</button>
</div>
</div>
{role === "RAUMBETREUER" && (
<div className="space-y-3">
<Label className="text-sm font-medium">Betreute Räume</Label>
<div className="max-h-48 space-y-2 overflow-y-auto rounded-lg border border-border p-3">
{rooms.map((room) => (
<div key={room.id} className="flex items-center space-x-3">
<Checkbox
id={String(room.id)}
checked={selectedRoomIds.includes(room.id)}
onCheckedChange={() => handleRoomToggle(room.id)}
/>
<label
htmlFor={String(room.id)}
className="text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70 cursor-pointer"
>
{room.name}
</label>
</div>
))}
</div>
{selectedRoomIds.length > 0 && (
<p className="text-sm text-muted-foreground">
{selectedRoomIds.length} Raum/Räume ausgewählt
</p>
)}
</div>
)}
</CardContent>
<CardFooter className="flex flex-col gap-4 pt-2">
<Button type="submit" className="w-full" disabled={isLoading}>
{isLoading ? (
<span className="flex items-center gap-2">
<span className="h-4 w-4 animate-spin rounded-full border-2 border-primary-foreground border-t-transparent" />
Registrierung...
</span>
) : (
<span className="flex items-center gap-2">
<UserPlus className="h-4 w-4" />
Registrieren
</span>
)}
</Button>
<p className="text-sm text-muted-foreground">
Bereits registriert?{" "}
<button
type="button"
onClick={onSwitchToLogin}
className="font-medium text-primary underline-offset-4 hover:underline"
>
Anmelden
</button>
</p>
</CardFooter>
</form>
</Card>
)
}