diff --git a/assets/reserve.js b/assets/reserve.js index 228caa4..1472a57 100644 --- a/assets/reserve.js +++ b/assets/reserve.js @@ -3,6 +3,7 @@ import { UtmEvent, UtmAccount } from "./tools/UtmEvent.js"; import { CookieBanner } from "./tools/CookieBanner.js"; import { FlowReserve } from "./tools/FlowReserve.js"; import { FlowDatePicker } from "./tools/FlowDatePicker.js"; +import { FlowAddToCart } from "./tools/FlowAddToCart.js"; import * as Turbo from "@hotwired/turbo"; import { onLCP, onINP, onCLS } from 'web-vitals'; import AOS from 'aos'; @@ -259,6 +260,9 @@ const registerComponents = () => { if(!customElements.get('flow-datepicker')) customElements.define('flow-datepicker',FlowDatePicker) + + if(!customElements.get('flow-add-to-cart')) + customElements.define('flow-add-to-cart',FlowAddToCart) }; document.addEventListener('DOMContentLoaded', () => { diff --git a/assets/tools/FlowAddToCart.js b/assets/tools/FlowAddToCart.js new file mode 100644 index 0000000..3c84a81 --- /dev/null +++ b/assets/tools/FlowAddToCart.js @@ -0,0 +1,72 @@ +export class FlowAddToCart extends HTMLElement { + constructor() { + super(); + } + + connectedCallback() { + this.btn = this.querySelector('button'); + if (!this.btn) return; + + this.productId = this.getAttribute('product-id'); + this.btn.addEventListener('click', (e) => { + e.preventDefault(); + this.addToCart(); + }); + } + + async addToCart() { + // 1. Check Dates + const dates = JSON.parse(localStorage.getItem('reservation_dates') || '{}'); + if (!dates.start || !dates.end) { + // Open Date Picker if no dates + document.dispatchEvent(new CustomEvent('open-date-picker')); + return; + } + + // 2. Loading State + const originalContent = this.btn.innerHTML; + this.btn.disabled = true; + this.btn.innerHTML = ''; + + try { + // 3. Check Availability + const response = await fetch('/produit/check', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ + id: this.productId, + start: dates.start, + end: dates.end + }) + }); + + if (!response.ok) throw new Error('Network error'); + const data = await response.json(); + + if (data.dispo) { + // 4. Add to Cart + const list = JSON.parse(localStorage.getItem('pl_list') || '[]'); + if (!list.includes(this.productId)) { + list.push(this.productId); + localStorage.setItem('pl_list', JSON.stringify(list)); + window.dispatchEvent(new CustomEvent('cart:updated')); + } + + // Open Cart + const cart = document.querySelector('[is="flow-reserve"]'); + if (cart) cart.open(); + + } else { + // 5. Not Available + alert("Ce produit n'est pas disponible pour les dates sélectionnées."); + } + + } catch (error) { + console.error(error); + alert("Une erreur est survenue."); + } finally { + this.btn.disabled = false; + this.btn.innerHTML = originalContent; + } + } +} diff --git a/templates/revervation/produit.twig b/templates/revervation/produit.twig index 2314048..75c9ad6 100644 --- a/templates/revervation/produit.twig +++ b/templates/revervation/produit.twig @@ -228,13 +228,18 @@ Structure soumise à des conditions spéciales.

+ + Nous contacter + + {% else %} + + + {% endif %} - - {{ (product.category == "2-7 ans") ? 'Nous contacter' : 'Vérifier la disponibilité' }} - -

Devis gratuit • Ludikevent • Qualité Pro