707 lines
25 KiB
JavaScript
707 lines
25 KiB
JavaScript
// 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();
|
|
|
|
// Quantity controls on product detail page
|
|
(function initQuantityControls() {
|
|
const decr = document.getElementById("qty-decr");
|
|
const incr = document.getElementById("qty-incr");
|
|
const valueEl = document.getElementById("qty-value");
|
|
if (!decr || !incr || !valueEl) return; // Not on product detail page
|
|
|
|
function parseQty() {
|
|
const n = parseInt(valueEl.textContent || "1", 10);
|
|
return Number.isFinite(n) && n > 0 ? n : 1;
|
|
}
|
|
decr.addEventListener("click", () => {
|
|
const next = Math.max(1, parseQty() - 1);
|
|
valueEl.textContent = String(next);
|
|
});
|
|
incr.addEventListener("click", () => {
|
|
const next = parseQty() + 1;
|
|
valueEl.textContent = String(next);
|
|
});
|
|
})();
|
|
|
|
// 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 = `
|
|
<div class=\"h-72 ${imageBgClass} flex items-center justify-center\">
|
|
<img src=\"${p.image}\" alt=\"${
|
|
p.alt || p.name
|
|
}\" class=\"w-full h-full object-cover\" />
|
|
</div>
|
|
<div class=\"${panelBgClass} p-6\">
|
|
<h3 class=\"font-poppins font-semibold text-2xl text-[#3A3A3A] mb-0\">${
|
|
p.name
|
|
}</h3>
|
|
</div>`;
|
|
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);
|
|
}
|
|
})();
|
|
|
|
// Blog search functionality (only runs on blog page)
|
|
const blogSearchInput = document.getElementById("blog-search-input");
|
|
if (blogSearchInput) {
|
|
const pagination = document.getElementById("blog-pagination");
|
|
const pageButtons = document.querySelectorAll(
|
|
"#blog-pagination .blog-page-btn"
|
|
);
|
|
const nextButton = document.getElementById("blog-next-btn");
|
|
const blogTagButtons = document.querySelectorAll(".tag-filter");
|
|
let activeTag = "";
|
|
let currentPage = 1;
|
|
const pageSize = 4;
|
|
|
|
function normalize(text) {
|
|
return (text || "")
|
|
.toLowerCase()
|
|
.replace(/[^a-z0-9]+/g, " ")
|
|
.trim();
|
|
}
|
|
function getFilteredArticles() {
|
|
const articles = Array.from(
|
|
document.querySelectorAll("#main-blog-content article")
|
|
);
|
|
articles.sort((a, b) => {
|
|
const ad = a.getAttribute("data-date") || "";
|
|
const bd = b.getAttribute("data-date") || "";
|
|
if (!ad && !bd) return 0;
|
|
return bd.localeCompare(ad);
|
|
});
|
|
const query = normalize(blogSearchInput.value.trim());
|
|
return articles.filter((article) => {
|
|
const title = article.querySelector("h2")?.textContent || "";
|
|
const excerpt = article.querySelector("p")?.textContent || "";
|
|
const haystack = normalize(`${title} ${excerpt}`);
|
|
const tagList = (article.getAttribute("data-tags") || "")
|
|
.split(",")
|
|
.map((t) => normalize(t));
|
|
const matchesQuery = query === "" || haystack.includes(query);
|
|
const matchesTag = activeTag === "" || tagList.includes(activeTag);
|
|
return matchesQuery && matchesTag;
|
|
});
|
|
}
|
|
function renderPage() {
|
|
const filtered = getFilteredArticles();
|
|
const total = filtered.length;
|
|
const totalPages = Math.max(1, Math.ceil(total / pageSize));
|
|
currentPage = Math.min(Math.max(1, currentPage), totalPages);
|
|
const start = (currentPage - 1) * pageSize;
|
|
const end = start + pageSize;
|
|
const toShow = new Set(filtered.slice(start, end));
|
|
document.querySelectorAll("#main-blog-content article").forEach((a) => {
|
|
a.style.display = toShow.has(a) ? "" : "none";
|
|
});
|
|
if (pagination) {
|
|
const hasQuery = blogSearchInput.value.trim().length > 0;
|
|
pagination.style.display = hasQuery ? "none" : "flex";
|
|
pageButtons.forEach((btn) => {
|
|
const p = Number(btn.getAttribute("data-page"));
|
|
btn.classList.toggle("bg-uc-gold", p === currentPage);
|
|
btn.classList.toggle("text-white", p === currentPage);
|
|
btn.classList.toggle("bg-linen", p !== currentPage);
|
|
btn.classList.toggle("text-black", p !== currentPage);
|
|
btn.style.display = p <= totalPages ? "inline-flex" : "none";
|
|
});
|
|
if (nextButton) {
|
|
nextButton.style.display = totalPages > 1 ? "inline-flex" : "none";
|
|
nextButton.disabled = currentPage >= totalPages;
|
|
}
|
|
}
|
|
}
|
|
function filterPosts() {
|
|
currentPage = 1;
|
|
renderPage();
|
|
}
|
|
blogSearchInput.addEventListener("input", filterPosts);
|
|
blogTagButtons.forEach((btn) => {
|
|
btn.addEventListener("click", () => {
|
|
const clickedTag = normalize(btn.getAttribute("data-tag"));
|
|
activeTag = activeTag === clickedTag ? "" : clickedTag;
|
|
blogTagButtons.forEach((b) => {
|
|
b.classList.remove("border-uc-gold", "bg-gray-50", "text-uc-gold");
|
|
b.setAttribute("aria-pressed", "false");
|
|
});
|
|
if (activeTag) {
|
|
btn.classList.add("border-uc-gold", "bg-gray-50", "text-uc-gold");
|
|
btn.setAttribute("aria-pressed", "true");
|
|
}
|
|
filterPosts();
|
|
});
|
|
});
|
|
pageButtons.forEach((btn) =>
|
|
btn.addEventListener("click", () => {
|
|
currentPage = Number(btn.getAttribute("data-page")) || 1;
|
|
renderPage();
|
|
})
|
|
);
|
|
if (nextButton) {
|
|
nextButton.addEventListener("click", () => {
|
|
currentPage += 1;
|
|
renderPage();
|
|
});
|
|
}
|
|
renderPage();
|
|
}
|
|
|
|
// Inline "Read more" expansion for blog posts
|
|
const articlesForExcerpt = document.querySelectorAll(
|
|
"#main-blog-content article"
|
|
);
|
|
|
|
function truncateToWords(text, maxWords) {
|
|
const words = (text || "").trim().split(/\s+/);
|
|
if (words.length <= maxWords) return { text, truncated: false };
|
|
return { text: words.slice(0, maxWords).join(" ") + "…", truncated: true };
|
|
}
|
|
|
|
articlesForExcerpt.forEach((article) => {
|
|
const excerptP = article.querySelector("p");
|
|
const readMoreBtn = article.querySelector(".read-more-toggle");
|
|
if (!excerptP || !readMoreBtn) return;
|
|
|
|
const fullExcerpt = excerptP.textContent || "";
|
|
const { text: truncated, truncated: isTruncated } = truncateToWords(
|
|
fullExcerpt,
|
|
80
|
|
);
|
|
|
|
if (isTruncated) {
|
|
// Store full text and show truncated preview
|
|
excerptP.dataset.excerptFull = fullExcerpt;
|
|
excerptP.textContent = truncated;
|
|
readMoreBtn.style.display = "inline-block";
|
|
} else {
|
|
// Nothing to expand; hide the control
|
|
readMoreBtn.style.display = "none";
|
|
}
|
|
|
|
// Click to expand (delegated fallback added below as well)
|
|
readMoreBtn.addEventListener("click", (ev) => {
|
|
ev.preventDefault();
|
|
if (excerptP.dataset.excerptFull) {
|
|
excerptP.textContent = excerptP.dataset.excerptFull;
|
|
delete excerptP.dataset.excerptFull;
|
|
}
|
|
const fullBlock = article.querySelector(".full-content");
|
|
if (fullBlock) fullBlock.classList.remove("hidden");
|
|
readMoreBtn.style.display = "none";
|
|
});
|
|
});
|
|
|
|
// Safety net: delegated handler in case markup changes
|
|
document.addEventListener("click", (e) => {
|
|
const trigger = e.target.closest(".read-more-toggle");
|
|
if (!trigger) return;
|
|
e.preventDefault();
|
|
const article = trigger.closest("article");
|
|
if (!article) return;
|
|
const excerptP = article.querySelector("p");
|
|
if (excerptP?.dataset?.excerptFull) {
|
|
excerptP.textContent = excerptP.dataset.excerptFull;
|
|
delete excerptP.dataset.excerptFull;
|
|
}
|
|
const fullBlock = article.querySelector(".full-content");
|
|
if (fullBlock) fullBlock.classList.remove("hidden");
|
|
trigger.style.display = "none";
|
|
});
|
|
|
|
// 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);
|
|
});
|
|
});
|
|
}
|
|
// Story arrow button functionality
|
|
const storyArrowButton = document.getElementById("story-arrow-button");
|
|
if (storyArrowButton) {
|
|
storyArrowButton.addEventListener("click", function () {
|
|
// You can customize this action - for now, let's scroll to the products section
|
|
const productsSection = document.getElementById("products");
|
|
if (productsSection) {
|
|
const headerHeight = 112;
|
|
const targetPosition = productsSection.offsetTop - headerHeight;
|
|
|
|
window.scrollTo({
|
|
top: targetPosition,
|
|
behavior: "smooth",
|
|
});
|
|
}
|
|
});
|
|
}
|
|
|
|
// Product detail page functionality
|
|
(async function initProductDetail() {
|
|
console.log("Product detail script running...");
|
|
|
|
// 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;
|
|
}
|
|
|
|
// 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 product title (the main product title, not the breadcrumb)
|
|
const allH1s = document.querySelectorAll("h1");
|
|
console.log("All H1 elements:", allH1s);
|
|
if (allH1s.length > 1) {
|
|
const mainProductTitle = allH1s[1]; // The second h1 should be the product title
|
|
console.log("Main product title element:", mainProductTitle);
|
|
if (mainProductTitle) {
|
|
mainProductTitle.textContent = product.name;
|
|
}
|
|
}
|
|
|
|
// Update product description - find by text content
|
|
const allParagraphs = document.querySelectorAll("p");
|
|
console.log("All paragraphs:", allParagraphs);
|
|
const descriptionEl = Array.from(allParagraphs).find(
|
|
(p) =>
|
|
p.textContent &&
|
|
p.textContent.includes(
|
|
"Setting the bar as one of the loudest speakers"
|
|
)
|
|
);
|
|
console.log("Description element:", descriptionEl);
|
|
if (descriptionEl) {
|
|
descriptionEl.textContent = product.description;
|
|
}
|
|
|
|
// Update main product image - find by alt text
|
|
const allImages = document.querySelectorAll("img");
|
|
console.log("All images:", allImages);
|
|
const mainImage = Array.from(allImages).find(
|
|
(img) => img.alt && img.alt.includes("Asgaard sofa")
|
|
);
|
|
console.log("Main image element:", mainImage);
|
|
if (mainImage) {
|
|
mainImage.src = product.image;
|
|
mainImage.alt = product.alt || product.name;
|
|
}
|
|
|
|
// Update thumbnail images - find by alt text
|
|
if (product.images && product.images.length > 0) {
|
|
const allImages = document.querySelectorAll("img");
|
|
const thumbnails = Array.from(allImages).filter(
|
|
(img) =>
|
|
img.alt &&
|
|
(img.alt.includes("Outdoor sofa set") ||
|
|
img.alt.includes("Stuart sofa") ||
|
|
img.alt.includes("Maya sofa"))
|
|
);
|
|
console.log("Thumbnail images found:", thumbnails);
|
|
product.images.forEach((imageSrc, index) => {
|
|
if (thumbnails[index]) {
|
|
thumbnails[index].src = imageSrc;
|
|
thumbnails[index].alt = product.alt || product.name;
|
|
}
|
|
});
|
|
}
|
|
|
|
// Update size options - use the specific size-button class
|
|
if (product.sizes) {
|
|
const sizeButtons = document.querySelectorAll(".size-button");
|
|
console.log("Size buttons found:", sizeButtons);
|
|
|
|
// Hide all size buttons first
|
|
sizeButtons.forEach((button) => {
|
|
button.style.display = "none";
|
|
});
|
|
|
|
// Show and update only the buttons we need
|
|
product.sizes.forEach((size, index) => {
|
|
if (sizeButtons[index]) {
|
|
sizeButtons[index].style.display = "flex";
|
|
sizeButtons[index].textContent = size;
|
|
// Set selected size
|
|
if (size === product.selectedSize) {
|
|
sizeButtons[index].classList.remove(
|
|
"bg-floral-white",
|
|
"text-black"
|
|
);
|
|
sizeButtons[index].classList.add("bg-uc-gold", "text-white");
|
|
} else {
|
|
sizeButtons[index].classList.remove("bg-uc-gold", "text-white");
|
|
sizeButtons[index].classList.add("bg-floral-white", "text-black");
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
// Update color options - find only the rounded color buttons, not size buttons
|
|
if (product.colors) {
|
|
const allButtons = document.querySelectorAll("button");
|
|
const colorButtons = Array.from(allButtons).filter(
|
|
(button) =>
|
|
button.classList.contains("w-8") &&
|
|
button.classList.contains("h-8") &&
|
|
button.classList.contains("rounded-full") &&
|
|
!button.textContent // Color buttons should not have text content
|
|
);
|
|
console.log("Color buttons found:", colorButtons);
|
|
|
|
product.colors.forEach((color, index) => {
|
|
if (colorButtons[index]) {
|
|
colorButtons[index].style.backgroundColor = color.value;
|
|
// Set selected color
|
|
if (color.selected) {
|
|
colorButtons[index].classList.add("border-2", "border-black");
|
|
} else {
|
|
colorButtons[index].classList.remove("border-2", "border-black");
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
// 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 Tags
|
|
const tagsLabel = Array.from(allSpans).find(
|
|
(span) => span.textContent === "Tags"
|
|
);
|
|
if (tagsLabel && product.tags) {
|
|
const tagsValue =
|
|
tagsLabel.parentElement.querySelector("span:last-child");
|
|
if (tagsValue) {
|
|
tagsValue.textContent = product.tags.join(", ");
|
|
}
|
|
}
|
|
|
|
// 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
|
|
if (product.descriptionLong) {
|
|
const descriptionContainer = document.querySelector(
|
|
".max-w-5xl.mx-auto.space-y-6"
|
|
);
|
|
if (descriptionContainer) {
|
|
const descriptionParagraphs =
|
|
descriptionContainer.querySelectorAll("p");
|
|
console.log("Description paragraphs found:", descriptionParagraphs);
|
|
|
|
// Update each paragraph with the product's description content
|
|
product.descriptionLong.forEach((paragraph, index) => {
|
|
if (descriptionParagraphs[index]) {
|
|
descriptionParagraphs[index].textContent = paragraph;
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
// Update gallery images
|
|
if (product.galleryPairs) {
|
|
// Find gallery images by alt text
|
|
const allImages = document.querySelectorAll("img");
|
|
const galleryImages = Array.from(allImages).filter(
|
|
(img) =>
|
|
img.alt &&
|
|
(img.alt.includes("Sofa variant left") ||
|
|
img.alt.includes("Sofa variant right"))
|
|
);
|
|
console.log("Gallery images found:", galleryImages);
|
|
|
|
product.galleryPairs.forEach((pair, index) => {
|
|
if (galleryImages[index * 2]) {
|
|
galleryImages[index * 2].src = pair.left;
|
|
galleryImages[index * 2].alt = product.alt || product.name;
|
|
}
|
|
if (galleryImages[index * 2 + 1]) {
|
|
galleryImages[index * 2 + 1].src = pair.right;
|
|
galleryImages[index * 2 + 1].alt = product.alt || product.name;
|
|
}
|
|
});
|
|
}
|
|
|
|
// 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 relatedProducts = data.products
|
|
.filter((p) => p.category === product.category && p.id !== product.id)
|
|
.slice(0, 4);
|
|
|
|
console.log("Related products found:", relatedProducts);
|
|
|
|
relatedGrid.innerHTML = relatedProducts
|
|
.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 ${
|
|
p.name.toLowerCase().includes("asgaard")
|
|
? "bg-linen"
|
|
: "bg-white"
|
|
} flex items-center justify-center">
|
|
<img src="${p.image}" alt="${
|
|
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">${
|
|
p.name
|
|
}</h3>
|
|
</div>
|
|
</div>
|
|
</a>
|
|
`
|
|
)
|
|
.join("");
|
|
}
|
|
} catch (error) {
|
|
console.error("Error loading product data:", error);
|
|
}
|
|
})();
|
|
}
|
|
|
|
if (document.readyState === "loading") {
|
|
document.addEventListener("DOMContentLoaded", initSite);
|
|
} else {
|
|
initSite();
|
|
}
|