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:
Emma781227
2026-06-24 10:04:18 +02:00
parent 25be38027d
commit 428bf2597a
13 changed files with 366 additions and 197 deletions

View File

@@ -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}&nbsp;!!
</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>
)
}