<!DOCTYPE html>
<!--
Template name: Nova
Template author: FreeBootstrap.net
Author website: https://freebootstrap.net/
License: https://freebootstrap.net/license
-->
<html lang="fr">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>5sur5Séjour — Créer un séjour scolaire en ligne (données hébergées en France)</title>
<meta name="description" content="Partagez photos, vidéos et messages vocaux avec les familles. Gratuit pour les écoles publiques (hors option voix). Démo 15–30 min pour partenaires.">
<!-- Open Graph / Twitter -->
<meta property="og:title" content="Créer un séjour scolaire en ligne — 5sur5Séjour">
<meta property="og:description" content="Plateforme familles & écoles. Données en France. Démo 15–30 min.">
<meta property="og:type" content="website">
<meta property="og:url" content="https://5sur5sejour.fr/">
<meta property="og:image" content="https://5sur5sejour.fr/static/og/landing.jpg">
<meta name="twitter:card" content="summary_large_image">
<!-- Robots -->
<meta name="robots" content="index,follow,max-image-preview:large">
<!-- Preload police/logo (si utilisés) -->
<link rel="preload" href="/assets/fonts/inter-var.woff2" as="font" type="font/woff2" crossorigin>
<link rel="preload" href="/static/og/creer-sejour.jpg" as="image"> <title>5sur5séjour - Plateforme de partage de photos, vidéos et messages vocaux</title>
<!-- ======= Google Font =======-->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@100..900&display=swap" rel="stylesheet">
<!-- End Google Font-->
<!-- ======= Styles =======-->
<link href="{{ asset('Accueil/vendors/bootstrap/bootstrap.min.css') }}" rel="stylesheet">
<link href="{{ asset('Accueil/vendors/bootstrap-icons/font/bootstrap-icons.min.css') }}" rel="stylesheet">
<link href="{{ asset('Accueil/vendors/glightbox/glightbox.min.css') }}" rel="stylesheet">
<link href="{{ asset('Accueil/vendors/swiper/swiper-bundle.min.css') }}" rel="stylesheet">
<link href="{{ asset('Accueil/vendors/aos/aos.css') }}" rel="stylesheet">
<!-- End Styles-->
<!-- ======= Theme Style =======-->
<link href="{{ asset('Accueil/css/style_nova.css') }}?v={{ "now"|date("Y-m-d-H-i-s") }}" rel="stylesheet">
<!-- End Theme Style-->
<!-- ======= Apply theme =======-->
<script>
// Apply the theme as early as possible to avoid flicker
(function() {
const storedTheme = localStorage.getItem('theme') || 'light';
document.documentElement.setAttribute('data-bs-theme', storedTheme);
})();
</script>
</head>
<body>
<!-- MODALE -->
<div class="modal fade" id="demoModal" tabindex="-1" aria-hidden="true">
<div class="modal-dialog modal-lg modal-dialog-centered">
<div class="modal-content">
<div class="modal-header">
<h5 id="demoTitle" class="modal-title">Demander une démo guidée</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Fermer"></button>
</div>
<div class="modal-body">
<ul class="nav nav-tabs" id="demoTabs" role="tablist">
<li class="nav-item" role="presentation">
<button class="nav-link active" id="tab-calendar" data-bs-toggle="tab" data-bs-target="#pane-calendar" type="button" role="tab">
Réserver un créneau
</button>
</li>
<li class="nav-item" role="presentation">
<button class="nav-link" id="tab-callback" data-bs-toggle="tab" data-bs-target="#pane-callback" type="button" role="tab">
Être rappelé
</button>
</li>
</ul>
<div class="tab-content pt-3">
<!-- Calendrier -->
<div class="tab-pane fade show active" id="pane-calendar" role="tabpanel">
<div class="text-center mb-3">
<h6 class="mb-2">Réservez votre créneau de démonstration</h6>
<p class="text-muted small">Choisissez un créneau qui vous convient pour une démo personnalisée</p>
</div>
<div class="ratio ratio-16x9 border rounded">
<iframe src="https://calendly.com/5sur5sejour/demo" title="Calendrier de réservation" loading="lazy" frameborder="0"></iframe>
</div>
<p class="small text-muted mt-2 mb-0">
<i class="bi bi-clock me-1"></i> Créneau visio 15–30 min ·
<i class="bi bi-check-circle me-1"></i> Confirmation instantanée ·
<i class="bi bi-shield-check me-1"></i> 100% gratuit
</p>
</div>
<!-- Formulaire callback -->
<div class="tab-pane fade" id="pane-callback" role="tabpanel">
<div class="text-center mb-3">
<h6 class="mb-2">Être rappelé par un expert</h6>
<p class="text-muted small">Laissez-nous vos coordonnées et nous vous rappelons sous 24h</p>
</div>
<form id="contactForm" class="needs-validation" method="post" action="{{ path('app_contact') }}" novalidate>
<input type="hidden" name="topic" id="topic" value="demo">
<input type="hidden" name="pack" id="pack" value="">
<input type="hidden" name="objet" id="objet" value="demo">
<input type="text" name="website" class="visually-hidden" tabindex="-1" autocomplete="off">
<div class="row g-3">
<div class="col-md-6">
<label class="form-label">Nom & prénom</label>
<input type="text" class="form-control" name="name" required
placeholder="Votre nom complet">
<div class="invalid-feedback">Veuillez saisir votre nom et prénom.</div>
</div>
<div class="col-md-6">
<label class="form-label">Établissement</label>
<input type="text" class="form-control" name="organization" required
placeholder="Nom de votre établissement">
<div class="invalid-feedback">Veuillez saisir le nom de votre établissement.</div>
</div>
<div class="col-md-6">
<label class="form-label">Email pro</label>
<input type="email" class="form-control" name="email" required
placeholder="votre.email@etablissement.fr">
<div class="invalid-feedback">Veuillez saisir une adresse email valide.</div>
</div>
<div class="col-md-6">
<label class="form-label">Téléphone</label>
<input type="tel" class="form-control" name="telephone" required
placeholder="06 12 34 56 78" pattern="[0-9\s\+\-\(\)]{10,}">
<div class="invalid-feedback">Veuillez saisir un numéro de téléphone valide.</div>
</div>
<div class="col-md-6">
<label class="form-label">Nb. de séjours / an</label>
<select class="form-select" name="sejours_count" required>
<option value="" selected>Choisir…</option>
<option value="1-3">1–3</option>
<option value="4-10">4–10</option>
<option value="11-30">11–30</option>
<option value="30+">30+</option>
</select>
<div class="invalid-feedback">Veuillez sélectionner le nombre de séjours.</div>
</div>
<div class="col-12">
<label class="form-label">Message (optionnel)</label>
<textarea class="form-control" name="message" rows="3"
placeholder="Décrivez brièvement vos besoins : type de séjours, nombre d'enfants, questions spécifiques..."></textarea>
</div>
<div class="col-12">
<div class="form-check">
<input class="form-check-input" type="checkbox" value="1" id="consent" name="consent" required>
<label class="form-check-label" for="consent">J'accepte d'être contacté (RGPD).</label>
<div class="invalid-feedback">Vous devez accepter d'être contacté pour continuer.</div>
</div>
</div>
<div class="col-12 d-grid d-sm-flex gap-2">
<button id="submitBtn" class="btn btn-primary px-4" type="submit">
<i class="bi bi-telephone me-2"></i>Être rappelé sous 24h
</button>
<a class="btn btn-outline-secondary px-4" href="mailto:contact@5sur5sejour.fr">
<i class="bi bi-envelope me-2"></i>Nous écrire
</a>
</div>
</div>
<p class="small text-muted mt-2 mb-0">
Si la structure ne prend pas en charge <strong>Parent Premium</strong>, les familles peuvent l'activer (2,90 € / parent / séjour) pour l'accès complet, boîte vocale illimitée incluse. <span class="text-primary-emphasis">Recommandé : prise en charge par la structure.</span>
</p>
</form>
</div>
</div>
</div>
<div class="modal-footer">
<p class="small text-muted mb-0">Sans engagement · Données hébergées en France</p>
</div>
</div>
</div>
</div>
<!-- MODALE CRÉER MON SÉJOUR -->
<div class="modal fade" id="createSejourModal" tabindex="-1" aria-labelledby="createSejourTitle" aria-hidden="true">
<div class="modal-dialog modal-xl modal-dialog-centered modal-dialog-scrollable">
<div class="modal-content">
<div class="modal-header border-bottom-0">
<div class="w-100">
<h5 id="createSejourTitle" class="modal-title mb-2">Créer mon espace séjour</h5>
<div class="d-flex align-items-center gap-2">
<span id="stepLabel" class="badge bg-primary">Étape 1/2</span>
<small class="text-muted" id="stepDescription">Choisissez votre profil</small>
</div>
</div>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Fermer"></button>
</div>
<div class="modal-body px-4">
<!-- ÉTAPE 1 : Choix du profil -->
<div id="step1" class="step-content">
<p class="lead text-center mb-4">Sélectionnez le type d'espace séjour que vous souhaitez créer :</p>
<div class="row g-3">
<!-- École publique -->
<div class="col-md-4">
<a class="card h-100 border-2 hover-shadow text-decoration-none" href="{{ path('app_ecoles_publiques_creer') }}">
<div class="card-body text-center p-4">
<div class="fs-1 mb-3">🏫</div>
<h6 class="card-title fw-bold mb-2">École publique</h6>
<p class="card-text small text-muted mb-3">
Accès gratuit (hors option boîte vocale).
</p>
<span class="badge bg-success">✅ Gratuit</span>
</div>
</a>
</div>
<!-- Partenaire -->
<div class="col-md-4 d-none">
<div class="card h-100 select-role border-2 hover-shadow" role="button" tabindex="0">
<div class="card-body text-center p-4">
<div class="fs-1 mb-3">🤝</div>
<h6 class="card-title fw-bold mb-2">Partenaire / Organisme</h6>
<p class="card-text small text-muted mb-3">
Association, centre, école privée… Démo + contrat.
</p>
<span class="badge bg-purple">🚀 Partenariat</span>
</div>
</div>
</div>
<div class="col-md-4">
<a class="card h-100 border-2 hover-shadow text-decoration-none" href="{{ path('pack_annuel_partenaires') }}">
<div class="card-body text-center p-4">
<div class="fs-1 mb-3">🤝</div>
<h6 class="card-title fw-bold mb-2">Partenaire</h6>
<p class="card-text small text-muted mb-3">
Association, centre, école privée… Démo + contrat.
</p>
<span class="badge bg-purple">🚀 Partenariat</span>
</div>
</a>
</div>
<!-- Création simple -->
<div class="col-md-4">
<a class="card h-100 border-2 hover-shadow text-decoration-none" href="{{ path('app_creation_simple_creer') }}">
<div class="card-body text-center p-4">
<div class="fs-1 mb-3">✨</div>
<h6 class="card-title fw-bold mb-2">Création simple</h6>
<p class="card-text small text-muted mb-3">
Créer un espace séjour. Paiement par les parents ou par la structure.
</p>
<span class="badge bg-primary">🎯 Flexible</span>
</div>
</a>
</div>
</div>
</div>
<!-- ÉTAPE 2 : Formulaires selon le profil -->
<div id="step2" class="step-content d-none">
<!-- Panneau Partenaire -->
<div id="pane-partenaire" class="role-pane d-none">
<div class="alert alert-info mb-4">
<strong>🤝 Partenaire / Organisme</strong><br>
<small>Démo 15–30 min · Accompagnement contrat & onboarding.</small>
</div>
<ul class="nav nav-tabs mb-3" id="partenaireTabsNav" role="tablist">
<li class="nav-item" role="presentation">
<button class="nav-link active" id="tab-partenaire-demo" data-bs-toggle="tab" data-bs-target="#pane-partenaire-demo" type="button" role="tab">
Réserver une démo
</button>
</li>
<li class="nav-item" role="presentation">
<button class="nav-link" id="tab-partenaire-callback" data-bs-toggle="tab" data-bs-target="#pane-partenaire-callback" type="button" role="tab">
Être rappelé
</button>
</li>
</ul>
<div class="tab-content">
<!-- Calendly pour démo partenaire -->
<div class="tab-pane fade show active" id="pane-partenaire-demo" role="tabpanel">
<div class="text-center mb-3">
<p class="text-muted small mb-2">Choisissez un créneau pour une démo personnalisée</p>
</div>
<div class="ratio ratio-16x9 border rounded">
<iframe data-src="https://calendly.com/5sur5sejour/demo" title="Calendrier de réservation partenaire" loading="lazy" frameborder="0"></iframe>
</div>
<p class="small text-muted mt-2 mb-0">
<i class="bi bi-clock me-1"></i> Créneau visio 15–30 min ·
<i class="bi bi-check-circle me-1"></i> Accompagnement contrat ·
<i class="bi bi-shield-check me-1"></i> 100% gratuit
</p>
</div>
<!-- Formulaire rappel partenaire -->
<div class="tab-pane fade" id="pane-partenaire-callback" role="tabpanel">
<form id="formPartenaire" method="post" action="/contact/partenaire" class="needs-validation" novalidate>
<input type="text" name="website" class="visually-hidden" tabindex="-1" autocomplete="off">
<div class="row g-3">
<div class="col-md-6">
<label class="form-label">Nom & prénom <span class="text-danger">*</span></label>
<input type="text" class="form-control" name="name" required
placeholder="Votre nom complet">
<div class="invalid-feedback">Veuillez saisir votre nom et prénom.</div>
</div>
<div class="col-md-6">
<label class="form-label">Structure <span class="text-danger">*</span></label>
<input type="text" class="form-control" name="organization" required
placeholder="Nom de votre structure">
<div class="invalid-feedback">Veuillez saisir le nom de votre structure.</div>
</div>
<div class="col-md-6">
<label class="form-label">Email pro <span class="text-danger">*</span></label>
<input type="email" class="form-control" name="email" required
placeholder="votre.email@structure.fr">
<div class="invalid-feedback">Veuillez saisir une adresse email valide.</div>
</div>
<div class="col-md-6">
<label class="form-label">Téléphone (optionnel)</label>
<input type="tel" class="form-control" name="telephone"
placeholder="06 12 34 56 78">
</div>
<div class="col-12">
<label class="form-label">Message (optionnel)</label>
<textarea class="form-control" name="message" rows="3"
placeholder="Décrivez brièvement vos besoins..."></textarea>
</div>
<div class="col-12">
<div class="form-check">
<input class="form-check-input" type="checkbox" value="1" id="consent_partenaire" name="consent" required>
<label class="form-check-label" for="consent_partenaire">
J'accepte d'être contacté (RGPD) <span class="text-danger">*</span>
</label>
<div class="invalid-feedback">Vous devez accepter d'être contacté.</div>
</div>
</div>
<div class="col-12 d-flex gap-2">
<button type="submit" class="btn btn-primary px-4">
<i class="bi bi-telephone me-2"></i>Être rappelé sous 24 h
</button>
<a class="btn btn-outline-secondary px-4" href="mailto:contact@5sur5sejour.fr">
Nous écrire
</a>
</div>
</div>
</form>
</div>
</div>
</div>
<!-- Panneau Création simple -->
<div id="pane-autre" class="role-pane d-none">
<div class="alert alert-primary mb-4">
<strong>✨ Créer un espace séjour</strong><br>
<small>Type PP (Partenaire Payant) - Les familles peuvent activer Parent Premium (2,90 € / parent / séjour).</small>
</div>
<form id="formAutre" method="post" action="/Accompagnateur/register" class="needs-validation" novalidate>
<input type="text" name="website" class="visually-hidden" tabindex="-1" autocomplete="off">
<input type="hidden" name="type_user" value="PP">
<input type="hidden" name="connpay" value="1">
<div class="row g-3">
<div class="col-md-6">
<label class="form-label">Nom <span class="text-danger">*</span></label>
<input type="text" class="form-control" name="nom_acc" required
placeholder="Votre nom">
<div class="invalid-feedback">Veuillez saisir votre nom.</div>
</div>
<div class="col-md-6">
<label class="form-label">Prénom <span class="text-danger">*</span></label>
<input type="text" class="form-control" name="prenom_acc" required
placeholder="Votre prénom">
<div class="invalid-feedback">Veuillez saisir votre prénom.</div>
</div>
<div class="col-md-12">
<label class="form-label">Fonction <span class="text-danger">*</span></label>
<select class="form-select" name="fonction" required>
<option value="">Choisir votre fonction</option>
<option value="1">Enseignant(e)</option>
<option value="2">Principal(e)</option>
<option value="3">Professeur(e)</option>
<option value="4">CPE</option>
<option value="5">Directeur(trice) d'école</option>
<option value="6">Animateur(trice)</option>
<option value="7">Directeur(trice) séjour</option>
<option value="8">Directeur(trice) centre de loisirs / ALSH</option>
<option value="9">Coordinateur(trice) enfance jeunesse</option>
<option value="10">Educateur(trice)</option>
<option value="11">Président(e)</option>
<option value="12">Autre</option>
</select>
<div class="invalid-feedback">Veuillez sélectionner votre fonction.</div>
</div>
<div class="col-md-12">
<label class="form-label">Structure / Organisme <span class="text-danger">*</span></label>
<input type="text" class="form-control" name="etablisment" required
placeholder="Nom de votre structure ou organisation">
<div class="invalid-feedback">Veuillez saisir le nom de votre structure.</div>
</div>
<div class="col-md-12">
<label class="form-label">Adresse structure</label>
<input type="text" class="form-control" name="adressetablisment"
placeholder="Adresse de votre structure">
</div>
<div class="col-md-6">
<label class="form-label">Code postal</label>
<input type="text" class="form-control" name="CODEpOSTALetablisment"
placeholder="Code postal" maxlength="5">
</div>
<div class="col-md-6">
<label class="form-label">Ville</label>
<input type="text" class="form-control" name="villeetablisment"
placeholder="Ville de votre structure">
</div>
<div class="col-md-6">
<label class="form-label">N° de Téléphone mobile <span class="text-danger">*</span></label>
<input type="tel" class="form-control" name="phone_acc" required
placeholder="06 12 34 56 78" pattern="[0-9\s\+\-\(\)]{10,}">
<div class="invalid-feedback">Veuillez saisir un numéro de téléphone valide.</div>
</div>
<div class="col-md-6">
<label class="form-label">Email <span class="text-danger">*</span></label>
<input type="email" class="form-control" name="email" required
placeholder="votre.email@structure.fr">
<div class="invalid-feedback">Veuillez saisir une adresse email valide.</div>
</div>
<!-- Informations du séjour -->
<div class="col-12 mt-4">
<h6 class="text-primary">📍 Informations du séjour</h6>
<hr>
</div>
<div class="col-md-12">
<label class="form-label">Thème du séjour <span class="text-danger">*</span></label>
<input type="text" class="form-control" name="theme_sejour" required
placeholder="Ex: Séjour ski, Camp d'été...">
<div class="invalid-feedback">Veuillez saisir le thème du séjour.</div>
</div>
<div class="col-md-12">
<label class="form-label">Adresse du séjour</label>
<input type="text" class="form-control" name="adress_sejour"
placeholder="Adresse du lieu de séjour">
</div>
<div class="col-md-6">
<label class="form-label">Code postal</label>
<input type="text" class="form-control" name="codePostal"
placeholder="Code postal" maxlength="5">
</div>
<div class="col-md-6">
<label class="form-label">Pays <span class="text-danger">*</span></label>
<select class="form-select" name="pays" required>
<option value="">Choisir un pays</option>
<option value="France" selected>France</option>
<option value="Belgique">Belgique</option>
<option value="Suisse">Suisse</option>
<option value="Espagne">Espagne</option>
<option value="Italie">Italie</option>
<option value="Allemagne">Allemagne</option>
<option value="Royaume-Uni">Royaume-Uni</option>
<option value="Autre">Autre</option>
</select>
<div class="invalid-feedback">Veuillez sélectionner un pays.</div>
</div>
<div class="col-md-6">
<label class="form-label">Ville du séjour</label>
<input type="text" class="form-control" name="ville"
placeholder="Ville du séjour">
</div>
<div class="col-md-6">
<label class="form-label">Nombre de participants</label>
<input type="number" class="form-control" name="NbEnfant" min="1"
placeholder="Nombre d'enfants">
</div>
<div class="col-md-6">
<label class="form-label">Date début séjour <span class="text-danger">*</span></label>
<input type="date" class="form-control" name="date_debut_sejour" required>
<div class="invalid-feedback">Veuillez saisir la date de début.</div>
</div>
<div class="col-md-6">
<label class="form-label">Date fin séjour <span class="text-danger">*</span></label>
<input type="date" class="form-control" name="date_fin_sejour" required>
<div class="invalid-feedback">Veuillez saisir la date de fin.</div>
</div>
<div class="col-12 d-flex gap-2 mt-4">
<button type="submit" class="btn btn-primary px-4">
<i class="bi bi-rocket me-2"></i>Créer mon espace séjour (Type PP)
</button>
<a href="#" class="btn btn-outline-secondary" data-action="cta_demo">
Besoin d'aide ? Démo
</a>
</div>
</div>
</form>
</div>
<button type="button" id="backToStep1" class="btn btn-link mt-3">
<i class="bi bi-arrow-left me-1"></i> Retour au choix du profil
</button>
</div>
</div>
<div class="modal-footer border-top-0">
<p class="small text-muted mb-0">Sans engagement · Données hébergées en France 🇫🇷</p>
</div>
</div>
</div>
</div>
<style>
.select-role {
cursor: pointer;
transition: all 0.3s ease;
}
.select-role:hover,
.select-role:focus {
transform: translateY(-5px);
box-shadow: 0 4px 12px rgba(0,0,0,0.15);
border-color: var(--bs-primary) !important;
}
.select-role:active {
transform: translateY(-2px);
}
.hover-shadow {
transition: box-shadow 0.3s ease;
}
.bg-purple {
background-color: #6f42c1 !important;
}
</style>
<script>
// Protection contre les erreurs de la toolbar Symfony
(function() {
// Désactiver complètement Sfjs
window.Sfjs = {
loadToolbar: function() { console.log('Sfjs.loadToolbar désactivé'); },
showToolbar: function() { console.log('Sfjs.showToolbar désactivé'); },
hideToolbar: function() { console.log('Sfjs.hideToolbar désactivé'); },
initToolbar: function() { console.log('Sfjs.initToolbar désactivé'); }
};
// Désactiver les requêtes vers _wdt si elles échouent
const originalFetch = window.fetch;
window.fetch = function(...args) {
const url = args[0];
if (typeof url === 'string' && url.includes('/_wdt/')) {
console.warn('Requête vers _wdt bloquée:', url);
return Promise.reject(new Error('Toolbar Symfony désactivée'));
}
return originalFetch.apply(this, args);
};
// Désactiver XMLHttpRequest vers _wdt
const originalXHROpen = XMLHttpRequest.prototype.open;
const originalXHRSend = XMLHttpRequest.prototype.send;
XMLHttpRequest.prototype.open = function(method, url, ...args) {
this._url = url; // Stocker l'URL pour vérification dans send
if (typeof url === 'string' && url.includes('/_wdt/')) {
console.warn('Requête XHR vers _wdt bloquée:', url);
this._blocked = true;
return;
}
this._blocked = false;
return originalXHROpen.apply(this, [method, url, ...args]);
};
XMLHttpRequest.prototype.send = function(payload) {
if (this._blocked) {
console.warn('Envoi XHR bloqué pour:', this._url);
return; // Ne pas envoyer si bloqué
}
return originalXHRSend.apply(this, arguments);
};
})();
// Supprimer complètement la toolbar Symfony du DOM
function removeSymfonyToolbar() {
const toolbar = document.querySelector('.sf-toolbar');
if (toolbar) {
toolbar.remove();
console.log('Toolbar Symfony supprimée du DOM');
}
const clearer = document.querySelector('.sf-toolbar-clearer');
if (clearer) {
clearer.remove();
}
const minitoolbar = document.querySelector('.sf-minitoolbar');
if (minitoolbar) {
minitoolbar.remove();
}
}
// Supprimer immédiatement
removeSymfonyToolbar();
// Observer pour supprimer la toolbar dès qu'elle apparaît
const observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
if (mutation.type === 'childList') {
mutation.addedNodes.forEach(function(node) {
if (node.nodeType === 1) { // Element node
if (node.classList && (node.classList.contains('sf-toolbar') || node.classList.contains('sf-minitoolbar'))) {
node.remove();
console.log('Toolbar Symfony supprimée par l\'observer');
}
// Vérifier aussi les enfants
const toolbars = node.querySelectorAll && node.querySelectorAll('.sf-toolbar, .sf-minitoolbar, .sf-toolbar-clearer');
if (toolbars) {
toolbars.forEach(tb => tb.remove());
}
}
});
}
});
});
observer.observe(document.body, {
childList: true,
subtree: true
});
// Ajouter du CSS pour masquer la toolbar Symfony
const style = document.createElement('style');
style.textContent = `
.sf-toolbar, .sf-toolbar-clearer, .sf-minitoolbar {
display: none !important;
visibility: hidden !important;
opacity: 0 !important;
height: 0 !important;
width: 0 !important;
overflow: hidden !important;
}
`;
document.head.appendChild(style);
// Masquer la toolbar Symfony si elle cause des problèmes
document.addEventListener('DOMContentLoaded', function() {
// Masquer la toolbar Symfony après 2 secondes si elle n'est pas chargée
setTimeout(() => {
const toolbar = document.querySelector('.sf-toolbar');
if (toolbar && toolbar.classList.contains('sf-display-none')) {
toolbar.style.display = 'none';
console.log('Toolbar Symfony masquée pour éviter les erreurs 404');
}
}, 2000);
// Ouvre la modale avec l'onglet adapté + pré-remplissage
document.addEventListener('click', (e) => {
// Éviter les conflits avec la toolbar Symfony
if (e.target.closest('.sf-toolbar') || e.target.closest('[id^="sf"]')) {
return;
}
const a = e.target.closest('a[data-action="cta_demo"], a[data-action="cta_expert"]');
if (!a) return;
e.preventDefault();
const isExpert = a.dataset.action === 'cta_expert';
const pack = a.dataset.pack || '';
document.getElementById('demoTitle').textContent = isExpert ? 'Parler à un expert' : 'Demander une démo guidée';
document.getElementById('objet').value = isExpert ? 'expert' : 'demo';
document.getElementById('topic').value = isExpert ? 'expert' : 'demo';
document.getElementById('pack').value = pack;
// Onglet par défaut : expert => rappel / demo => calendrier
const triggerId = isExpert ? 'tab-callback' : 'tab-calendar';
const tabElement = document.getElementById(triggerId);
if (tabElement) {
// Désactiver tous les onglets
document.querySelectorAll('#demoTabs .nav-link').forEach(tab => {
tab.classList.remove('active');
tab.setAttribute('aria-selected', 'false');
});
// Désactiver tous les panneaux
document.querySelectorAll('.tab-pane').forEach(pane => {
pane.classList.remove('show', 'active');
});
// Activer l'onglet sélectionné
tabElement.classList.add('active');
tabElement.setAttribute('aria-selected', 'true');
// Activer le panneau correspondant
const targetPane = document.querySelector(tabElement.getAttribute('data-bs-target'));
if (targetPane) {
targetPane.classList.add('show', 'active');
}
}
const modal = bootstrap.Modal.getOrCreateInstance(document.getElementById('demoModal'));
modal.show();
});
// Validation form + anti double-submit pour le formulaire de démo
(function () {
const form = document.getElementById('contactForm');
const btn = document.getElementById('submitBtn');
if (!form || !btn) return;
// Protection contre les soumissions multiples
let isSubmitting = false;
// Nettoyer les classes d'erreur quand l'utilisateur tape
form.addEventListener('input', function(e) {
if (e.target.classList.contains('is-invalid')) {
e.target.classList.remove('is-invalid');
}
});
form.addEventListener('submit', function(e){
e.preventDefault(); // Toujours empêcher la soumission normale
// Éviter les soumissions multiples
if (isSubmitting) return;
isSubmitting = true;
// Nettoyer les messages précédents
const existingAlerts = form.parentNode.querySelectorAll('.alert');
existingAlerts.forEach(alert => alert.remove());
if (!form.checkValidity()) {
e.stopPropagation();
form.classList.add('was-validated');
// Afficher les messages d'erreur pour chaque champ invalide
const invalidFields = form.querySelectorAll(':invalid');
invalidFields.forEach(field => {
field.classList.add('is-invalid');
});
// Afficher un message d'erreur général
const errorAlert = document.createElement('div');
errorAlert.className = 'alert alert-warning mt-3';
errorAlert.innerHTML = `
<div class="d-flex align-items-center">
<i class="bi bi-exclamation-triangle-fill me-2"></i>
<div>
<strong>Veuillez corriger les erreurs :</strong><br>
Tous les champs marqués d'un astérisque (*) sont obligatoires.
</div>
</div>
`;
form.parentNode.insertBefore(errorAlert, form.nextSibling);
// Supprimer le message après 5 secondes
setTimeout(() => {
if (errorAlert.parentNode) {
errorAlert.parentNode.removeChild(errorAlert);
}
}, 5000);
isSubmitting = false;
return;
}
// Désactiver le bouton pendant l'envoi
btn.disabled = true;
const originalText = btn.textContent;
btn.textContent = 'Envoi en cours…';
// Récupérer les données du formulaire
const formData = new FormData(form);
// Debug : afficher les données envoyées
console.log('=== DEBUG FORMULAIRE ===');
console.log('Données du formulaire :');
const formDataObj = {};
for (let [key, value] of formData.entries()) {
console.log(key + ': "' + value + '"');
formDataObj[key] = value;
}
console.log('Objet complet:', formDataObj);
// Vérifier les champs obligatoires
const requiredFields = ['name', 'organization', 'email', 'telephone', 'sejours_count', 'consent'];
const missingFields = [];
requiredFields.forEach(field => {
if (!formDataObj[field] || formDataObj[field].trim() === '') {
missingFields.push(field);
}
});
if (missingFields.length > 0) {
console.error('Champs manquants:', missingFields);
alert('Champs manquants: ' + missingFields.join(', '));
isSubmitting = false;
return;
}
console.log('Tous les champs obligatoires sont remplis ✅');
// Envoyer la requête AJAX
fetch(form.action, {
method: 'POST',
body: formData,
headers: {
'X-Requested-With': 'XMLHttpRequest'
}
})
.then(response => response.json())
.then(data => {
if (data.success) {
// Afficher le message de succès
const successAlert = document.createElement('div');
successAlert.className = 'alert alert-success mt-3';
successAlert.innerHTML = `
<div class="d-flex align-items-center">
<i class="bi bi-check-circle-fill me-2"></i>
<div>
<strong>Demande envoyée !</strong><br>
${data.message}
</div>
</div>
`;
form.parentNode.insertBefore(successAlert, form.nextSibling);
// Réinitialiser le formulaire
form.reset();
form.classList.remove('was-validated');
// Fermer le modal après 3 secondes
setTimeout(() => {
const modal = bootstrap.Modal.getInstance(document.getElementById('demoModal'));
if (modal) modal.hide();
}, 3000);
} else {
// Afficher le message d'erreur
const errorAlert = document.createElement('div');
errorAlert.className = 'alert alert-danger mt-3';
errorAlert.innerHTML = `
<div class="d-flex align-items-center">
<i class="bi bi-exclamation-triangle-fill me-2"></i>
<div>
<strong>Erreur :</strong><br>
${data.message}
</div>
</div>
`;
form.parentNode.insertBefore(errorAlert, form.nextSibling);
// Supprimer le message d'erreur après 8 secondes
setTimeout(() => {
if (errorAlert.parentNode) {
errorAlert.parentNode.removeChild(errorAlert);
}
}, 8000);
}
})
.catch(error => {
console.error('Erreur:', error);
const errorAlert = document.createElement('div');
errorAlert.className = 'alert alert-danger mt-3';
errorAlert.innerHTML = `
<div class="d-flex align-items-center">
<i class="bi bi-exclamation-triangle-fill me-2"></i>
<div>
<strong>Erreur technique :</strong><br>
Une erreur est survenue lors de l'envoi. Veuillez réessayer plus tard.
</div>
</div>
`;
form.parentNode.insertBefore(errorAlert, form.nextSibling);
// Supprimer le message d'erreur après 10 secondes
setTimeout(() => {
if (errorAlert.parentNode) {
errorAlert.parentNode.removeChild(errorAlert);
}
}, 10000);
})
.finally(() => {
// Réactiver le bouton et le flag de soumission
btn.disabled = false;
btn.textContent = originalText;
isSubmitting = false;
// Supprimer les anciennes alertes après 5 secondes
setTimeout(() => {
const alerts = form.parentNode.querySelectorAll('.alert');
alerts.forEach(alert => alert.remove());
}, 5000);
});
});
})();
// ===== GESTION MODALE "CRÉER MON SÉJOUR" =====
const createSejourModal = document.getElementById('createSejourModal');
const step1 = document.getElementById('step1');
const step2 = document.getElementById('step2');
const stepLabel = document.getElementById('stepLabel');
const stepDescription = document.getElementById('stepDescription');
const backToStep1Btn = document.getElementById('backToStep1');
let currentRole = null;
let isSubmittingCreate = false;
// Fonction helper pour le tracking GA4
function trackEvent(eventName, params = {}) {
if (typeof gtag === 'function') {
gtag('event', eventName, params);
console.log('📊 GA4 Event:', eventName, params);
}
}
// Reset de la modale à l'ouverture
createSejourModal.addEventListener('show.bs.modal', function () {
// Reset aux valeurs initiales
step1.classList.remove('d-none');
step2.classList.add('d-none');
stepLabel.textContent = 'Étape 1/2';
stepDescription.textContent = 'Choisissez votre profil';
currentRole = null;
// Masquer tous les panneaux de formulaire
document.querySelectorAll('.role-pane').forEach(pane => pane.classList.add('d-none'));
// Reset de tous les formulaires
['formEcole', 'formPartenaire', 'formAutre'].forEach(formId => {
const form = document.getElementById(formId);
if (form) {
form.reset();
form.classList.remove('was-validated');
}
});
// Focus sur le titre de la modale
setTimeout(() => {
document.getElementById('createSejourTitle').focus();
}, 300);
});
// Gestion du clic sur les cartes de sélection de rôle
document.querySelectorAll('.select-role').forEach(card => {
card.addEventListener('click', function() {
const role = this.dataset.role;
selectRole(role);
});
// Support du clavier
card.addEventListener('keypress', function(e) {
if (e.key === 'Enter' || e.key === ' ') {
e.preventDefault();
const role = this.dataset.role;
selectRole(role);
}
});
});
function selectRole(role) {
currentRole = role;
// Track event GA4
trackEvent('step_select_role', { role: role });
// Si école publique → Redirection directe vers /Accompagnateur/login avec type EF
if (role === 'ecole_publique') {
// Fermer la modale
bootstrap.Modal.getInstance(createSejourModal)?.hide();
// Rediriger vers la page de login avec le paramètre type EF et source
window.location.href = '/Accompagnateur/login?type=EF&from=modal';
return;
}
// Passage à l'étape 2 pour les autres profils
step1.classList.add('d-none');
step2.classList.remove('d-none');
stepLabel.textContent = 'Étape 2/2';
// Afficher le panneau correspondant
document.querySelectorAll('.role-pane').forEach(pane => pane.classList.add('d-none'));
let roleLabel = '';
if (role === 'partenaire') {
document.getElementById('pane-partenaire').classList.remove('d-none');
roleLabel = 'Partenaire / Organisme';
// Lazy load Calendly pour le partenaire
lazyLoadCalendlyIfNeeded('#pane-partenaire-demo iframe');
} else if (role === 'autre') {
document.getElementById('pane-autre').classList.remove('d-none');
roleLabel = 'Création simple';
setTimeout(() => document.querySelector('#pane-autre input')?.focus(), 300);
}
stepDescription.textContent = roleLabel;
}
// Retour à l'étape 1
backToStep1Btn.addEventListener('click', function() {
step1.classList.remove('d-none');
step2.classList.add('d-none');
stepLabel.textContent = 'Étape 1/2';
stepDescription.textContent = 'Choisissez votre profil';
currentRole = null;
});
// Lazy load Calendly
function lazyLoadCalendlyIfNeeded(selector) {
const iframe = document.querySelector(selector);
if (iframe && iframe.hasAttribute('data-src') && !iframe.src) {
iframe.src = iframe.getAttribute('data-src');
console.log('📅 Calendly chargé:', iframe.src);
}
}
// Lazy load Calendly pour modale démo (onglet calendrier)
const tabCalendar = document.getElementById('tab-calendar');
if (tabCalendar) {
tabCalendar.addEventListener('shown.bs.tab', function() {
lazyLoadCalendlyIfNeeded('#pane-calendar iframe');
});
}
// Lazy load Calendly pour modale créer séjour (onglet demo partenaire)
const tabPartenaireDemo = document.getElementById('tab-partenaire-demo');
if (tabPartenaireDemo) {
tabPartenaireDemo.addEventListener('shown.bs.tab', function() {
lazyLoadCalendlyIfNeeded('#pane-partenaire-demo iframe');
});
}
// Gestion des radios "qui paie" avec tracking
document.querySelectorAll('input[name="payer"]').forEach(radio => {
radio.addEventListener('change', function() {
trackEvent('toggle_payer', { who_pays: this.value });
});
});
// Fonction générique de soumission de formulaire avec AJAX
function setupFormSubmission(formId, onSuccess) {
const form = document.getElementById(formId);
if (!form) return;
form.addEventListener('submit', function(e) {
e.preventDefault();
// Éviter les doubles soumissions
if (isSubmittingCreate) {
return;
}
// Valider le formulaire
if (!form.checkValidity()) {
form.classList.add('was-validated');
// Afficher un message d'avertissement
const warningAlert = document.createElement('div');
warningAlert.className = 'alert alert-warning mt-3';
warningAlert.innerHTML = `
<div class="d-flex align-items-center">
<i class="bi bi-exclamation-triangle-fill me-2"></i>
<div>
<strong>Veuillez corriger les erreurs :</strong><br>
Tous les champs marqués d'un astérisque (*) sont obligatoires.
</div>
</div>
`;
form.parentNode.insertBefore(warningAlert, form.nextSibling);
setTimeout(() => warningAlert.remove(), 5000);
return;
}
isSubmittingCreate = true;
// Track event GA4
trackEvent('form_submit', { form_id: formId });
// Désactiver le bouton
const btn = form.querySelector('button[type="submit"]');
btn.disabled = true;
const originalText = btn.textContent;
btn.innerHTML = '<span class="spinner-border spinner-border-sm me-2"></span>Envoi en cours…';
// Soumettre via fetch
const formData = new FormData(form);
fetch(form.action, {
method: 'POST',
body: formData,
headers: {
'X-Requested-With': 'XMLHttpRequest'
}
})
.then(response => response.json())
.then(data => {
if (data.idSejour) {
// Succès ! Le séjour a été créé
// Track event GA4 de succès
trackEvent('create_sejour_success', {
role: currentRole,
sejour_id: data.idSejour,
code_sejour: data.codeSejour || 'N/A'
});
// Afficher le message de succès
const successAlert = document.createElement('div');
successAlert.className = 'alert alert-success mt-3';
successAlert.innerHTML = `
<div class="d-flex align-items-center">
<i class="bi bi-check-circle-fill me-2"></i>
<div>
<strong>✅ Séjour créé avec succès !</strong><br>
${data.codeSejour ? 'Code séjour : <strong>' + data.codeSejour + '</strong><br>' : ''}
Vous allez être redirigé vers votre espace...
</div>
</div>
`;
form.parentNode.insertBefore(successAlert, form.nextSibling);
// Reset le formulaire
form.reset();
form.classList.remove('was-validated');
// Rediriger après 2 secondes vers l'espace accompagnateur
setTimeout(() => {
}, 2000);
// Callback optionnel
if (onSuccess) onSuccess(data);
} else if (data.success === false) {
// Erreur métier
const errorAlert = document.createElement('div');
errorAlert.className = 'alert alert-danger mt-3';
errorAlert.innerHTML = `
<div class="d-flex align-items-center">
<i class="bi bi-x-circle-fill me-2"></i>
<div>
<strong>Erreur :</strong><br>
${data.message || 'Une erreur est survenue lors de la création du séjour.'}
</div>
</div>
`;
form.parentNode.insertBefore(errorAlert, form.nextSibling);
setTimeout(() => errorAlert.remove(), 7000);
} else {
// Réponse inattendue
console.warn('Réponse inattendue:', data);
const warningAlert = document.createElement('div');
warningAlert.className = 'alert alert-warning mt-3';
warningAlert.innerHTML = `
<div class="d-flex align-items-center">
<i class="bi bi-exclamation-triangle-fill me-2"></i>
<div>
<strong>Attention :</strong><br>
La création du séjour a peut-être réussi. Vérifiez votre espace.
</div>
</div>
`;
form.parentNode.insertBefore(warningAlert, form.nextSibling);
setTimeout(() => {
window.location.href = '/Accompagnateur/login';
}, 3000);
}
})
.catch(error => {
console.error('Erreur:', error);
const errorAlert = document.createElement('div');
errorAlert.className = 'alert alert-danger mt-3';
errorAlert.innerHTML = `
<div class="d-flex align-items-center">
<i class="bi bi-x-circle-fill me-2"></i>
<div>
<strong>Erreur technique :</strong><br>
Une erreur réseau est survenue. Veuillez réessayer plus tard.
</div>
</div>
`;
form.parentNode.insertBefore(errorAlert, form.nextSibling);
setTimeout(() => errorAlert.remove(), 7000);
})
.finally(() => {
btn.disabled = false;
btn.innerHTML = originalText;
isSubmittingCreate = false;
});
});
}
// Setup tous les formulaires de la modale "Créer mon séjour"
// formEcole supprimé car redirection directe vers /Accompagnateur/login
setupFormSubmission('formPartenaire');
setupFormSubmission('formAutre');
// Délégation d'événements pour tous les CTA avec data-action
document.addEventListener('click', function(e) {
// Éviter les conflits avec la toolbar Symfony
if (e.target.closest('.sf-toolbar') || e.target.closest('[id^="sf"]')) {
return;
}
const target = e.target.closest('[data-action]');
if (!target) return;
const action = target.dataset.action;
const pack = target.dataset.pack || '';
// Track event GA4
trackEvent('cta_open_modal', { action: action, pack: pack });
if (action === 'cta_create') {
// Ouvrir la modale "Créer mon séjour"
e.preventDefault();
const modal = new bootstrap.Modal(createSejourModal);
modal.show();
} else if (action === 'cta_demo' || action === 'cta_expert') {
// Ouvrir la modale demo/expert existante
e.preventDefault();
const demoModal = document.getElementById('demoModal');
const modal = new bootstrap.Modal(demoModal);
const isExpert = action === 'cta_expert';
// Changer le titre
document.getElementById('demoTitle').textContent = isExpert ? 'Parler à un expert' : 'Demander une démo guidée';
// Pré-remplir les champs cachés
document.getElementById('objet').value = isExpert ? 'expert' : 'demo';
document.getElementById('topic').value = isExpert ? 'expert' : 'demo';
document.getElementById('pack').value = pack;
// Activer le bon onglet
const tabCalendar = document.getElementById('tab-calendar');
const tabCallback = document.getElementById('tab-callback');
const paneCalendar = document.getElementById('pane-calendar');
const paneCallback = document.getElementById('pane-callback');
if (isExpert) {
// Expert → Onglet "Être rappelé"
tabCalendar.classList.remove('active');
tabCallback.classList.add('active');
paneCalendar.classList.remove('show', 'active');
paneCallback.classList.add('show', 'active');
} else {
// Démo → Onglet "Réserver un créneau"
tabCallback.classList.remove('active');
tabCalendar.classList.add('active');
paneCallback.classList.remove('show', 'active');
paneCalendar.classList.add('show', 'active');
// Lazy load Calendly
lazyLoadCalendlyIfNeeded('#pane-calendar iframe');
}
modal.show();
}
});
}); // Fin du DOMContentLoaded
</script>
<!-- ======= Site Wrap =======-->
<div class="site-wrap">
<!-- ======= Header =======-->
<header class="fbs__net-navbar navbar navbar-expand-lg dark" aria-label="freebootstrap.net navbar">
<div class="container d-flex align-items-center justify-content-between">
<!-- Start Logo-->
<a class="navbar-brand w-auto" href="#">
<img class="logo dark img-fluid" src="{{ asset('Accueil/imagesAccueil/logoHeader.png') }}" alt="5sur5séjour logo" style="height: 65px;">
</a>
<!-- End Logo-->
<!-- Start offcanvas-->
<div class="offcanvas offcanvas-start w-75" id="fbs__net-navbars" tabindex="-1" aria-labelledby="fbs__net-navbarsLabel">
<div class="offcanvas-header">
<div class="offcanvas-header-logo">
<a class="logo-link" id="fbs__net-navbarsLabel" href="#">
<img class="logo light img-fluid" src="{{ asset('Accueil/imagesAccueil/logoHeader.png') }}" alt="5sur5séjour logo" style="height: 60px;">
</a>
</div>
<button class="btn-close btn-close-black" type="button" data-bs-dismiss="offcanvas" aria-label="Close"></button>
</div>
<div class="offcanvas-body align-items-lg-center">
<ul class="navbar-nav nav me-auto ps-lg-5 mb-2 mb-lg-0">
<li class="nav-item"><a class="nav-link scroll-link" href="#about">A propos</a></li>
<li class="nav-item"><a class="nav-link scroll-link" href="#how-it-works">Comment ça marche</a></li>
<li class="nav-item"><a class="nav-link scroll-link" href="#pricing">Nos offres</a></li>
<li class="nav-item"><a class="nav-link scroll-link" href="#contact">Contact</a></li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" data-bs-toggle="dropdown" aria-expanded="false">Nos produits <i class="bi bi-chevron-down"></i></a>
<ul class="dropdown-menu">
<li class="nav-item"><a class="nav-link" href="{{ path('pack_annuel_partenaires') }}">Pack Annuel Partenaires</a></li>
<li><hr class="dropdown-divider"></li>
{% for produit in produit %}
{% if produit.labeleType!="Connexion" %}
<li class="nav-item"><a class="nav-link scroll-link" href="{{path('album',{'id':produit.labeleType})}}"> {{produit.labeleType}}</a></li>
{% endif %}
{% endfor %}
</ul>
</li>
</ul>
</div>
</div>
<!-- End offcanvas-->
<div class="ms-auto w-auto">
<div class="header-social d-flex align-items-center gap-1">
<a class="btn btn-primary py-2" href="#jemeconnecte">Je me connecte</a>
<button class="fbs__net-navbar-toggler justify-content-center align-items-center ms-auto" data-bs-toggle="offcanvas" data-bs-target="#fbs__net-navbars" aria-controls="fbs__net-navbars" aria-label="Toggle navigation" aria-expanded="false">
<svg class="fbs__net-icon-menu" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewbox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<line x1="21" x2="3" y1="6" y2="6"></line>
<line x1="15" x2="3" y1="12" y2="12"></line>
<line x1="17" x2="3" y1="18" y2="18"></line>
</svg>
<svg class="fbs__net-icon-close" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewbox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M18 6 6 18"></path>
<path d="m6 6 12 12"></path>
</svg>
</button>
</div>
</div>
</div>
</header>
<!-- End Header-->
<!-- ======= Main =======-->
<main>
<!-- ======= Hero =======-->
<section class="hero__v6 section" id="home">
<div class="container">
<div class="row">
<div class="col-lg-6 mb-4 mb-lg-0">
<div class="row">
<div class="col-lg-11">
<span class="hero-subtitle text-uppercase" data-aos="fade-up" data-aos-delay="0">La solution sécurisée qui rassure les familles et libère vos équipes</span>
<h1 class="hero-title mb-3" data-aos="fade-up" data-aos-delay="100"> Avec 5sur5Séjour, transformez chaque séjour en une expérience sereine et valorisante.</h1>
<p class="hero-description mb-4 mb-lg-5" data-aos="fade-up" data-aos-delay="200">🤝 Un accompagnement humain dédié| 📞 Des appels vocaux automatiques aux familles | 🔒 100% conforme RGPD & hébergé en France</p>
<a class="btn btn-lg btn-primary px-4 w-100 w-sm-auto" style="background:color-mix(in srgb, var(--bs-secondary), transparent 70%);color:#41a2aa"
href="{{ path('pack_annuel_partenaires') }}">
Devenir partenaire
<svg class="ms-2" xmlns="http://www.w3.org/2000/svg" width="18" height="18" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
<path d="M7 7h10v10"></path><path d="M7 17 17 7"></path>
</svg>
</a>
</div>
</div>
</div>
<div class="col-lg-6">
<div class="hero-img">
<img class="img-card img-fluid" style="background: radial-gradient(gray, transparent);border-radius: 30px;" src="{{ asset('Accueil/imagesAccueil/demo1.png') }}" alt="Image card" data-aos="fade-down" data-aos-delay="600">
<img class="img-main img-fluid rounded-4" src="{{ asset('images/smiling_5sur5.svg') }}" alt="Hero Image" data-aos="fade-in" data-aos-delay="500">
</div>
<!-- Bouton CTA -->
<!-- CTAs -->
<div class="d-flex flex-wrap gap-3 align-items-center mb-2" data-aos="fade-up" data-aos-delay="250" style="margin-top:15%">
<a class="btn btn-lg btn-primary px-4 w-100 w-sm-auto" href="#" data-action="cta_create" data-pack="creation">
Créer mon espace séjour
<svg class="ms-2" xmlns="http://www.w3.org/2000/svg" width="18" height="18" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
<path d="M7 7h10v10"></path><path d="M7 17 17 7"></path>
</svg>
</a>
</div>
<!-- Preuve sociale courte -->
<div class="logos mt-4" data-aos="fade-up" data-aos-delay="350">
<p class="text-primary-emphasis text-uppercase small mt-4 mb-0">
Déjà adopté par <strong>1 500+</strong> écoles, centres de loisirs et associations en France
</p>
</div>
</div>
</div>
</div>
<!-- End Hero-->
</section>
<!-- End Hero-->
<!-- ======= Vignettes Section =======-->
<section class="about_wrap_area aboutWrapper mb-5">
<div class="container" id="jemeconnecte">
<div class="row">
<div class="col-xl-4 col-md-4 col-lg-4">
<div class="single_service_wrap text-center vignetteContent" data-aos="fade-up" data-aos-delay="0">
<img class="imageParent" src="{{ asset('Accueil/imagesAccueil/son_sejour.svg') }}" alt="Parent">
<h3 class="titreVignette">Vous êtes parent</h3>
<p class="txtVignette">Consultez les photos et vidéos à tout moment, <b>et soyez appelé dès qu'un nouveau message vocal est déposé — restez connectés au séjour, où que vous soyez.</b> </p>
<a href="{{ path('app_back_Parent') }}" class="btn btn-primary py-2">Je me connecte</a>
</div>
</div>
<div class="col-xl-4 col-md-4 col-lg-4">
<div class="single_service_wrap text-center vignetteContent" data-aos="fade-up" data-aos-delay="200">
<img class="imageAcc" src="{{ asset('Accueil/imagesAccueil/espceAcc.svg') }}" alt="Accompagnateur">
<h3 class="titreVignette titreAcc">Vous êtes accompagnateur</h3>
<p class="txtVignette txtAcc">Partagez facilement photos et messages pour rassurer les familles — créez et gérez vos séjours en toute simplicité. </p>
<a data-bs-toggle="modal" data-bs-target="#loginModal" class="btn btn-primary py-2">Je me connecte</a>
</div>
</div>
<div class="col-xl-4 col-md-4 col-lg-4">
<div class="single_service_wrap text-center vignetteContent" data-aos="fade-up" data-aos-delay="400">
<img class="imagePartenaire" src="{{ asset('Accueil/imagesAccueil/espcPart.svg') }}" alt="Partenaire">
<h3 class="titreVignette titrePartenaire">Vous êtes partenaire</br></h3>
<p class="txtVignette txtPartenaire">
<br/>Créez et gérez tous vos séjours depuis un espace dédié, avec un service client sur mesure et des outils pensés pour vous.</p>
<a data-bs-toggle="modal" data-bs-target="#partnerLoginModal" class="btn btn-primary py-2">Je me connecte</a>
</div>
</div>
</div>
</div>
</section>
<!-- End Vignettes -->
<!-- ======= Pourquoi nous choisir =======-->
<section class="section features__v2" id="about">
<div class="container">
<div class="row">
<div class="col-12">
<div class="d-lg-flex p-5 rounded-4 content" data-aos="fade-in" data-aos-delay="0">
<div class="row">
<div class="col-lg-5 mb-5 mb-lg-0" data-aos="fade-up" data-aos-delay="0">
<div class="row">
<div class="col-lg-11">
<div class="h-100 flex-column justify-content-between d-flex">
<div>
<h2 class="mb-4">Pourquoi nous choisir pour vos séjours</h2>
<p class="mb-5">5sur5séjour n'est pas qu'un outil pour les animateurs.
C'est une solution complète pour les professionnels qui veulent gagner du temps, rassurer les familles, et moderniser leur image.</p>
</div>
<div class="align-self-start">
<a class="btn btn-play d-inline-flex align-items-center gap-2" href="#" data-action="cta_create" data-pack="video">
<i class="bi bi-play-fill"></i> Créer mon espace séjour maintenant
</a>
</div>
</div>
</div>
</div>
</div>
<div class="col-lg-7">
<div class="row justify-content-end">
<div class="col-lg-11">
<div class="row">
<div class="col-sm-6" data-aos="fade-up" data-aos-delay="0">
<div class="icon text-center mb-4"><i class="bi bi-person-check fs-4"></i></div>
<h3 class="fs-6 fw-bold mb-3">Partage sécurisé</h3>
<p>Galerie privée photos/vidéos, droits par groupes/classes, consentements intégrés..</p>
</div>
<div class="col-sm-6" data-aos="fade-up" data-aos-delay="100">
<div class="icon text-center mb-4"><i class="bi bi-graph-up fs-4"></i></div>
<h3 class="fs-6 fw-bold mb-3">Boîte vocale automatique </h3>
<p>Chaque message déclenche un appel aux parents, même sans internet..</p>
</div>
<div class="col-sm-6" data-aos="fade-up" data-aos-delay="200">
<div class="icon text-center mb-4"><i class="bi bi-headset fs-4"></i></div>
<h3 class="fs-6 fw-bold mb-3">Temps gagné</h3>
<p>Publication en 2 clics, appels envoyés pour vous..</p>
</div>
<div class="col-sm-6" data-aos="fade-up" data-aos-delay="300">
<div class="icon text-center mb-4"><i class="bi bi-gift fs-4"></i></div>
<h3 class="fs-6 fw-bold mb-3">Support humain</h3>
<p>Onboarding, modèles prêts à l'emploi, assistance pendant les séjours..</p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
<!-- End Features-->
<!-- ======= About =======-->
<section class="about__v4 section" id="about">
<div class="container">
<div class="row">
<div class="col-md-6 order-md-2">
<div class="row justify-content-end">
<div class="col-md-11 mb-4 mb-md-0">
<span class="subtitle text-uppercase mb-3" data-aos="fade-up" data-aos-delay="0">Service unique en France</span>
<h2 class="mb-4" data-aos="fade-up" data-aos-delay="100">La boîte vocale 5sur5 : vos messages, écoutés tout de suite</h2>
<div data-aos="fade-up" data-aos-delay="200">
<p>Chaque message publié déclenche automatiquement un appel aux parents — zéro rappel manuel, zéro oubli.</p>
</div>
<h4 class="small fw-bold mt-4 mb-3" data-aos="fade-up" data-aos-delay="300">La voix est bien plus consultée qu'un SMS/mail.</h4>
<ul class="d-flex flex-row flex-wrap list-unstyled gap-3 features" data-aos="fade-up" data-aos-delay="400">
<li class="d-flex align-items-center gap-2"><span class="icon rounded-circle text-center"><i class="bi bi-check"></i></span><span class="text">Impact x2–3</span></li>
<li class="d-flex align-items-center gap-2"><span class="icon rounded-circle text-center"><i class="bi bi-check"></i></span><span class="text">Illimitée & asynchrone</span></li>
<li class="d-flex align-items-center gap-2"><span class="icon rounded-circle text-center"><i class="bi bi-check"></i></span><span class="text">Traçable & conforme</span></li>
<li class="d-flex align-items-center gap-2"><span class="icon rounded-circle text-center"><i class="bi bi-check"></i></span><span class="text">Transparente</span></li>
<li class="d-flex align-items-center gap-2"><span class="icon rounded-circle text-center"><i class="bi bi-check"></i></span><span class="text">24h/24</span></li>
</ul>
</div>
</div>
</div>
<div class="col-md-6">
<div class="img-wrap position-relative">
<img class="img-fluid rounded-4" src="{{ asset('Accueil/imagesAccueil/feature.png') }}" alt="Sécurité 5sur5séjour" data-aos="fade-up" data-aos-delay="0" style="width: 100%; height: 300px; object-fit: cover;">
<div class="mission-statement p-4 rounded-4 d-flex gap-4" data-aos="fade-up" data-aos-delay="100">
<div class="mission-icon text-center rounded-circle"><i class="bi bi-lightbulb fs-4"></i></div>
<div>
<h3 class="text-uppercase fw-bold">Notre mission</h3>
<p class="fs-5 mb-0">Notre mission est de vous offrir une solution simple, fiable et professionnelle pour partager le séjour avec les familles.</p>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
<!-- End About-->
<!-- ======= How it works =======-->
<section class="section howitworks__v1" id="how-it-works">
<div class="container">
<div class="row mb-5">
<div class="col-md-6 text-center mx-auto">
<span class="subtitle text-uppercase mb-3" data-aos="fade-up" data-aos-delay="0">Comment ça marche</span>
<h2 data-aos="fade-up" data-aos-delay="100">Comment ça marche</h2>
<p data-aos="fade-up" data-aos-delay="200">Une plateforme complète qui centralise contenus et communications, pour partager le séjour avec les familles en toute simplicité, sans surcharge pour les équipes.</p>
</div>
</div>
<div class="row g-md-5">
<div class="col-md-6 col-lg-3">
<div class="step-card text-center h-100 d-flex flex-column justify-content-start position-relative" data-aos="fade-up" data-aos-delay="0">
<div data-aos="fade-right" data-aos-delay="500">
<img class="arch-line" src="{{ asset('Accueil/imagesAccueil/arch-line.png') }}" alt="Flèche animation">
</div>
<span class="step-number rounded-circle text-center fw-bold mb-5 mx-auto">1</span>
<div>
<h3 class="fs-5 mb-4">Créez l'espace séjour</h3>
<p>Créez votre séjour en quelques clics… ou confiez-nous l'import de plusieurs séjours, on s'occupe de tout..</p>
</div>
</div>
</div>
<div class="col-md-6 col-lg-3" data-aos="fade-up" data-aos-delay="600">
<div class="step-card reverse text-center h-100 d-flex flex-column justify-content-start position-relative">
<div data-aos="fade-right" data-aos-delay="1100">
<img class="arch-line reverse" src="{{ asset('Accueil/imagesAccueil/arch-line-reverse.png') }}" alt="Flèche animation">
</div>
<span class="step-number rounded-circle text-center fw-bold mb-5 mx-auto">2</span>
<h3 class="fs-5 mb-4">Invitez les familles</h3>
<p>Envoyez le code de séjour aux familles pour qu'ils rejoignent l'espace séjour. </p>
</div>
</div>
<div class="col-md-6 col-lg-3" data-aos="fade-up" data-aos-delay="1200">
<div class="step-card text-center h-100 d-flex flex-column justify-content-start position-relative">
<div data-aos="fade-right" data-aos-delay="1700">
<img class="arch-line" src="{{ asset('Accueil/imagesAccueil/arch-line.png') }}" alt="Flèche animation">
</div>
<span class="step-number rounded-circle text-center fw-bold mb-5 mx-auto">3</span>
<h3 class="fs-5 mb-4">Publiez en 2 clics</h3>
<p>Diffusez vos photos, vidéos et messages vocaux en toute simplicité.</p>
</div>
</div>
<div class="col-md-6 col-lg-3" data-aos="fade-up" data-aos-delay="1800">
<div class="step-card last text-center h-100 d-flex flex-column justify-content-start position-relative">
<span class="step-number rounded-circle text-center fw-bold mb-5 mx-auto">4</span>
<div>
<h3 class="fs-5 mb-4">Bilan & archive</h3>
<p>À la fin du séjour, accédez à un bilan complet avec statistiques, et proposez aux familles un album souvenir personnalisé.</p>
</div>
</div>
</div>
</div>
</div>
</section>
<!-- End How it works-->
<!-- ======= Pricing =======-->
<section class="section pricing__v2" id="">
<div class="container">
<div class="row mb-5">
<div class="col-md-5 mx-auto text-center">
<span class="subtitle text-uppercase mb-3" data-aos="fade-up" data-aos-delay="0">Packs Partenaires</span>
<h2 class="mb-3" data-aos="fade-up" data-aos-delay="100">Plateforme premium & boîte vocale automatique</h2>
<p data-aos="fade-up" data-aos-delay="200">Des tarifs simples, pensés pour les écoles, centres et associations. Sans engagement, mise en place en 24 h..</p>
</div>
</div>
<section class="section py-6" id="packs">
<div class="container">
<!-- Titre + micro-preuve + offre écoles publiques -->
<section class="section py-6" id="pricing">
<div class="container">
<div class="text-center mb-4">
<h2 class="mb-2">Packs Partenaires — plateforme premium & boîte vocale automatique</h2>
<p class="text-muted mb-2">Des tarifs simples, pensés pour les écoles, centres et associations. Sans engagement, mise en place en 24 h.</p>
<div class="small text-primary-emphasis">🎓 <strong>Écoles publiques :</strong> accès plateforme gratuit (hors options familles)</div>
</div>
<div class="row g-4">
<!-- Accès -->
<div class="col-md-4" data-aos="fade-up" data-aos-delay="100">
<div class="p-5 rounded-4 price-table h-100 shadow-sm">
<div class="small text-muted mb-1">Pour démarrer</div>
<h3 class="mb-1">Accès (Plateforme)</h3>
<div class="display-6 fw-semibold">290 € <span class="fs-6 fw-normal">/ an / structure</span></div>
<ul class="mt-3 mb-4">
<li>Galerie privée <strong>photos & vidéos</strong> (groupes/classes)</li>
<li>Consentements & <strong>RGPD</strong> (hébergé en France)</li>
<li>Rôles & droits (direction, accompagnateurs, collectivités)</li>
<li><strong>Boîte vocale web incluse</strong> (enregistrement + écoute web)</li>
</ul>
<div class="text-muted small mb-2">Bénéfice : jusqu'à <strong>–50%</strong> d'appels entrants</div>
<button type="button" class="btn btn-outline-primary w-100" data-bs-toggle="modal" data-bs-target="#checkoutChoiceModal" data-pack="access" data-pack-price="290">Choisir ce pack</button>
<a class="special-link d-inline-flex gap-2 align-items-center text-decoration-none my-4" href="#"><span class="icons"><i class="icon-1 bi bi-arrow-right-short"></i><i class="icon-2 bi bi-arrow-right-short"> </i></span><span>En savoir plus</span></a>
</div>
</div>
<!-- Sérénité -->
<div class="col-md-4" data-aos="fade-up" data-aos-delay="200">
<div class="p-5 rounded-4 price-table popular h-100 shadow-lg position-relative border border-primary">
<span class="position-absolute top-0 start-50 translate-middle badge rounded-pill bg-primary">Le plus utilisé</span>
<div class="small text-muted mb-1 mt-3">Voix activable</div>
<h3 class="mb-1">Sérénité</h3>
<div class="display-6 fw-semibold">390 € <span class="fs-6 fw-normal">/ an / structure</span></div>
<div class="text-muted mb-2">
+ <strong>0,90 €</strong> / parent / séjour
<span class="d-block small">appliqué uniquement si la voix est activée — <strong>appels illimités</strong></span>
</div>
<ul class="mt-2 mb-4">
<li>Tout <strong>Accès</strong></li>
<li><strong>Appels téléphoniques automatiques</strong> à chaque message</li>
<li><strong>Statistiques d'écoute</strong> & journal d'émission</li>
<li><strong>Assistance prioritaire</strong> pendant les séjours</li>
<li><strong>Onboarding live 1 h</strong> + création express du 1er séjour</li>
</ul>
<div class="text-muted small mb-2">Bénéfice : <strong>–70 à –80%</strong> d'appels ; <strong>>90%</strong> messages écoutés</div>
<button type="button" class="btn btn-primary w-100" style="background:white;color:var(--bs-primary)" data-bs-toggle="modal" data-bs-target="#checkoutChoiceModal" data-pack="serenite" data-pack-price="390">Choisir ce pack</button>
<a style="color:white"class="special-link d-inline-flex gap-2 align-items-center text-decoration-none my-4" href="#"><span class="icons"><i style="color:white"class="icon-1 bi bi-arrow-right-short"></i><i class="icon-2 bi bi-arrow-right-short"> </i></span><span>En savoir plus</span></a>
</div>
</div>
<!-- Pro Illimité -->
<div class="col-md-4" data-aos="fade-up" data-aos-delay="300">
<div class="p-5 rounded-4 price-table h-100 shadow-sm border" style="border-color:#E7C873">
<div class="small text-muted mb-1">Pour réseaux & multi-sites</div>
<h3 class="mb-1">Pro Illimité ✨</h3>
<div class="display-6 fw-semibold">990 € <span class="fs-6 fw-normal">/ an / structure</span></div>
<div class="text-muted mb-2"><strong>Aucun +0,90 €</strong> — appels téléphoniques illimités <strong>inclus</strong> toute l'année</div>
<ul class="mt-2 mb-4">
<li>Tout <strong>Sérénité</strong></li>
<li><strong>Création des séjours par notre équipe</strong> (quota annuel inclus)</li>
<li><strong>Pilotage multi-séjours</strong> + rapport mensuel synthétique</li>
<li><strong>Partage des bénéfices</strong> sur achats familles (albums, options)</li>
</ul>
<div class="text-muted small mb-2">Bénéfice : déploiement rapide ; jusqu'à <strong>–90%</strong> d'appels</div>
<button type="button" class="btn btn-primary w-100" data-bs-toggle="modal" data-bs-target="#checkoutChoiceModal" data-pack="pro_illimite" data-pack-price="990">Choisir ce pack</button>
<a class="special-link d-inline-flex gap-2 align-items-center text-decoration-none my-4" href="#"><span class="icons"><i class="icon-1 bi bi-arrow-right-short"></i><i class="icon-2 bi bi-arrow-right-short"> </i></span><span>En savoir plus</span></a>
</div>
</div>
</div>
<!-- Options familles — affichage discret -->
<hr class="my-4">
<div class="options-inline d-flex flex-wrap justify-content-center align-items-center gap-2 gap-md-3">
<span class="pill d-inline-flex align-items-center gap-2 px-3 py-2 rounded-pill">
<span aria-hidden="true">🎁</span>
<span class="fw-semibold">Achat groupé</span>
<span class="text-muted">— tarif réduit garenti</span>
</span>
<span class="vr d-none d-md-inline mx-1" style="opacity:.25;"></span>
<span class="pill d-inline-flex align-items-center gap-2 px-3 py-2 rounded-pill">
<span aria-hidden="true">⭐</span>
<span class="fw-semibold">Parent Premium</span>
<span class="text-muted">— 2,90 € / parent / séjour</span>
</span>
<span class="vr d-none d-md-inline mx-1" style="opacity:.25;"></span>
<a href="{{ path('pack_annuel_partenaires') }}" class="pill d-inline-flex align-items-center gap-2 px-3 py-2 rounded-pill text-decoration-none" style="background: linear-gradient(135deg, #2fa7a3, #1e7e7a); color: white;">
<span aria-hidden="true">🎯</span>
<span class="fw-semibold">Pack Annuel</span>
<span class="opacity-75">— 990 € / an, tout inclus</span>
</a>
</div>
<!-- Micro-notes claires & "nudge" partenaire -->
<p class="text-center small text-muted mt-2 mb-0">
<i class="bi bi-info-circle me-1" aria-hidden="true"></i>
<span class="fw-semibold">Si la structure ne prend pas en charge l'option Parent Premium</span>, les accompagnateurs(trices) peuvent l'activer eux-mêmes
(2,90 € / parent / séjour) pour accéder à la plateforme complète, <strong>boîte vocale illimitée incluse</strong>.
</p>
<p class="text-center small mt-1 mb-0 text-primary-emphasis">
Recommandé : <span class="fw-semibold">prise en charge par la structure</span> → 100% de familles informées, expérience sans friction.
</p>
</div>
</section>
</div>
</section>
</div>
</section>
<!-- End Pricing-->
<!-- ======= Stats =======-->
<section class="stats__v3 section">
<div class="container">
<div class="row">
<div class="col-12">
<div class="d-flex flex-wrap content rounded-4" data-aos="fade-up" data-aos-delay="0">
<div class="rounded-borders">
<div class="rounded-border-1"></div>
<div class="rounded-border-2"></div>
<div class="rounded-border-3"></div>
</div>
<div class="col-12 col-sm-6 col-md-4 mb-4 mb-md-0 text-center" data-aos="fade-up" data-aos-delay="80">
<div class="stat-item">
<h3 class="fs-1 fw-bold">+<span class="purecounter" data-purecounter-start="0" data-purecounter-end="90" data-purecounter-duration="2">0</span><span>%</span></h3>
<p class="mb-0">des familles connectées dès J1
Invitation simple, lien sécurisé</p>
</div>
</div>
<div class="col-12 col-sm-6 col-md-4 mb-4 mb-md-0 text-center" data-aos="fade-up" data-aos-delay="200">
<div class="stat-item">
<h3 class="fs-1 fw-bold"> > <span class="purecounter" data-purecounter-start="0" data-purecounter-end="370" data-purecounter-duration="2">0</span><span>k+</span></h3>
<p class="mb-0">enfants suivis
Confiance des établissements & associations</p>
</div>
</div>
<div class="col-12 col-sm-6 col-md-4 mb-4 mb-md-0 text-center" data-aos="fade-up" data-aos-delay="300">
<div class="stat-item">
<h3 class="fs-1 fw-bold"><span class="purecounter" data-purecounter-start="0" data-purecounter-end="20" data-purecounter-duration="2">0</span><span>K+</span></h3>
<p class="mb-0">séjours accompagnés
Partout en France et à l'étranger</p>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
<!-- End Stats-->
<!-- ======= Services =======-->
<section class="section services__v3" id="souvenirs">
<div class="container">
<div class="row mb-5">
<div class="col-md-8 mx-auto text-center">
<span class="subtitle text-uppercase mb-2" data-aos="fade-up" data-aos-delay="0">Produits 5sur5</span>
<h2 class="mb-2" data-aos="fade-up" data-aos-delay="100">
Souvenirs premium, <span class="whitespace-nowrap">fabriqués en France</span> — livraison gratuite
</h2>
<p class="text-muted" data-aos="fade-up" data-aos-delay="150">
Offrez aux familles un souvenir durable du séjour. Qualité premium, expédition rapide, et
possibilité d'<strong>achat groupé –20%</strong> pour les établissements.
</p>
</div>
</div>
<div class="row g-4">
<!-- Carte 1 : Albums -->
<div class="col-md-6 col-lg-4" data-aos="fade-up" data-aos-delay="0">
<div class="service-card p-4 rounded-4 h-100 d-flex flex-column justify-content-between gap-5">
<div>
<figure class="product-visual" style="" width: 100%;
height: 200px; /* hauteur demandée */
display: flex;
align-items: center;
justify-content: center; /* image centrée */
background: rgba(47,167,163,.06);
border-radius: 16px;
overflow: hidden;
margin-bottom: 16px;>
<img style=" max-width: 100%;
max-height: 100%;
object-fit: contain; /* garde le ratio, pas de crop */
display: block;"
src="https://5sur5sejour.com/images/produit/LivreSouvenir5sur5-1.jpg"
alt="Album photo premium 5sur5"
width="400" height="300" loading="lazy" decoding="async"
sizes="(min-width:992px) 330px, 90vw">
</figure>
<h3 class="fs-5 mb-3">Album photo premium</h3>
<p class="mb-4">
Le souvenir incontournable du séjour. Qualité soignée, fabrication locale en France et
<strong>livraison gratuite</strong> pour les familles.
</p>
</div>
<a class="special-link d-inline-flex gap-2 align-items-center text-decoration-none" href="https://futur.5sur5sejour.fr/Accueil5sur5/album/Album%20photos" target="_blank">
<span class="icons"><i class="icon-1 bi bi-arrow-right-short"></i><i class="icon-2 bi bi-arrow-right-short"></i></span>
<span>Voir les modèles d'albums</span>
</a>
</div>
</div>
<!-- Carte 2 : Tirages & souvenirs -->
<div class="col-md-6 col-lg-4" data-aos="fade-up" data-aos-delay="200">
<div class="service-card p-4 rounded-4 h-100 d-flex flex-column justify-content-between gap-5">
<div>
<figure class="product-visual" style="" width: 100%;
height: 200px; /* hauteur demandée */
display: flex;
align-items: center;
justify-content: center; /* image centrée */
background: rgba(47,167,163,.06);
border-radius: 16px;
overflow: hidden;
margin-bottom: 16px;>
<img style=" max-width: 100%;
max-height: 100%;
object-fit: contain; /* garde le ratio, pas de crop */
display: block;"
src="https://5sur5sejour.com/images/produit/PochettePhoto5sur5-2.jpg"
alt="Album photo premium 5sur5"
width="400" height="300" loading="lazy" decoding="async"
sizes="(min-width:992px) 330px, 90vw">
</figure>
<h3 class="fs-5 mb-3">Tirages & produits souvenirs</h3>
<p class="mb-4">
Tirages photo et articles souvenirs 5sur5 pour prolonger l'expérience du séjour.
Qualité premium, <strong>livraison gratuite</strong>.
</p>
</div>
<a class="special-link d-inline-flex gap-2 align-items-center text-decoration-none" href="{{ path('boutique5sur5_Souvenir') }}">
<span class="icons"><i class="icon-1 bi bi-arrow-right-short"></i><i class="icon-2 bi bi-arrow-right-short"></i></span>
<span>Découvrir les souvenirs</span>
</a>
</div>
</div>
<!-- Carte 3 : Achat groupé -20% -->
<div class="col-md-6 col-lg-4" data-aos="fade-up" data-aos-delay="300">
<div class="service-card p-4 rounded-4 h-100 d-flex flex-column justify-content-between gap-5">
<div>
<figure class="product-visual" style="" width: 100%;
height: 200px; /* hauteur demandée */
display: flex;
align-items: center;
justify-content: center; /* image centrée */
background: rgba(47,167,163,.06);
border-radius: 16px;
overflow: hidden;
margin-bottom: 16px;>
<img style=" max-width: 100%;
max-height: 100%;
object-fit: contain; /* garde le ratio, pas de crop */
display: block;"
src="https://5sur5sejour.com/images/produit/Album5sur5-3.jpg"
alt="Album photo premium 5sur5"
width="400" height="300" loading="lazy" decoding="async"
sizes="(min-width:992px) 330px, 90vw">
</figure>
<h3 class="fs-5 mb-3">Achat groupé établissement –20%</h3>
<p class="mb-4">
Activez l'option "achat groupé" pour la classe/le séjour et bénéficiez de
<strong>–20% de réduction</strong> avec <strong>livraison gratuite</strong>. Simple à organiser, apprécié des familles.
</p>
</div>
<a data-bs-toggle="modal"
data-bs-target="#groupBuyLite"
data-action="group_buy_open" class="special-link d-inline-flex gap-2 align-items-center text-decoration-none" href="#achat-groupe">
<span class="icons"><i class="icon-1 bi bi-arrow-right-short"></i><i class="icon-2 bi bi-arrow-right-short"></i></span>
<span>Activer l'achat groupé</span>
</a>
</div>
</div>
</div>
<!-- Micro-barre de réassurance (discrète) -->
<div class="text-center text-muted small mt-4">
Fabriqué en France · Livraison gratuite · Qualité premium 5sur5 · Possibilité de <strong>partage des bénéfices</strong> pour les partenaires
</div>
</div>
</section>
<!-- ======= Contact =======-->
<section class="section contact__v2" id="contact">
<div class="container">
<div class="row mb-5">
<div class="col-md-6 col-lg-7 mx-auto text-center">
<span class="subtitle text-uppercase mb-3" data-aos="fade-up" data-aos-delay="0">Contact</span>
<h2 class="h2 fw-bold mb-3" data-aos="fade-up" data-aos-delay="0">Nous contacter</h2>
<p data-aos="fade-up" data-aos-delay="100">Nous sommes à votre écoute pour répondre à vos questions et vous aider à mieux comprendre nos services.</p>
</div>
</div>
<div class="row">
<div class="col-md-6">
<div class="d-flex gap-5 flex-column">
<div class="d-flex align-items-start gap-3" data-aos="fade-up" data-aos-delay="0">
<div class="icon d-block"><i class="bi bi-telephone"></i></div>
<span>
<span class="d-block">Téléphone</span>
<strong>05 36 28 29 30</strong>
</span>
</div>
<div class="d-flex align-items-start gap-3" data-aos="fade-up" data-aos-delay="100">
<div class="icon d-block"><i class="bi bi-send"></i></div>
<span>
<span class="d-block">Email</span>
<strong>contact@5sur5sejour.com</strong>
</span>
</div>
<div class="d-flex align-items-start gap-3" data-aos="fade-up" data-aos-delay="200">
<div class="icon d-block"><i class="bi bi-geo-alt"></i></div>
<span>
<span class="d-block">Adresse</span>
<address class="fw-bold">5sur5séjour<br>France</address>
</span>
</div>
</div>
</div>
<div class="col-md-6">
<div class="form-wrapper" data-aos="fade-up" data-aos-delay="300">
<div class="text-center mb-4">
<a href="#" class="btn btn-primary btn-lg" data-action="cta_expert" data-pack="contact">
Parler à un expert maintenant
</a>
<p class="text-muted mt-3 mb-0">Ou utilisez le formulaire ci-dessous pour nous laisser un message</p>
</div>
<form id="contactFormSection" action="{{ path('app_contact') }}" method="POST">
<div class="row gap-3 mb-3">
<div class="col-md-12">
<label class="mb-2" for="name">Nom</label>
<input class="form-control" id="name" type="text" name="name" required="">
</div>
<div class="col-md-12">
<label class="mb-2" for="email">Email</label>
<input class="form-control" id="email" type="email" name="email" required="">
</div>
</div>
<div class="row gap-3 mb-3">
<div class="col-md-12">
<label class="mb-2" for="subject">Sujet</label>
<input class="form-control" id="subject" type="text" name="subject">
</div>
</div>
<div class="row gap-3 gap-md-0 mb-3">
<div class="col-md-12">
<label class="mb-2" for="message">Message</label>
<textarea class="form-control" id="message" name="message" rows="5" required=""></textarea>
</div>
</div>
<button class="btn btn-primary fw-semibold" type="submit">Envoyer le message</button>
</form>
<div class="mt-3 d-none alert alert-success" id="successMessageSection">Message envoyé avec succès !</div>
<div class="mt-3 d-none alert alert-danger" id="errorMessageSection">Échec de l'envoi du message. Veuillez réessayer plus tard.</div>
</div>
</div>
</div>
</div>
</section>
<!-- End Contact-->
<!-- ======= Footer =======-->
<footer class="footer pt-5 pb-5">
<div class="container">
<div class="row mb-5 pb-4">
<div class="col-md-7">
<h2 class="fs-5">Rejoignez notre newsletter</h2>
<p>Restez informé de nos dernières actualités et offres — rejoignez notre newsletter aujourd'hui !</p>
</div>
<div class="col-md-5">
<form class="d-flex gap-2">
<input class="form-control" type="email" placeholder="Votre email" required="">
<button class="btn btn-primary fs-6" type="submit">S'abonner</button>
</form>
</div>
</div>
<div class="row justify-content-between mb-5 g-xl-5">
<div class="col-md-4 mb-5 mb-lg-0">
<h3 class="mb-3">À propos</h3>
<p class="mb-4">5sur5séjour est la plateforme de référence pour les séjours scolaires et les colonies de vacances, permettant aux familles de suivre leur enfant tout au long du séjour.</p>
</div>
<div class="col-md-7">
<div class="row g-2">
<div class="col-md-6 col-lg-4 mb-4 mb-lg-0">
<h3 class="mb-3">Entreprise</h3>
<ul class="list-unstyled">
<li><a href="{{path('sur5')}}">À propos</a></li>
<li><a href = "{{path('Mentions_legales')}}" >Mentions légales</a></li>
<li><a href = "{{path('Conditons_generales')}}" >Conditions générales</a></li>
<li><a href = "{{path('Politique')}}" >Politique de confidentialité</a></li>
</ul>
</div>
<div class="col-md-6 col-lg-4 mb-4 mb-lg-0">
<h3 class="mb-3">Comptes</h3>
<ul class="list-unstyled">
<li><a href="#jemeconnecte">S'inscrire</a></li>
<li><a href="#jemeconnecte">Se connecter</a></li>
</ul>
</div>
<div class="col-md-6 col-lg-4 mb-4 mb-lg-0 quick-contact">
<h3 class="mb-3">Contact</h3>
<p class="d-flex mb-3"><i class="bi bi-geo-alt-fill me-3"></i><span>5sur5séjour<br>France</span></p>
<a class="d-flex mb-3" href="mailto:contact@5sur5sejour.com"><i class="bi bi-envelope-fill me-3"></i><span>contact@5sur5sejour.com</span></a>
<a class="d-flex mb-3" href="tel://05 36 28 29 30"><i class="bi bi-telephone-fill me-3"></i><span>05 36 28 29 30</span></a>
<a class="d-flex mb-3" href="https://5sur5sejour.com"><i class="bi bi-globe me-3"></i><span>5sur5sejour.com</span></a>
</div>
</div>
</div>
</div>
<div class="row credits pt-3">
<div class="col-xl-8 text-center text-xl-start mb-3 mb-xl-0">
©
<script>document.write(new Date().getFullYear());</script> 5sur5séjour.
Tous droits réservés.
</div>
</div>
</div>
</footer>
<!-- End Footer-->
</main>
</div>
<!-- ======= Back to Top =======-->
<button id="back-to-top"><i class="bi bi-arrow-up-short"></i></button>
<!-- End Back to top-->
<!-- ======= Javascripts =======-->
<script src="{{ asset('Accueil/vendors/bootstrap/bootstrap.bundle.min.js') }}"></script>
<script src="{{ asset('Accueil/vendors/gsap/gsap.min.js') }}"></script>
<script src="{{ asset('Accueil/vendors/imagesloaded/imagesloaded.pkgd.min.js') }}"></script>
<script src="{{ asset('Accueil/vendors/isotope/isotope.pkgd.min.js') }}"></script>
<script src="{{ asset('Accueil/vendors/glightbox/glightbox.min.js') }}"></script>
<script src="{{ asset('Accueil/vendors/swiper/swiper-bundle.min.js') }}"></script>
<script src="{{ asset('Accueil/vendors/aos/aos.js') }}"></script>
<script src="{{ asset('Accueil/vendors/purecounter/purecounter.js') }}"></script>
<script src="{{ asset('Accueil/js/js_nova.js') }}"></script>
<script src="{{ asset('Accueil/js/test-animations.js') }}"></script>
<!-- Initialize AOS -->
<script>
document.addEventListener('DOMContentLoaded', function() {
console.log('DOM loaded, initializing AOS...');
// Initialize AOS
AOS.init({
duration: 1000,
easing: 'ease-in-out',
once: true,
mirror: false
});
console.log('AOS initialized');
// Initialize PureCounter
new PureCounter();
// Initialize GLightbox
const lightbox = GLightbox({
selector: '.glightbox'
});
// Debug: Check if arch-line images are loaded
const archLines = document.querySelectorAll('.arch-line');
console.log('Found arch-line elements:', archLines.length);
archLines.forEach((line, index) => {
console.log(`Arch-line ${index + 1}:`, line.src, line.complete ? 'loaded' : 'loading...');
});
// Smooth scrolling for anchor links
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
anchor.addEventListener('click', function (e) {
e.preventDefault();
const target = document.querySelector(this.getAttribute('href'));
if (target) {
target.scrollIntoView({
behavior: 'smooth',
block: 'start'
});
}
});
});
// Back to top button
const backToTop = document.getElementById('back-to-top');
if (backToTop) {
window.addEventListener('scroll', function() {
if (window.pageYOffset > 100) {
backToTop.style.display = 'block';
} else {
backToTop.style.display = 'none';
}
});
backToTop.addEventListener('click', function() {
window.scrollTo({
top: 0,
behavior: 'smooth'
});
});
}
// Animation des flèches pour l'ancienne section
function startArrowAnimation() {
const arrowImg = document.querySelector('.MyImgFirstPosition');
const lineImg = document.querySelector('.MyLineFirstPosition');
if (arrowImg && lineImg) {
// Démarrer l'animation après 1 seconde
setTimeout(() => {
arrowImg.classList.add('Myimg');
lineImg.classList.add('MyLine');
}, 1000);
}
}
// Démarrer l'animation des flèches
startArrowAnimation();
// Slider simple (sans Owl Carousel pour l'instant)
let currentSlide = 0;
const slides = document.querySelectorAll('.single_slider');
function showSlide(index) {
slides.forEach((slide, i) => {
slide.style.display = i === index ? 'flex' : 'none';
});
}
function nextSlide() {
currentSlide = (currentSlide + 1) % slides.length;
showSlide(currentSlide);
}
// Initialiser le slider
if (slides.length > 0) {
showSlide(0);
// Changer de slide toutes les 5 secondes
setInterval(nextSlide, 5000);
}
// Nouveau slider functionality
let currentHeroSlide = 0;
const heroSlides = [
{
title: "Révolutionnez la Communication",
description: "Partagez vos aventures avec les familles en toute sécurité grâce à notre plateforme, agrémentée de photos, de vidéos et messages.",
image: "{{ asset('Accueil/imagesAccueil/slider/child-laughing.jpg') }}"
},
{
title: "La plateforme qui rassure les familles",
description: "Partagez vos souvenirs en toute sécurité avec des photos, vidéos et messages vocaux.",
image: "{{ asset('Accueil/imagesAccueil/secure.jpg') }}"
},
{
title: "Messages vocaux et photos",
description: "Restez connecté avec votre enfant tout au long du séjour grâce à notre technologie sécurisée.",
image: "{{ asset('Accueil/imagesAccueil/slider/bg-slider.svg') }}"
}
];
function changeSlide(direction) {
currentHeroSlide = (currentHeroSlide + direction + heroSlides.length) % heroSlides.length;
updateHeroSlider();
}
function updateHeroSlider() {
const titleElement = document.querySelector('.hero-slider-title');
const descriptionElement = document.querySelector('.hero-slider-description');
const imageElement = document.querySelector('.hero-slider-image img');
if (titleElement && descriptionElement && imageElement) {
// Animation de transition
titleElement.style.opacity = '0';
descriptionElement.style.opacity = '0';
setTimeout(() => {
titleElement.textContent = heroSlides[currentHeroSlide].title;
descriptionElement.textContent = heroSlides[currentHeroSlide].description;
imageElement.src = heroSlides[currentHeroSlide].image;
titleElement.style.opacity = '1';
descriptionElement.style.opacity = '1';
}, 300);
}
}
// Auto-play pour le nouveau slider
setInterval(() => {
changeSlide(1);
}, 6000);
// Gestion du formulaire de contact de la section contact
const contactFormSection = document.getElementById('contactFormSection');
const successMessageSection = document.getElementById('successMessageSection');
const errorMessageSection = document.getElementById('errorMessageSection');
if (contactFormSection) {
contactFormSection.addEventListener('submit', function(e) {
e.preventDefault();
// Masquer les messages précédents
successMessageSection.classList.add('d-none');
errorMessageSection.classList.add('d-none');
// Désactiver le bouton pendant l'envoi
const submitButton = contactFormSection.querySelector('button[type="submit"]');
const originalText = submitButton.textContent;
submitButton.textContent = 'Envoi en cours...';
submitButton.disabled = true;
// Récupérer les données du formulaire
const formData = new FormData(contactFormSection);
// Envoyer la requête AJAX
fetch(contactFormSection.action, {
method: 'POST',
body: formData,
headers: {
'X-Requested-With': 'XMLHttpRequest'
}
})
.then(response => response.json())
.then(data => {
if (data.success) {
// Afficher le message de succès
successMessageSection.textContent = data.message;
successMessageSection.classList.remove('d-none');
// Réinitialiser le formulaire
contactFormSection.reset();
} else {
// Afficher le message d'erreur
errorMessageSection.textContent = data.message;
errorMessageSection.classList.remove('d-none');
}
})
.catch(error => {
console.error('Erreur:', error);
errorMessageSection.textContent = 'Une erreur est survenue lors de l\'envoi du message. Veuillez réessayer plus tard.';
errorMessageSection.classList.remove('d-none');
})
.finally(() => {
// Réactiver le bouton
submitButton.textContent = originalText;
submitButton.disabled = false;
});
});
}
});
</script>
<!-- End JavaScripts-->
<!-- MODAL CONNEXION -->
<div class="modal fade" id="loginModal" tabindex="-1" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered modal-lg">
<div class="modal-content rounded-4">
<div class="modal-header border-0">
<h5 class="modal-title fw-bold">Accéder à mon espace de séjour </h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Fermer"></button>
</div>
<div class="modal-body p-4">
<div class="row g-4 align-items-center">
<div class="col-lg-5 text-center border-end">
<img src="/images/Accompagnateur/LogoEspaceAccom.svg" alt="Espace accompagnateur" class="img-fluid mb-3" style="max-height: 120px;">
<p class="small text-muted mb-0">
Retrouvez votre séjour, publiez vos contenus et rassurez les familles en temps réel.
</p>
</div>
<div class="col-lg-7">
<div class="titleAutre mb-3">Vous êtes accompagnateur et disposez déjà d'un identifiant et d'un mot de passe.</div>
<form method="post" class="fomru" action="{{ path('app_back_Acommpa') }}">
<div class="form-group d-grid gap-3">
<input type="text" value="" name="email" id="modalInputEmail" class="form-control" placeholder=" Code séjour de l'accompagnateur * ">
<input type="password" name="password" id="modalInputPassword" class="form-control" placeholder="mot de passe fourni à l'organisme * ">
<input type="hidden" name="_csrf_token" value="{{ csrf_token('authenticate') }}">
<div class="description"><a href="#" data-bs-toggle="modal" data-bs-target="#mdpoblier" style="color:#f09e7a;">Vous avez oublié votre mot de passe</a></div>
</div>
<div class="d-grid mt-4">
<button class="btn btn-primary rounded-3" type="submit">Je me connecte</button>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- MODAL MOT DE PASSE OUBLIÉ -->
<div class="modal fade" id="mdpoblier" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content" style="border-radius: 0px;top: 50px;width: 55%;margin: auto;min-width: 270px;">
<div class="modal-header">
<button type="button" class="close" data-bs-dismiss="modal" aria-label="Close">
<img src="{{ asset('images/Groupe_526.svg')}}">
</button>
</div>
<div class="modal-body" style="text-align:center">
<h5 class="modal-title" id="exampleModalLabel" style="margin-left:15px; margin-bottom: 15px">
<img class="imageLogo2" style="width: 58% !important;" src="{{ asset('Accueil/imagesAccueil/logoHeader.svg')}}">
</h5>
<div class="row no-margin" style="padding-bottom: 40px;">
<div class="col-md-12 col-sm-12 col-xs-12 descTitre">
<strong>Vous avez oublié votre mot de passe ? Contactez notre équipe 5sur5sejour au 05 36 28 29 30.</strong>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- MODAL CONNEXION PARTENAIRE -->
<div class="modal fade" id="partnerLoginModal" tabindex="-1" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered modal-lg">
<div class="modal-content rounded-4">
<div class="modal-header border-0">
<h5 class="modal-title fw-bold">Espace Partenaire - Connexion</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Fermer"></button>
</div>
<div class="modal-body p-4">
<div class="row g-4 align-items-center">
<div class="col-lg-5 text-center border-end">
<img src="{{ asset('Accueil/imagesAccueil/espcPart.svg') }}" alt="Espace partenaire" class="img-fluid mb-3" style="max-height: 120px;">
<p class="small text-muted mb-0">
Créez et gérez tous vos séjours depuis un espace dédié, avec un service client sur mesure et des outils pensés pour vous.
</p>
</div>
<div class="col-lg-7">
<div class="titleAutre mb-3">Vous êtes partenaire</div>
<div class="sous-titrecnx mb-3">Bienvenue dans votre espace 5 sur 5 séjour</div>
<div class="descriptioncnx mb-4">Entrez votre identifiant et votre mot de passe afin d'entrer dans votre plateforme d'administration</div>
<form method="post" action="{{ path('app_login_back_Partenaire') }}">
<div class="form-group d-grid gap-3">
<input type="text" name="email" id="partnerInputEmail" class="form-control" placeholder="Mail partenaire" value="">
<input type="password" name="password" id="partnerInputPassword" class="form-control" placeholder="Mot de passe">
<input type="hidden" name="_csrf_token" value="{{ csrf_token('authenticate') }}">
<div class="description">
<a href="/forgotPasspatenaire" style="color:#f09e7a;">Vous avez oublié votre mot de passe</a>
</div>
</div>
<div class="d-grid mt-4">
<button class="btn btn-primary rounded-3" type="submit">Je me connecte</button>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Modale ultra-légère -->
<div class="modal fade" id="groupBuyLite" tabindex="-1" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content rounded-4">
<div class="modal-header">
<h5 class="modal-title">Achat groupé — jusqu’à −20%</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Fermer"></button>
</div>
<div class="modal-body">
<ul class="small text-muted ps-3">
<li>Remise automatique selon le volume (ex. −10% dès 5, −15% dès 10, −20% dès 20).</li>
<li>Applicable sur albums, tirages et packs.</li>
<li>La structure peut prendre en charge Parent Premium (tarif préférentiel, voix illimitée incluse).</li>
</ul>
<div class="alert alert-info small mb-0">
<i class="bi bi-info-circle me-1"></i>
La remise sera affichée sur la boutique. Munissez-vous du <strong>code séjour</strong> si demandé.
</div>
</div>
<div class="modal-footer d-block">
<div class="d-grid d-sm-flex gap-2">
<!-- Redirection directe (aucun champ) -->
<a class="btn btn-primary"
href="/boutique?groupbuy=1&utm_source=site&utm_medium=modal&utm_campaign=group_buy"
data-action="group_buy_continue">
Aller à la boutique
</a>
<button class="btn btn-outline-secondary" data-bs-dismiss="modal">Plus tard</button>
</div>
<p class="small text-muted mt-2 mb-0">
Besoin d’aide ? <a href="#" data-action="cta_expert">Parler à un expert</a>
</p>
</div>
</div>
</div>
</div>
<!-- MODALE CHOIX DE PAIEMENT -->
<div class="modal fade" id="checkoutChoiceModal" tabindex="-1" aria-labelledby="checkoutChoiceModalLabel" aria-hidden="true" data-bs-backdrop="static" data-bs-keyboard="false">
<div class="modal-dialog modal-lg modal-dialog-centered">
<div class="modal-content">
<div class="modal-header border-0 pb-0">
<h5 class="modal-title w-100 text-center" id="checkoutChoiceModalLabel">
<i class="bi bi-credit-card-2-front me-2"></i>
Comment souhaitez-vous procéder ?
</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body px-5 py-4">
<!-- Récapitulatif du pack sélectionné -->
<div class="alert alert-primary border-primary mb-4 d-flex align-items-center justify-content-between" role="alert" id="packSummary" style="display: none !important;">
<div class="d-flex align-items-center gap-3">
<i class="bi bi-box-seam fs-3"></i>
<div>
<div class="fw-bold mb-1">Pack sélectionné</div>
<div class="h5 mb-0" id="packName">—</div>
</div>
</div>
<div class="text-end">
<div class="text-muted small">Montant annuel</div>
<div class="h4 mb-0 fw-bold" id="packPrice">—</div>
</div>
</div>
<p class="text-center text-muted mb-4">Choisissez le mode de souscription adapté à votre structure</p>
<div class="row g-4">
<!-- Card 1 — Souscription en ligne -->
<div class="col-lg-4 col-md-6">
<div class="card h-100 border-2 checkout-choice-card" data-choice="online" tabindex="0" role="button">
<div class="card-body d-flex flex-column">
<div class="mb-3">
<span class="badge bg-success text-white mb-2">Recommandé</span>
<h4 class="card-title mb-2">Souscrire en ligne</h4>
<p class="text-muted small">CB / SEPA — activation en 24 h. Facturation annuelle.</p>
</div>
<ul class="list-unstyled mb-4 flex-grow-1">
<li class="mb-2"><i class="bi bi-check-circle-fill text-success me-2"></i>Stripe Checkout sécurisé</li>
<li class="mb-2"><i class="bi bi-check-circle-fill text-success me-2"></i>Facture et mandat SEPA automatiques</li>
<li class="mb-2"><i class="bi bi-check-circle-fill text-success me-2"></i>Planifier l'onboarding (30 min)</li>
</ul>
<button class="btn btn-primary w-100" data-cta="checkout_online" data-loc="modal">
<i class="bi bi-credit-card me-2"></i>Payer & activer
</button>
</div>
</div>
</div>
<!-- Card 2 — Virement bancaire -->
<div class="col-lg-4 col-md-6">
<div class="card h-100 border-2 checkout-choice-card" data-choice="bank_transfer" tabindex="0" role="button">
<div class="card-body d-flex flex-column">
<div class="mb-3">
<span class="badge bg-info text-white mb-2">Économique</span>
<h4 class="card-title mb-2">Virement bancaire</h4>
<p class="text-muted small">Paiement par virement — activation sous 48h après réception.</p>
</div>
<ul class="list-unstyled mb-4 flex-grow-1">
<li class="mb-2"><i class="bi bi-check-circle-fill text-info me-2"></i>RIB fourni automatiquement</li>
<li class="mb-2"><i class="bi bi-check-circle-fill text-info me-2"></i>Facture proforma envoyée</li>
<li class="mb-2"><i class="bi bi-check-circle-fill text-info me-2"></i>Activation après réception</li>
</ul>
<button type="button" class="btn btn-outline-info w-100" data-bs-toggle="modal" data-bs-target="#bankTransferModal" data-bs-dismiss="modal">
<i class="bi bi-bank me-2"></i>Demander le RIB
</button>
</div>
</div>
</div>
<!-- Card 3 — Devis / Bon de commande -->
<div class="col-lg-4 col-md-6">
<div class="card h-100 border-2 checkout-choice-card" data-choice="quote" tabindex="0" role="button">
<div class="card-body d-flex flex-column">
<div class="mb-3">
<h4 class="card-title mb-2 mt-4">Demander un devis / BC</h4>
<p class="text-muted small">Adapté écoles publiques, collectivités, associations.</p>
</div>
<ul class="list-unstyled mb-4 flex-grow-1">
<li class="mb-2"><i class="bi bi-check-circle-fill text-primary me-2"></i>Devis PDF instantané</li>
<li class="mb-2"><i class="bi bi-check-circle-fill text-primary me-2"></i>DPA/RGPD, RIB, CGV joints</li>
<li class="mb-2"><i class="bi bi-check-circle-fill text-primary me-2"></i>E‑signature & upload du BC</li>
</ul>
<button class="btn btn-outline-primary w-100" data-cta="checkout_quote" data-loc="modal">
<i class="bi bi-file-earmark-text me-2"></i>Recevoir le devis
</button>
</div>
</div>
</div>
</div>
</div>
<div class="modal-footer border-0 pt-0">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Retour</button>
</div>
</div>
</div>
</div>
<!-- MODALE VIREMENT BANCAIRE (RIB) -->
<div class="modal fade" id="bankTransferModal" tabindex="-1" aria-labelledby="bankTransferModalLabel" aria-hidden="true" data-bs-backdrop="static" data-bs-keyboard="false">
<div class="modal-dialog modal-xl modal-dialog-centered">
<div class="modal-content">
<div class="modal-header border-0 pb-2">
<h5 class="modal-title w-100 text-center" id="bankTransferModalLabel">
<i class="bi bi-bank2 me-2 text-info"></i>
Virement bancaire — RIB instantané
</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body p-4">
<div class="row">
<!-- Colonne formulaire -->
<div class="col-lg-5">
<div class="card border-0 bg-light h-100">
<div class="card-body p-4">
<h6 class="text-info mb-3">
<i class="bi bi-person-circle me-2"></i>Vos informations
</h6>
<p class="text-muted small mb-4">Nous vous enverrons le RIB et la facture proforma par email</p>
<form id="rib-form" method="post" action="{{ path('bank_transfer_request') }}" data-event="rib_request_submit">
<div class="mb-4">
<label for="rib_fullname" class="form-label fw-semibold">
<i class="bi bi-person me-1"></i>Nom & prénom *
</label>
<input id="rib_fullname" name="full_name" class="form-control form-control-lg" required
placeholder="Ex: Marie Dupont" autocomplete="name">
</div>
<div class="mb-4">
<label for="rib_email" class="form-label fw-semibold">
<i class="bi bi-envelope me-1"></i>Email de facturation *
</label>
<input id="rib_email" name="billing_email" type="email" class="form-control form-control-lg" required
placeholder="Ex: comptabilite@ecole.fr" autocomplete="email">
</div>
<div class="mb-4">
<label for="rib_company" class="form-label fw-semibold">
<i class="bi bi-building me-1"></i>Nom de la structure
</label>
<input id="rib_company" name="company" class="form-control form-control-lg"
placeholder="Ex: École Primaire Jean Moulin" autocomplete="organization">
</div>
<!-- Contexte pack (sera rempli dynamiquement) -->
<input type="hidden" name="pack_id" id="rib_pack_id" value="">
<div class="d-grid">
<button class="btn btn-info btn-lg py-3" id="rib-submit" type="submit" data-cta="rib_request" data-loc="wire">
<i class="bi bi-bank me-2"></i>Obtenir le RIB instantanément
</button>
</div>
<p class="text-muted text-center small mt-3 mb-0">
<i class="bi bi-shield-check me-1"></i>
Sécurisé • Données hébergées en France • Conforme RGPD
</p>
</form>
</div>
</div>
</div>
<!-- Colonne RIB -->
<div class="col-lg-7">
<div id="rib-panel" class="card border-info" style="display: none;">
<div class="card-header bg-info text-white">
<h6 class="mb-0">
<i class="bi bi-bank me-2"></i>Coordonnées bancaires 5sur5séjour
</h6>
</div>
<div class="card-body p-4">
<div class="row g-4">
<div class="col-md-6">
<div class="border-bottom pb-2 mb-2">
<div class="text-muted small text-uppercase fw-bold">Titulaire du compte</div>
<div class="h6 mb-0">S.A.S. TRUST CONSEILS</div>
</div>
</div>
<div class="col-md-6">
<div class="border-bottom pb-2 mb-2">
<div class="text-muted small text-uppercase fw-bold">Banque</div>
<div class="h6 mb-0">CR CENTRE EST</div>
</div>
</div>
<div class="col-12">
<div class="border-bottom pb-2 mb-2">
<div class="text-muted small text-uppercase fw-bold">IBAN</div>
<div class="d-flex align-items-center gap-3">
<code id="iban-text" class="user-select-all h6 mb-0 text-primary">FR76 1780 6009 6304 1603 4748 776</code>
<button type="button" class="btn btn-outline-primary" data-cta="copy_iban" aria-label="Copier l'IBAN" onclick="copyToClipboard('iban-text', this)">
<i class="bi bi-clipboard me-1"></i>Copier
</button>
</div>
</div>
</div>
<div class="col-md-6">
<div class="border-bottom pb-2 mb-2">
<div class="text-muted small text-uppercase fw-bold">Code BIC</div>
<div class="d-flex align-items-center gap-3">
<code id="bic-text" class="user-select-all h6 mb-0 text-primary">AGRIFRPP878</code>
<button type="button" class="btn btn-outline-primary btn-sm" data-cta="copy_bic" aria-label="Copier le BIC" onclick="copyToClipboard('bic-text', this)">
<i class="bi bi-clipboard"></i>
</button>
</div>
</div>
</div>
<div class="col-md-6">
<div class="border-bottom pb-2 mb-2">
<div class="text-muted small text-uppercase fw-bold">Référence à indiquer</div>
<div class="h6 mb-0 text-success">PACK-PRO-<span id="rib-ref-date"></span></div>
</div>
</div>
</div>
<div class="alert alert-success mt-4" role="alert">
<i class="bi bi-check-circle me-2"></i>
<strong>Email envoyé !</strong> Vous recevrez le RIB et la facture proforma à <span id="rib-email-echo" class="fw-bold">votre adresse</span>.
</div>
<div class="d-flex flex-wrap gap-3 mt-4">
<a class="btn btn-primary" href="#" id="proforma-download-link" data-cta="download_proforma">
<i class="bi bi-download me-2"></i>Télécharger la facture proforma
</a>
<a class="btn btn-outline-secondary" href="https://calendly.com/5sur5sejour/demo" target="_blank" data-cta="book_call">
<i class="bi bi-telephone me-2"></i>Planifier un appel
</a>
</div>
<div class="text-muted small mt-3">
<i class="bi bi-info-circle me-1"></i>
Activation de votre compte sous 48h après réception du virement.
</div>
</div>
</div>
<!-- Message d'attente -->
<div id="rib-waiting" class="text-center p-5">
<i class="bi bi-bank2 text-muted" style="font-size: 4rem;"></i>
<h5 class="text-muted mt-3">Remplissez le formulaire pour obtenir le RIB</h5>
<p class="text-muted">Vos coordonnées bancaires apparaîtront ici instantanément</p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
console.log('✅ Page Accueil - Modale checkout initialisée');
// Mapping des packs
const packLabels = {
'access': 'Pack Accès',
'serenite': 'Pack Sérénité',
'pro_illimite': 'Pack Pro Illimité ✨'
};
// Récupérer le pack sélectionné lors de l'ouverture de la modale
const checkoutModal = document.getElementById('checkoutChoiceModal');
const bankTransferModal = document.getElementById('bankTransferModal');
let selectedPack = null;
let selectedPackPrice = null;
if (checkoutModal) {
checkoutModal.addEventListener('show.bs.modal', function(event) {
const button = event.relatedTarget;
selectedPack = button.getAttribute('data-pack');
selectedPackPrice = button.getAttribute('data-pack-price');
console.log('📦 Pack sélectionné:', selectedPack, '- Prix:', selectedPackPrice + '€');
// Afficher le récapitulatif du pack
const packSummary = document.getElementById('packSummary');
const packName = document.getElementById('packName');
const packPrice = document.getElementById('packPrice');
if (packSummary && packName && packPrice) {
packName.textContent = packLabels[selectedPack] || selectedPack;
packPrice.textContent = selectedPackPrice + ' € / an';
packSummary.style.display = 'flex';
}
});
}
// Transférer le pack sélectionné au modal RIB
if (bankTransferModal) {
bankTransferModal.addEventListener('show.bs.modal', function(event) {
console.log('📦 Ouverture modal RIB avec pack:', selectedPack);
// Remplir le champ caché avec le pack sélectionné
const ribPackIdField = document.getElementById('rib_pack_id');
if (ribPackIdField && selectedPack) {
ribPackIdField.value = selectedPack;
}
});
}
// =========================
// GESTION DU FORMULAIRE RIB
// =========================
const ribForm = document.getElementById('rib-form');
const ribSubmit = document.getElementById('rib-submit');
const ribPanel = document.getElementById('rib-panel');
const ribWaiting = document.getElementById('rib-waiting');
const ribEmailEcho = document.getElementById('rib-email-echo');
const ribRefDate = document.getElementById('rib-ref-date');
const proformaDownloadLink = document.getElementById('proforma-download-link');
if (ribForm && ribSubmit) {
// Set current date for reference
if (ribRefDate) {
const now = new Date();
const dateStr = now.getFullYear().toString().slice(-2) +
(now.getMonth() + 1).toString().padStart(2, '0') +
now.getDate().toString().padStart(2, '0');
ribRefDate.textContent = dateStr;
}
ribForm.addEventListener('submit', function(e) {
e.preventDefault();
// Get form data
const formData = new FormData(ribForm);
const fullName = formData.get('full_name');
const billingEmail = formData.get('billing_email');
const company = formData.get('company');
const packId = formData.get('pack_id');
// Validation
if (!fullName || fullName.trim().length < 2) {
showFieldError('rib_fullname', 'Veuillez saisir votre nom complet');
return;
}
if (!billingEmail || !isValidEmail(billingEmail)) {
showFieldError('rib_email', 'Veuillez saisir une adresse email valide');
return;
}
// Clear any previous errors
clearFieldErrors();
// Show loading state
ribSubmit.disabled = true;
ribSubmit.innerHTML = '<i class="bi bi-hourglass-split me-2"></i>Envoi en cours...';
// Send to backend
fetch('{{ path("bank_transfer_request") }}', {
method: 'POST',
body: formData
})
.then(res => res.json())
.then(data => {
if (data.success) {
showRibSuccess(billingEmail, fullName, company, data.requestNumber);
} else {
throw new Error(data.message || 'Erreur lors de l\'envoi');
}
})
.catch(err => {
alert('❌ Erreur : ' + err.message);
ribSubmit.disabled = false;
ribSubmit.innerHTML = '<i class="bi bi-bank me-2"></i>Obtenir le RIB instantanément';
});
});
}
function showFieldError(fieldId, message) {
const field = document.getElementById(fieldId);
if (field) {
field.classList.add('is-invalid');
// Remove existing error message
const existingError = field.parentNode.querySelector('.invalid-feedback');
if (existingError) {
existingError.remove();
}
// Add new error message
const errorDiv = document.createElement('div');
errorDiv.className = 'invalid-feedback';
errorDiv.textContent = message;
field.parentNode.appendChild(errorDiv);
}
}
function clearFieldErrors() {
const invalidFields = document.querySelectorAll('.is-invalid');
invalidFields.forEach(field => {
field.classList.remove('is-invalid');
});
const errorMessages = document.querySelectorAll('.invalid-feedback');
errorMessages.forEach(error => {
error.remove();
});
}
function showRibSuccess(email, name, company, requestNumber) {
// Hide waiting message
if (ribWaiting) {
ribWaiting.style.display = 'none';
}
// Show RIB panel
if (ribPanel) {
ribPanel.style.display = 'block';
}
// Update email echo
if (ribEmailEcho) {
ribEmailEcho.textContent = email;
}
// Generate proforma download link
if (proformaDownloadLink && requestNumber) {
proformaDownloadLink.href = '/proforma-download/' + requestNumber;
}
// Scroll to RIB panel
if (ribPanel) {
ribPanel.scrollIntoView({ behavior: 'smooth', block: 'start' });
}
// Reset button
if (ribSubmit) {
ribSubmit.disabled = false;
ribSubmit.innerHTML = '<i class="bi bi-bank me-2"></i>Obtenir le RIB instantanément';
}
console.log('✅ RIB request submitted:', { name, email, company });
}
function isValidEmail(email) {
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
return emailRegex.test(email);
}
// Gérer le clic sur "Payer & activer" (Stripe)
document.querySelector('[data-cta="checkout_online"]')?.addEventListener('click', function() {
alert('Paiement Stripe en cours de développement\n\nPack : ' + selectedPack + '\nPrix : ' + selectedPackPrice + '€');
});
// Gérer le clic sur "Recevoir le devis"
document.querySelector('[data-cta="checkout_quote"]')?.addEventListener('click', function() {
alert('Génération de devis en cours de développement\n\nPack : ' + selectedPack + '\nPrix : ' + selectedPackPrice + '€');
});
});
// Copy to clipboard function
function copyToClipboard(elementId, button) {
const element = document.getElementById(elementId);
if (element) {
const text = element.textContent;
navigator.clipboard.writeText(text).then(() => {
// Show success feedback
const originalText = button.innerHTML;
button.innerHTML = '<i class="bi bi-check"></i> Copié !';
button.classList.remove('btn-outline-primary');
button.classList.add('btn-success');
setTimeout(() => {
button.innerHTML = originalText;
button.classList.remove('btn-success');
button.classList.add('btn-outline-primary');
}, 2000);
}).catch(err => {
console.error('Erreur copie:', err);
alert('Impossible de copier. Copiez manuellement : ' + text);
});
}
}
</script>
</body>
</html>