/**
* Shared HTML Components
* Eliminates duplication across HTML files
*/
// Component templates
const Components = {
/**
* Render cart drawer HTML
* @returns {string} Cart drawer HTML
*/
cartDrawer: () => `
`,
/**
* Render wishlist drawer HTML
* @returns {string} Wishlist drawer HTML
*/
wishlistDrawer: () => `
`,
/**
* Render navbar HTML
* @param {Object} options - Navbar options
* @param {string} options.activePage - Current active page
* @returns {string} Navbar HTML
*/
navbar: ({ activePage = "" } = {}) => {
const isActive = (page) => (page === activePage ? "active" : "");
return `
`;
},
/**
* Render footer HTML
* @returns {string} Footer HTML
*/
footer: () => `
`,
/**
* Render notification container
* @returns {string} Notification container HTML
*/
notificationContainer: () => `
`,
};
/**
* Initialize components in the DOM
* @param {Object} options - Component options
* @param {boolean} options.navbar - Include navbar
* @param {boolean} options.footer - Include footer
* @param {boolean} options.cart - Include cart drawer
* @param {boolean} options.wishlist - Include wishlist drawer
* @param {boolean} options.notifications - Include notifications
* @param {string} options.activePage - Active page for navbar
*/
function initializeComponents({
navbar = true,
footer = true,
cart = true,
wishlist = true,
notifications = true,
activePage = "",
} = {}) {
// Inject components into DOM
if (navbar) {
const navPlaceholder = document.getElementById("navbar-placeholder");
if (navPlaceholder) {
navPlaceholder.innerHTML = Components.navbar({ activePage });
}
}
if (footer) {
const footerPlaceholder = document.getElementById("footer-placeholder");
if (footerPlaceholder) {
footerPlaceholder.innerHTML = Components.footer();
}
}
if (cart) {
const cartPlaceholder = document.getElementById("cart-drawer-placeholder");
if (cartPlaceholder) {
cartPlaceholder.innerHTML = Components.cartDrawer();
}
}
if (wishlist) {
const wishlistPlaceholder = document.getElementById(
"wishlist-drawer-placeholder"
);
if (wishlistPlaceholder) {
wishlistPlaceholder.innerHTML = Components.wishlistDrawer();
}
}
if (notifications) {
const notificationPlaceholder = document.getElementById(
"notification-placeholder"
);
if (notificationPlaceholder) {
notificationPlaceholder.innerHTML = Components.notificationContainer();
}
}
// Initialize mobile menu toggle
initMobileMenu();
// Initialize cart and wishlist interactions
if (cart) initCartDrawer();
if (wishlist) initWishlistDrawer();
}
/**
* Initialize mobile menu functionality
*/
function initMobileMenu() {
const menuToggle = document.getElementById("mobileMenuToggle");
const navMenu = document.getElementById("navMenu");
if (menuToggle && navMenu) {
menuToggle.addEventListener("click", () => {
navMenu.classList.toggle("active");
menuToggle.classList.toggle("active");
});
// Close menu when clicking outside
document.addEventListener("click", (e) => {
if (
!menuToggle.contains(e.target) &&
!navMenu.contains(e.target) &&
navMenu.classList.contains("active")
) {
navMenu.classList.remove("active");
menuToggle.classList.remove("active");
}
});
}
}
/**
* Initialize cart drawer functionality
*/
function initCartDrawer() {
const cartBtn = document.getElementById("cartBtn");
const cartDrawer = document.getElementById("cartDrawer");
const closeCart = document.getElementById("closeCart");
if (cartBtn && cartDrawer) {
cartBtn.addEventListener("click", () => {
cartDrawer.classList.add("active");
document.body.style.overflow = "hidden";
updateCartUI();
});
if (closeCart) {
closeCart.addEventListener("click", () => {
cartDrawer.classList.remove("active");
document.body.style.overflow = "";
});
}
// Close on overlay click
cartDrawer.addEventListener("click", (e) => {
if (e.target === cartDrawer) {
cartDrawer.classList.remove("active");
document.body.style.overflow = "";
}
});
}
// Initialize checkout button
const checkoutBtn = document.getElementById("checkoutBtn");
if (checkoutBtn) {
checkoutBtn.addEventListener("click", () => {
window.location.href = "/checkout";
});
}
}
/**
* Initialize wishlist drawer functionality
*/
function initWishlistDrawer() {
const wishlistBtn = document.getElementById("wishlistBtn");
const wishlistDrawer = document.getElementById("wishlistDrawer");
const closeWishlist = document.getElementById("closeWishlist");
if (wishlistBtn && wishlistDrawer) {
wishlistBtn.addEventListener("click", () => {
wishlistDrawer.classList.add("active");
document.body.style.overflow = "hidden";
updateWishlistUI();
});
if (closeWishlist) {
closeWishlist.addEventListener("click", () => {
wishlistDrawer.classList.remove("active");
document.body.style.overflow = "";
});
}
// Close on overlay click
wishlistDrawer.addEventListener("click", (e) => {
if (e.target === wishlistDrawer) {
wishlistDrawer.classList.remove("active");
document.body.style.overflow = "";
}
});
}
}
/**
* Update cart UI with current items
*/
function updateCartUI() {
if (typeof CartUtils === "undefined") return;
const cart = CartUtils.getCart();
const cartItems = document.getElementById("cartItems");
const cartTotal = document.getElementById("cartTotal");
const cartBadge = document.getElementById("cartBadge");
if (cartBadge) {
cartBadge.textContent = cart.length;
cartBadge.style.display = cart.length > 0 ? "flex" : "none";
}
if (!cartItems) return;
if (cart.length === 0) {
cartItems.innerHTML = 'Your cart is empty
';
if (cartTotal) cartTotal.textContent = "$0.00";
return;
}
cartItems.innerHTML = cart
.map(
(item) => `
${item.name}
${formatPrice(item.price)}
${item.quantity}
`
)
.join("");
if (cartTotal) {
cartTotal.textContent = formatPrice(CartUtils.getCartTotal());
}
}
/**
* Update wishlist UI with current items
*/
function updateWishlistUI() {
if (typeof WishlistUtils === "undefined") return;
const wishlist = WishlistUtils.getWishlist();
const wishlistItems = document.getElementById("wishlistItems");
const wishlistBadge = document.getElementById("wishlistBadge");
if (wishlistBadge) {
wishlistBadge.textContent = wishlist.length;
wishlistBadge.style.display = wishlist.length > 0 ? "flex" : "none";
}
if (!wishlistItems) return;
if (wishlist.length === 0) {
wishlistItems.innerHTML =
'Your wishlist is empty
';
return;
}
wishlistItems.innerHTML = wishlist
.map(
(item) => `
${item.name}
${formatPrice(item.price)}
`
)
.join("");
}
// Global functions for inline event handlers
window.increaseQuantity = (productId) => {
if (typeof CartUtils !== "undefined") {
const cart = CartUtils.getCart();
const item = cart.find((item) => item.id === productId);
if (item) {
CartUtils.updateQuantity(productId, item.quantity + 1);
updateCartUI();
}
}
};
window.decreaseQuantity = (productId) => {
if (typeof CartUtils !== "undefined") {
const cart = CartUtils.getCart();
const item = cart.find((item) => item.id === productId);
if (item && item.quantity > 1) {
CartUtils.updateQuantity(productId, item.quantity - 1);
updateCartUI();
}
}
};
window.removeFromCart = (productId) => {
if (typeof CartUtils !== "undefined") {
CartUtils.removeFromCart(productId);
updateCartUI();
showNotification("Item removed from cart", "info");
}
};
window.removeFromWishlist = (productId) => {
if (typeof WishlistUtils !== "undefined") {
WishlistUtils.removeFromWishlist(productId);
updateWishlistUI();
showNotification("Item removed from wishlist", "info");
}
};
window.moveToCart = (productId) => {
if (
typeof WishlistUtils !== "undefined" &&
typeof CartUtils !== "undefined"
) {
const wishlist = WishlistUtils.getWishlist();
const item = wishlist.find((item) => item.id === productId);
if (item) {
CartUtils.addToCart(item);
WishlistUtils.removeFromWishlist(productId);
updateWishlistUI();
updateCartUI();
showNotification("Item moved to cart", "success");
}
}
};
// Initialize on DOM load
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", () => {
// Auto-initialize if data attribute is set
const autoInit = document.body.dataset.autoInitComponents;
if (autoInit !== "false") {
initializeComponents({
activePage: document.body.dataset.activePage || "",
});
}
});
} else {
// Already loaded
const autoInit = document.body.dataset.autoInitComponents;
if (autoInit !== "false") {
initializeComponents({
activePage: document.body.dataset.activePage || "",
});
}
}
// Export for manual initialization
window.Components = Components;
window.initializeComponents = initializeComponents;