import React, { useState, useEffect } from 'react'; import { createPortal } from 'react-dom'; import { IMaskInput } from 'react-imask'; import axios from 'axios'; export default function Registration(props) { const [formData, setFormData] = useState({ prenom: 'Malick', nom: 'Tounkara', telephone: '770000088', email: 'testregister@mail.com', password: 'password', confirmPassword: 'password', region: 'Dakar', ville: 'Dakar', adresse: 'Castor', agreeTerms: false }); const [errors, setErrors] = useState({}); const [isSubmitting, setIsSubmitting] = useState(false); const [serverError, setServerError] = useState(null); const [showPassword, setShowPassword] = useState(false); const [isSuccess, setIsSuccess] = useState(false); useEffect(() => { if (isSuccess) { window.scrollTo({ top: 0, behavior: 'smooth' }); const authHeader = document.querySelector('.auth-header'); if (authHeader) { authHeader.style.display = 'none'; } const wrapper = document.querySelector('.react-registration-wrapper'); if (wrapper) { let sibling = wrapper.nextElementSibling; while (sibling) { sibling.style.display = 'none'; sibling = sibling.nextElementSibling; } } } }, [isSuccess]); // Modals state const [showTermsModal, setShowTermsModal] = useState(false); const [showPrivacyModal, setShowPrivacyModal] = useState(false); const CITY_TO_REGION = { 'Dakar': 'Dakar', 'Guédiawaye': 'Dakar', 'Pikine': 'Dakar', 'Rufisque': 'Dakar', 'Bargny': 'Dakar', 'Keur Massar': 'Dakar', 'Sébikotane': 'Dakar', 'Diamniadio': 'Dakar', 'Thiès': 'Thiès', 'Tivaouane': 'Thiès', 'Mbour': 'Thiès', 'Joal-Fadiouth': 'Thiès', 'Ngaparou': 'Thiès', 'Saly': 'Thiès', 'Popenguine': 'Thiès', 'Pout': 'Thiès', 'Saint-Louis': 'Saint-Louis', 'Richard-Toll': 'Saint-Louis', 'Dagana': 'Saint-Louis', 'Podor': 'Saint-Louis', 'Louga': 'Louga', 'Kébémer': 'Louga', 'Linguère': 'Louga', 'Diourbel': 'Diourbel', 'Mbacké': 'Diourbel', 'Bambey': 'Diourbel', 'Kaolack': 'Kaolack', 'Nioro du Rip': 'Kaolack', 'Guinguinéo': 'Kaolack', 'Fatick': 'Fatick', 'Foundiougne': 'Fatick', 'Gossas': 'Fatick', 'Kaffrine': 'Kaffrine', 'Birkilane': 'Kaffrine', 'Koungheul': 'Kaffrine', 'Malem Hodar': 'Kaffrine', 'Kolda': 'Kolda', 'Velingara': 'Kolda', 'Medina Yoro Foulah': 'Kolda', 'Sédhiou': 'Sédhiou', 'Bounkiling': 'Sédhiou', 'Goudomp': 'Sédhiou', 'Ziguinchor': 'Ziguinchor', 'Bignona': 'Ziguinchor', 'Oussouye': 'Ziguinchor', 'Tambacounda': 'Tambacounda', 'Bakel': 'Tambacounda', 'Goudiry': 'Tambacounda', 'Koumpentoum': 'Tambacounda', 'Kédougou': 'Kédougou', 'Salémata': 'Kédougou', 'Saraya': 'Kédougou', 'Matam': 'Matam', 'Kanel': 'Matam', 'Ranérou': 'Matam' }; const validateField = (name, value, currentData) => { let error = ''; switch (name) { case 'prenom': if (!value) error = 'Le prénom est requis'; else if (value.length < 2) error = 'Le prénom doit contenir au moins 2 caractères'; break; case 'nom': if (!value) error = 'Le nom est requis'; else if (value.length < 2) error = 'Le nom doit contenir au moins 2 caractères'; break; case 'telephone': const phoneValue = value.replace(/[\s-]/g, ''); const phoneRegex = /^\+221(7[05678]|30|33)\d{7}$/; if (!value || phoneValue === '+2217') { error = 'Le téléphone est requis'; } else if (!phoneRegex.test(phoneValue)) { error = 'Format invalide (ex: +221 77 123 45 67)'; } break; case 'email': if (!value) error = "L'email est requis"; else if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value)) error = 'Email invalide'; break; case 'password': if (!value) error = 'Le mot de passe est requis'; else if (value.length < 4) error = 'Le mot de passe doit contenir au moins 4 caractères'; break; case 'confirmPassword': if (!value) error = 'Veuillez confirmer le mot de passe'; else if (value !== currentData.password) error = 'Les mots de passe ne correspondent pas'; break; case 'agreeTerms': if (!value) error = 'Vous devez accepter les conditions'; break; case 'ville': if (!value) error = 'La ville est requise'; break; case 'adresse': if (!value) error = "L'adresse est requise"; break; default: break; } return error; }; const handleChange = (e) => { const { name, value, type, checked } = e.target; const finalValue = type === 'checkbox' ? checked : value; let newFormData = { ...formData, [name]: finalValue }; // Auto-assign region based on city selection if (name === 'ville') { const correspondingRegion = CITY_TO_REGION[finalValue] || ''; newFormData = { ...newFormData, region: correspondingRegion }; } setFormData(newFormData); const error = validateField(name, finalValue, newFormData); setErrors(prev => ({ ...prev, [name]: error, ...(name === 'ville' ? { region: '' } : {}) // Clear region error when ville is selected })); }; const handleSubmit = async (e) => { e.preventDefault(); const newErrors = {}; Object.keys(formData).forEach(key => { if (key === 'region' && formData.ville) return; // Skip region validation if ville is present (auto-filled) const error = validateField(key, formData[key], formData); if (error) newErrors[key] = error; }); if (Object.keys(newErrors).length > 0) { setErrors(newErrors); setTimeout(() => { const firstError = document.querySelector('.is-invalid, .alert-danger'); if (firstError) { firstError.scrollIntoView({ behavior: 'smooth', block: 'center' }); } }, 100); return; } setIsSubmitting(true); setServerError(null); // Récupération du jeton reCAPTCHA let recaptchaToken = null; try { if (typeof window.grecaptcha !== 'undefined') { await new Promise(resolve => window.grecaptcha.ready(resolve)); recaptchaToken = await window.grecaptcha.execute(window.RECAPTCHA_SITE_KEY, { action: 'registration' }); } } catch (recapError) { console.error('reCAPTCHA Error:', recapError); } const payloadData = { ...formData, telephone: formData.telephone.replace(/[\s]/g, ''), recaptcha_token: recaptchaToken }; try { const response = await axios.post(props.submitUrl || '/api-register', payloadData, { headers: { 'Content-Type': 'application/json', } }); setIsSuccess(true); } catch (error) { if (error.response && error.response.data) { const data = error.response.data; if (data.errors) { setErrors(prev => ({ ...prev, ...data.errors })); } else { setServerError(data.error || 'Une erreur est survenue lors de l\'inscription.'); } } else { setServerError('Erreur de connexion au serveur.'); } setTimeout(() => { const firstError = document.querySelector('.is-invalid, .alert-danger'); if (firstError) { firstError.scrollIntoView({ behavior: 'smooth', block: 'center' }); } else { window.scrollTo({ top: 0, behavior: 'smooth' }); } }, 100); } finally { setIsSubmitting(false); } }; if (isSuccess) { return (

Vérifiez votre boîte mail !

Votre compte a été créé avec succès. Un lien de confirmation vous a été envoyé à l'adresse {formData.email}.
Veuillez cliquer sur ce lien pour activer votre compte.

Attention : Pensez à vérifier votre dossier Spams ou Courrier indésirable.
Aller à la page de connexion
); } return ( <>
{serverError && (
{serverError}
)}
Tous les champs ci-dessous sont obligatoires.
{errors.prenom &&
{errors.prenom}
}
{errors.nom &&
{errors.nom}
}
{ handleChange({ target: { name: 'telephone', value: value } }); }} placeholder="+221 7X XXX XX XX" className={`form-control form-control-custom ${errors.telephone ? 'is-invalid' : ''}`} /> {errors.telephone &&
{errors.telephone}
}
{errors.email &&
{errors.email}
}
{errors.ville &&
{errors.ville}
}
{errors.adresse &&
{errors.adresse}
}
setShowPassword(!showPassword)} >
{errors.password &&
{errors.password}
}
setShowPassword(!showPassword)} >
{errors.confirmPassword &&
{errors.confirmPassword}
}
{errors.agreeTerms &&
{errors.agreeTerms}
}
{serverError && (
{serverError}
)}

