// Global script initialization test console.log("=== MAIN.JS LOADED ==="); console.log("Current pathname:", window.location.pathname); console.log( "Is comparison page:", window.location.pathname.includes("product-comparison.html") ); // Helper function to fix image paths for admin dashboard preview function fixImagePath(imagePath) { if (!imagePath) return imagePath; // If the path starts with "assets/", prepend "../" for admin dashboard preview if (imagePath.startsWith("assets/")) { return "../" + imagePath; } return imagePath; } // Update year in footer and handle smooth scrolling function initSite() { // Update footer year const footer = document.querySelector("footer p"); if (footer) { const currentYear = new Date().getFullYear(); footer.innerHTML = footer.innerHTML.replace("2024", currentYear); } // Smooth scrolling for navigation links const navLinks = document.querySelectorAll('.nav-link[href^="#"]'); navLinks.forEach((link) => { link.addEventListener("click", function (e) { e.preventDefault(); const targetId = this.getAttribute("href").substring(1); const targetElement = document.getElementById(targetId); if (targetElement) { const headerHeight = 112; const targetPosition = targetElement.offsetTop - headerHeight; window.scrollTo({ top: targetPosition, behavior: "smooth" }); } }); }); // Handle cross-page navigation links (links that point to other pages with anchors) const crossPageLinks = document.querySelectorAll('.nav-link[href*=".html#"]'); crossPageLinks.forEach((link) => { link.addEventListener("click", function () { // allow default navigation }); }); // Remove any lingering .active classes and avoid adding new ones const allNavLinks = document.querySelectorAll(".nav-link"); allNavLinks.forEach((a) => a.classList.remove("active")); // Do not add page-specific active state anymore // const currentPage = window.location.pathname.split("/").pop() || "index.html"; // const currentPageLink = document.querySelector(`.nav-link[href="${currentPage}"]`); // if (currentPageLink) currentPageLink.classList.add("active"); // Disable scroll-based active highlighting // (Keeping function for potential future use, but it does nothing now.) function updateActiveLink() { // no-op: active highlighting disabled globally } window.addEventListener("scroll", updateActiveLink); updateActiveLink(); // Related products (dynamic) (async function initRelated() { const grid = document.getElementById("related-grid"); if (!grid) return; // Don't run this function on product detail pages - let the product detail function handle it const urlParams = new URLSearchParams(window.location.search); const productId = urlParams.get("id"); if (productId) return; try { const res = await fetch("data/products.json", { cache: "no-store" }); const data = await res.json(); const products = Array.isArray(data.products) ? data.products : []; // Determine current product's category from the title text (fallback seating) const title = document.querySelector("h1"); const currentName = (title?.textContent || "").trim(); const current = products.find( (p) => (p.name || "").trim() === currentName ); const category = current?.category || "seating"; // Filter related: same category but not the current product const related = products.filter( (p) => p.category === category && p.name !== currentName ); let page = 1; const pageSize = 4; function render() { grid.innerHTML = ""; const start = 0; const end = page * pageSize; // cumulative show-more related.slice(start, end).forEach((p) => { const card = document.createElement("article"); card.className = "rounded-lg overflow-hidden bg-white shadow-sm"; // Distinct image background for Asgaard sofa to match others const imageBgClass = (p.name || "").toLowerCase() === "asgaard sofa" ? "bg-linen" : "bg-white"; const panelBgClass = "bg-light-bg"; card.innerHTML = `
\"${

${ p.name }

