Files
fotospiel-app/resources/js/pages/auth/register.tsx

252 lines
13 KiB
TypeScript

import React from 'react';
import { useForm, router } from '@inertiajs/react';
import { Head } from '@inertiajs/react';
import { LoaderCircle } from 'lucide-react';
interface RegisterProps {
package?: {
id: number;
name: string;
description: string;
price: number;
} | null;
}
export default function Register({ package: initialPackage }: RegisterProps) {
const { data, setData, post, processing, errors } = useForm({
name: '',
username: '',
email: '',
password: '',
password_confirmation: '',
first_name: '',
last_name: '',
address: '',
phone: '',
privacy_consent: false,
package_id: initialPackage?.id || null,
});
const submit = (e: React.FormEvent) => {
e.preventDefault();
router.post('/register');
};
return (
<div className="min-h-screen flex items-center justify-center bg-gray-50 py-12 px-4 sm:px-6 lg:px-8">
<Head title="Registrieren" />
<div className="max-w-md w-full space-y-8">
<div>
<h2 className="mt-6 text-center text-3xl font-extrabold text-gray-900">
Registrieren
</h2>
{initialPackage && (
<div className="mt-4 p-4 bg-blue-50 border border-blue-200 rounded-md">
<h3 className="text-lg font-semibold text-blue-900 mb-2">{initialPackage.name}</h3>
<p className="text-blue-800 mb-2">{initialPackage.description}</p>
<p className="text-sm text-blue-700">
{initialPackage.price === 0 ? 'Kostenlos' : `${initialPackage.price}`}
</p>
</div>
)}
</div>
<form onSubmit={submit} className="mt-8 space-y-6">
<div className="space-y-4">
<div>
<label htmlFor="name" className="block text-sm font-medium text-gray-700">
Name
</label>
<input
id="name"
name="name"
type="text"
required
autoFocus
value={data.name}
onChange={(e) => setData('name', e.target.value)}
className="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm placeholder-gray-400 focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm"
placeholder="Vollständiger Name"
/>
{errors.name && <p className="mt-2 text-sm text-red-600">{errors.name}</p>}
</div>
<div>
<label htmlFor="username" className="block text-sm font-medium text-gray-700">
Benutzername
</label>
<input
id="username"
name="username"
type="text"
required
value={data.username}
onChange={(e) => setData('username', e.target.value)}
className="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm placeholder-gray-400 focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm"
placeholder="Benutzername"
/>
{errors.username && <p className="text-sm text-red-600">{errors.username}</p>}
</div>
<div>
<label htmlFor="email" className="block text-sm font-medium text-gray-700">
E-Mail-Adresse
</label>
<input
id="email"
name="email"
type="email"
required
value={data.email}
onChange={(e) => setData('email', e.target.value)}
className="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm placeholder-gray-400 focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm"
placeholder="email@example.com"
/>
{errors.email && <p className="text-sm text-red-600">{errors.email}</p>}
</div>
<div>
<label htmlFor="first_name" className="block text-sm font-medium text-gray-700">
Vorname
</label>
<input
id="first_name"
name="first_name"
type="text"
required
value={data.first_name}
onChange={(e) => setData('first_name', e.target.value)}
className="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm placeholder-gray-400 focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm"
placeholder="Vorname"
/>
{errors.first_name && <p className="text-sm text-red-600">{errors.first_name}</p>}
</div>
<div>
<label htmlFor="last_name" className="block text-sm font-medium text-gray-700">
Nachname
</label>
<input
id="last_name"
name="last_name"
type="text"
required
value={data.last_name}
onChange={(e) => setData('last_name', e.target.value)}
className="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm placeholder-gray-400 focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm"
placeholder="Nachname"
/>
{errors.last_name && <p className="text-sm text-red-600">{errors.last_name}</p>}
</div>
<div>
<label htmlFor="address" className="block text-sm font-medium text-gray-700">
Adresse
</label>
<textarea
id="address"
name="address"
required
value={data.address}
onChange={(e) => setData('address', e.target.value)}
rows={3}
className="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm placeholder-gray-400 focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm"
placeholder="Adresse"
/>
{errors.address && <p className="text-sm text-red-600">{errors.address}</p>}
</div>
<div>
<label htmlFor="phone" className="block text-sm font-medium text-gray-700">
Telefon
</label>
<input
id="phone"
name="phone"
type="tel"
required
value={data.phone}
onChange={(e) => setData('phone', e.target.value)}
className="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm placeholder-gray-400 focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm"
placeholder="Telefonnummer"
/>
{errors.phone && <p className="text-sm text-red-600">{errors.phone}</p>}
</div>
<div>
<label htmlFor="password" className="block text-sm font-medium text-gray-700">
Passwort
</label>
<input
id="password"
name="password"
type="password"
required
value={data.password}
onChange={(e) => setData('password', e.target.value)}
className="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm placeholder-gray-400 focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm"
placeholder="Passwort"
/>
{errors.password && <p className="text-sm text-red-600">{errors.password}</p>}
</div>
<div>
<label htmlFor="password_confirmation" className="block text-sm font-medium text-gray-700">
Passwort bestätigen
</label>
<input
id="password_confirmation"
name="password_confirmation"
type="password"
required
value={data.password_confirmation}
onChange={(e) => setData('password_confirmation', e.target.value)}
className="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm placeholder-gray-400 focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm"
placeholder="Passwort bestätigen"
/>
{errors.password_confirmation && <p className="text-sm text-red-600">{errors.password_confirmation}</p>}
</div>
<div className="flex items-start">
<input
id="privacy_consent"
name="privacy_consent"
type="checkbox"
required
checked={data.privacy_consent}
onChange={(e) => setData('privacy_consent', e.target.checked)}
className="h-4 w-4 text-blue-600 focus:ring-blue-500 border-gray-300 rounded"
/>
<label htmlFor="privacy_consent" className="ml-2 block text-sm text-gray-900">
Ich stimme der{' '}
<a href="/de/datenschutz" className="text-blue-600 hover:underline">
Datenschutzerklärung
</a>{' '}
zu.
</label>
{errors.privacy_consent && <p className="mt-2 text-sm text-red-600">{errors.privacy_consent}</p>}
</div>
</div>
<button
type="submit"
disabled={processing}
className="group relative w-full flex justify-center py-2 px-4 border border-transparent text-sm font-medium rounded-md text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 transition duration-300 disabled:opacity-50"
>
{processing && <LoaderCircle className="h-4 w-4 animate-spin mr-2" />}
Account erstellen
</button>
<div className="text-center">
<p className="text-sm text-gray-600">
Bereits registriert?{' '}
<a href="/login" className="font-medium text-blue-600 hover:text-blue-500">
Anmelden
</a>
</p>
</div>
</form>
</div>
</div>
);
}