feat(ReserverController): Ajoute l'endpoint JSON pour le panier de réservation.

♻️ refactor(FlowReserve.js): Refactorise l'affichage du panier et gère les dates.
This commit is contained in:
Serreau Jovann
2026-01-30 18:10:01 +01:00
parent 85319230bf
commit 5cb93029b4
2 changed files with 99 additions and 2 deletions

View File

@@ -145,6 +145,14 @@ export class FlowReserve extends HTMLAnchorElement {
footer.innerHTML = '';
const ids = this.getList();
// Retrieve dates from localStorage
let dates = { start: null, end: null };
try {
dates = JSON.parse(localStorage.getItem('reservation_dates') || '{}');
} catch (e) {
console.warn('Invalid reservation dates in localStorage');
}
if (ids.length === 0) {
this.renderEmpty(container, footer);
@@ -155,12 +163,26 @@ export class FlowReserve extends HTMLAnchorElement {
const response = await fetch(this.apiUrl, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ ids })
body: JSON.stringify({
ids,
start: dates.start,
end: dates.end
})
});
if (!response.ok) throw new Error('Erreur réseau');
const data = await response.json();
// Merge client-side dates if server didn't return them (or to prioritize client choice)
if (!data.start_date && dates.start) data.start_date = this.formatDate(dates.start);
if (!data.end_date && dates.end) data.end_date = this.formatDate(dates.end);
// Fallback: if server returns dates in a format we can use directly, fine.
// If we just want to display what is in local storage:
if (dates.start) data.start_date = this.formatDate(dates.start);
if (dates.end) data.end_date = this.formatDate(dates.end);
this.renderList(container, footer, data);
} catch (error) {
@@ -220,7 +242,7 @@ export class FlowReserve extends HTMLAnchorElement {
</div>
<div class="flex justify-between items-end mt-2">
<span class="text-[#0782bc] font-black text-sm">${this.formatPrice(product.priceTTC1Day || product.priceHt1Day)} <span class="text-[9px] text-slate-400 font-bold">/j</span></span>
<button class="text-red-400 hover:text-red-600 p-1" onclick="document.querySelector('[is=flow-reserve]').removeFromList('${product.id}')">
<button class="text-red-400 hover:text-red-600 p-1 remove-btn" data-remove-id="${product.id}">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"/></svg>
</button>
</div>
@@ -230,6 +252,14 @@ export class FlowReserve extends HTMLAnchorElement {
container.innerHTML = `<div class="space-y-3">${datesHtml}${productsHtml}</div>`;
// Attach event listeners for remove buttons
container.querySelectorAll('.remove-btn').forEach(btn => {
btn.addEventListener('click', (e) => {
e.preventDefault();
this.removeFromList(btn.dataset.removeId);
});
});
// --- RENDER FOOTER (TOTALS) ---
const total = data.total || {};
const hasTva = total.totalTva > 0;
@@ -257,6 +287,16 @@ export class FlowReserve extends HTMLAnchorElement {
`;
}
formatDate(dateString) {
if (!dateString) return '';
try {
const date = new Date(dateString);
return new Intl.DateTimeFormat('fr-FR').format(date);
} catch (e) {
return dateString;
}
}
formatPrice(amount) {
if (amount === undefined || amount === null) return '-';
return new Intl.NumberFormat('fr-FR', { style: 'currency', currency: 'EUR' }).format(amount);