Files
THE-TIP-TOP/frontend/src/pages/AuthCallback.jsx

77 lines
2.2 KiB
JavaScript

import { useEffect, useRef, useState } from 'react'
import { useNavigate, useSearchParams, Link } from 'react-router-dom'
import { useAuth } from '../context/AuthContext'
// Point d'arrivée après un aller-retour OAuth : le backend nous renvoie ici
// avec le JWT et le profil encodés dans l'URL.
export default function AuthCallback() {
const navigate = useNavigate()
const [searchParams] = useSearchParams()
const { login } = useAuth()
const errorParam = searchParams.get('error')
const [error, setError] = useState(errorParam || '')
// StrictMode monte deux fois en dev : on ne traite le token qu'une seule fois.
const handled = useRef(false)
useEffect(() => {
if (handled.current) return
handled.current = true
if (errorParam) return
const token = searchParams.get('token')
const encodedUser = searchParams.get('user')
if (!token || !encodedUser) {
setTimeout(() => {
setError('Réponse de connexion incomplète.')
}, 0)
return
}
try {
const user = JSON.parse(atob(encodedUser))
login(user, token)
if (user.role === 'ADMIN') {
navigate('/admin', { replace: true })
} else if (user.role === 'EMPLOYEE') {
navigate('/employe', { replace: true })
} else {
navigate('/mes-gains', { replace: true })
}
} catch {
setTimeout(() => {
setError('Réponse de connexion illisible.')
}, 0)
}
}, [searchParams, errorParam, login, navigate])
if (error) {
return (
<div className="min-h-screen bg-white flex flex-col justify-center items-center px-8 max-w-sm mx-auto text-center">
<div className="mb-4 px-4 py-3 rounded-lg bg-red-50 border border-red-200 text-red-600 text-sm">
{error}
</div>
<Link
to="/connexion"
className="text-sm text-[#006B6B] font-medium hover:underline"
>
Retour à la connexion
</Link>
</div>
)
}
return (
<div className="min-h-screen bg-white flex flex-col justify-center items-center px-8 max-w-sm mx-auto text-center">
<p className="text-gray-500 text-sm">
Connexion en cours…
</p>
</div>
)
}