Athenaeum/static/js/cart.js
2025-06-01 11:09:37 +02:00

298 lines
11 KiB
JavaScript

document.addEventListener('DOMContentLoaded', function() {
const cartItemsContainer = document.getElementById('cart-items');
const checkoutBtn = document.getElementById('checkoutBtn');
const localPickupCheckbox = document.getElementById('localPickup');
// Załaduj zawartość koszyka
loadCart();
// Dodaj event listeners
if (localPickupCheckbox) {
// JEDEN listener dla checkboxa
localPickupCheckbox.addEventListener('change', function() {
// Pobierz aktualny stan koszyka i zaktualizuj podsumowanie
const cartItems = Array.from(document.querySelectorAll('.card.mb-3')).map(card => {
const bookId = card.querySelector('.decrease-btn').dataset.bookId;
const quantity = parseInt(card.querySelector('.quantity-display').textContent);
const cena = parseFloat(card.querySelector('.card-text').textContent.replace(' PLN', ''));
const tytul = card.querySelector('.card-title').textContent;
const obraz_url = card.querySelector('img').src;
return {
book_id: parseInt(bookId),
quantity,
cena,
tytul,
obraz_url
};
});
updateSummary(cartItems);
});
}
if (checkoutBtn) {
checkoutBtn.addEventListener('click', handleCheckout);
}
});
async function loadCart() {
const cartItemsContainer = document.getElementById('cart-items');
if (!cartItemsContainer) return;
cartItemsContainer.innerHTML = `
<div class="text-center py-5">
<div class="spinner-border text-primary" role="status">
<span class="visually-hidden">Ładowanie...</span>
</div>
</div>
`;
try {
const response = await fetch('/api/cart', {
credentials: 'include'
});
if (!response.ok) {
throw new Error(`Błąd HTTP: ${response.status}`);
}
const cartItems = await response.json();
displayCartItems(cartItems);
updateSummary(cartItems);
} catch (error) {
console.error('Błąd ładowania koszyka:', error);
cartItemsContainer.innerHTML = `
<div class="alert alert-danger">Wystąpił błąd podczas ładowania koszyka: ${error.message}</div>
`;
}
}
function displayCartItems(cartItems) {
const cartItemsContainer = document.getElementById('cart-items');
if (!cartItemsContainer) return;
if (cartItems.length === 0) {
cartItemsContainer.innerHTML = `
<div class="alert alert-info">
Twój koszyk jest pusty
</div>
`;
return;
}
cartItemsContainer.innerHTML = '';
cartItems.forEach(item => {
const itemElement = `
<div class="card mb-3">
<div class="row g-0">
<div class="col-md-2">
<img src="${item.obraz_url}" class="img-fluid rounded-start" alt="${item.tytul}">
</div>
<div class="col-md-6">
<div class="card-body">
<h5 class="card-title">${item.tytul}</h5>
<p class="card-text">${item.cena} PLN</p>
</div>
</div>
<div class="col-md-4 d-flex align-items-center justify-content-end pe-3">
<div class="d-flex align-items-center">
<button class="btn btn-sm btn-outline-secondary decrease-btn" data-book-id="${item.book_id}">
<i class="bi bi-dash"></i>
</button>
<span class="mx-2 quantity-display">${item.quantity}</span>
<button class="btn btn-sm btn-outline-secondary increase-btn" data-book-id="${item.book_id}">
<i class="bi bi-plus"></i>
</button>
<button class="btn btn-sm btn-danger ms-2 remove-btn" data-book-id="${item.book_id}">
<i class="bi bi-trash"></i>
</button>
</div>
</div>
</div>
</div>
`;
cartItemsContainer.innerHTML += itemElement;
});
// Dodaj event listeners dla przycisków
document.querySelectorAll('.decrease-btn').forEach(btn => {
btn.addEventListener('click', () => updateCartItemQuantity(btn.dataset.bookId, -1));
});
document.querySelectorAll('.increase-btn').forEach(btn => {
btn.addEventListener('click', () => updateCartItemQuantity(btn.dataset.bookId, 1));
});
document.querySelectorAll('.remove-btn').forEach(btn => {
btn.addEventListener('click', () => removeCartItem(btn.dataset.bookId));
});
}
async function updateCartItemQuantity(bookId, change) {
try {
const response = await fetch('/api/update-cart-quantity', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
book_id: parseInt(bookId),
change: change
}),
credentials: 'include'
});
if (response.ok) {
const quantityElement = document.querySelector(`.decrease-btn[data-book-id="${bookId}"]`).nextElementSibling;
const currentQuantity = parseInt(quantityElement.textContent);
const newQuantity = currentQuantity + change;
// Jeśli nowa ilość jest mniejsza lub równa 0, usuń produkt
if (newQuantity <= 0) {
const cartItem = quantityElement.closest('.card');
cartItem.style.opacity = '0';
setTimeout(() => {
cartItem.remove();
updateSummaryFromDOM();
}, 300);
// Dodatkowo wyślij żądanie usunięcia z serwera
await fetch(`/api/remove-from-cart/${bookId}`, {
method: 'DELETE',
credentials: 'include'
});
} else {
// Animacja zmiany ilości
quantityElement.textContent = newQuantity;
updateSummaryFromDOM();
}
} else {
alert('Błąd aktualizacji ilości');
}
} catch (error) {
console.error('Błąd:', error);
alert('Wystąpił błąd podczas aktualizacji ilości');
}
}
// Funkcja do aktualizacji podsumowania na podstawie DOM
function updateSummaryFromDOM() {
const cartItems = Array.from(document.querySelectorAll('.card.mb-3')).map(card => {
const bookId = card.querySelector('.decrease-btn').dataset.bookId;
const quantity = parseInt(card.querySelector('.quantity-display').textContent);
const cena = parseFloat(card.querySelector('.card-text').textContent.replace(' PLN', ''));
const tytul = card.querySelector('.card-title').textContent;
const obraz_url = card.querySelector('img').src;
return {
book_id: parseInt(bookId),
quantity,
cena,
tytul,
obraz_url
};
});
updateSummary(cartItems);
}
function updateSummary(cartItems) {
const localPickupCheckbox = document.getElementById('localPickup');
const productsValueEl = document.getElementById('products-value');
const deliveryValueEl = document.getElementById('delivery-value');
const totalValueEl = document.getElementById('total-value');
if (!productsValueEl || !deliveryValueEl || !totalValueEl) return;
// Oblicz wartość produktów
let productsValue = 0;
if (cartItems && cartItems.length > 0) {
productsValue = cartItems.reduce((total, item) => {
return total + (item.cena * item.quantity);
}, 0);
}
productsValueEl.textContent = productsValue.toFixed(2) + ' PLN';
// Oblicz koszt dostawy
const deliveryCost = localPickupCheckbox && localPickupCheckbox.checked ? 0 : 12.99;
deliveryValueEl.textContent = deliveryCost.toFixed(2) + ' PLN';
const totalValue = productsValue + deliveryCost;
totalValueEl.textContent = totalValue.toFixed(2) + ' PLN';
}
async function removeCartItem(bookId) {
try {
const response = await fetch(`/api/remove-from-cart/${bookId}`, {
method: 'DELETE',
credentials: 'include'
});
if (response.ok) {
loadCart();
} else {
alert('Błąd usuwania z koszyka');
}
} catch (error) {
console.error('Błąd:', error);
alert('Wystąpił błąd podczas usuwania z koszyka');
}
}
async function handleCheckout() {
const cartItemsContainer = document.getElementById('cart-items');
const localPickupCheckbox = document.getElementById('localPickup');
if (!cartItemsContainer || cartItemsContainer.innerHTML.includes('Twój koszyk jest pusty')) {
alert('Twój koszyk jest pusty!');
return;
}
try {
// Pobierz aktualną zawartość koszyka
const response = await fetch('/api/cart', {
credentials: 'include'
});
if (!response.ok) {
throw new Error('Błąd ładowania koszyka');
}
const cartItems = await response.json();
// Przygotuj dane do zamówienia
const checkoutData = {
items: cartItems.map(item => ({
book_id: item.book_id,
quantity: item.quantity
})),
total: parseFloat(document.getElementById('total-value').textContent),
delivery_type: localPickupCheckbox.checked ? "local" : "shipping"
};
// Wyślij zamówienie
const checkoutResponse = await fetch('/api/checkout', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(checkoutData),
credentials: 'include'
});
if (checkoutResponse.ok) {
window.location.href = '/thankyou.html';
} else {
const errorData = await checkoutResponse.json();
alert(`Błąd składania zamówienia: ${errorData.message || 'Nieznany błąd'}`);
}
} catch (error) {
console.error('Błąd:', error);
alert('Wystąpił błąd podczas składania zamówienia');
}
}