Files
SkyArtShop/website/public/product.html
Local Server f8068ba54c webupdate
2026-01-19 01:17:43 -06:00

1446 lines
45 KiB
HTML

<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description" content="Product Details - Sky Art Shop" />
<title>Product - Sky Art Shop</title>
<link rel="icon" type="image/png" href="/favicon.png" />
<!-- Fonts -->
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link
href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=Poppins:wght@600;700;800&display=swap"
rel="stylesheet"
/>
<!-- Icons -->
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css"
/>
<!-- Modern Theme CSS -->
<link rel="stylesheet" href="/assets/css/modern-theme.css?v=fix34" />
<link rel="stylesheet" href="/assets/css/mobile-fixes.css?v=20260119fix3" />
<style>
/* Product page breadcrumb - force single line */
.product-breadcrumb {
display: flex !important;
flex-direction: row !important;
flex-wrap: nowrap !important;
align-items: center !important;
gap: 4px !important;
justify-content: flex-start;
margin-bottom: var(--spacing-lg);
font-size: 0.85rem;
}
.product-breadcrumb a,
.product-breadcrumb span {
display: inline-block !important;
white-space: nowrap !important;
flex-shrink: 0 !important;
}
.product-breadcrumb a {
color: var(--text-secondary);
text-decoration: none;
}
.product-breadcrumb a:hover {
color: var(--text-primary);
}
.product-breadcrumb span {
color: var(--text-light);
}
/* Mobile breadcrumb - even smaller */
@media (max-width: 768px) {
.product-breadcrumb {
font-size: 0.75rem !important;
gap: 3px !important;
margin-bottom: 12px !important;
}
/* Product detail mobile fixes */
.product-detail {
display: block !important;
width: 100% !important;
max-width: 100% !important;
padding: var(--spacing-md) 0 !important;
box-sizing: border-box !important;
}
.product-gallery {
position: static !important;
width: 100% !important;
max-width: 100% !important;
margin-bottom: var(--spacing-lg) !important;
}
.main-image {
position: relative !important;
width: 100% !important;
max-width: 100% !important;
height: 0 !important;
padding-bottom: 100% !important;
overflow: hidden !important;
border-radius: var(--radius-lg) !important;
}
.main-image img {
position: absolute !important;
top: 0 !important;
left: 0 !important;
width: 100% !important;
height: 100% !important;
object-fit: cover !important;
}
.thumbnail-gallery {
width: 100% !important;
max-width: 100% !important;
}
.product-details {
width: 100% !important;
max-width: 100% !important;
box-sizing: border-box !important;
}
.product-details h1,
#productName {
font-size: 1.3rem !important;
word-break: break-word !important;
overflow-wrap: break-word !important;
}
.container {
max-width: 100% !important;
overflow-x: hidden !important;
}
}
.product-detail {
display: grid;
grid-template-columns: 1fr 1fr;
gap: var(--spacing-2xl);
padding: var(--spacing-2xl) 0;
}
.product-gallery {
position: sticky;
top: calc(var(--navbar-height) + var(--spacing-lg));
}
.main-image {
width: 100%;
aspect-ratio: 1;
border-radius: var(--radius-lg);
overflow: hidden;
background: var(--bg-white);
margin-bottom: var(--spacing-md);
}
.main-image img {
width: 100%;
height: 100%;
object-fit: cover;
transition: var(--transition-smooth);
}
.thumbnail-gallery {
display: flex;
gap: var(--spacing-sm);
overflow-x: auto;
}
.thumbnail {
width: 80px;
height: 80px;
border-radius: var(--radius-sm);
overflow: hidden;
cursor: pointer;
border: 2px solid transparent;
transition: var(--transition-fast);
flex-shrink: 0;
}
.thumbnail:hover,
.thumbnail.active {
border-color: var(--primary-pink-dark);
}
.thumbnail img {
width: 100%;
height: 100%;
object-fit: cover;
}
.product-details h1 {
font-family: var(--font-heading);
font-size: 2.25rem;
margin-bottom: var(--spacing-sm);
}
.product-meta {
display: flex;
align-items: center;
gap: var(--spacing-lg);
margin-bottom: var(--spacing-lg);
color: var(--text-light);
font-size: 0.95rem;
}
.product-meta span {
display: flex;
align-items: center;
gap: var(--spacing-xs);
}
.product-price-large {
font-size: 2rem;
font-weight: 700;
color: var(--text-primary);
margin-bottom: var(--spacing-lg);
}
.product-description {
color: var(--text-secondary);
line-height: 1.8;
margin-bottom: var(--spacing-lg);
max-height: 150px;
overflow-y: auto;
padding-right: var(--spacing-sm);
}
.product-description::-webkit-scrollbar {
width: 6px;
}
.product-description::-webkit-scrollbar-track {
background: var(--bg-light);
border-radius: 3px;
}
.product-description::-webkit-scrollbar-thumb {
background: var(--primary-pink);
border-radius: 3px;
}
.product-description::-webkit-scrollbar-thumb:hover {
background: var(--primary-pink-dark);
}
/* Full description section - separate section below product grid */
.full-description-section {
display: grid;
grid-template-columns: 1fr 1fr;
gap: var(--spacing-xl);
margin-top: var(--spacing-xl);
padding: var(--spacing-xl);
background: var(--bg-white);
border-radius: var(--radius-lg);
box-shadow: var(--shadow-sm);
}
.full-description-section h3 {
font-family: var(--font-heading);
font-size: 1.5rem;
margin-bottom: var(--spacing-md);
color: var(--text-primary);
display: flex;
align-items: center;
gap: var(--spacing-sm);
}
.full-description-section h3 i {
color: var(--primary-pink);
}
.full-description-content {
color: var(--text-secondary);
line-height: 1.9;
font-size: 1rem;
max-height: 350px;
overflow-y: auto;
padding-right: var(--spacing-md);
}
.full-description-content::-webkit-scrollbar {
width: 8px;
}
.full-description-content::-webkit-scrollbar-track {
background: var(--bg-light);
border-radius: 4px;
}
.full-description-content::-webkit-scrollbar-thumb {
background: linear-gradient(
180deg,
var(--primary-pink) 0%,
var(--primary-pink-dark) 100%
);
border-radius: 4px;
}
.full-description-content::-webkit-scrollbar-thumb:hover {
background: var(--primary-pink-dark);
}
.full-description-left {
/* Description column - left side */
}
.full-description-right {
/* Additional info column - right side */
padding-left: var(--spacing-lg);
border-left: 1px solid var(--border-light);
}
.product-specs {
display: flex;
flex-direction: column;
gap: var(--spacing-md);
}
.spec-item {
display: flex;
justify-content: space-between;
padding: var(--spacing-sm) 0;
border-bottom: 1px solid var(--border-light);
}
.spec-item:last-child {
border-bottom: none;
}
.spec-label {
font-weight: 500;
color: var(--text-secondary);
}
.spec-value {
color: var(--text-primary);
font-weight: 600;
}
@media (max-width: 768px) {
.full-description-section {
grid-template-columns: 1fr;
}
.full-description-right {
padding-left: 0;
padding-top: var(--spacing-lg);
border-left: none;
border-top: 1px solid var(--border-light);
}
.full-description-content {
max-height: 250px;
}
}
.full-description-content p {
margin-bottom: var(--spacing-md);
}
/* Rich text content styling */
.product-description p,
.product-description ul,
.product-description ol,
.full-description-content ul,
.full-description-content ol {
margin-bottom: var(--spacing-md);
}
.product-description ul,
.product-description ol,
.full-description-content ul,
.full-description-content ol {
padding-left: var(--spacing-lg);
}
.product-description li,
.full-description-content li {
margin-bottom: var(--spacing-xs);
}
.product-description h1,
.product-description h2,
.product-description h3,
.full-description-content h1,
.full-description-content h2,
.full-description-content h3 {
margin-top: var(--spacing-lg);
margin-bottom: var(--spacing-sm);
color: var(--text-primary);
}
.product-description a,
.full-description-content a {
color: var(--primary-pink-dark);
text-decoration: underline;
}
.product-description strong,
.full-description-content strong {
font-weight: 600;
}
.read-more-btn {
background: none;
border: none;
color: var(--primary-pink-dark);
font-weight: 600;
cursor: pointer;
padding: 0;
font-size: 0.9rem;
display: inline-flex;
align-items: center;
gap: var(--spacing-xs);
transition: var(--transition-fast);
}
.read-more-btn:hover {
color: var(--text-primary);
}
.product-options {
margin-bottom: var(--spacing-xl);
}
.option-label {
font-weight: 600;
margin-bottom: var(--spacing-sm);
display: block;
}
.color-options {
display: flex;
gap: var(--spacing-sm);
flex-wrap: wrap;
}
.color-option {
width: 32px;
height: 32px;
border-radius: var(--radius-full);
cursor: pointer;
border: 2px solid var(--border-light);
transition: var(--transition-fast);
position: relative;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
}
.color-option::after {
content: attr(title);
position: absolute;
bottom: 100%;
left: 50%;
transform: translateX(-50%);
background: var(--text-primary);
color: var(--bg-white);
padding: 4px 8px;
border-radius: var(--radius-sm);
font-size: 0.75rem;
white-space: nowrap;
opacity: 0;
visibility: hidden;
transition: var(--transition-fast);
margin-bottom: 6px;
pointer-events: none;
}
.color-option:hover::after {
opacity: 1;
visibility: visible;
}
.color-option:hover,
.color-option.active {
border-color: var(--text-primary);
transform: scale(1.15);
}
.quantity-selector {
display: flex;
align-items: center;
gap: var(--spacing-md);
margin-bottom: var(--spacing-xl);
}
.qty-control {
display: flex;
align-items: center;
border: 2px solid var(--border-light);
border-radius: var(--radius-md);
overflow: hidden;
}
.qty-control button {
width: 44px;
height: 44px;
border: none;
background: var(--bg-white);
font-size: 1.2rem;
cursor: pointer;
transition: var(--transition-fast);
}
.qty-control button:hover {
background: var(--primary-pink-light);
}
.qty-control input {
width: 60px;
height: 44px;
border: none;
text-align: center;
font-size: 1rem;
font-weight: 600;
}
.qty-control input:focus {
outline: none;
}
.add-actions {
display: flex;
gap: var(--spacing-sm);
margin-bottom: var(--spacing-xl);
}
.add-actions .btn {
height: 44px;
padding: 0 var(--spacing-lg);
font-size: 0.9rem;
display: inline-flex;
align-items: center;
justify-content: center;
gap: var(--spacing-xs);
}
.add-actions .btn i {
font-size: 1rem;
}
.wishlist-btn-large {
width: 44px;
height: 44px;
min-width: 44px;
border-radius: var(--radius-md);
border: 2px solid var(--border-light);
background: var(--bg-white);
font-size: 1.1rem;
cursor: pointer;
transition: var(--transition-fast);
display: flex;
align-items: center;
justify-content: center;
}
.wishlist-btn-large:hover {
background: var(--primary-pink-light);
border-color: var(--primary-pink);
}
.wishlist-btn-large.active {
background: var(--primary-pink);
border-color: var(--primary-pink);
color: var(--text-primary);
}
.product-features {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: var(--spacing-md);
}
.feature-item {
display: flex;
align-items: center;
gap: var(--spacing-sm);
padding: var(--spacing-md);
background: var(--primary-pink-light);
border-radius: var(--radius-sm);
font-size: 0.9rem;
}
.feature-item i {
color: var(--text-primary);
font-size: 1.1rem;
}
@media (max-width: 992px) {
.product-detail {
grid-template-columns: 1fr;
}
.product-gallery {
position: static;
}
/* Related Products - Horizontal Scroll on Mobile/Tablet */
#relatedProducts.products-grid {
display: flex !important;
flex-wrap: nowrap !important;
overflow-x: auto !important;
overflow-y: hidden !important;
scroll-behavior: smooth;
-webkit-overflow-scrolling: touch;
scroll-snap-type: x mandatory;
gap: 12px;
padding-bottom: 12px;
}
#relatedProducts.products-grid .product-card {
flex: 0 0 160px;
min-width: 160px;
max-width: 160px;
scroll-snap-align: start;
}
}
@media (max-width: 480px) {
#relatedProducts.products-grid .product-card {
flex: 0 0 140px;
min-width: 140px;
max-width: 140px;
}
}
</style>
</head>
<body>
<!-- Navigation -->
<header class="nav-wrapper">
<nav class="navbar">
<a href="/home" class="nav-brand">
<img
src="/uploads/cat-png-1767324141436-368259437.png"
alt="Sky Art Shop Logo"
/>
<span>Sky Art Shop</span>
</a>
<ul class="nav-menu">
<li><a href="/home" class="nav-link">Home</a></li>
<li><a href="/shop" class="nav-link">Shop</a></li>
<li><a href="/portfolio" class="nav-link">Portfolio</a></li>
<li><a href="/blog" class="nav-link">Blog</a></li>
<li><a href="/about" class="nav-link">About</a></li>
<li><a href="/contact" class="nav-link">Contact</a></li>
</ul>
<div class="nav-actions">
<a href="/signin" class="nav-icon-btn" title="Sign In">
<i class="bi bi-person"></i>
</a>
<button class="nav-icon-btn wishlist-btn-nav" title="Wishlist">
<i class="bi bi-heart"></i>
<span class="badge wishlist-count" style="display: none">0</span>
</button>
<button class="nav-icon-btn cart-btn" title="Cart">
<i class="bi bi-bag"></i>
<span class="badge cart-count" style="display: none">0</span>
</button>
<button class="nav-mobile-toggle" aria-label="Toggle menu">
<span></span>
<span></span>
<span></span>
</button>
</div>
</nav>
</header>
<!-- Page Content -->
<main class="page-content">
<section class="section" style="padding-top: var(--spacing-lg)">
<div class="container">
<!-- Breadcrumb as single line text -->
<p
style="
font-size: 0.9rem;
margin: 0 0 16px 0;
color: #666;
white-space: nowrap;
"
>
<a href="/home" style="color: #888; text-decoration: none">Home</a>
/
<a href="/shop" style="color: #888; text-decoration: none">Shop</a>
/ <span id="productCategory" style="color: #666">Category</span>
</p>
<!-- Product Detail -->
<div class="product-detail">
<!-- Gallery -->
<div class="product-gallery">
<div class="main-image">
<img
src="https://images.unsplash.com/photo-1513519245088-0e12902e35a6?w=800&q=80"
alt="Product"
id="mainImage"
/>
</div>
<div class="thumbnail-gallery" id="thumbnailGallery">
<!-- Thumbnails loaded via JS -->
</div>
</div>
<!-- Details -->
<div class="product-details">
<h1 id="productName">Loading...</h1>
<div class="product-meta">
<span
><i class="bi bi-tag"></i>
<span id="productCategoryMeta">Category</span></span
>
<span
><i class="bi bi-box"></i> SKU:
<span id="productSKU">N/A</span></span
>
</div>
<div class="product-price-large">
$<span id="productPrice">0.00</span>
</div>
<!-- Color Options (if available) -->
<div
class="product-options"
id="colorOptions"
style="display: none"
>
<span class="option-label"
>Color: <span id="selectedColor"></span
></span>
<div class="color-options" id="colorOptionsContainer">
<!-- Colors loaded via JS -->
</div>
</div>
<!-- Quantity -->
<div class="quantity-selector">
<span class="option-label">Quantity:</span>
<div class="qty-control">
<button type="button" id="qtyMinus">-</button>
<input type="number" id="quantity" value="1" min="1" />
<button type="button" id="qtyPlus">+</button>
</div>
<span
id="stockStatus"
style="color: var(--text-light); font-size: 0.9rem"
>In Stock</span
>
</div>
<!-- Actions -->
<div class="add-actions">
<button class="btn btn-primary" id="addToCartBtn">
<i class="bi bi-cart-plus"></i> Add to Cart
</button>
<button class="wishlist-btn-large" id="wishlistBtn">
<i class="bi bi-heart"></i>
</button>
</div>
<!-- Features -->
<div class="product-features">
<div class="feature-item">
<i class="bi bi-truck"></i>
<span
>Shipping with BPMS, IDS, Post Office and Ezy Delivery</span
>
</div>
<div class="feature-item">
<i class="bi bi-geo-alt"></i>
<span>Pickup/Delivery in Belmopan</span>
</div>
<div class="feature-item">
<i class="bi bi-shield-check"></i>
<span>Secure checkout</span>
</div>
<div class="feature-item">
<i class="bi bi-award"></i>
<span>Quality guaranteed</span>
</div>
</div>
</div>
</div>
<!-- Full Description Section - Separate section below product grid -->
<div
class="full-description-section"
id="fullDescriptionSection"
style="display: none"
>
<div class="full-description-left">
<h3><i class="bi bi-info-circle"></i> About This Item</h3>
<div class="full-description-content" id="fullDescriptionContent">
<!-- Full description loaded via JS -->
</div>
</div>
<div class="full-description-right">
<h3><i class="bi bi-list-check"></i> Product Details</h3>
<div class="product-specs" id="productSpecs">
<div class="spec-item">
<span class="spec-label">SKU</span>
<span class="spec-value" id="specSku">N/A</span>
</div>
<div class="spec-item">
<span class="spec-label">Category</span>
<span class="spec-value" id="specCategory">N/A</span>
</div>
<div class="spec-item">
<span class="spec-label">Material</span>
<span class="spec-value" id="specMaterial">N/A</span>
</div>
<div class="spec-item">
<span class="spec-label">Dimensions</span>
<span class="spec-value" id="specDimensions">N/A</span>
</div>
<div class="spec-item">
<span class="spec-label">Weight</span>
<span class="spec-value" id="specWeight">N/A</span>
</div>
</div>
</div>
</div>
</div>
</section>
<!-- Related Products -->
<section class="section" style="background: var(--bg-white)">
<div class="container">
<div class="section-header">
<h2 class="section-title">You May Also Like</h2>
</div>
<div class="products-grid" id="relatedProducts">
<div
class="loading-spinner"
style="grid-column: 1/-1; margin: 40px auto"
></div>
</div>
</div>
</section>
</main>
<!-- Footer -->
<footer class="footer">
<div class="container">
<div class="footer-grid">
<div class="footer-about">
<div class="footer-brand">
<img
src="/uploads/cat-png-1767324141436-368259437.png"
alt="Sky Art Shop"
/>
<span>Sky Art Shop</span>
</div>
<p>
Your one-stop shop for scrapbooking, journaling, cardmaking, and
collaging stationery. Quality products for all your creative
needs.
</p>
<div class="footer-social" id="footerSocialLinks">
<a
href="#"
class="social-link"
id="footerFacebook"
style="display: none"
><i class="bi bi-facebook"></i
></a>
<a
href="#"
class="social-link"
id="footerInstagram"
style="display: none"
><i class="bi bi-instagram"></i
></a>
<a
href="#"
class="social-link"
id="footerTwitter"
style="display: none"
><i class="bi bi-twitter-x"></i
></a>
<a
href="#"
class="social-link"
id="footerYoutube"
style="display: none"
><i class="bi bi-youtube"></i
></a>
<a
href="#"
class="social-link"
id="footerPinterest"
style="display: none"
><i class="bi bi-pinterest"></i
></a>
<a
href="#"
class="social-link"
id="footerTiktok"
style="display: none"
><i class="bi bi-tiktok"></i
></a>
<a
href="#"
class="social-link"
id="footerWhatsapp"
style="display: none"
><i class="bi bi-whatsapp"></i
></a>
<a
href="#"
class="social-link"
id="footerLinkedin"
style="display: none"
><i class="bi bi-linkedin"></i
></a>
</div>
</div>
<div class="footer-column">
<h4>Quick Links</h4>
<ul class="footer-links">
<li><a href="/home">Home</a></li>
<li><a href="/shop">Shop</a></li>
<li><a href="/portfolio">Portfolio</a></li>
<li><a href="/blog">Blog</a></li>
<li><a href="/about">About Us</a></li>
<li><a href="/contact">Contact</a></li>
</ul>
</div>
<div class="footer-column">
<h4>Customer Service</h4>
<ul class="footer-links">
<li><a href="/faq">FAQ</a></li>
<li><a href="/shipping-info">Shipping Info</a></li>
<li><a href="/returns">Returns & Refunds</a></li>
<li><a href="/privacy">Privacy Policy</a></li>
</ul>
</div>
<div class="footer-column">
<h4>Contact Us</h4>
<ul class="footer-links">
<li><i class="bi bi-envelope"></i> skyartshop12.11@gmail.com</li>
<li><i class="bi bi-telephone"></i> (501) 608-0409</li>
<li><i class="bi bi-geo-alt"></i> Belmopan, Cayo District</li>
</ul>
</div>
</div>
<div class="footer-bottom">
<p>&copy; 2026 Sky Art Shop. All rights reserved.</p>
<p>
Made with
<i class="bi bi-heart-fill" style="color: var(--primary-pink)"></i>
for creative souls
</p>
</div>
</div>
</footer>
<!-- Cart Drawer -->
<div class="cart-overlay"></div>
<div class="cart-drawer">
<div class="cart-header">
<h3>Shopping Cart</h3>
<button class="cart-close"><i class="bi bi-x"></i></button>
</div>
<div class="cart-items"></div>
<div class="cart-footer">
<div class="cart-total">
<span>Total:</span>
<span class="cart-total-amount">$0.00</span>
</div>
<a href="/checkout" class="btn btn-primary cart-checkout-btn"
>Checkout</a
>
</div>
</div>
<!-- Wishlist Drawer -->
<div class="wishlist-overlay"></div>
<div class="wishlist-drawer">
<div class="wishlist-header">
<h3><i class="bi bi-heart"></i> My Wishlist</h3>
<button class="wishlist-close"><i class="bi bi-x"></i></button>
</div>
<div class="wishlist-items"></div>
<div class="wishlist-footer">
<a href="/shop" class="btn btn-outline">Continue Shopping</a>
</div>
</div>
<!-- Scripts -->
<script src="/assets/js/mobile-touch-fix.js"></script>
<script src="/assets/js/modern-theme.js?v=20260118g"></script>
<script src="/assets/js/customer-auth.js?v=20260116c"></script>
<script>
let currentProduct = null;
let quantity = 1;
document.addEventListener("DOMContentLoaded", async () => {
// Get product slug from URL
const pathParts = window.location.pathname.split("/");
const productSlug = pathParts[pathParts.length - 1];
console.log("Loading product with slug:", productSlug);
// Load product
currentProduct = await API.loadProduct(productSlug);
console.log("Product loaded:", currentProduct);
if (currentProduct) {
renderProduct(currentProduct);
// Save to recently viewed (per-device tracking)
saveRecentlyViewed(currentProduct.id, currentProduct);
loadRelatedProducts(currentProduct.category);
} else {
console.error("Product not found for slug:", productSlug);
document.querySelector(".product-details").innerHTML =
'<p style="padding: 40px; text-align: center;">Product not found. <a href="/shop">Return to Shop</a></p>';
}
// Quantity controls
document.getElementById("qtyMinus").addEventListener("click", () => {
if (quantity > 1) {
quantity--;
document.getElementById("quantity").value = quantity;
}
});
document.getElementById("qtyPlus").addEventListener("click", () => {
quantity++;
document.getElementById("quantity").value = quantity;
});
document.getElementById("quantity").addEventListener("change", (e) => {
quantity = Math.max(1, parseInt(e.target.value) || 1);
e.target.value = quantity;
});
// Add to cart
document
.getElementById("addToCartBtn")
.addEventListener("click", function () {
if (currentProduct) {
const btn = this;
const originalText = btn.innerHTML;
// Get selected color if any
const activeColor = document.querySelector(
".color-option.active",
);
const selectedColor = activeColor?.dataset.color || null;
const selectedImage =
activeColor?.dataset.image ||
currentProduct.images?.[0]?.image_url ||
currentProduct.imageurl ||
"";
const selectedPrice = activeColor
? parseFloat(activeColor.dataset.price)
: currentProduct.price;
// Create unique cart ID for color variants (productId-color)
const cartItemId = selectedColor
? `${currentProduct.id}-${selectedColor
.replace(/\s+/g, "-")
.toLowerCase()}`
: currentProduct.id;
for (let i = 0; i < quantity; i++) {
SkyArtShop.addToCart({
id: cartItemId,
productId: currentProduct.id,
name: currentProduct.name,
price: selectedPrice,
image: selectedImage,
color: selectedColor,
});
}
// Visual feedback
btn.innerHTML = '<i class="bi bi-check"></i> Added!';
btn.style.background = "#27ae60";
btn.style.borderColor = "#27ae60";
setTimeout(() => {
btn.innerHTML = originalText;
btn.style.background = "";
btn.style.borderColor = "";
}, 1500);
}
});
// Wishlist
document
.getElementById("wishlistBtn")
.addEventListener("click", function () {
if (currentProduct) {
const btn = this;
// Get selected color if any
const activeColor = document.querySelector(
".color-option.active",
);
const selectedColor = activeColor?.dataset.color || null;
const selectedImage =
activeColor?.dataset.image ||
currentProduct.images?.[0]?.image_url ||
currentProduct.imageurl ||
"";
const selectedPrice = activeColor
? parseFloat(activeColor.dataset.price)
: currentProduct.price;
// Create unique wishlist ID for color variants
const wishlistItemId = selectedColor
? `${currentProduct.id}-${selectedColor
.replace(/\s+/g, "-")
.toLowerCase()}`
: currentProduct.id;
const isInWishlist = SkyArtShop.isInWishlist(wishlistItemId);
SkyArtShop.toggleWishlist({
id: wishlistItemId,
productId: currentProduct.id,
name: currentProduct.name,
price: selectedPrice,
image: selectedImage,
color: selectedColor,
});
updateWishlistButton();
// Visual feedback animation
btn.style.transform = "scale(1.2)";
setTimeout(() => {
btn.style.transform = "";
}, 200);
}
});
});
// Helper function to update stock display
function updateStockDisplay(stockQty) {
const stockEl = document.getElementById("stockStatus");
const addToCartBtn = document.getElementById("addToCartBtn");
if (stockQty > 0) {
if (stockQty < 10) {
stockEl.textContent = `Only ${stockQty} left`;
stockEl.style.color = "#e67e22";
} else {
stockEl.textContent = `${stockQty} in Stock`;
stockEl.style.color = "#27ae60";
}
addToCartBtn.disabled = false;
} else {
stockEl.textContent = "Out of Stock";
stockEl.style.color = "#e74c3c";
addToCartBtn.disabled = true;
}
}
function renderProduct(product) {
document.title = `${product.name} - Sky Art Shop`;
// Basic info
document.getElementById("productName").textContent = product.name;
document.getElementById("productPrice").textContent = parseFloat(
product.price,
).toFixed(2);
// Handle description - show full version only
const fullDescription =
product.description ||
product.shortdescription ||
"No description available.";
const fullDescSection = document.getElementById(
"fullDescriptionSection",
);
const fullDescContent = document.getElementById(
"fullDescriptionContent",
);
fullDescContent.innerHTML = fullDescription;
// Always show the full description section
fullDescSection.style.display = "grid";
// Populate spec fields
const specSku = document.getElementById("specSku");
const specCategory = document.getElementById("specCategory");
const specMaterial = document.getElementById("specMaterial");
const specDimensions = document.getElementById("specDimensions");
const specWeight = document.getElementById("specWeight");
if (specSku) specSku.textContent = product.sku || "N/A";
if (specCategory)
specCategory.textContent = product.category || "General";
if (specMaterial) specMaterial.textContent = product.material || "N/A";
if (specDimensions)
specDimensions.textContent = product.dimensions || "N/A";
if (specWeight)
specWeight.textContent = product.weight
? `${product.weight} oz`
: "N/A";
document.getElementById("productCategory").textContent =
product.category || "Products";
document.getElementById("productCategoryMeta").textContent =
product.category || "General";
document.getElementById("productSKU").textContent =
product.sku || "N/A";
// Stock status
const stockEl = document.getElementById("stockStatus");
if (product.stockquantity > 0) {
if (product.stockquantity < 10) {
stockEl.textContent = `Only ${product.stockquantity} left`;
stockEl.style.color = "#e67e22";
} else {
stockEl.textContent = "In Stock";
stockEl.style.color = "#27ae60";
}
} else {
stockEl.textContent = "Out of Stock";
stockEl.style.color = "#e74c3c";
document.getElementById("addToCartBtn").disabled = true;
}
// Main image
const mainImage = document.getElementById("mainImage");
const primaryImage =
product.images?.find((img) => img.is_primary) || product.images?.[0];
// Use primary image from images array, or fallback to imageurl field, or placeholder
mainImage.src =
primaryImage?.image_url ||
product.imageurl ||
"https://images.unsplash.com/photo-1513519245088-0e12902e35a6?w=800&q=80";
// Thumbnails - show if we have images array, or create one from imageurl
const thumbnailGallery = document.getElementById("thumbnailGallery");
let displayImages =
product.images && product.images.length > 0
? product.images
: product.imageurl
? [{ image_url: product.imageurl, alt_text: product.name }]
: [];
if (displayImages.length > 0) {
thumbnailGallery.innerHTML = displayImages
.map(
(img, index) => `
<div class="thumbnail ${index === 0 ? "active" : ""}" data-image="${
img.image_url
}">
<img src="${img.image_url}" alt="${img.alt_text || product.name}">
</div>
`,
)
.join("");
// Thumbnail click handler
thumbnailGallery.querySelectorAll(".thumbnail").forEach((thumb) => {
thumb.addEventListener("click", () => {
thumbnailGallery
.querySelectorAll(".thumbnail")
.forEach((t) => t.classList.remove("active"));
thumb.classList.add("active");
mainImage.src = thumb.dataset.image;
});
});
}
// Color options
const colorVariants = product.images?.filter((img) => img.color_code);
if (colorVariants && colorVariants.length > 0) {
document.getElementById("colorOptions").style.display = "block";
const container = document.getElementById("colorOptionsContainer");
container.innerHTML = colorVariants
.map(
(v, index) => `
<div class="color-option ${index === 0 ? "active" : ""}"
style="background-color: ${v.color_code};"
data-color="${v.color_variant}"
data-image="${v.image_url}"
data-price="${v.variant_price || product.price}"
data-stock="${v.variant_stock || 0}"
title="${v.color_variant}">
</div>
`,
)
.join("");
document.getElementById("selectedColor").textContent =
colorVariants[0].color_variant;
// Update price if first variant has a variant price
if (colorVariants[0].variant_price) {
document.getElementById("productPrice").textContent = parseFloat(
colorVariants[0].variant_price,
).toFixed(2);
}
// Update stock for first color variant
updateStockDisplay(colorVariants[0].variant_stock || 0);
container.querySelectorAll(".color-option").forEach((opt) => {
opt.addEventListener("click", () => {
container
.querySelectorAll(".color-option")
.forEach((o) => o.classList.remove("active"));
opt.classList.add("active");
document.getElementById("selectedColor").textContent =
opt.dataset.color;
mainImage.src = opt.dataset.image;
// Update price to variant price
const variantPrice = parseFloat(opt.dataset.price);
document.getElementById("productPrice").textContent =
variantPrice.toFixed(2);
// Update stock display for selected color variant
const variantStock = parseInt(opt.dataset.stock) || 0;
updateStockDisplay(variantStock);
// Update wishlist button state for this color
updateWishlistButton();
});
});
}
// Update wishlist button
updateWishlistButton();
}
function updateWishlistButton() {
const btn = document.getElementById("wishlistBtn");
if (!currentProduct) return;
// Check for color variant wishlist ID
const activeColor = document.querySelector(".color-option.active");
const selectedColor = activeColor?.dataset.color || null;
const wishlistItemId = selectedColor
? `${currentProduct.id}-${selectedColor
.replace(/\s+/g, "-")
.toLowerCase()}`
: currentProduct.id;
if (SkyArtShop.isInWishlist(wishlistItemId)) {
btn.classList.add("active");
btn.innerHTML = '<i class="bi bi-heart-fill"></i>';
} else {
btn.classList.remove("active");
btn.innerHTML = '<i class="bi bi-heart"></i>';
}
}
// Recently viewed products tracking (per-device using localStorage)
function getRecentlyViewed() {
try {
return JSON.parse(
localStorage.getItem("skyart_recently_viewed") || "[]",
);
} catch {
return [];
}
}
function saveRecentlyViewed(productId, productData) {
const recent = getRecentlyViewed();
// Remove if already exists
const filtered = recent.filter((p) => p.id !== productId);
// Add to beginning
filtered.unshift({
id: productId,
name: productData.name,
category: productData.category,
timestamp: Date.now(),
});
// Keep only last 10
const trimmed = filtered.slice(0, 10);
localStorage.setItem("skyart_recently_viewed", JSON.stringify(trimmed));
}
async function loadRelatedProducts(category) {
const allProducts = await API.loadAllProducts();
const recentlyViewed = getRecentlyViewed();
// Get recently viewed product IDs (excluding current product)
const recentIds = recentlyViewed
.filter((p) => p.id !== currentProduct?.id)
.map((p) => p.id);
// First try to show products from same category that user hasn't viewed recently
let related = allProducts
.filter((p) => p.category === category && p.id !== currentProduct?.id)
.slice(0, 4);
// If user has recently viewed products, prioritize showing complementary items
// from categories they've shown interest in
if (related.length < 4 && recentlyViewed.length > 0) {
const viewedCategories = [
...new Set(recentlyViewed.map((p) => p.category)),
];
const complementary = allProducts
.filter(
(p) =>
viewedCategories.includes(p.category) &&
p.id !== currentProduct?.id &&
!related.some((r) => r.id === p.id),
)
.slice(0, 4 - related.length);
related = [...related, ...complementary];
}
const grid = document.getElementById("relatedProducts");
if (related.length > 0) {
ProductRenderer.renderProducts(grid, related);
} else {
// Show random other products if no matches
const others = allProducts
.filter((p) => p.id !== currentProduct?.id)
.slice(0, 4);
ProductRenderer.renderProducts(grid, others);
}
}
// Click handler for related products navigation
document.addEventListener("click", (e) => {
const productCard = e.target.closest(".product-card");
if (
productCard &&
!e.target.closest(".add-to-cart-btn") &&
!e.target.closest(".wishlist-btn") &&
!e.target.closest(".quick-view-btn")
) {
e.preventDefault();
const slug = productCard.dataset.productSlug;
if (slug) {
window.location.href = `/product/${slug}`;
} else {
const productId = productCard.dataset.productId;
if (productId) {
window.location.href = `/product/${productId}`;
}
}
}
});
</script>
<script src="/assets/js/accessibility.js"></script>
</body>
</html>