cart.astro raw

   1  ---
   2  import Base from '../layouts/Base.astro';
   3  ---
   4  <Base title="Количка">
   5    <section class="section">
   6      <div class="container">
   7        <h1 data-i18n="cartTitle">Количка</h1>
   8        <div id="cart-contents"></div>
   9        <div id="cart-summary" class="cart-summary" style="display:none">
  10           <div class="cart-total">
  11            <span data-i18n="cartTotal">Общо: </span>
  12            <span id="cart-total-amount"> 0.00 EUR</span>
  13          </div>
  14          <a href="/checkout" class="btn btn-primary btn-lg" style="margin-top:1rem" data-i18n="toCheckout">Към плащане</a>
  15        </div>
  16        <div id="cart-empty" style="display:none">
  17          <p data-i18n="cartEmpty">Количката е празна.</p>
  18          <a href="/shop" class="btn btn-outline" data-i18n="shopNow">Разгледайте продуктите</a>
  19        </div>
  20      </div>
  21    </section>
  22  </Base>
  23  
  24  <script>
  25    import { getCart, setQty, removeItem, formatLv, escapeHtml } from '../lib/cart-client';
  26    import { currentLang } from '../lib/i18n';
  27  
  28    function renderCart() {
  29      const cart = getCart();
  30      const container = document.getElementById('cart-contents')!;
  31      const summary = document.getElementById('cart-summary')!;
  32      const empty = document.getElementById('cart-empty')!;
  33      const lang = currentLang();
  34  
  35      if (cart.length === 0) {
  36        container.innerHTML = '';
  37        summary.style.display = 'none';
  38        empty.style.display = 'block';
  39        return;
  40      }
  41  
  42      empty.style.display = 'none';
  43      summary.style.display = 'block';
  44  
  45      let total = 0;
  46      container.innerHTML = `<div class="cart-items">${cart.map((item, i) => {
  47        total += item.price_cents * item.qty;
  48        const displayName = lang === 'en' && item.name_en ? item.name_en : item.name;
  49        const unitLabel = lang === 'en' ? 'g' : 'г';
  50        return `<div class="cart-item">
  51          <img src="${escapeHtml(item.image)}" alt="${escapeHtml(displayName)}" width="80" height="80" />
  52          <div class="cart-item-info">
  53            <h3>${escapeHtml(displayName)}</h3>
  54            <p>${formatLv(item.price_cents)} / ${item.unit_size}${unitLabel}</p>
  55          </div>
  56          <div class="cart-item-qty">
  57            <button class="qty-btn" data-i="${i}" data-dir="-1">-</button>
  58            <span>${item.qty} бр.</span>
  59            <button class="qty-btn" data-i="${i}" data-dir="1" ${item.qty >= item.stock ? 'disabled' : ''}>+</button>
  60          </div>
  61          <div class="cart-item-total">${formatLv(item.price_cents * item.qty)}</div>
  62          <button class="cart-item-remove" data-i="${i}">&times;</button>
  63        </div>`;
  64      }).join('')}</div>`;
  65  
  66      document.getElementById('cart-total-amount')!.textContent = formatLv(total);
  67  
  68      document.querySelectorAll('.qty-btn').forEach(el => {
  69        const btn = el as HTMLButtonElement;
  70        btn.addEventListener('click', () => {
  71          const i = parseInt(btn.dataset.i!);
  72          const cart = getCart();
  73          setQty(i, cart[i].qty + parseInt(btn.dataset.dir!));
  74          renderCart();
  75        });
  76      });
  77      document.querySelectorAll('.cart-item-remove').forEach(el => {
  78        const btn = el as HTMLButtonElement;
  79        btn.addEventListener('click', () => {
  80          removeItem(parseInt(btn.dataset.i!));
  81          renderCart();
  82        });
  83      });
  84    }
  85    renderCart();
  86    window.addEventListener('lang-changed', renderCart);
  87  </script>
  88  
  89  <style is:global>
  90    #cart-contents { margin-top: 1rem; }
  91    .qty-btn:disabled { opacity: 0.35; cursor: not-allowed; }
  92    .cart-item-remove {
  93      background: none;
  94      border: none;
  95      font-size: 1.2rem;
  96      color: #999;
  97      cursor: pointer;
  98      padding: 0 4px;
  99      line-height: 1;
 100      flex-shrink: 0;
 101    }
 102    .cart-item-remove:hover { color: #c0392b; }
 103  </style>
 104