class RsvReservationSummary extends HTMLElement {
// ---- Lifecycle ----------------------------------------------------------
connectedCallback() {
this._all_slots = new Map(); // name → { slots, price_per_block }
this._form = this.closest('form');
this._build();
if (this._form) {
this._handler = e => {
this._all_slots.set(e.detail.name, {
slots: e.detail.slots,
price_per_block: e.detail.price_per_block,
});
this._render();
};
this._form.addEventListener('rsv:slots-changed', this._handler);
}
}
disconnectedCallback() {
if (this._form && this._handler) {
this._form.removeEventListener('rsv:slots-changed', this._handler);
}
}
// ---- Private ------------------------------------------------------------
_build() {
const s = ReservairStrings.summary;
this.innerHTML = `
`;
this.hidden = true;
this.querySelector('.rsv-summary-clear').addEventListener('click', () => {
this._form?.querySelectorAll('rsv-reservation-selector').forEach(sel => sel.clear());
});
}
_render() {
const all_slots = [...this._all_slots.values()].flatMap(({ slots, price_per_block }) =>
slots.map(s => ({ ...s, price_per_block }))
);
console.log(all_slots);
const n = all_slots.length;
const list = this.querySelector('.rsv-summary-list');
const count_el = this.querySelector('.rsv-summary-count');
const price_el = this.querySelector('.rsv-summary-price');
const s = ReservairStrings.summary;
const locale = navigator.language;
this.hidden = n === 0;
if (n === 0) {
list.replaceChildren();
count_el.textContent = '';
price_el.textContent = '';
return;
}
const time_opts = { hour: '2-digit', minute: '2-digit' };
list.replaceChildren(...all_slots.map(slot => {
const start = new Date(slot.start_utc);
const end = new Date(slot.end_utc);
const li = document.createElement('li');
li.className = 'rsv-summary-item';
li.innerHTML = `
${start.toLocaleDateString(locale, { weekday: 'long', day: 'numeric', month: 'long' })}
${start.toLocaleTimeString(locale, time_opts)} – ${end.toLocaleTimeString(locale, time_opts)}
${slot.price_per_block > 0 ? `${slot.price_per_block} ${s.currency}` : ''}
`;
return li;
}));
const total = all_slots.reduce((sum, slot) => sum + slot.price_per_block, 0);
count_el.textContent = this._fmt_count(n);
price_el.textContent = total > 0 ? `${total} ${s.currency}` : '';
}
_fmt_count(n) {
const s = ReservairStrings.summary;
if (n === 1) return s.count_one;
if (n < 5) return s.count_few.replace('%d', n);
return s.count_many.replace('%d', n);
}
}
customElements.define('rsv-reservation-summary', RsvReservationSummary);