191 lines
6.8 KiB
JavaScript
191 lines
6.8 KiB
JavaScript
export class FlowFormuleConfigurator extends HTMLElement {
|
|
constructor() {
|
|
super();
|
|
this.counts = { structure: 0, alimentaire: 0, barnum: 0 };
|
|
this.selection = [];
|
|
this.blocked = false;
|
|
this.mode = 'free';
|
|
}
|
|
|
|
connectedCallback() {
|
|
try {
|
|
this.limits = JSON.parse(this.getAttribute('data-limits') || '{}');
|
|
this.prices = JSON.parse(this.getAttribute('data-prices') || '{}');
|
|
} catch (e) {
|
|
console.error('Invalid limits/prices JSON', e);
|
|
return;
|
|
}
|
|
|
|
this.formuleId = this.getAttribute('data-formule-id');
|
|
this.mode = this.getAttribute('data-mode') || 'free';
|
|
this.validateBtn = this.querySelector('#btn-validate-pack');
|
|
|
|
if (this.mode === 'pack') {
|
|
try {
|
|
this.selection = JSON.parse(this.getAttribute('data-preselected-ids') || '[]');
|
|
} catch (e) { console.error('Invalid preselected-ids JSON', e); }
|
|
} else {
|
|
this.querySelectorAll('.product-card').forEach(card => {
|
|
card.addEventListener('click', (e) => {
|
|
e.preventDefault();
|
|
this.toggleItem(card);
|
|
});
|
|
});
|
|
}
|
|
|
|
if (this.validateBtn) {
|
|
this.validateBtn.addEventListener('click', (e) => {
|
|
e.preventDefault();
|
|
this.validate();
|
|
});
|
|
}
|
|
|
|
this.checkDuration();
|
|
this.updateUI();
|
|
}
|
|
|
|
checkDuration() {
|
|
const datesStr = sessionStorage.getItem('reservation_dates');
|
|
if (!datesStr) return;
|
|
|
|
try {
|
|
const dates = JSON.parse(datesStr);
|
|
if (!dates.start || !dates.end) return;
|
|
|
|
const start = new Date(dates.start);
|
|
const end = new Date(dates.end);
|
|
const diffTime = Math.abs(end - start);
|
|
const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24)) + 1;
|
|
|
|
let message = null;
|
|
let block = false;
|
|
|
|
if (diffDays > 5) {
|
|
message = `Attention : La durée de votre réservation (${diffDays} jours) dépasse la limite autorisée de 5 jours pour cette formule.`;
|
|
block = true;
|
|
} else if (diffDays >= 3 && diffDays <= 5) {
|
|
message = `Information : Pour une durée de ${diffDays} jours, le tarif "5 jours" sera appliqué automatiquement.`;
|
|
}
|
|
|
|
if (message) {
|
|
let msgContainer = this.querySelector('.formule-warning');
|
|
if (!msgContainer) {
|
|
msgContainer = document.createElement('div');
|
|
this.prepend(msgContainer);
|
|
}
|
|
msgContainer.className = `formule-warning p-4 mb-6 rounded-2xl text-sm font-bold text-center border-2 ${block ? 'bg-red-50 border-red-100 text-red-600' : 'bg-blue-50 border-blue-100 text-blue-600'}`;
|
|
msgContainer.innerHTML = message;
|
|
}
|
|
|
|
this.blocked = block;
|
|
this.updateUI();
|
|
|
|
} catch (e) { console.error(e); }
|
|
}
|
|
|
|
toggleItem(el) {
|
|
if (this.blocked || this.mode === 'pack') return;
|
|
|
|
const category = el.getAttribute('data-category');
|
|
const id = el.getAttribute('data-id');
|
|
const isSelected = el.getAttribute('data-selected') === 'true';
|
|
|
|
if (isSelected) {
|
|
this.deselect(el, category, id);
|
|
} else {
|
|
if (this.counts[category] < this.limits[category]) {
|
|
this.select(el, category, id);
|
|
} else {
|
|
this.shake(el);
|
|
}
|
|
}
|
|
this.updateUI();
|
|
}
|
|
|
|
select(el, category, id) {
|
|
el.setAttribute('data-selected', 'true');
|
|
el.classList.add('ring-4', 'ring-[#f39e36]', 'scale-95');
|
|
|
|
const indicator = el.querySelector('.selection-indicator');
|
|
if (indicator) {
|
|
indicator.classList.remove('opacity-0', 'group-hover:opacity-100');
|
|
indicator.classList.add('opacity-100');
|
|
indicator.querySelector('div')?.classList.remove('hidden');
|
|
}
|
|
|
|
this.counts[category]++;
|
|
this.selection.push(id);
|
|
}
|
|
|
|
deselect(el, category, id) {
|
|
el.setAttribute('data-selected', 'false');
|
|
el.classList.remove('ring-4', 'ring-[#f39e36]', 'scale-95');
|
|
|
|
const indicator = el.querySelector('.selection-indicator');
|
|
if (indicator) {
|
|
indicator.classList.remove('opacity-100');
|
|
indicator.classList.add('opacity-0', 'group-hover:opacity-100');
|
|
indicator.querySelector('div')?.classList.add('hidden');
|
|
}
|
|
|
|
this.counts[category]--;
|
|
this.selection = this.selection.filter(item => item !== id);
|
|
}
|
|
|
|
shake(el) {
|
|
el.classList.add('animate-pulse');
|
|
setTimeout(() => el.classList.remove('animate-pulse'), 500);
|
|
alert("Limite atteinte pour cette catégorie.");
|
|
}
|
|
|
|
updateUI() {
|
|
if (this.mode === 'free') {
|
|
['structure', 'alimentaire', 'barnum'].forEach(cat => {
|
|
const span = this.querySelector(`#count-${cat}`);
|
|
if (span) span.innerText = this.counts[cat];
|
|
});
|
|
}
|
|
|
|
const total = this.selection.length;
|
|
if (this.validateBtn) {
|
|
if (this.blocked) {
|
|
this.validateBtn.innerText = 'Durée non autorisée (> 5j)';
|
|
this.validateBtn.classList.add('opacity-50', 'pointer-events-none', 'translate-y-4', 'bg-red-600');
|
|
this.validateBtn.classList.remove('bg-slate-900', 'hover:bg-[#fc0e50]');
|
|
} else {
|
|
this.validateBtn.innerText = this.mode === 'pack' ? 'Réserver ce pack' : `Valider mon pack (${total})`;
|
|
this.validateBtn.classList.remove('bg-red-600');
|
|
this.validateBtn.classList.add('bg-slate-900', 'hover:bg-[#fc0e50]');
|
|
|
|
if (total > 0) {
|
|
this.validateBtn.classList.remove('opacity-50', 'pointer-events-none', 'translate-y-4');
|
|
} else {
|
|
this.validateBtn.classList.add('opacity-50', 'pointer-events-none', 'translate-y-4');
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
validate() {
|
|
if (this.blocked || this.selection.length === 0) return;
|
|
|
|
sessionStorage.setItem('active_formule', this.formuleId);
|
|
|
|
let list = [];
|
|
try {
|
|
list = JSON.parse(sessionStorage.getItem('pl_list') || '[]');
|
|
} catch(e) {}
|
|
|
|
const newItems = this.selection.filter(id => !list.includes(id));
|
|
if (newItems.length > 0) {
|
|
list = [...list, ...newItems];
|
|
sessionStorage.setItem('pl_list', JSON.stringify(list));
|
|
}
|
|
|
|
window.dispatchEvent(new CustomEvent('cart:updated'));
|
|
|
|
const cart = document.querySelector('[is="flow-reserve"]');
|
|
if (cart) cart.open();
|
|
}
|
|
}
|