{% extends 'vitrine/base.html.twig' %}
{% import 'vitrine/macros/svg_illustration_macros.twig' as svg %}
{% block title "Réserver" %}
{% block description %}{% trans %}Réservez votre moment de détente{% endtrans %}{% endblock %}
{% block stylesheets %}
{{ parent() }}
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/swiper@11/swiper-bundle.min.css" />
{{ encore_entry_link_tags('tunnel') }}
{% endblock %}
{% block javascripts %}
{{ parent() }}
{{ encore_entry_script_tags('tunnel') }}
<script src="https://unpkg.com/swiper/swiper-bundle.min.js"></script>
<script type="text/javascript" src="https://api.payplug.com/js/1/form.latest.js"></script>
<script async defer src="https://api.mapbox.com/mapbox-assembly/v1.5.1/assembly.js"></script>
<script id="search-js" defer="" src="https://api.mapbox.com/search-js/v1.0.0-beta.21/web.js"></script>
<script>
const ACCESS_TOKEN = '{{ mapbox_access_token }}';
const COUNTRIES = '{{ mapbox_countries }}'.split(',');
const script = document.getElementById('search-js');
script.onload = () => {
const collection = mapboxsearch.autofill({
accessToken: ACCESS_TOKEN,
options: { COUNTRIES }
});
};
</script>
{% include 'form/components/js-translations.html.twig' %}
{% endblock %}
{% block main %}
<div id="background-override">
<video data-step="start" class="background-video" src="https://i.gyazo.com/d9d0bd5636691cfdf72d4db0a4132c09.mp4" muted playsinline autoplay loop></video>
<div data-step="second-step" class="tunnel-hidden background-image swiper-full">
<div class="swiper swiper-bath">
<div class="swiper-wrapper">
<div class="swiper-slide">
<img src="https://i.gyazo.com/b7d32e07063d6a51fc24bfe3b70da6ca.jpg" alt="Baignoire 1">
</div>
<div class="swiper-slide">
<img src="https://i.gyazo.com/b7d32e07063d6a51fc24bfe3b70da6ca.jpg" alt="Baignoire 1">
</div>
<div class="swiper-slide">
<img src="https://i.gyazo.com/b7d32e07063d6a51fc24bfe3b70da6ca.jpg" alt="Baignoire 3">
</div>
</div>
<div class="swiper-pagination"></div>
</div>
</div>
<div data-step="fourth-step" class="tunnel-hidden background-image swiper-full">
<div class="swiper swiper-extra">
<div class="swiper-wrapper">
<div class="swiper-slide">
<img src="https://i.gyazo.com/84c7b90fc6ff6c31478eae19f38bd03d.jpg" alt="Extra 1">
</div>
<div class="swiper-slide">
<img src="https://i.gyazo.com/84c7b90fc6ff6c31478eae19f38bd03d.jpg" alt="Extra 2">
</div>
<div class="swiper-slide">
<img src="https://i.gyazo.com/84c7b90fc6ff6c31478eae19f38bd03d.jpg" alt="Extra 3">
</div>
</div>
<div class="swiper-pagination"></div>
</div>
</div>
</div>
{% form_theme form 'form/theme_tunnel.html.twig' %}
{{ form_start(form, { 'attr': {
'class': 'to-submit w-full',
'data-entity-id': edit is defined and reservationId is defined ? reservationId : null
}}) }}
<div class="not-animate-childs md:pt-32 pt-24 justify-items-center">
<div id="progress-bar" class="progress-bar-container tunnel-hidden" style="{{ code is defined ? "display: none" : "" }}">
<p class="progress-bar-steps">
{% trans %}Étape{% endtrans %} <span id="step-count">1</span> {% trans %}sur{% endtrans %} 6
</p>
<div class="progress-bar">
<div class="progress-bar-fill"></div>
</div>
</div>
<section id="start" class="tunnel-hidden content-column-center-48 tunnel-step">
{% if code is defined %}
<h2 class="title text-center mt-24 text-4xl">
{% trans %}Votre carte cadeau{% endtrans %}
</h2>
<div class="recapitulatif-container content-column-24 max-w-400">
<div class="content-column-8">
<h3>
{% if token.offer == 90 %}
La Grande Bulle (90 min)
{% else %}
La Bulle (60 min)
{% endif %}
</h3>
<p class="text-opacity-70">
{{ token.nbParticipants }} {% trans %}personne(s){% endtrans %}
· {{ token.solo + token.duo }} {% trans %}baignoire(s){% endtrans %}
</p>
</div>
{% if services is defined and services|length > 0 %}
<div class="content-column-8">
<h4>{% trans %}Extras inclus{% endtrans %}</h4>
{% for service in services %}
<p class="text-opacity-70">{{ service.name }} × {{ service.quantity }}</p>
{% endfor %}
</div>
{% endif %}
<div class="flex-between w-full">
<p><b>{% trans %}Valeur{% endtrans %}</b></p>
<p><b>{{ priceOffered }}€</b></p>
</div>
</div>
<div class="tunnel-footer m-auto content-column-8">
{% include "tunnel/components/primary-button.html.twig" with {
'action': 'goToDateStep', 'label': 'Choisir la date'
} %}
{% include "tunnel/components/secondary-button.html.twig" with {
'action': 'goToFirstStep', 'label': 'Modifier l\'offre'
} %}
</div>
{% else %}
<h2 class="title text-center mt-24 text-4xl">
{% trans %}Offrez-vous un moment de détente avec vos proches{% endtrans %}
</h2>
<div class="tunnel-footer m-auto">
{% include "tunnel/components/primary-button.html.twig" with {'action': 'nextStep', 'label': 'Commencer' } %}
<a href="{{ path('reservation_carte_cadeau_tunnel') }}">
<button class="rounded-btn-secondary btn" type="button">
<span>{{ "J'ai une carte cadeau"|trans }}</span>
</button>
</a>
</div>
{% endif %}
</section>
<section id="first-step" class="tunnel-hidden tunnel-step">
<div class="content-column-center-48 ">
<div class="content-column-8-center">
<h2 class="title text-center">
{% trans %}Combien serez-vous ?{% endtrans %}
</h2>
<p class="text-opacity-70 text-center">
{% trans %}Vous profiterez de votre espace en toute intimité, quel que soit votre nombre.{% endtrans %}
</p>
</div>
<div class="my-6">
{{ form_widget(form.nbParticipants) }}
</div>
<div class="tunnel-footer">
<div class="infoContainer w-full text-center" style="display: none">
<p class="stepInfo">
</p>
</div>
{% include "tunnel/components/primary-button.html.twig" with {'action': 'nextStep', 'label': 'Suivant' } %}
{% include "tunnel/components/secondary-button.html.twig" with {'action': 'goToPrivatisation', 'label': 'Privatiser le spa' } %}
</div>
</div>
</section>
<section id="second-step" class="tunnel-hidden tunnel-step">
<div class="swiper-button-prev-bath swiper-button-prev"></div>
<div class="swiper-button-next-bath swiper-button-next"></div>
<div class="content-column-center-48 ">
<div class="content-column-8-center">
<h2 class="title text-center">
{% trans %}Combien de baignoires voulez-vous utiliser ?{% endtrans %}
</h2>
<p class="text-opacity-70 text-center">
{% trans %}Nos baignoires sont conçues pour accueillir 2 personnes confortablement.{% endtrans %}
</p>
</div>
<div class="max-w-400">
{{ form_widget(form.nbBath) }}
</div>
<div class="tunnel-footer">
<div class="totalDifferencePriceContainer w-full flex-between" style="display: none">
<p class="small-text-opacity-70">
{% trans %}Supplément à régler{% endtrans %}
</p>
<p>
<b>+</b><b class="totalDifferencePrice"></b>
</p>
</div>
<div class="totalContainer w-full flex-between" style="display: none">
<p class="small-text-opacity-70">
{% trans %}Total pour{% endtrans %} <span class="totalPerson">1</span> {% trans %}personne(s){% endtrans %}
</p>
<p>
<b class="totalPrice"></b>
</p>
</div>
{% include "tunnel/components/primary-button.html.twig" with {'action': 'nextStep', 'label': 'Suivant' } %}
{% include "tunnel/components/secondary-button.html.twig" with {'action': 'previousStep', 'label': 'Précédent' } %}
</div>
</div>
</section>
<section id="third-step" class="tunnel-hidden tunnel-step">
<div class="content-column-center-48">
<h2 class="title text-center">
{% trans %}Choisissez une offre{% endtrans %}
</h2>
<div class="w-full">
{{ form_widget(form.offer) }}
</div>
<div class="tunnel-footer">
<div class="totalDifferencePriceContainer w-full flex-between" style="display: none">
<p class="small-text-opacity-70">
{% trans %}Supplément à régler{% endtrans %}
</p>
<p>
<b>+</b><b class="totalDifferencePrice"></b>
</p>
</div>
<div class="totalContainer w-full flex-between" style="display: none">
<p class="small-text-opacity-70">
{% trans %}Total pour{% endtrans %} <span class="totalPerson">1</span> {% trans %}personne(s){% endtrans %}
</p>
<p>
<b class="totalPrice"></b>
</p>
</div>
{% include "tunnel/components/primary-button.html.twig" with {'action': 'nextStep', 'label': 'Suivant' } %}
{% include "tunnel/components/secondary-button.html.twig" with {'action': 'previousStep', 'label': 'Précédent' } %}
</div>
</div>
</section>
<section id="fourth-step" class="tunnel-hidden tunnel-step">
<div class="swiper-button-prev-extra swiper-button-prev"></div>
<div class="swiper-button-next-extra swiper-button-next"></div>
<div class="content-column-center-48 ">
<div class="content-column-8">
<h2 class="title text-center">
{% trans %}Un petit plaisir à ajouter ?{% endtrans %}
</h2>
</div>
<div class="extra-container max-w-400">
{{ form_row(form.extraReservations) }}
</div>
<div class="tunnel-footer">
<div class="totalDifferencePriceContainer w-full flex-between" style="display: none">
<p class="small-text-opacity-70">
{% trans %}Supplément à régler{% endtrans %}
</p>
<p>
<b>+</b><b class="totalDifferencePrice"></b>
</p>
</div>
<div class="totalContainer w-full flex-between" style="display: none">
<p class="small-text-opacity-70">
{% trans %}Total pour{% endtrans %} <span class="totalPerson">1</span> {% trans %}personne(s){% endtrans %}
</p>
<p>
<b class="totalPrice"></b>
</p>
</div>
{% include "tunnel/components/primary-button.html.twig" with {'action': 'nextStep', 'label': 'Suivant' } %}
{% include "tunnel/components/secondary-button.html.twig" with {'action': 'previousStep', 'label': 'Précédent' } %}
</div>
</div>
</section>
<section id="fifth-step" class="tunnel-hidden tunnel-step">
<div class="content-column-center-48 ">
<div class="content-column-8">
<h2 class="title text-center">
{% trans %}Choisissez une date{% endtrans %}
</h2>
</div>
<div class="date-container max-w-400 content-column-16">
{{ form_widget(form.date) }}
</div>
<div class="tunnel-footer">
<div class="totalDifferencePriceContainer w-full flex-between" style="display: none">
<p class="small-text-opacity-70">
{% trans %}Supplément à régler{% endtrans %}
</p>
<p>
<b>+</b><b class="totalDifferencePrice"></b>
</p>
</div>
<div class="totalContainer w-full flex-between" style="display: none">
<p class="small-text-opacity-70">
{% trans %}Total pour{% endtrans %} <span class="totalPerson">1</span> {% trans %}personne(s){% endtrans %}
</p>
<p>
<b class="totalPrice"></b>
</p>
</div>
{% include "tunnel/components/primary-button.html.twig" with {'action': 'nextStep', 'label': 'Suivant' } %}
{% include "tunnel/components/secondary-button.html.twig" with {'action': 'previousStep', 'label': 'Précédent' } %}
</div>
</div>
</section>
<section id="sixth-step" class="tunnel-hidden tunnel-step">
<div class="content-column-center-48">
<div class="content-column-8-center">
<h2 class="title text-center">
{% trans %}Récapitulons{% endtrans %}
</h2>
</div>
<div class="content-row-48-center max-w-1200">
<div class="gsap-sticky">
{% include "tunnel/components/recapitulatif.html.twig" %}
</div>
<div class="contact-container wrapper-form-right flex-1">
<div class="content-column-16">
<h2 class="p-16-0">
{% trans %}Contact{% endtrans %}
</h2>
{{ form_row(form.contact) }}
<h2 class="p-16-0">
{% trans %}Participants{% endtrans %}
</h2>
{{ form_row(form.participants) }}
{{ form_row(form.cgv) }}
<p style="font-size: 14px;">
(*) {% trans %}Champs obligatoires{% endtrans %}
</p>
</div>
</div>
</div>
<div class="tunnel-footer">
<div class="infoContainer w-full text-center" style="display: none">
<p class="stepInfo">
</p>
</div>
{% include 'form/components/rgpd.html.twig' with {'sujet': 'réservation'} %}
{% include "tunnel/components/primary-button.html.twig" with {'action': 'createPayment', 'label': 'payment.pay'|trans } %}
{% include "tunnel/components/secondary-button.html.twig" with {'action': 'goToFirstStep', 'label': 'Modifier' } %}
</div>
</div>
</section>
</div>
{{ form_end(form) }}
<script src="{{ asset('js/tunnel.js') }}"></script>
<script src="{{ asset('js/tunnel/swiper.js') }}"></script>
<script>
const oldPrice = {{ priceOffered|default(0) }};
const usingCode = {{ code is defined ? "true" : "false" }};
const editMode = {{ edit is defined ? "true" : "false" }};
const entityId = {{ edit is defined and reservationId is defined ? reservationId : "null" }};
// Make editMode and entityId available globally for offer availability checks
window.editMode = editMode;
window.entityId = entityId;
const waitlistData = {{ waitlistData|default(null)|json_encode|raw }};
let submitButton = document.querySelector(".submit-btn");
// on dom ready
document.addEventListener('DOMContentLoaded', function() {
if (usingCode) {
updateUI(0);
}
if (editMode) {
updateUI(1);
// Initialize offer availability check for edit mode
if (typeof initializeOfferAvailabilityForEdit === 'function') {
initializeOfferAvailabilityForEdit();
}
}
if (waitlistData) {
window.waitlistData = waitlistData;
// Pre-fill form fields from waitlist data
const soloInput = document.querySelector('.solo');
const duoInput = document.querySelector('.duo');
const nbBathInput = document.querySelector('.nbBath');
const nbParticipantsInput = document.querySelector('.nbParticipants');
if (soloInput) soloInput.value = waitlistData.solo;
if (duoInput) duoInput.value = waitlistData.duo;
if (nbBathInput) nbBathInput.value = waitlistData.solo + waitlistData.duo;
if (nbParticipantsInput) nbParticipantsInput.value = waitlistData.solo + (waitlistData.duo * 2);
// Set offer radio button
const offerInput = document.querySelector('input.offer-option[value="' + waitlistData.offer + '"]');
if (offerInput) {
offerInput.checked = true;
offerInput.dispatchEvent(new Event('change', { bubbles: true }));
}
// Navigate to date step (step 5)
updateUI(5);
}
});
window.addEventListener('message', function (event) {
// Check if the message is coming from the PayPlug origin
if (event.origin === "https://secure.payplug.com") {
// Check if the message data indicates the lightbox was closed
if (event.data === "closePayPlugFrame") {
// Re-enable the submit button
submitButton.removeAttribute("disabled");
submitButton.querySelector(".spinner").style.display = "none";
}
}
});
function openCarteCadeauModal() {
const tokenValue = prompt("Entrez le code de votre carte cadeau");
// Check if the user provided a value
if (tokenValue) {
const baseUrl = "{{ path('reservation_carte_cadeau_tunnel') }}";
window.location.href = `${baseUrl}?code=${encodeURIComponent(tokenValue)}`;
}
}
function createPayment() {
let form = document.querySelector("form.to-submit");
let formExtras = new FormData(form);
let formData = {};
submitButton.removeAttribute("disabled");
displayStepInfo(submitButton, "");
for (let entry of formExtras.entries()) {
formData[entry[0]] = entry[1];
}
if (!form.checkValidity()) {
displayStepInfo(submitButton, "Veuillez remplir tous les champs obligatoires");
form.reportValidity();
return;
}
{% if code is defined %}
formData["code"] = "{{ code }}";
{% endif %}
submitButton.disabled = true;
submitButton.querySelector(".spinner").style.display = "block";
$.ajax({
url: "{{ paymentUrl }}",
dataType: "json",
type: "Post",
async: true,
data: formData,
success: function (data) {
if(data.action === 'payment') {
Payplug.showPayment(data.url);
} else if (data.action === 'redirect') {
window.location.href = data.url;
} else if (data.action === 'error') {
alert(data.message);
submitButton.removeAttribute("disabled");
submitButton.querySelector(".spinner").style.display = "none";
} else {
alert('Nous sommes désolés, une erreur est survenue lors de la prise de votre réservation, nous avons besoin que vous recommenciez.');
submitButton.removeAttribute("disabled");
submitButton.querySelector(".spinner").style.display = "none";
// window.location.reload();
}
},
error: function (data) {
alert(data);
}
});
}
</script>
{% endblock %}