`; grid.appendChild(card); }); // Toggle show-more visibility const btn = document.getElementById("related-show-more"); if (btn) { const hasMore = related.length > page * pageSize; btn.style.display = hasMore ? "inline-flex" : "none"; // Ensure centered label btn.classList.add("inline-flex", "items-center", "justify-center"); } } const btn = document.getElementById("related-show-more"); if (btn) { btn.addEventListener("click", () => { page += 1; render(); }); } render(); } catch (e) { console.error("Failed to load related products:", e); } })(); // Footer newsletter subscribe validation and feedback (works on all pages) const siteFooter = document.querySelector("footer"); if (siteFooter) { const emailInputs = siteFooter.querySelectorAll('input[type="email"]'); emailInputs.forEach((emailInput) => { const inputRow = emailInput.closest(".flex") || emailInput.parentElement; let subscribeButton = inputRow ? inputRow.querySelector("button") : null; if (!subscribeButton) { subscribeButton = emailInput.parentElement?.querySelector("button"); } if (!subscribeButton) return; subscribeButton.type = "button"; let feedback = inputRow ? inputRow.nextElementSibling : null; if (!(feedback instanceof HTMLElement) || !feedback.dataset.feedback) { feedback = document.createElement("div"); feedback.dataset.feedback = "newsletter"; if (inputRow && inputRow.parentElement) { inputRow.parentElement.insertBefore(feedback, inputRow.nextSibling); } } feedback.className = "hidden mt-3 rounded-lg px-4 py-3 font-playfair text-base"; function showMessage(text, type) { feedback.textContent = text; feedback.className = "mt-3 rounded-lg px-4 py-3 font-playfair text-base"; if (type === "success") { feedback.classList.add( "bg-green-50", "border", "border-green-200", "text-green-800" ); } else { feedback.classList.add( "bg-red-50", "border", "border-red-200", "text-red-800" ); } feedback.classList.remove("hidden"); setTimeout(() => feedback.classList.add("hidden"), 3000); } subscribeButton.addEventListener("click", (e) => { e.preventDefault(); const value = (emailInput.value || "").trim(); const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; emailInput.classList.remove("border-red-500"); if (!emailRegex.test(value)) { emailInput.classList.add("border-red-500"); showMessage("Please enter a valid email address.", "error"); emailInput.focus(); return; } showMessage("Thank you for subscribing!", "success"); emailInput.value = ""; subscribeButton.disabled = true; setTimeout(() => (subscribeButton.disabled = false), 1200); }); }); } } // Image enlargement modal functionality (global) function addImageEnlargementListeners() { // Target both main product image AND gallery carousel images const mainProductImage = document.querySelector( ".w-full.h-80.md\\:w-\\[500px\\].md\\:h-\\[500px\\] img[data-enlarge-src]" ); const galleryImages = document.querySelectorAll( "#product-gallery-images img[data-enlarge-src]" ); const modal = document.getElementById("image-modal"); const modalImage = document.getElementById("modal-image"); const modalCloseBtn = document.getElementById("modal-close-btn"); console.log("Adding image enlargement listeners..."); console.log("Found main product image:", !!mainProductImage); console.log("Found gallery images:", galleryImages.length); console.log("Modal elements:", { modal: !!modal, modalImage: !!modalImage, modalCloseBtn: !!modalCloseBtn, }); if (!modal || !modalImage || !modalCloseBtn) { console.log("Modal elements not found, skipping image enlargement setup"); return; } // Add click listener to main product image if (mainProductImage) { console.log( `Adding click listener to main product image:`, mainProductImage.src ); mainProductImage.removeEventListener("click", handleImageClick); mainProductImage.addEventListener("click", handleImageClick); } else { console.log("Main product image not found"); } // Add click listeners to gallery carousel images galleryImages.forEach((img, index) => { console.log( `Adding click listener to gallery image ${index + 1}:`, img.src ); img.removeEventListener("click", handleImageClick); img.addEventListener("click", handleImageClick); }); function handleImageClick(e) { console.log("Image clicked!", this.src); const imageSrc = this.getAttribute("data-enlarge-src"); const imageAlt = this.getAttribute("alt"); console.log("Opening modal with image:", imageSrc); modalImage.src = imageSrc; modalImage.alt = imageAlt; // Show modal with animation modal.classList.remove("hidden"); document.body.style.overflow = "hidden"; // Prevent background scrolling // Trigger animation after a brief delay setTimeout(() => { modalImage.classList.remove("scale-95"); modalImage.classList.add("scale-100"); }, 10); } // Close modal functionality function closeModal() { // Animate out modalImage.classList.remove("scale-100"); modalImage.classList.add("scale-95"); // Hide modal after animation setTimeout(() => { modal.classList.add("hidden"); document.body.style.overflow = ""; // Restore scrolling }, 300); } modalCloseBtn.addEventListener("click", closeModal); // Close modal when clicking outside the image modal.addEventListener("click", function (e) { if (e.target === modal) { closeModal(); } }); // Close modal with Escape key document.addEventListener("keydown", function (e) { if (e.key === "Escape" && !modal.classList.contains("hidden")) { closeModal(); } }); } // Thumbnail click functionality (global) function addThumbnailClickListeners() { const thumbnails = document.querySelectorAll("[data-thumbnail-src]"); const mainImageContainer = document.querySelector( ".w-full.h-80.md\\:w-\\[500px\\].md\\:h-\\[500px\\]" ); console.log("Adding thumbnail click listeners..."); console.log("Found thumbnails:", thumbnails.length); console.log("Main image container:", !!mainImageContainer); if (!mainImageContainer) { console.log("Main image container not found"); return; } thumbnails.forEach((thumbnail, index) => { thumbnail.addEventListener("click", function () { const imageSrc = this.getAttribute("data-thumbnail-src"); console.log(`Thumbnail ${index + 1} clicked, switching to:`, imageSrc); // Update the main product image const mainImg = mainImageContainer.querySelector("img"); if (mainImg) { mainImg.src = imageSrc; mainImg.setAttribute("data-enlarge-src", imageSrc); console.log("Main image updated to:", imageSrc); } }); }); } // Function to update product details (for preview updates) function updateProductDetails(product) { console.log("Updating product details with:", product); // Update page title document.title = `${product.name} - KHY`; // Update the "Product Details" title with the actual product name const productDetailsTitle = document.getElementById("product-details-title"); if (productDetailsTitle) { productDetailsTitle.textContent = product.name; } // Update product title const productTitle = document.getElementById("product-title"); if (productTitle) { productTitle.textContent = product.name; } // Update product description const productDescription = document.getElementById("product-description"); if (productDescription) { productDescription.textContent = product.description; } // Update long description const productDescriptionContent = document.getElementById( "product-description-content" ); if (productDescriptionContent && product.descriptionLong) { if (Array.isArray(product.descriptionLong)) { productDescriptionContent.innerHTML = product.descriptionLong .map((para) => `

${para}

`) .join(""); } else { productDescriptionContent.innerHTML = `

${product.descriptionLong}

`; } } // Update specifications const specificationsContainer = document.getElementById( "product-specifications" ); if (specificationsContainer && product.additionalInformation) { specificationsContainer.innerHTML = ""; Object.entries(product.additionalInformation).forEach(([key, value]) => { if (value) { const specItem = document.createElement("div"); specItem.className = "flex justify-between items-center py-1"; specItem.innerHTML = ` ${key}: ${value} `; specificationsContainer.appendChild(specItem); } }); } // Update images if (product.images && product.images.length > 0) { // Update main image const mainImg = document.getElementById("main-product-image"); if (mainImg) { const imageSrc = fixImagePath(product.images[0]); mainImg.src = imageSrc; mainImg.setAttribute("data-enlarge-src", imageSrc); } // Update thumbnails const thumbnailContainer = document.getElementById("thumbnail-container"); if (thumbnailContainer) { thumbnailContainer.innerHTML = ""; product.images.forEach((img, index) => { const thumbnail = document.createElement("img"); thumbnail.src = fixImagePath(img); thumbnail.alt = `Product image ${index + 1}`; thumbnail.className = "thumbnail cursor-pointer transition-opacity duration-200 hover:opacity-70"; thumbnail.setAttribute("data-thumbnail-src", fixImagePath(img)); thumbnailContainer.appendChild(thumbnail); }); } } console.log("Product details updated successfully"); } // Make the function globally available window.updateProductDetails = updateProductDetails; // Product detail page functionality async function initProductDetail() { console.log("Product detail script running..."); console.log("Current URL:", window.location.href); // Check if we're on the product detail page const productTitle = document.querySelector("h1"); if (!productTitle) { console.log("No h1 found, not on product detail page"); return; } console.log("Found h1 element:", productTitle); // Get product ID from URL const urlParams = new URLSearchParams(window.location.search); const productId = parseInt(urlParams.get("id")); console.log("Product ID from URL:", productId); if (!productId) { console.log("No product ID found in URL"); return; } try { // Load product data const response = await fetch("data/products.json"); const data = await response.json(); const product = data.products.find((p) => p.id === productId); if (!product) { console.error("Product not found:", productId); return; } console.log("Loading product:", product); // Update page title document.title = `${product.name} - KHY`; // Update the "Product Details" title with the actual product name const productDetailsTitle = document.getElementById( "product-details-title" ); if (productDetailsTitle) { productDetailsTitle.textContent = product.name; } // Update product title (the main product title, not the breadcrumb) const productTitle = document.getElementById("product-title"); console.log("Product title element:", productTitle); if (productTitle) { productTitle.textContent = product.name; console.log("Updated product title to:", product.name); } // Update product description const productDescription = document.getElementById("product-description"); console.log("Product description element:", productDescription); if (productDescription) { productDescription.textContent = product.description; console.log("Updated product description to:", product.description); } // Update main product image const mainImageContainer = document.querySelector( ".w-full.h-80.md\\:w-\\[500px\\].md\\:h-\\[500px\\]" ); console.log("Main image container:", mainImageContainer); if (mainImageContainer) { mainImageContainer.innerHTML = ` ${product.alt || product.name} `; console.log("Updated main image to:", product.image); // Add image enlargement functionality to the main product image setTimeout(() => { addImageEnlargementListeners(); }, 100); } // Update thumbnail images const thumbnailContainer = document.querySelector( ".flex.flex-row.md\\:flex-col.gap-3.md\\:gap-4" ); console.log("Thumbnail container:", thumbnailContainer); if (thumbnailContainer && product.images) { thumbnailContainer.innerHTML = product.images .slice(0, 4) .map( (img, index) => `
${product.name} ${index + 1}
` ) .join(""); console.log("Updated thumbnails with", product.images.length, "images"); // Add click event listeners to thumbnails addThumbnailClickListeners(); } // Update product specifications const specificationsContainer = document.getElementById( "product-specifications" ); console.log("Specifications container:", specificationsContainer); if (specificationsContainer && product.additionalInformation) { const specifications = []; // Add key specifications from additionalInformation if (product.additionalInformation.Material) { specifications.push({ label: "Material", value: product.additionalInformation.Material, }); } if (product.additionalInformation.Design) { specifications.push({ label: "Design", value: product.additionalInformation.Design, }); } if (product.additionalInformation["Finish Options"]) { specifications.push({ label: "Finish Options", value: product.additionalInformation["Finish Options"], }); } if (product.additionalInformation.Headrest) { specifications.push({ label: "Headrest", value: product.additionalInformation.Headrest, }); } if (product.additionalInformation["Use Cases"]) { specifications.push({ label: "Use Cases", value: product.additionalInformation["Use Cases"], }); } if (product.additionalInformation.Ergonomics) { specifications.push({ label: "Ergonomics", value: product.additionalInformation.Ergonomics, }); } if (product.additionalInformation.Maintenance) { specifications.push({ label: "Maintenance", value: product.additionalInformation.Maintenance, }); } if (product.additionalInformation.Durability) { specifications.push({ label: "Durability", value: product.additionalInformation.Durability, }); } if (product.additionalInformation.Warranty) { specifications.push({ label: "Warranty", value: product.additionalInformation.Warranty, }); } // Render specifications specificationsContainer.innerHTML = specifications .map( (spec) => `
${spec.label}: ${spec.value}
` ) .join(""); console.log( "Updated specifications with", specifications.length, "items" ); } // Update product metadata - find by text content const allSpans = document.querySelectorAll("span"); // Find and update Model No. const modelNoLabel = Array.from(allSpans).find( (span) => span.textContent === "Model No." ); if (modelNoLabel && product.modelNo) { const modelNoValue = modelNoLabel.parentElement.querySelector("span:last-child"); if (modelNoValue) { modelNoValue.textContent = product.modelNo; } } // Find and update Category const categoryLabel = Array.from(allSpans).find( (span) => span.textContent === "Category" ); if (categoryLabel && product.category) { const categoryValue = categoryLabel.parentElement.querySelector("span:last-child"); if (categoryValue) { categoryValue.textContent = product.category.charAt(0).toUpperCase() + product.category.slice(1); } } // Find and update Dimensions const dimensionsLabel = Array.from(allSpans).find( (span) => span.textContent === "Dimension" ); console.log("Dimensions label found:", dimensionsLabel); console.log("Product dimensions:", product.dimensions); if (dimensionsLabel && product.dimensions) { const dimensionsValue = dimensionsLabel.parentElement.querySelector("span:last-child"); console.log("Dimensions value element:", dimensionsValue); if (dimensionsValue) { dimensionsValue.textContent = product.dimensions; console.log("Updated dimensions to:", product.dimensions); } } // Update description content const descriptionContainer = document.getElementById( "product-description-content" ); console.log("Description content container:", descriptionContainer); if (descriptionContainer && product.descriptionLong) { descriptionContainer.innerHTML = product.descriptionLong .map( (paragraph) => `

