mirror of
https://git.kh3group.com/georgebiri/khy_website.git
synced 2026-07-02 07:03:33 +00:00
feat: add product comparison page
This commit is contained in:
parent
a3689ca143
commit
ec844c6c88
12 changed files with 2108 additions and 86 deletions
454
scripts/main.js
454
scripts/main.js
|
|
@ -1,3 +1,11 @@
|
|||
// 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")
|
||||
);
|
||||
|
||||
// Update year in footer and handle smooth scrolling
|
||||
function initSite() {
|
||||
// Update footer year
|
||||
|
|
@ -700,6 +708,452 @@ function initSite() {
|
|||
})();
|
||||
}
|
||||
|
||||
// Product Comparison Page Functionality
|
||||
function initProductComparison() {
|
||||
console.log("=== INITIALIZING PRODUCT COMPARISON ===");
|
||||
|
||||
// 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 });
|
||||
|
||||
// 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);
|
||||
updateProductCard(1, product1);
|
||||
updateComparisonTable(product1, 1);
|
||||
}
|
||||
|
||||
if (product2) {
|
||||
console.log("Updating product card 2 with:", product2.name);
|
||||
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 = `<img src="${product.image}" alt="${product.name}" class="w-full h-full object-cover rounded-lg">`;
|
||||
}
|
||||
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 all sections
|
||||
const sections = ["general", "product", "dimensions", "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.salesPackage || "N/A", // Sales Package
|
||||
product.modelNo || "N/A", // Model Number
|
||||
product.additionalInformation?.Material || "N/A", // Secondary Material
|
||||
product.configuration || "N/A", // Configuration
|
||||
product.additionalInformation?.Upholstery || "N/A", // Upholstery Material
|
||||
product.colors?.[0]?.name || "N/A", // Upholstery Color
|
||||
];
|
||||
break;
|
||||
case "product":
|
||||
sectionData = [
|
||||
product.fillingMaterial || "N/A", // Filling Material
|
||||
product.finishType || "N/A", // Finish Type
|
||||
product.adjustableHeadrest || "N/A", // Adjustable Headrest
|
||||
product.maxLoadCapacity || "N/A", // Maximum Load Capacity
|
||||
product.originOfManufacture || "N/A", // Origin of Manufacture
|
||||
];
|
||||
break;
|
||||
case "dimensions":
|
||||
const dims = product.dimensions?.split(" x ") || [];
|
||||
sectionData = [
|
||||
dims[0] || "N/A", // Width
|
||||
dims[1] || "N/A", // Height
|
||||
dims[2] || "N/A", // Depth
|
||||
product.weight || "N/A", // Weight
|
||||
product.seatHeight || "N/A", // Seat Height
|
||||
product.legHeight || "N/A", // Leg Height
|
||||
];
|
||||
break;
|
||||
case "warranty":
|
||||
sectionData = [
|
||||
product.additionalInformation?.Warranty || "N/A", // Warranty Summary
|
||||
product.warrantyServiceType || "N/A", // Warranty Service Type
|
||||
product.coveredInWarranty || "N/A", // Covered in Warranty
|
||||
product.notCoveredInWarranty || "N/A", // Not Covered in Warranty
|
||||
product.additionalInformation?.Warranty || "N/A", // Domestic Warranty
|
||||
];
|
||||
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 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();
|
||||
}
|
||||
});
|
||||
|
||||
// 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 {
|
||||
|
|
|
|||
|
|
@ -93,8 +93,15 @@ class ProductManager {
|
|||
|
||||
// Create individual product card HTML
|
||||
createProductCard(product) {
|
||||
// Check if we're in comparison mode
|
||||
const urlParams = new URLSearchParams(window.location.search);
|
||||
const returnTo = urlParams.get("returnTo");
|
||||
const isComparisonMode = returnTo === "comparison";
|
||||
|
||||
return `
|
||||
<div class="group relative bg-light-bg rounded-lg overflow-hidden hover:shadow-lg transition-shadow">
|
||||
<div class="group relative bg-light-bg rounded-lg overflow-hidden hover:shadow-lg transition-shadow product-card" data-product-id="${
|
||||
product.id
|
||||
}">
|
||||
<div class="relative h-80 overflow-hidden">
|
||||
<img
|
||||
src="${product.image}"
|
||||
|
|
@ -105,10 +112,12 @@ class ProductManager {
|
|||
<div class="absolute inset-0 bg-dark-charcoal bg-opacity-70 opacity-0 group-hover:opacity-100 transition-opacity duration-300 flex items-center justify-center">
|
||||
<div class="text-center">
|
||||
<button
|
||||
class="bg-white text-uc-gold font-poppins font-semibold px-8 py-3 rounded-md hover:bg-uc-gold hover:text-white transition-colors"
|
||||
class="bg-white text-uc-gold font-poppins font-semibold px-8 py-3 rounded-md hover:bg-uc-gold hover:text-white transition-colors ${
|
||||
isComparisonMode ? "cursor-pointer" : ""
|
||||
}"
|
||||
onclick="productManager.viewProduct(${product.id})"
|
||||
>
|
||||
View
|
||||
${isComparisonMode ? "Add to Comparison" : "View"}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -290,8 +299,37 @@ class ProductManager {
|
|||
viewProduct(productId) {
|
||||
const product = this.products.find((p) => p.id === productId);
|
||||
if (product) {
|
||||
// Navigate to product detail page with product ID
|
||||
window.location.href = `product-detail.html?id=${productId}`;
|
||||
// Check if we're in comparison mode
|
||||
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");
|
||||
|
||||
if (returnTo === "comparison" && slot) {
|
||||
// Navigate back to comparison page with the selected product
|
||||
let comparisonUrl = "product-comparison.html?";
|
||||
|
||||
if (slot === "1") {
|
||||
// Replace product 1
|
||||
comparisonUrl += `product1=${productId}`;
|
||||
if (product2Id) {
|
||||
comparisonUrl += `&product2=${product2Id}`;
|
||||
}
|
||||
} else {
|
||||
// Replace product 2
|
||||
if (product1Id) {
|
||||
comparisonUrl += `product1=${product1Id}&`;
|
||||
}
|
||||
comparisonUrl += `product2=${productId}`;
|
||||
}
|
||||
|
||||
console.log("Navigating to comparison page:", comparisonUrl);
|
||||
window.location.href = comparisonUrl;
|
||||
} else {
|
||||
// Normal mode - navigate to product detail page
|
||||
window.location.href = `product-detail.html?id=${productId}`;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue