Files
ludikevent_crm/assets/tools/FlowFormuleConfigurator.js

191 lines
6.8 KiB
JavaScript
Raw Normal View History

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();
}
}