${paragraph}

` ) .join(""); console.log( "Updated description content with", product.descriptionLong.length, "paragraphs" ); } // Update gallery images with carousel const galleryContainer = document.getElementById("product-gallery-images"); const galleryBackBtn = document.getElementById("gallery-back-btn"); const galleryNextBtn = document.getElementById("gallery-next-btn"); console.log("Gallery container:", galleryContainer); console.log("Product galleryPairs:", product.galleryPairs); if (galleryContainer && product.galleryPairs) { // galleryPairs is now a simple array of image paths const allGalleryImages = product.galleryPairs; console.log("All gallery images:", allGalleryImages); // Store gallery images for carousel window.currentGalleryImages = allGalleryImages; window.currentGalleryIndex = 0; console.log("About to call renderGalleryCarousel..."); // Render initial gallery view renderGalleryCarousel(); // Show navigation arrows for looped carousel (always show if more than 2 images) if (allGalleryImages.length > 2) { galleryBackBtn.style.display = "block"; galleryNextBtn.style.display = "block"; } else { galleryBackBtn.style.display = "none"; galleryNextBtn.style.display = "none"; } console.log( "Gallery carousel:", allGalleryImages.length, "gallery images total (sliding)" ); } function renderGalleryCarousel() { console.log("renderGalleryCarousel called"); console.log("window.currentGalleryImages:", window.currentGalleryImages); console.log("galleryContainer:", galleryContainer); if (!window.currentGalleryImages || !galleryContainer) { console.log( "Early return: missing currentGalleryImages or galleryContainer" ); return; } console.log( "Rendering gallery carousel with", window.currentGalleryImages.length, "images" ); // Handle single image vs multiple images if (window.currentGalleryImages.length === 1) { // Single image - show only one image, hide arrows const image1 = window.currentGalleryImages[0]; console.log("Rendering single image:", image1); galleryContainer.innerHTML = ` `; // Hide arrows for single image galleryBackBtn.style.display = "none"; galleryNextBtn.style.display = "none"; } else { // Multiple images - show 2 images with carousel const image1 = window.currentGalleryImages[window.currentGalleryIndex]; const image2Index = (window.currentGalleryIndex + 1) % window.currentGalleryImages.length; const image2 = window.currentGalleryImages[image2Index]; console.log("Rendering multiple images:", image1, image2); galleryContainer.innerHTML = ` `; // Show arrows for multiple images galleryBackBtn.style.display = "block"; galleryBackBtn.style.opacity = "1"; galleryBackBtn.style.pointerEvents = "auto"; galleryNextBtn.style.display = "block"; galleryNextBtn.style.opacity = "1"; galleryNextBtn.style.pointerEvents = "auto"; } // Add click event listeners to gallery images for enlargement console.log("About to call addImageEnlargementListeners for gallery..."); addImageEnlargementListeners(); } // Add click handlers for looped gallery carousel navigation if (galleryBackBtn) { galleryBackBtn.addEventListener("click", function () { // Left arrow moves forward: if at last position, go to 0 window.currentGalleryIndex = (window.currentGalleryIndex + 1) % window.currentGalleryImages.length; renderGalleryCarousel(); }); } if (galleryNextBtn) { galleryNextBtn.addEventListener("click", function () { // Right arrow moves backward: if at 0, go to last position window.currentGalleryIndex = window.currentGalleryIndex === 0 ? window.currentGalleryImages.length - 1 : window.currentGalleryIndex - 1; renderGalleryCarousel(); }); } // Update related products section const relatedGrid = document.getElementById("related-grid"); if (relatedGrid && product.category) { console.log("Current product category:", product.category); console.log( "All products:", data.products.map((p) => ({ id: p.id, name: p.name, category: p.category, })) ); // Filter related products by category (excluding current product) const allRelatedProducts = data.products.filter( (p) => p.category === product.category && p.id !== product.id ); console.log("All related products found:", allRelatedProducts); let currentPage = 1; const pageSize = 4; function renderRelatedProducts() { const start = 0; const end = currentPage * pageSize; const productsToShow = allRelatedProducts.slice(start, end); relatedGrid.innerHTML = productsToShow .map( (p) => `
${
              p.alt || p.name
            }

