90 lines
2.9 KiB
JavaScript
90 lines
2.9 KiB
JavaScript
import {
|
||
hydrateCart,
|
||
subscribe,
|
||
getSnapshot,
|
||
updateQuantity,
|
||
removeItem,
|
||
formatPrice,
|
||
} from "/js/cart.js";
|
||
|
||
function escapeHtml(s) {
|
||
return String(s)
|
||
.replaceAll("&", "&")
|
||
.replaceAll("<", "<")
|
||
.replaceAll(">", ">")
|
||
.replaceAll('"', """);
|
||
}
|
||
|
||
/** Cart page: items + totals only (checkout is a separate step). */
|
||
export function initCartPage() {
|
||
const root = document.querySelector("[data-cart-page]");
|
||
if (!root) return;
|
||
|
||
hydrateCart();
|
||
const list = root.querySelector("[data-cart-lines]");
|
||
const totalEl = root.querySelector("[data-cart-total]");
|
||
const checkoutBtn = root.querySelector("[data-cart-checkout]");
|
||
const emptyEl = root.querySelector("[data-cart-empty]");
|
||
const contentEl = root.querySelector("[data-cart-content]");
|
||
|
||
function render(snap) {
|
||
const empty = !snap.items.length;
|
||
if (emptyEl) emptyEl.hidden = !empty;
|
||
if (contentEl) contentEl.hidden = empty;
|
||
if (checkoutBtn) {
|
||
if (empty) checkoutBtn.setAttribute("disabled", "");
|
||
else checkoutBtn.removeAttribute("disabled");
|
||
}
|
||
if (!list || !totalEl) return;
|
||
|
||
if (empty) {
|
||
list.innerHTML = "";
|
||
totalEl.textContent = formatPrice(0);
|
||
return;
|
||
}
|
||
|
||
list.innerHTML = snap.items
|
||
.map(
|
||
(item) => `
|
||
<div class="cart-line" data-id="${escapeHtml(item.productId)}">
|
||
${
|
||
item.image
|
||
? `<img src="${escapeHtml(item.image)}" alt="" width="72" height="96" />`
|
||
: `<div style="width:72px;height:96px;background:#f7f7f7"></div>`
|
||
}
|
||
<div style="flex:1;min-width:0">
|
||
<a href="/products/${escapeHtml(item.slug)}/">${escapeHtml(item.name)}</a>
|
||
<div class="text-muted" style="font-size:0.85rem;margin-top:0.25rem">${formatPrice(item.price)}</div>
|
||
<div class="qty-controls">
|
||
<button type="button" data-qty-dec aria-label="کاهش تعداد">−</button>
|
||
<span>${item.quantity}</span>
|
||
<button type="button" data-qty-inc aria-label="افزایش تعداد">+</button>
|
||
<button type="button" data-qty-remove aria-label="حذف از سبد" style="margin-inline-start:0.5rem;font-size:0.75rem;color:#8a8a8a">حذف</button>
|
||
</div>
|
||
</div>
|
||
</div>`
|
||
)
|
||
.join("");
|
||
|
||
totalEl.textContent = formatPrice(snap.subtotal);
|
||
|
||
list.querySelectorAll(".cart-line").forEach((row) => {
|
||
const id = row.getAttribute("data-id");
|
||
const item = snap.items.find((i) => i.productId === id);
|
||
if (!item || !id) return;
|
||
row.querySelector("[data-qty-dec]")?.addEventListener("click", () =>
|
||
updateQuantity(id, item.quantity - 1)
|
||
);
|
||
row.querySelector("[data-qty-inc]")?.addEventListener("click", () =>
|
||
updateQuantity(id, item.quantity + 1)
|
||
);
|
||
row.querySelector("[data-qty-remove]")?.addEventListener("click", () =>
|
||
removeItem(id)
|
||
);
|
||
});
|
||
}
|
||
|
||
subscribe(render);
|
||
render(getSnapshot());
|
||
}
|