263 lines
8.4 KiB
TypeScript
263 lines
8.4 KiB
TypeScript
'use client';
|
|
|
|
import { useState, useEffect } from 'react';
|
|
import { useRouter } from 'next/navigation';
|
|
import { useSession } from 'next-auth/react';
|
|
import { Button } from '@/components/ui/Button';
|
|
import { Input } from '@/components/ui/Input';
|
|
import Link from 'next/link';
|
|
import { TowerLogo } from '@/components/TowerLogo';
|
|
import { TowerBackground } from '@/components/TowerBackground';
|
|
|
|
export default function RegisterPage() {
|
|
const [email, setEmail] = useState('');
|
|
const [name, setName] = useState('');
|
|
const [firstName, setFirstName] = useState('');
|
|
const [lastName, setLastName] = useState('');
|
|
const [password, setPassword] = useState('');
|
|
const [confirmPassword, setConfirmPassword] = useState('');
|
|
const [error, setError] = useState('');
|
|
const [isLoading, setIsLoading] = useState(false);
|
|
const router = useRouter();
|
|
const { data: session, status } = useSession();
|
|
|
|
// Redirection si l'utilisateur est déjà connecté
|
|
useEffect(() => {
|
|
if (status === 'authenticated' && session) {
|
|
router.push('/');
|
|
}
|
|
}, [status, session, router]);
|
|
|
|
const handleSubmit = async (e: React.FormEvent) => {
|
|
e.preventDefault();
|
|
setIsLoading(true);
|
|
setError('');
|
|
|
|
// Validation côté client
|
|
if (password !== confirmPassword) {
|
|
setError('Les mots de passe ne correspondent pas');
|
|
setIsLoading(false);
|
|
return;
|
|
}
|
|
|
|
if (password.length < 6) {
|
|
setError('Le mot de passe doit contenir au moins 6 caractères');
|
|
setIsLoading(false);
|
|
return;
|
|
}
|
|
|
|
try {
|
|
const response = await fetch('/api/auth/register', {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
},
|
|
body: JSON.stringify({
|
|
email,
|
|
name,
|
|
firstName,
|
|
lastName,
|
|
password,
|
|
}),
|
|
});
|
|
|
|
const data = await response.json();
|
|
|
|
if (!response.ok) {
|
|
throw new Error(data.error || 'Une erreur est survenue');
|
|
}
|
|
|
|
// Rediriger vers la page de login avec un message de succès
|
|
router.push('/login?message=Compte créé avec succès');
|
|
} catch (error) {
|
|
setError(
|
|
error instanceof Error ? error.message : 'Une erreur est survenue'
|
|
);
|
|
} finally {
|
|
setIsLoading(false);
|
|
}
|
|
};
|
|
|
|
// Afficher un loader pendant la vérification de session
|
|
if (status === 'loading') {
|
|
return (
|
|
<div className="min-h-screen relative overflow-hidden">
|
|
<TowerBackground />
|
|
<div className="relative z-10 min-h-screen flex items-center justify-center">
|
|
<div className="text-[var(--foreground)]">Chargement...</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
// Ne pas afficher le formulaire si l'utilisateur est connecté
|
|
if (status === 'authenticated') {
|
|
return null;
|
|
}
|
|
|
|
return (
|
|
<div className="min-h-screen relative overflow-hidden">
|
|
<TowerBackground />
|
|
|
|
{/* Contenu principal */}
|
|
<div className="relative z-10 min-h-screen flex items-center justify-center p-4">
|
|
<div className="w-full max-w-md">
|
|
{/* Logo et titre */}
|
|
<TowerLogo size="md" className="mb-8" />
|
|
|
|
{/* Formulaire */}
|
|
<div className="bg-[var(--card)]/80 backdrop-blur-sm rounded-2xl shadow-xl border border-[var(--border)] p-8">
|
|
<h2 className="text-2xl font-mono font-bold text-[var(--foreground)] text-center mb-6">
|
|
Créer un compte
|
|
</h2>
|
|
<form className="space-y-6" onSubmit={handleSubmit}>
|
|
<div className="space-y-4">
|
|
<div>
|
|
<label
|
|
htmlFor="email"
|
|
className="block text-sm font-medium text-[var(--foreground)] mb-2"
|
|
>
|
|
Email
|
|
</label>
|
|
<Input
|
|
id="email"
|
|
name="email"
|
|
type="email"
|
|
required
|
|
value={email}
|
|
onChange={(e) => setEmail(e.target.value)}
|
|
placeholder="votre@email.com"
|
|
className="w-full"
|
|
/>
|
|
</div>
|
|
|
|
<div className="grid grid-cols-2 gap-4">
|
|
<div>
|
|
<label
|
|
htmlFor="firstName"
|
|
className="block text-sm font-medium text-[var(--foreground)] mb-2"
|
|
>
|
|
Prénom
|
|
</label>
|
|
<Input
|
|
id="firstName"
|
|
name="firstName"
|
|
type="text"
|
|
value={firstName}
|
|
onChange={(e) => setFirstName(e.target.value)}
|
|
placeholder="Prénom"
|
|
className="w-full"
|
|
/>
|
|
</div>
|
|
|
|
<div>
|
|
<label
|
|
htmlFor="lastName"
|
|
className="block text-sm font-medium text-[var(--foreground)] mb-2"
|
|
>
|
|
Nom
|
|
</label>
|
|
<Input
|
|
id="lastName"
|
|
name="lastName"
|
|
type="text"
|
|
value={lastName}
|
|
onChange={(e) => setLastName(e.target.value)}
|
|
placeholder="Nom"
|
|
className="w-full"
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
<div>
|
|
<label
|
|
htmlFor="name"
|
|
className="block text-sm font-medium text-[var(--foreground)] mb-2"
|
|
>
|
|
Nom d'affichage (optionnel)
|
|
</label>
|
|
<Input
|
|
id="name"
|
|
name="name"
|
|
type="text"
|
|
value={name}
|
|
onChange={(e) => setName(e.target.value)}
|
|
placeholder="Nom d'affichage personnalisé"
|
|
className="w-full"
|
|
/>
|
|
</div>
|
|
|
|
<div>
|
|
<label
|
|
htmlFor="password"
|
|
className="block text-sm font-medium text-[var(--foreground)] mb-2"
|
|
>
|
|
Mot de passe
|
|
</label>
|
|
<Input
|
|
id="password"
|
|
name="password"
|
|
type="password"
|
|
required
|
|
value={password}
|
|
onChange={(e) => setPassword(e.target.value)}
|
|
placeholder="Minimum 6 caractères"
|
|
className="w-full"
|
|
/>
|
|
</div>
|
|
|
|
<div>
|
|
<label
|
|
htmlFor="confirmPassword"
|
|
className="block text-sm font-medium text-[var(--foreground)] mb-2"
|
|
>
|
|
Confirmer le mot de passe
|
|
</label>
|
|
<Input
|
|
id="confirmPassword"
|
|
name="confirmPassword"
|
|
type="password"
|
|
required
|
|
value={confirmPassword}
|
|
onChange={(e) => setConfirmPassword(e.target.value)}
|
|
placeholder="Répétez le mot de passe"
|
|
className="w-full"
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
{error && (
|
|
<div className="text-[var(--destructive)] text-sm text-center bg-[var(--destructive)]/10 p-3 rounded-lg border border-[var(--destructive)]/20">
|
|
{error}
|
|
</div>
|
|
)}
|
|
|
|
<div>
|
|
<Button
|
|
type="submit"
|
|
disabled={isLoading}
|
|
className="w-full py-3 text-lg font-mono"
|
|
>
|
|
{isLoading ? 'Création du compte...' : 'Créer le compte'}
|
|
</Button>
|
|
</div>
|
|
|
|
<div className="text-center text-sm text-[var(--muted-foreground)]">
|
|
<p>
|
|
Déjà un compte ?{' '}
|
|
<Link
|
|
href="/login"
|
|
className="text-[var(--primary)] hover:underline font-medium"
|
|
>
|
|
Se connecter
|
|
</Link>
|
|
</p>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|