377 lines
11 KiB
JavaScript
377 lines
11 KiB
JavaScript
/**
|
|
* Enhanced Cart and Wishlist Management System
|
|
* Amazon/eBay-style product display with images and details
|
|
*/
|
|
|
|
class ShoppingManager {
|
|
constructor() {
|
|
this.cart = this.loadFromStorage("skyart_cart") || [];
|
|
this.wishlist = this.loadFromStorage("skyart_wishlist") || [];
|
|
this.init();
|
|
}
|
|
|
|
init() {
|
|
this.updateAllBadges();
|
|
this.setupEventListeners();
|
|
this.renderCart();
|
|
this.renderWishlist();
|
|
}
|
|
|
|
loadFromStorage(key) {
|
|
try {
|
|
const data = localStorage.getItem(key);
|
|
return data ? JSON.parse(data) : null;
|
|
} catch (e) {
|
|
console.error("Error loading from storage:", e);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
saveToStorage(key, data) {
|
|
try {
|
|
localStorage.setItem(key, JSON.stringify(data));
|
|
} catch (e) {
|
|
console.error("Error saving to storage:", e);
|
|
}
|
|
}
|
|
|
|
setupEventListeners() {
|
|
// Cart toggle
|
|
const cartToggle = document.getElementById("cartToggle");
|
|
const cartPanel = document.getElementById("cartPanel");
|
|
const cartClose = document.getElementById("cartClose");
|
|
|
|
if (cartToggle) {
|
|
cartToggle.addEventListener("click", (e) => {
|
|
e.stopPropagation();
|
|
cartPanel?.classList.toggle("active");
|
|
document.getElementById("wishlistPanel")?.classList.remove("active");
|
|
});
|
|
}
|
|
|
|
if (cartClose) {
|
|
cartClose.addEventListener("click", (e) => {
|
|
e.stopPropagation();
|
|
cartPanel?.classList.remove("active");
|
|
});
|
|
}
|
|
|
|
// Wishlist toggle
|
|
const wishlistToggle = document.getElementById("wishlistToggle");
|
|
const wishlistPanel = document.getElementById("wishlistPanel");
|
|
const wishlistClose = document.getElementById("wishlistClose");
|
|
|
|
if (wishlistToggle) {
|
|
wishlistToggle.addEventListener("click", (e) => {
|
|
e.stopPropagation();
|
|
wishlistPanel?.classList.toggle("active");
|
|
cartPanel?.classList.remove("active");
|
|
});
|
|
}
|
|
|
|
if (wishlistClose) {
|
|
wishlistClose.addEventListener("click", (e) => {
|
|
e.stopPropagation();
|
|
wishlistPanel?.classList.remove("active");
|
|
});
|
|
}
|
|
|
|
// Mobile menu
|
|
const mobileToggle = document.getElementById("mobileMenuToggle");
|
|
const mobileMenu = document.getElementById("mobileMenu");
|
|
const mobileClose = document.getElementById("mobileMenuClose");
|
|
|
|
if (mobileToggle) {
|
|
mobileToggle.addEventListener("click", () => {
|
|
mobileMenu?.classList.toggle("active");
|
|
document.body.style.overflow = mobileMenu?.classList.contains("active")
|
|
? "hidden"
|
|
: "";
|
|
});
|
|
}
|
|
|
|
if (mobileClose) {
|
|
mobileClose.addEventListener("click", () => {
|
|
mobileMenu?.classList.remove("active");
|
|
document.body.style.overflow = "";
|
|
});
|
|
}
|
|
|
|
// Close dropdowns on outside click
|
|
document.addEventListener("click", (e) => {
|
|
if (!e.target.closest(".cart-dropdown-wrapper")) {
|
|
cartPanel?.classList.remove("active");
|
|
}
|
|
if (!e.target.closest(".wishlist-dropdown-wrapper")) {
|
|
wishlistPanel?.classList.remove("active");
|
|
}
|
|
});
|
|
}
|
|
|
|
// Add to Cart
|
|
addToCart(product, quantity = 1) {
|
|
const existingItem = this.cart.find((item) => item.id === product.id);
|
|
|
|
if (existingItem) {
|
|
existingItem.quantity += quantity;
|
|
} else {
|
|
this.cart.push({
|
|
id: product.id,
|
|
name: product.name,
|
|
price: parseFloat(product.price),
|
|
imageurl: product.imageurl,
|
|
quantity: quantity,
|
|
addedAt: new Date().toISOString(),
|
|
});
|
|
}
|
|
|
|
this.saveToStorage("skyart_cart", this.cart);
|
|
this.updateAllBadges();
|
|
this.renderCart();
|
|
this.showNotification(`${product.name} added to cart!`, "success");
|
|
}
|
|
|
|
// Remove from Cart
|
|
removeFromCart(productId) {
|
|
this.cart = this.cart.filter((item) => item.id !== productId);
|
|
this.saveToStorage("skyart_cart", this.cart);
|
|
this.updateAllBadges();
|
|
this.renderCart();
|
|
this.showNotification("Item removed from cart", "info");
|
|
}
|
|
|
|
// Update Cart Quantity
|
|
updateCartQuantity(productId, quantity) {
|
|
const item = this.cart.find((item) => item.id === productId);
|
|
if (item) {
|
|
if (quantity <= 0) {
|
|
this.removeFromCart(productId);
|
|
} else {
|
|
item.quantity = quantity;
|
|
this.saveToStorage("skyart_cart", this.cart);
|
|
this.updateAllBadges();
|
|
this.renderCart();
|
|
}
|
|
}
|
|
}
|
|
|
|
// Add to Wishlist
|
|
addToWishlist(product) {
|
|
const exists = this.wishlist.find((item) => item.id === product.id);
|
|
|
|
if (!exists) {
|
|
this.wishlist.push({
|
|
id: product.id,
|
|
name: product.name,
|
|
price: parseFloat(product.price),
|
|
imageurl: product.imageurl,
|
|
addedAt: new Date().toISOString(),
|
|
});
|
|
|
|
this.saveToStorage("skyart_wishlist", this.wishlist);
|
|
this.updateAllBadges();
|
|
this.renderWishlist();
|
|
this.showNotification(`${product.name} added to wishlist!`, "success");
|
|
} else {
|
|
this.showNotification("Already in wishlist", "info");
|
|
}
|
|
}
|
|
|
|
// Remove from Wishlist
|
|
removeFromWishlist(productId) {
|
|
this.wishlist = this.wishlist.filter((item) => item.id !== productId);
|
|
this.saveToStorage("skyart_wishlist", this.wishlist);
|
|
this.updateAllBadges();
|
|
this.renderWishlist();
|
|
this.showNotification("Item removed from wishlist", "info");
|
|
}
|
|
|
|
// Move from Wishlist to Cart
|
|
moveToCart(productId) {
|
|
const item = this.wishlist.find((item) => item.id === productId);
|
|
if (item) {
|
|
this.addToCart(item, 1);
|
|
this.removeFromWishlist(productId);
|
|
}
|
|
}
|
|
|
|
// Update All Badges
|
|
updateAllBadges() {
|
|
const cartCount = this.cart.reduce((sum, item) => sum + item.quantity, 0);
|
|
const wishlistCount = this.wishlist.length;
|
|
|
|
const cartBadge = document.getElementById("cartCount");
|
|
const wishlistBadge = document.getElementById("wishlistCount");
|
|
|
|
if (cartBadge) {
|
|
cartBadge.textContent = cartCount;
|
|
cartBadge.style.display = cartCount > 0 ? "flex" : "none";
|
|
}
|
|
|
|
if (wishlistBadge) {
|
|
wishlistBadge.textContent = wishlistCount;
|
|
wishlistBadge.style.display = wishlistCount > 0 ? "flex" : "none";
|
|
}
|
|
}
|
|
|
|
// Render Cart
|
|
renderCart() {
|
|
const cartContent = document.getElementById("cartContent");
|
|
const cartSubtotal = document.getElementById("cartSubtotal");
|
|
|
|
if (!cartContent) return;
|
|
|
|
if (this.cart.length === 0) {
|
|
cartContent.innerHTML = '<p class="empty-state">Your cart is empty</p>';
|
|
if (cartSubtotal) cartSubtotal.textContent = "$0.00";
|
|
return;
|
|
}
|
|
|
|
const subtotal = this.cart.reduce(
|
|
(sum, item) => sum + item.price * item.quantity,
|
|
0
|
|
);
|
|
|
|
cartContent.innerHTML = this.cart
|
|
.map(
|
|
(item) => `
|
|
<div class="cart-item" data-product-id="${item.id}">
|
|
<div class="cart-item-image">
|
|
<img src="${item.imageurl || "/assets/images/placeholder.jpg"}"
|
|
alt="${item.name}"
|
|
onerror="this.src='/assets/images/placeholder.jpg'" />
|
|
</div>
|
|
<div class="cart-item-details">
|
|
<h4 class="cart-item-name">${item.name}</h4>
|
|
<p class="cart-item-price">$${item.price.toFixed(2)}</p>
|
|
<div class="cart-item-quantity">
|
|
<button class="qty-btn" onclick="shoppingManager.updateCartQuantity('${
|
|
item.id
|
|
}', ${item.quantity - 1})">
|
|
<i class="bi bi-dash"></i>
|
|
</button>
|
|
<span class="qty-value">${item.quantity}</span>
|
|
<button class="qty-btn" onclick="shoppingManager.updateCartQuantity('${
|
|
item.id
|
|
}', ${item.quantity + 1})">
|
|
<i class="bi bi-plus"></i>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
<div class="cart-item-actions">
|
|
<button class="cart-item-remove" onclick="shoppingManager.removeFromCart('${
|
|
item.id
|
|
}')" title="Remove">
|
|
<i class="bi bi-trash"></i>
|
|
</button>
|
|
<p class="cart-item-total">$${(item.price * item.quantity).toFixed(
|
|
2
|
|
)}</p>
|
|
</div>
|
|
</div>
|
|
`
|
|
)
|
|
.join("");
|
|
|
|
if (cartSubtotal) {
|
|
cartSubtotal.textContent = `$${subtotal.toFixed(2)}`;
|
|
}
|
|
}
|
|
|
|
// Render Wishlist
|
|
renderWishlist() {
|
|
const wishlistContent = document.getElementById("wishlistContent");
|
|
|
|
if (!wishlistContent) return;
|
|
|
|
if (this.wishlist.length === 0) {
|
|
wishlistContent.innerHTML =
|
|
'<p class="empty-state">Your wishlist is empty</p>';
|
|
return;
|
|
}
|
|
|
|
wishlistContent.innerHTML = this.wishlist
|
|
.map(
|
|
(item) => `
|
|
<div class="wishlist-item" data-product-id="${item.id}">
|
|
<div class="wishlist-item-image">
|
|
<img src="${item.imageurl || "/assets/images/placeholder.jpg"}"
|
|
alt="${item.name}"
|
|
onerror="this.src='/assets/images/placeholder.jpg'" />
|
|
</div>
|
|
<div class="wishlist-item-details">
|
|
<h4 class="wishlist-item-name">${item.name}</h4>
|
|
<p class="wishlist-item-price">$${item.price.toFixed(2)}</p>
|
|
<button class="btn-move-to-cart" onclick="shoppingManager.moveToCart('${
|
|
item.id
|
|
}')">
|
|
<i class="bi bi-cart-plus"></i> Add to Cart
|
|
</button>
|
|
</div>
|
|
<button class="wishlist-item-remove" onclick="shoppingManager.removeFromWishlist('${
|
|
item.id
|
|
}')" title="Remove">
|
|
<i class="bi bi-x-lg"></i>
|
|
</button>
|
|
</div>
|
|
`
|
|
)
|
|
.join("");
|
|
}
|
|
|
|
// Show Notification
|
|
showNotification(message, type = "info") {
|
|
const notification = document.createElement("div");
|
|
notification.className = `notification notification-${type}`;
|
|
notification.innerHTML = `
|
|
<i class="bi bi-${
|
|
type === "success" ? "check-circle" : "info-circle"
|
|
}"></i>
|
|
<span>${message}</span>
|
|
`;
|
|
|
|
document.body.appendChild(notification);
|
|
|
|
setTimeout(() => notification.classList.add("show"), 10);
|
|
setTimeout(() => {
|
|
notification.classList.remove("show");
|
|
setTimeout(() => notification.remove(), 300);
|
|
}, 3000);
|
|
}
|
|
|
|
// Get Cart Total
|
|
getCartTotal() {
|
|
return this.cart.reduce((sum, item) => sum + item.price * item.quantity, 0);
|
|
}
|
|
|
|
// Get Cart Count
|
|
getCartCount() {
|
|
return this.cart.reduce((sum, item) => sum + item.quantity, 0);
|
|
}
|
|
|
|
// Clear Cart
|
|
clearCart() {
|
|
this.cart = [];
|
|
this.saveToStorage("skyart_cart", this.cart);
|
|
this.updateAllBadges();
|
|
this.renderCart();
|
|
}
|
|
}
|
|
|
|
// Initialize Shopping Manager
|
|
const shoppingManager = new ShoppingManager();
|
|
|
|
// Make it globally available
|
|
window.shoppingManager = shoppingManager;
|
|
|
|
// Navigation active state
|
|
document.addEventListener("DOMContentLoaded", () => {
|
|
const currentPage = window.location.pathname.split("/").pop() || "home.html";
|
|
document.querySelectorAll(".nav-link, .mobile-link").forEach((link) => {
|
|
const linkPage = link.getAttribute("href")?.split("/").pop();
|
|
if (linkPage === currentPage) {
|
|
link.classList.add("active");
|
|
}
|
|
});
|
|
});
|