refactor: enhance product detail page layout and specifications display

- Updated product-detail.html to improve spacing and layout for product description and specifications.
- Removed static size and color options sections to streamline the design.
- Added dynamic rendering of product specifications in JavaScript for better user experience.
- Adjusted CSS for improved margin and height settings across various elements.
This commit is contained in:
George Birikorang 2025-09-17 22:24:55 -07:00
parent 8c42edd511
commit 197f862045
4 changed files with 385 additions and 778 deletions

View file

@ -330,58 +330,58 @@ function addThumbnailClickListeners() {
mainImg.setAttribute("data-enlarge-src", imageSrc);
console.log("Main image updated to:", imageSrc);
}
});
});
});
}
}
// Product detail page functionality
// Product detail page functionality
async function initProductDetail() {
console.log("Product detail script running...");
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;
}
// 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);
// 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);
if (!productId) {
console.log("No product ID found in URL");
return;
}
console.log("Loading product:", product);
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);
// Update page title
document.title = `${product.name} - KHY`;
if (!product) {
console.error("Product not found:", productId);
return;
}
// Update the "Product Details" title with the actual product name
const productDetailsTitle = document.getElementById(
"product-details-title"
);
if (productDetailsTitle) {
productDetailsTitle.textContent = product.name;
}
console.log("Loading product:", product);
// Update product title (the main product title, not the breadcrumb)
// 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) {
@ -445,97 +445,148 @@ async function initProductDetail() {
addThumbnailClickListeners();
}
// Update size options
const sizeContainer = document.getElementById("size-buttons-container");
console.log("Size container:", sizeContainer);
if (sizeContainer && product.sizes) {
sizeContainer.innerHTML = product.sizes
.map(
(size, index) => `
<button
class="w-8 h-8 ${
index === 0
? "bg-uc-gold text-white"
: "bg-floral-white text-black"
} font-playfair font-normal text-sm rounded flex items-center justify-center size-button"
>
${size}
</button>
`
)
.join("");
console.log("Updated size options with", product.sizes.length, "sizes");
}
// 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) => `
<div class="flex justify-between items-start py-1 border-b border-gray-100 last:border-b-0">
<span class="font-playfair font-normal text-xs text-quick-silver flex-shrink-0 mr-4">
${spec.label}:
</span>
<span class="font-playfair font-normal text-xs text-black text-right">
${spec.value}
</span>
</div>
`
)
.join("");
// Update color options
const colorContainer = document.getElementById("color-buttons-container");
console.log("Color container:", colorContainer);
if (colorContainer && product.colors) {
colorContainer.innerHTML = product.colors
.map(
(color, index) => `
<button
class="w-8 h-8 rounded-full ${
index === 0 ? "border-2 border-black" : ""
}"
style="background-color: ${color}"
></button>
`
)
.join("");
console.log(
"Updated color options with",
product.colors.length,
"colors"
"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 =
// 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);
// 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);
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
// Update description content
const descriptionContainer = document.getElementById(
"product-description-content"
);
@ -691,40 +742,40 @@ async function initProductDetail() {
? 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,
}))
);
// 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
);
// 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);
console.log("All related products found:", allRelatedProducts);
let currentPage = 1;
const pageSize = 4;
let currentPage = 1;
const pageSize = 4;
function renderRelatedProducts() {
const start = 0;
const end = currentPage * pageSize;
const productsToShow = allRelatedProducts.slice(start, end);
function renderRelatedProducts() {
const start = 0;
const end = currentPage * pageSize;
const productsToShow = allRelatedProducts.slice(start, end);
relatedGrid.innerHTML = productsToShow
.map(
(p) => `
relatedGrid.innerHTML = productsToShow
.map(
(p) => `
<a href="product-detail.html?id=${p.id}" class="block">
<div class="rounded-lg overflow-hidden bg-white shadow-sm hover:shadow-lg transition-shadow">
<div class="h-72 ${
@ -733,8 +784,8 @@ async function initProductDetail() {
: "bg-white"
} flex items-center justify-center">
<img src="${p.image}" alt="${
p.alt || p.name
}" class="w-full h-full object-cover" />
p.alt || p.name
}" class="w-full h-full object-cover" />
</div>
<div class="bg-light-bg p-6">
<h3 class="font-poppins font-semibold text-2xl text-[#3A3A3A] mb-0">${
@ -744,37 +795,37 @@ async function initProductDetail() {
</div>
</a>
`
)
.join("");
)
.join("");
// Handle "Show More" button visibility
// 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) {
const hasMore = allRelatedProducts.length > end;
showMoreBtn.style.display = hasMore ? "inline-flex" : "none";
showMoreBtn.classList.add(
"inline-flex",
"items-center",
"justify-center"
);
showMoreBtn.addEventListener("click", () => {
currentPage += 1;
renderRelatedProducts();
});
}
}
// 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();
}
// Initial render
renderRelatedProducts();
} catch (error) {
console.error("Error loading product data:", error);
}
} catch (error) {
console.error("Error loading product data:", error);
}
}
// Product Comparison Page Functionality
@ -1286,7 +1337,7 @@ function initHeroCarousel() {
// Ensure image always fits its container uniformly
heroImage.style.height = "100%";
heroImage.style.objectFit = "cover";
heroImage.style.objectFit = "cover";
// Fade in new image
heroImage.style.opacity = "1";