Ou continuez avec
Google Google
{/* Terms Modal */} {showTermsModal && createPortal( <>

Conditions d'Utilisation

1. Acceptation des conditions : L'accès et l'utilisation de la plateforme "Objets Trouvés Sénégal" impliquent votre pleine acceptation de ces Conditions d'Utilisation.

2. Objectif du service : Notre plateforme facilite la mise en relation entre les personnes ayant trouvé ou perdu des objets, ou documents d'identité sur le territoire national, en particulier au Sénégal.

3. Responsabilité de l'utilisateur : L'utilisateur s'engage à publier des annonces authentiques concernant les objets perdus ou trouvés. Sous aucun prétexte, cette plateforme ne doit être utilisée pour extorquer, tromper ou monnayer sa bonne foi.

4. Suspension du compte : Nous nous réservons le droit de suspendre ou supprimer tout compte en cas de comportement abusif, frauduleux ou en contradiction totale avec les valeurs du service et de la communauté.

, document.body )} {/* Privacy Policy Modal */} {showPrivacyModal && createPortal( <>

Politique de Confidentialité

1. Collecte des données : Nous récoltons uniquement les informations minimales utiles au fonctionnement de la plateforme (Nom, Prénom, Email, et Téléphone).

2. Utilisation et finalité : Votre numéro de téléphone et votre e-mail seront utilisés exclusivement pour assurer la mise en relation entre "trouveurs" et "perdants". Nous ne partagerons ni ne revendrons vos données personnelles pour des fins publicitaires illégitimes.

3. Protection des données : Les mots de passe sont hachés de manière sécurisée en base de données. L'hébergement de votre compte est sujet à des normes strictes de cybersécurité pour protéger toutes vos informations partagées avec la plateforme Objets Trouvés Sénégal.

4. Vos droits : Conformément à la réglementation sénégalaise relative à la protection des données (CDP), vous avez le plein droit d'accès, rectification et suppression de vos données de notre fichier à tout moment sur simple demande.

, document.body )} ); }