${ p.name }

` ) .join(""); // Handle "Show More" button visibility const showMoreBtn = document.getElementById("related-show-more"); if (showMoreBtn) { const hasMore = allRelatedProducts.length > end; showMoreBtn.style.display = hasMore ? "inline-flex" : "none"; showMoreBtn.classList.add( "inline-flex", "items-center", "justify-center" ); } } // Add event listener for "Show More" button const showMoreBtn = document.getElementById("related-show-more"); if (showMoreBtn) { showMoreBtn.addEventListener("click", () => { currentPage += 1; renderRelatedProducts(); }); } // Initial render renderRelatedProducts(); } } catch (error) { console.error("Error loading product data:", error); } } // Product Comparison Page Functionality function initProductComparison() { console.log("=== INITIALIZING PRODUCT COMPARISON ==="); // Prevent running twice (it's invoked in multiple places) if (window.__cmpInitialized) { console.log("[Comparison] Already initialized, skipping"); return; } window.__cmpInitialized = true; // Get product IDs from URL parameters const urlParams = new URLSearchParams(window.location.search); const product1Id = urlParams.get("product1"); const product2Id = urlParams.get("product2"); console.log("URL Parameters:", { product1Id, product2Id }); // Keep references to the two products for event handlers let cmpProduct1 = null; let cmpProduct2 = null; // Fetch product data fetch("data/products.json") .then((response) => { console.log("Fetch response status:", response.status); return response.json(); }) .then((data) => { console.log("Products data loaded:", data); console.log("Total products:", data.products.length); // Find products by ID const product1 = data.products.find((p) => p.id == product1Id); const product2 = data.products.find((p) => p.id == product2Id); console.log("Found products:", { product1, product2 }); // Update product cards if (product1) { console.log("Updating product card 1 with:", product1.name); cmpProduct1 = product1; updateProductCard(1, product1); updateComparisonTable(product1, 1); } if (product2) { console.log("Updating product card 2 with:", product2.name); cmpProduct2 = product2; updateProductCard(2, product2); updateComparisonTable(product2, 2); } // Populate dropdown populateProductDropdown(data.products); // Update View More link with current comparison state updateViewMoreLink(product1Id, product2Id); }) .catch((error) => { console.error("Error loading products:", error); }); } function updateProductCard(slotNumber, product) { console.log(`=== UPDATING PRODUCT CARD ${slotNumber} ===`); console.log("Product data:", product); const cardContainer = document.querySelector(`.product-card-${slotNumber}`); console.log("Card container found:", cardContainer); if (cardContainer) { const imageContainer = cardContainer.querySelector("div"); const title = cardContainer.querySelector("p"); console.log("Image container found:", imageContainer); console.log("Title element found:", title); if (imageContainer) { console.log("Replacing image container with:", product.image); // Replace the placeholder div with an image imageContainer.innerHTML = `${product.name}`; } if (title) { console.log("Updating title to:", product.name); title.textContent = product.name; } } else { console.log(`Product card container .product-card-${slotNumber} not found`); } } function updateComparisonTable(product, slotNumber) { console.log(`=== UPDATING COMPARISON TABLE FOR SLOT ${slotNumber} ===`); console.log("Product:", product); // Update only sections present in the HTML const sections = ["general", "warranty"]; sections.forEach((section) => { console.log(`Updating ${section} section...`); updateTableSection(section, product, slotNumber); }); } function updateTableSection(sectionName, product, slotNumber) { console.log( `=== UPDATING TABLE SECTION: ${sectionName} (SLOT ${slotNumber}) ===` ); const sectionData = getProductSectionData(product, sectionName); // Find the section header const section = document.querySelector( `.comparison-table .${sectionName}-section` ); if (!section) { console.log(`Section ${sectionName}-section not found`); return; } // Find the table that comes after this section header const sectionTable = section.nextElementSibling; if (!sectionTable) { console.log(`Table after ${sectionName}-section not found`); return; } // Find all flex rows and filter to only those with data columns const allRows = sectionTable.querySelectorAll(".flex.items-center"); const rows = Array.from(allRows).filter((row) => row.querySelector(".column-1") ); console.log( `Found ${rows.length} data rows in ${sectionName} section (out of ${allRows.length} total rows)` ); if (rows.length > 0 && sectionData) { console.log("Updating rows with data:", sectionData); // Update each row with the corresponding data rows.forEach((row, index) => { if (index < sectionData.length) { const column = row.querySelector(`.column-${slotNumber}`); if (column) { console.log( `Updating row ${index + 1} with data: ${sectionData[index]}` ); console.log(`Row element:`, row); console.log(`Column element:`, column); console.log(`Column text before update: "${column.textContent}"`); column.textContent = sectionData[index]; console.log(`Column text after update: "${column.textContent}"`); } else { console.log(`Column ${slotNumber} not found in row ${index + 1}`); } } }); console.log("Table section updated successfully."); } else { console.log("No rows found or section data is empty, skipping update."); console.log("Rows found:", rows.length); console.log("Section data:", sectionData); } } function getProductSectionData(product, sectionName) { console.log(`=== GETTING PRODUCT SECTION DATA: ${sectionName} ===`); console.log("Product:", product); let sectionData; switch (sectionName) { case "general": sectionData = [ product.additionalInformation?.Material || "N/A", // Materials product.additionalInformation?.Design || "N/A", // Design product.additionalInformation?.["Use Cases"] || "N/A", // Use Cases ]; break; case "warranty": sectionData = [ product.additionalInformation?.Warranty || "N/A", // Warranty Summary only ]; break; default: sectionData = []; } console.log(`Section data for ${sectionName}:`, sectionData); console.log(`Detailed breakdown for ${sectionName}:`); sectionData.forEach((item, index) => { console.log(` Item ${index + 1}: "${item}"`); }); return sectionData; } function populateProductDropdown(products) { const dropdown = document.getElementById("product-dropdown"); if (dropdown) { // Clear existing options except the first one while (dropdown.children.length > 1) { dropdown.removeChild(dropdown.lastChild); } // Add all products products.forEach((product) => { const option = document.createElement("option"); option.value = product.id; option.textContent = product.name; dropdown.appendChild(option); }); // Add event listener for product selection dropdown.addEventListener("change", function () { const selectedProductId = this.value; console.log("Product selected from dropdown:", selectedProductId); if (selectedProductId && selectedProductId !== "Choose a Product") { // Find the selected product const selectedProduct = products.find((p) => p.id == selectedProductId); if (selectedProduct) { console.log("Selected product found:", selectedProduct); // Update the second product slot updateProductCard(2, selectedProduct); updateComparisonTable(selectedProduct, 2); // Update URL to include the second product updateURLParameter("product2", selectedProductId); // Reset dropdown to default option this.value = "Choose a Product"; } } }); } } function updateURLParameter(param, value) { const url = new URL(window.location); url.searchParams.set(param, value); window.history.replaceState({}, "", url); } function updateViewMoreLink(product1Id, product2Id) { const viewMoreLink = document.querySelector( 'a[href*="product-catalog.html"]' ); if (viewMoreLink) { // Determine which slot is available (1 or 2) let availableSlot = 1; if (!product1Id) { availableSlot = 1; } else if (!product2Id) { availableSlot = 2; } else { // Both slots are filled, default to slot 2 for replacement availableSlot = 2; } let newHref = `product-catalog.html?returnTo=comparison&slot=${availableSlot}`; if (product1Id) newHref += `&product1=${product1Id}`; if (product2Id) newHref += `&product2=${product2Id}`; viewMoreLink.href = newHref; console.log("Updated View More link:", newHref); } } // Initialize product comparison if on comparison page console.log("=== CHECKING IF COMPARISON PAGE INITIALIZATION SHOULD RUN ==="); console.log( "Pathname includes product-comparison.html:", window.location.pathname.includes("product-comparison.html") ); if (window.location.pathname.includes("product-comparison.html")) { console.log("Product comparison page detected, initializing immediately"); initProductComparison(); // Also try on DOMContentLoaded as backup document.addEventListener("DOMContentLoaded", function () { console.log("Product comparison page DOMContentLoaded backup"); initProductComparison(); }); } // Product Detail Page - Compare Products functionality function initProductDetailCompare() { console.log("=== INITIALIZING PRODUCT DETAIL COMPARE ==="); console.log("Current URL:", window.location.href); console.log("Pathname:", window.location.pathname); // Try to find the button immediately let compareButton = document.getElementById("compare-products-btn"); console.log("Button found by ID:", compareButton); if (!compareButton) { console.log("Button not found by ID, trying text search..."); const buttons = document.querySelectorAll("button"); console.log("Total buttons found:", buttons.length); buttons.forEach((button, index) => { console.log(`Button ${index}: "${button.textContent.trim()}"`); }); compareButton = Array.from(buttons).find( (button) => button.textContent.trim() === "Compare Products" ); console.log("Button found by text search:", compareButton); } if (compareButton) { console.log("=== ADDING CLICK LISTENER ==="); // Remove any existing listeners first compareButton.removeEventListener("click", handleCompareClick); compareButton.addEventListener("click", handleCompareClick); // Also add a direct onclick handler as backup compareButton.onclick = handleCompareClick; console.log("Click listener added successfully"); console.log("Button element:", compareButton); console.log("Button text content:", compareButton.textContent); } else { console.log("=== BUTTON NOT FOUND ==="); console.log("Compare Products button not found"); } } // Separate function for the click handler function handleCompareClick(event) { console.log("Compare Products button clicked"); event.preventDefault(); event.stopPropagation(); // Get current product ID from URL const urlParams = new URLSearchParams(window.location.search); const productId = urlParams.get("id"); console.log("Product ID from URL:", productId); if (productId) { // Navigate to comparison page with current product as product1 const comparisonUrl = `product-comparison.html?product1=${productId}`; console.log("Navigating to:", comparisonUrl); window.location.href = comparisonUrl; } else { // If no product ID, just go to comparison page console.log("No product ID found, navigating to comparison page"); window.location.href = "product-comparison.html"; } } // Initialize immediately if we're on the product detail page if (window.location.pathname.includes("product-detail.html")) { console.log( "Product detail page detected, initializing compare functionality immediately" ); initProductDetailCompare(); // Also initialize product detail loading initProductDetail(); } // Also try to initialize on DOMContentLoaded document.addEventListener("DOMContentLoaded", function () { console.log("DOMContentLoaded event fired"); if (window.location.pathname.includes("product-detail.html")) { console.log("Product detail page detected in DOMContentLoaded"); initProductDetailCompare(); // Also initialize product detail loading initProductDetail(); } }); // Initialize product comparison if on comparison page if (window.location.pathname.includes("product-comparison.html")) { document.addEventListener("DOMContentLoaded", function () { initProductComparison(); }); } // Initialize comparison functionality if on product catalog page if (window.location.pathname.includes("product-catalog.html")) { console.log("=== PRODUCT CATALOG PAGE DETECTED ==="); document.addEventListener("DOMContentLoaded", function () { console.log( "=== DOM CONTENT LOADED - INITIALIZING PRODUCT CATALOG COMPARISON ===" ); initProductCatalogComparison(); }); } // Product Catalog - Handle comparison page returns function initProductCatalogComparison() { const urlParams = new URLSearchParams(window.location.search); const returnTo = urlParams.get("returnTo"); const slot = urlParams.get("slot"); const product1Id = urlParams.get("product1"); const product2Id = urlParams.get("product2"); console.log("Product catalog comparison params:", { returnTo, slot, product1Id, product2Id, }); if (returnTo === "comparison" && slot) { console.log("Setting up comparison return functionality for slot:", slot); // Note: Product card click handling is now done in products.js viewProduct method console.log( "Comparison mode activated - View buttons will navigate to comparison page" ); } } // Replace Poppins with Playfair in all font references function updateFontClasses() { // Find all elements with font-poppins class and replace with font-playfair const poppinsElements = document.querySelectorAll(".font-poppins"); poppinsElements.forEach((element) => { element.classList.remove("font-poppins"); element.classList.add("font-playfair"); }); } // Run font update on page load document.addEventListener("DOMContentLoaded", function () { updateFontClasses(); }); if (document.readyState === "loading") { document.addEventListener("DOMContentLoaded", initSite); } else { initSite(); } // Initialize page functionality document.addEventListener("DOMContentLoaded", function () { initHeroCarousel(); initMobileMenu(); initCuratedCardsTap(); }); // Hero Carousel Functionality function initHeroCarousel() { const arrowButton = document.getElementById("story-arrow-button"); const heroImage = document.querySelector("#hero-image img"); if (!arrowButton || !heroImage) return; // Carousel images array const carouselImages = [ "../assets/images/our_story/chair.jpg", "../assets/images/our_story/booth.png", "../assets/images/our_story/screen.jpg", "../assets/images/our_story/table.jpg", "../assets/images/our_story/chair2.jpg", "../assets/images/our_story/storage.jpg", ]; let currentImageIndex = 0; // Function to update image with fade transition function updateImage(newIndex) { const newImage = new Image(); newImage.onload = function () { // Fade out current image heroImage.style.opacity = "0"; setTimeout(() => { // Change image source heroImage.src = carouselImages[newIndex]; heroImage.alt = `Carousel image ${newIndex + 1}`; // Ensure image always fits its container uniformly heroImage.style.height = "100%"; heroImage.style.objectFit = "cover"; // Fade in new image heroImage.style.opacity = "1"; // Update indicators updateIndicators(newIndex); }, 300); }; newImage.src = carouselImages[newIndex]; } // Function to update carousel indicators function updateIndicators(activeIndex) { for (let i = 0; i < 6; i++) { const indicator = document.getElementById(`carousel-indicator-${i}`); if (indicator) { indicator.style.opacity = i === activeIndex ? "1" : "0.5"; } } } // Arrow button click handler arrowButton.addEventListener("click", (e) => { e.preventDefault(); e.stopPropagation(); currentImageIndex = (currentImageIndex + 1) % carouselImages.length; updateImage(currentImageIndex); }); // Indicator click handlers for (let i = 0; i < 6; i++) { const indicator = document.getElementById(`carousel-indicator-${i}`); if (indicator) { indicator.addEventListener("click", (e) => { e.preventDefault(); e.stopPropagation(); currentImageIndex = i; updateImage(currentImageIndex); }); } } // No dynamic height capture needed; CSS handles sizing // Auto-advance carousel every 5 seconds setInterval(() => { currentImageIndex = (currentImageIndex + 1) % carouselImages.length; updateImage(currentImageIndex); }, 5000); } // Tap-to-toggle for curated cards on touch devices function initCuratedCardsTap() { try { const cards = document.querySelectorAll(".curated-card"); if (!cards || cards.length === 0) return; // Only enable on coarse pointers (touch) const isTouchLike = window.matchMedia( "(hover: none), (pointer: coarse)" ).matches; if (!isTouchLike) return; cards.forEach((card) => { card.addEventListener("click", (e) => { // Toggle active state; second tap removes it card.classList.toggle("is-active"); }); // Optional: remove active when tapping outside the card document.addEventListener("click", (evt) => { if (!card.contains(evt.target)) { card.classList.remove("is-active"); } }); }); } catch (err) { console.warn("Failed to init curated card tap behavior:", err); } } // Mobile Menu Functionality function initMobileMenu() { const mobileMenuButton = document.getElementById("mobile-menu-button"); const mobileMenuClose = document.getElementById("mobile-menu-close"); const mobileMenu = document.getElementById("mobile-menu"); const mobileMenuOverlay = document.getElementById("mobile-menu-overlay"); if ( !mobileMenuButton || !mobileMenuClose || !mobileMenu || !mobileMenuOverlay ) { console.log("Mobile menu elements not found"); return; } // Function to open mobile menu function openMobileMenu() { mobileMenu.classList.remove("translate-x-full"); mobileMenuOverlay.classList.remove("hidden"); document.body.style.overflow = "hidden"; // Prevent background scrolling } // Function to close mobile menu function closeMobileMenu() { mobileMenu.classList.add("translate-x-full"); mobileMenuOverlay.classList.add("hidden"); document.body.style.overflow = ""; // Restore scrolling } // Event listeners mobileMenuButton.addEventListener("click", openMobileMenu); mobileMenuClose.addEventListener("click", closeMobileMenu); mobileMenuOverlay.addEventListener("click", closeMobileMenu); // Close menu when clicking on navigation links const mobileNavLinks = mobileMenu.querySelectorAll("a"); mobileNavLinks.forEach((link) => { link.addEventListener("click", closeMobileMenu); }); // Close menu on escape key document.addEventListener("keydown", (e) => { if ( e.key === "Escape" && !mobileMenu.classList.contains("translate-x-full") ) { closeMobileMenu(); } }); // Handle window resize - close menu if screen becomes large window.addEventListener("resize", () => { if (window.innerWidth >= 640) { // sm breakpoint closeMobileMenu(); } }); } // Version: 4.8 - Added mobile hamburger menu functionality