{% extends 'base.html.twig' %}
{% block title %}IMMY BEAUTY - Inscription{% endblock %}
{% block stylesheets %}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/intl-tel-input/17.0.8/css/intlTelInput.css"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/intl-tel-input/17.0.8/js/intlTelInput.min.js"></script>
<style>
.form-group { margin-bottom: 0.8rem !important; }
.form-label { margin-bottom: 0.2rem; color: #555; font-size: 0.9rem; }
.form-control { padding: 0.5rem 0.75rem; }
.registration-form {
background: white;
padding: 2rem;
border-radius: 10px;
box-shadow: 0 0 20px rgba(0,0,0,0.05);
}
.promo-code-section {
margin: 1.5rem 0;
padding: 1rem;
background: #f8f9fa;
border-radius: 8px;
border: 1px dashed #dee2e6;
}
.promo-code-toggle {
color: #FF6B6B;
text-decoration: none;
cursor: pointer;
display: inline-flex;
align-items: center;
font-size: 0.9rem;
}
.promo-code-input {
background: white;
border: 2px solid #FF6B6B;
border-radius: 4px;
padding: 0.5rem;
font-size: 1rem;
text-transform: uppercase;
letter-spacing: 1px;
text-align: center;
}
.promo-code-info {
font-size: 0.8rem;
color: #666;
margin-top: 0.5rem;
}
</style>
{% endblock %}
{% block body %}
<div class="container mt-4">
<div class="row justify-content-center">
<div class="col-md-6">
<form method="post" action="{{ path('api_register') }}" class="registration-form">
<input type="hidden" name="_csrf_token" value="{{ csrf_token('register') }}">
<h2 class="text-center mb-2">Rejoignez IMMY BEAUTY</h2>
<p class="text-center text-muted mb-4 small">Créez votre compte et commencez à cumuler des avantages exclusifs</p>
<div class="row">
<div class="col-md-6">
<div class="form-group">
<label class="form-label">Prénom</label>
<input type="text" id="prenom" name="prenom" class="form-control" required autofocus>
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label class="form-label">Nom</label>
<input type="text" id="nom" name="nom" class="form-control" required>
</div>
</div>
</div>
<div class="form-group">
<label class="form-label">Date de naissance</label>
<input type="date" id="birthdate" name="birthdate" class="form-control" required>
</div>
<div class="row">
<div class="col-md-6">
<div class="form-group">
<label class="form-label">Email</label>
<input type="email" id="email" name="email" class="form-control" required>
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label class="form-label">Téléphone</label>
<input type="tel" id="telephone" name="telephone" class="form-control" required maxlength="10">
</div>
</div>
</div>
<div class="form-group mb-3">
<label class="form-label d-flex align-items-center">
<span>Code cadeau</span>
<span class="ms-2 badge bg-secondary" style="font-size: 0.7em;">Facultatif</span>
</label>
<div class="input-group">
<input type="text"
id="promo_code"
name="promo_code"
class="form-control"
placeholder="Uniquement si vous avez reçu un code par email"
autocomplete="off">
<button class="btn btn-outline-secondary verify-code"
type="button"
id="verify-code">
<i class="fas fa-check"></i>
</button>
</div>
<small class="text-muted">Laissez vide si vous n'avez pas de code</small>
<div id="promo-status" class="form-text mt-1"></div>
</div>
<div class="row">
<div class="col-md-6">
<div class="form-group">
<label class="form-label">Mot de passe</label>
<input type="password" id="password" name="password" class="form-control" required>
<small class="form-text text-muted">8 caractères minimum</small>
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label class="form-label">Confirmer</label>
<input type="password" id="confirm_password" name="confirm_password" class="form-control" required>
</div>
</div>
</div>
<div class="form-group mt-4">
<button type="submit" class="btn btn-primary w-100">Créer mon compte</button>
</div>
<div class="text-center mt-3">
<span class="small">Déjà membre ? <a href="{{ path('connexion') }}" class="text-decoration-none">Connectez-vous</a></span>
</div>
</form>
</div>
</div>
</div>
<section class="ftco-section">
<div class="container">
<div class="row">
<div class="col-md-4 ftco-animate">
<div class="media d-block text-center block-6 services">
<div class="icon d-flex mb-3"><span class="fas fa-user-plus"></span></div>
<div class="media-body">
<h3 class="heading">INSCRIVEZ VOUS</h3>
<p>Commencez votre voyage pour gagner des points et profiter d'avantages exclusifs.</p>
</div>
</div>
</div>
<div class="col-md-4 ftco-animate">
<div class="media d-block text-center block-6 services">
<div class="icon d-flex mb-3"><span class="fas fa-trophy"></span></div>
<div class="media-body">
<h3 class="heading">CUMULEZ DES POINTS</h3>
<p>Plus vous collectez de points, plus vous débloquez de récompenses et de privilèges spéciaux.</p>
</div>
</div>
</div>
<div class="col-md-4 ftco-animate">
<div class="media d-block text-center block-6 services">
<div class="icon d-flex mb-3"><span class="fas fa-gift"></span></div>
<div class="media-body">
<h3 class="heading">PROFITEZ DES AVANTAGES</h3>
<p>Échangez vos points contre des réductions, des produits gratuits ou des services spéciaux.</p>
</div>
</div>
</div>
</div>
</div>
</section>
{% endblock %}
{% block btn_reserver %}
{% endblock %}
{% block javascripts %}
{{ parent() }}
<script>
$(document).ready(function() {
const urlParams = new URLSearchParams(window.location.search);
const codeFromUrl = urlParams.get('code');
if (codeFromUrl) {
// Pré-rempli le champ
$('#promo_code').val(codeFromUrl);
// Attendre que l'email soit rempli pour vérifier automatiquement
$('#email').on('change', function() {
const email = $(this).val().trim();
if (email) {
$('#verify-code').click(); // Déclenche la vérification
}
});
}
$('form').submit(function(e) {
e.preventDefault();
// Récupération et nettoyage des données
const formData = {
prenom: $('#prenom').val().trim(),
nom: $('#nom').val().trim(),
email: $('#email').val().trim().toLowerCase(),
telephone: $('#telephone').val().trim().replace(/\D/g, ''),
password: $('#password').val(),
confirm_password: $('#confirm_password').val(),
birthdate: $('#birthdate').val(),
promo_code: $('#promo_code').val().trim(),
_csrf_token: $('[name="_csrf_token"]').val()
};
if (formData.promo_code) {
formData.promo_verified = Boolean($('#promo_code').prop('readonly'));
}
// Validation complète
const errors = [];
// Validation nom/prénom
if (!formData.prenom || formData.prenom.length < 2) {
errors.push('Le prénom doit contenir au moins 2 caractères');
}
if (!formData.nom || formData.nom.length < 2) {
errors.push('Le nom doit contenir au moins 2 caractères');
}
// Validation email
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
if (!emailRegex.test(formData.email)) {
errors.push('Adresse email invalide');
}
// Validation téléphone
if (!/^0[1-9][0-9]{8}$/.test(formData.telephone)) {
errors.push('Le numéro de téléphone doit commencer par 0 et contenir 10 chiffres');
}
// Validation date de naissance
const birthDate = new Date(formData.birthdate);
const today = new Date();
let age = today.getFullYear() - birthDate.getFullYear();
const m = today.getMonth() - birthDate.getMonth();
if (m < 0 || (m === 0 && today.getDate() < birthDate.getDate())) {
age--;
}
if (!formData.birthdate) {
errors.push('La date de naissance est obligatoire');
} else if (age < 16) {
errors.push('Vous devez avoir au moins 16 ans pour vous inscrire');
}
// Validation mot de passe
const passwordRegex = /^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d@$!%*#?&]{8,}$/;
if (!passwordRegex.test(formData.password)) {
errors.push('Le mot de passe doit contenir au moins 8 caractères, une lettre et un chiffre');
}
if (formData.password !== formData.confirm_password) {
errors.push('Les mots de passe ne correspondent pas');
}
// Affichage des erreurs
if (errors.length > 0) {
errors.forEach(error => toastr.error(error));
return;
}
// Envoi sécurisé
$.ajax({
type: 'POST',
url: '{{ path('api_register') }}',
data: formData,
dataType: 'json',
headers: {
'X-CSRF-Token': formData._csrf_token
},
success: function(response) {
if (response.success) {
localStorage.setItem('registerSuccess', 'Inscription réussie ! Vous êtes désormais connecté.');
window.location.href = '{{ path('app_fidelite') }}';
} else {
toastr.error(response.message || 'Une erreur est survenue');
}
},
error: function(xhr) {
const errorMsg = xhr.responseJSON?.message || "Une erreur est survenue lors de l'inscription.";
toastr.error(errorMsg);
}
});
});
// Masquer les caractères spéciaux dans les champs texte
$('input[type="text"]').on('input', function() {
this.value = this.value.replace(/[<>]/g, '');
});
// Formatter le téléphone en temps réel
$('#telephone').on('input', function() {
this.value = this.value.replace(/\D/g, '').substring(0, 10);
});
});
$('#verify-code').click(function() {
const code = $('#promo_code').val().trim();
const email = $('#email').val().trim();
if (!code) {
toastr.error('Veuillez entrer un code');
return;
}
if (!email) {
toastr.error('Veuillez d\'abord remplir votre email');
return;
}
const $button = $(this);
const $status = $('#promo-status');
$button.prop('disabled', true).html('<i class="fas fa-spinner fa-spin"></i>');
$.ajax({
url: '{{ path('verify_promo_code') }}',
method: 'POST',
data: {
code: code,
email: email,
_token: '{{ csrf_token('promo_verify') }}'
},
success: function(response) {
if (response.valid) {
$status.html(`<small class="text-success">
<i class="fas fa-check-circle"></i> ${response.message}
</small>`);
$('#promo_code').prop('readonly', true);
$button.html('<i class="fas fa-check"></i>').addClass('btn-success');
} else {
$status.html(`<small class="text-danger">
<i class="fas fa-times-circle"></i> ${response.message}
</small>`);
$button.prop('disabled', false).html('<i class="fas fa-check"></i>');
}
},
error: function(xhr) {
let message = xhr.responseJSON?.message || 'Une erreur est survenue';
$status.html(`<small class="text-danger">
<i class="fas fa-times-circle"></i> ${message}
</small>`);
$button.prop('disabled', false).html('<i class="fas fa-check"></i>');
}
});
});
</script>
{% endblock %}