Refonte front : flux inscription/connexion, saisie code et historique gains
- Redesign Connexion, Inscription avec modal succès et compte à rebours - Page SaisirCodeUnique connectée au backend avec overlay Félicitation - Page Perdu pour les codes invalides/déjà utilisés - MesGains redesigné en timeline avec appel API et bouton saisir nouveau code - Profile redesigné avec onglets et données depuis localStorage - Service game.js ajouté (participateApi, myGainsApi) - Ajout des designs de référence dans frontend/Design/ Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,18 +1,25 @@
|
||||
import { useState } from 'react'
|
||||
import { useState, useEffect } from 'react'
|
||||
import { Link, useNavigate } from 'react-router-dom'
|
||||
import { registerApi } from '../services/auth'
|
||||
|
||||
export default function Inscription() {
|
||||
const navigate = useNavigate()
|
||||
const [form, setForm] = useState({
|
||||
email: '',
|
||||
lastName: '',
|
||||
firstName: '',
|
||||
password: '',
|
||||
})
|
||||
const [form, setForm] = useState({ email: '', lastName: '', firstName: '', password: '' })
|
||||
const [showPassword, setShowPassword] = useState(false)
|
||||
const [error, setError] = useState('')
|
||||
const [loading, setLoading] = useState(false)
|
||||
const [successName, setSuccessName] = useState(null)
|
||||
const [countdown, setCountdown] = useState(5)
|
||||
|
||||
useEffect(() => {
|
||||
if (successName === null) return
|
||||
if (countdown === 0) {
|
||||
navigate('/saisir-code-unique')
|
||||
return
|
||||
}
|
||||
const t = setTimeout(() => setCountdown((c) => c - 1), 1000)
|
||||
return () => clearTimeout(t)
|
||||
}, [successName, countdown, navigate])
|
||||
|
||||
const handleChange = (e) => {
|
||||
const { name, value } = e.target
|
||||
@@ -30,7 +37,7 @@ export default function Inscription() {
|
||||
lastname: form.lastName,
|
||||
password: form.password,
|
||||
})
|
||||
navigate('/connexion', { state: { registered: true } })
|
||||
setSuccessName(form.firstName)
|
||||
} catch (err) {
|
||||
setError(err.message)
|
||||
} finally {
|
||||
@@ -53,7 +60,6 @@ export default function Inscription() {
|
||||
)}
|
||||
|
||||
<form onSubmit={handleSubmit} className="space-y-5">
|
||||
|
||||
<div>
|
||||
<label className="block text-sm font-medium text-gray-800 mb-1">
|
||||
Adresse email <span className="text-gray-800">*</span>
|
||||
@@ -120,9 +126,7 @@ export default function Inscription() {
|
||||
aria-label="Afficher/masquer le mot de passe"
|
||||
>
|
||||
<div className="w-6 h-6 rounded-full border-2 border-gray-400 flex items-center justify-center">
|
||||
{showPassword && (
|
||||
<div className="w-1.5 h-1.5 rounded-full bg-gray-400" />
|
||||
)}
|
||||
{showPassword && <div className="w-1.5 h-1.5 rounded-full bg-gray-400" />}
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
@@ -144,32 +148,42 @@ export default function Inscription() {
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-2 gap-3">
|
||||
<button
|
||||
type="button"
|
||||
className="flex items-center justify-center gap-2 border border-gray-200 rounded-lg py-3 text-sm text-gray-700 hover:bg-gray-50 transition-colors"
|
||||
>
|
||||
<div className="w-5 h-5 rounded-full border border-gray-400 flex items-center justify-center text-[10px] font-bold text-gray-500">
|
||||
G
|
||||
</div>
|
||||
<button type="button" className="flex items-center justify-center gap-2 border border-gray-200 rounded-lg py-3 text-sm text-gray-700 hover:bg-gray-50 transition-colors">
|
||||
<div className="w-5 h-5 rounded-full border border-gray-400 flex items-center justify-center text-[10px] font-bold text-gray-500">G</div>
|
||||
Google
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
className="flex items-center justify-center gap-2 border border-gray-200 rounded-lg py-3 text-sm text-gray-700 hover:bg-gray-50 transition-colors"
|
||||
>
|
||||
<div className="w-5 h-5 rounded-full border border-gray-400 flex items-center justify-center text-[10px] font-bold text-gray-500">
|
||||
f
|
||||
</div>
|
||||
<button type="button" className="flex items-center justify-center gap-2 border border-gray-200 rounded-lg py-3 text-sm text-gray-700 hover:bg-gray-50 transition-colors">
|
||||
<div className="w-5 h-5 rounded-full border border-gray-400 flex items-center justify-center text-[10px] font-bold text-gray-500">f</div>
|
||||
Facebook
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<p className="text-center text-sm text-gray-500 mt-8">
|
||||
Vous avez déjà un compte ?{' '}
|
||||
<Link to="/connexion" className="text-gray-700 font-medium hover:underline">
|
||||
Se connecter
|
||||
</Link>
|
||||
<Link to="/connexion" className="text-gray-700 font-medium hover:underline">Se connecter</Link>
|
||||
</p>
|
||||
|
||||
{/* Modal succès */}
|
||||
{successName !== null && (
|
||||
<div className="fixed inset-0 bg-black/40 flex items-center justify-center z-50 px-6">
|
||||
<div className="bg-white rounded-2xl p-8 w-full max-w-sm text-center shadow-xl">
|
||||
<div className="flex justify-center mb-5">
|
||||
<div className="w-16 h-16 bg-green-500 rounded-full flex items-center justify-center">
|
||||
<svg className="w-9 h-9 text-white" fill="none" stroke="currentColor" strokeWidth={3} viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" d="M5 13l4 4L19 7" />
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
<h2 className="text-2xl font-bold text-gray-900 mb-2">
|
||||
Bienvenue {successName} !!
|
||||
</h2>
|
||||
<p className="text-gray-500 text-sm leading-relaxed">
|
||||
Votre compte a été créé avec succès. Vous serez redirigé vers l'étape suivante dans{' '}
|
||||
<span className="font-semibold text-[#006B6B]">{countdown}</span> secondes.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user