๐ product.php
๐ Path: /home/u621169360/domains/papayawhip-cod-251399.hostingersite.com/public_html/product.php
๐ Size: 102.3 KB
๐ Perm: 0644
๐ MIME: text/x-php
<?php
session_start();
require_once __DIR__ . '/admin-panal/includes/db.php';
$id = (int)($_GET['id'] ?? 0);
if (!$id) {
echo "<h1>Product Not Found</h1><a href='shop.php'>Return to Shop</a>";
exit;
}
$stmt = $pdo->prepare('
SELECT p.*, c.name AS category_name, c.slug AS category_slug, c.size_chart AS category_size_chart, c.measurement_type, s.name AS subcategory_name
FROM products p
LEFT JOIN categories c ON c.id = CAST(SUBSTRING_INDEX(p.category_id, ",", 1) AS UNSIGNED)
LEFT JOIN subcategories s ON s.id = CAST(SUBSTRING_INDEX(p.subcategory_id, ",", 1) AS UNSIGNED)
WHERE p.id = ? AND p.is_active = 1
');
$stmt->execute([$id]);
$product = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$product) {
echo "<h1>Product Not Found</h1><a href='shop.php'>Return to Shop</a>";
exit;
}
// Decode JSON fields
$fabricSpecs = json_decode($product['fabric_specs'], true) ?? [];
$swatches = json_decode($product['design_swatches'], true) ?? [];
$stitchOpts = json_decode($product['stitch_options'], true) ?? [];
$sizes = json_decode($product['sizes'], true) ?? [];
$trustStrip = json_decode($product['trust_strip'], true) ?? [];
$extraAddons = json_decode($product['extra_addons'], true) ?? [];
$mainImg = 'assets/placeholder-product.jpg';
if (!empty($swatches[0]['thumb'])) {
$mainImg = $swatches[0]['thumb'];
} elseif (!empty($swatches[0]['src'])) {
$mainImg = $swatches[0]['src']; // Fallback
} elseif (!empty($swatches[0]['gallery'])) {
$mainImg = $swatches[0]['gallery'][0];
}
$mainVid = '';
if (($mainImg === 'assets/placeholder-product.jpg' || empty($mainImg)) && !empty($swatches[0]['videos'])) {
$mainVid = $swatches[0]['videos'][0];
}
$basePrice = (float)$product['price_usd'];
// Related products โ same category, exclude current
$catIds = array_filter(array_map('trim', explode(',', $product['category_id'] ?? '')));
$relatedProducts = [];
if (!empty($catIds)) {
$clauses = [];
foreach ($catIds as $cid) {
$clauses[] = "FIND_IN_SET(?, p.category_id)";
}
$sql = "
SELECT p.*
FROM products p
WHERE (" . implode(' OR ', $clauses) . ") AND p.id != ? AND p.is_active = 1
ORDER BY RAND()
LIMIT 8
";
$relStmt = $pdo->prepare($sql);
$params = $catIds;
$params[] = $id;
$relStmt->execute($params);
$relatedProducts = $relStmt->fetchAll(PDO::FETCH_ASSOC);
}
$isFallbackRel = false;
if (empty($relatedProducts)) {
$relStmt = $pdo->prepare("
SELECT p.*
FROM products p
WHERE p.id != ? AND p.is_active = 1
ORDER BY RAND()
LIMIT 8
");
$relStmt->execute([$id]);
$relatedProducts = $relStmt->fetchAll(PDO::FETCH_ASSOC);
$isFallbackRel = true;
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<!-- Google tag (gtag.js) -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-Z2X2T395KZ"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'G-Z2X2T395KZ');
</script>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title><?= (!empty($product['sku']) ? htmlspecialchars($product['sku']) . ' โ ' : '') ?><?= htmlspecialchars($product['name']) ?> โ Elegance of India</title>
<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=Playfair+Display:ital@0;1&family=Roboto:ital,wght@0,300;0,400;0,500;0,700;1,400&display=swap" rel="stylesheet" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.0/css/all.min.css" />
<link rel="stylesheet" href="style.css" />
<!-- SweetAlert2 -->
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
<style>
:root {
--white: #ffffff;
--black: #111111;
}
/* โโ SweetAlert Custom styling โโ */
.swal-title-custom {
font-family: 'Playfair Display', serif !important;
font-weight: 400 !important;
font-size: 1.8rem !important;
color: #111 !important;
}
.swal-popup-custom {
border-radius: 0 !important;
font-family: 'Roboto', sans-serif !important;
}
.swal2-html-container {
font-size: 0.9rem !important;
color: #666 !important;
letter-spacing: 0.02em !important;
}
.swal-confirm-custom {
border-radius: 0 !important;
padding: 12px 24px !important;
font-size: 0.75rem !important;
font-weight: 700 !important;
letter-spacing: 0.15em !important;
text-transform: uppercase !important;
background: #111 !important;
color: #fff !important;
border: none !important;
margin-left: 10px !important;
}
.swal-cancel-custom {
border-radius: 0 !important;
padding: 12px 24px !important;
font-size: 0.75rem !important;
font-weight: 700 !important;
letter-spacing: 0.15em !important;
text-transform: uppercase !important;
background: #fff !important;
color: #111 !important;
border: 1px solid #111 !important;
}
/* โโ PRODUCT DETAIL LAYOUT โโ */
.pdp-wrapper {
max-width: 1300px;
margin: 0 auto;
padding: 32px 24px 60px;
}
.pdp-breadcrumb {
font-size: 10.5px;
letter-spacing: 0.06em;
color: var(--charcoal);
display: flex;
align-items: center;
gap: 8px;
margin-bottom: 28px;
}
.pdp-breadcrumb a { color: var(--charcoal); text-decoration: none; }
.pdp-breadcrumb a:hover { color: var(--gold); }
.pdp-breadcrumb .sep { color: var(--mid-gray); font-size: 9px; }
.pdp-breadcrumb .current { color: var(--gold); font-style: italic; }
.pdp-layout {
display: grid;
grid-template-columns: 440px 1fr;
gap: 36px;
align-items: flex-start;
}
/* โโ GALLERY โโ */
.pdp-gallery {
display: flex;
flex-direction: column;
gap: 10px;
}
.pdp-main-media {
width: 100%;
display: block;
overflow: hidden;
position: relative;
}
.pdp-main-media img, .pdp-main-media video {
width: 100%;
height: auto;
display: block;
}
.pdp-main-media img {
cursor: zoom-in;
transition: transform 0.3s ease-out;
}
.pdp-main-media:hover img {
transform: scale(2);
}
.pdp-zoom-btn {
position: absolute;
bottom: 16px;
right: 16px;
width: 36px;
height: 36px;
border-radius: 50%;
background: rgba(255, 255, 255, 0.9);
color: #111;
border: 1px solid #ddd;
display: flex;
align-items: center;
justify-content: center;
font-size: 15px;
cursor: pointer;
z-index: 10;
box-shadow: 0 4px 10px rgba(0,0,0,0.15);
transition: all 0.3s ease;
}
.pdp-zoom-btn:hover {
background: #111;
color: #fff;
transform: scale(1.05);
}
.pdp-swal-zoom-popup {
background: transparent !important;
max-width: 95vw !important;
}
.pdp-swal-zoom-image {
max-height: 90vh !important;
object-fit: contain;
margin: 0 !important;
}
.pdp-main-media video {
background: #000;
}
/* Video section */
.pdp-video-container {
margin-top: 30px;
padding-top: 20px;
border-top: 1px solid var(--mid-gray);
}
.pdp-video-title {
font-size: 10px;
font-weight: 700;
letter-spacing: 0.18em;
text-transform: uppercase;
color: var(--black);
margin-bottom: 12px;
}
.pdp-video-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 10px;
}
.pdp-video-item {
background: #000;
position: relative;
cursor: pointer;
}
.pdp-video-item video {
width: 100%;
height: 100%;
display: block;
}
.video-play-overlay {
position: absolute;
inset: 0;
display: flex;
align-items: center;
justify-content: center;
background: rgba(0,0,0,0.2);
color: #fff;
font-size: 24px;
transition: background 0.3s;
}
.pdp-video-item:hover .video-play-overlay {
background: rgba(0,0,0,0.4);
}
/* โโ PRODUCT INFO โโ */
.pdp-info {
position: sticky;
top: 100px;
}
.pdp-badge {
display: inline-block;
font-size: 9px;
font-weight: 700;
letter-spacing: 0.2em;
text-transform: uppercase;
color: var(--gold);
border: 1px solid var(--gold);
padding: 4px 12px;
margin-bottom: 16px;
}
.pdp-name {
font-size: 26px;
font-weight: 300;
color: var(--black);
line-height: 1.3;
margin-bottom: 8px;
}
/* Design swatches */
.pdp-design-label {
font-size: 10px;
font-weight: 700;
letter-spacing: 0.18em;
text-transform: uppercase;
color: var(--black);
margin-bottom: 8px;
}
.pdp-design-grid {
display: flex;
flex-wrap: wrap;
gap: 7px;
margin-bottom: 16px;
}
.design-swatch {
width: 68px;
cursor: pointer;
border: 2px solid transparent;
transition: border-color 0.2s;
text-align: center;
}
.design-swatch.active { border-color: var(--black); }
.design-swatch img, .design-swatch video {
width: 100%;
height: 80px;
display: block;
object-fit: cover;
}
.design-swatch span {
font-size: 8px;
letter-spacing: 0.06em;
color: var(--charcoal);
display: block;
padding: 3px 0 2px;
}
.design-swatch.active span { color: var(--black); font-weight: 600; }
.pdp-price {
font-size: 22px;
font-weight: 500;
color: var(--charcoal);
letter-spacing: 0.03em;
margin-bottom: 8px;
}
.pdp-shipping-note {
font-size: 10px;
letter-spacing: 0.08em;
color: var(--charcoal);
display: flex;
align-items: center;
gap: 6px;
margin-bottom: 20px;
}
.pdp-shipping-note i { color: var(--gold); font-size: 11px; }
.pdp-divider {
height: 1px;
background: var(--mid-gray);
margin: 20px 0;
}
/* Fabric details */
.pdp-spec-list {
display: grid;
grid-template-columns: auto 1fr;
gap: 8px 20px;
margin-bottom: 20px;
}
.pdp-spec-label {
font-size: 10px;
font-weight: 600;
letter-spacing: 0.14em;
text-transform: uppercase;
color: var(--charcoal);
}
.pdp-spec-value {
font-size: 11px;
letter-spacing: 0.08em;
color: #000;
}
/* Stitching selector (radio-style) */
.pdp-stitch-label {
font-size: 10px;
font-weight: 700;
letter-spacing: 0.18em;
text-transform: uppercase;
color: var(--black);
margin-bottom: 12px;
}
.pdp-stitch-grid {
display: flex;
flex-wrap: wrap;
gap: 8px;
margin-bottom: 16px;
}
.stitch-btn {
padding: 10px 16px;
font-size: 10px;
font-weight: 600;
letter-spacing: 0.1em;
text-transform: uppercase;
color: var(--charcoal);
background: var(--white);
border: 1px solid var(--mid-gray);
cursor: pointer;
transition: background 0.2s, color 0.2s, border-color 0.2s;
text-align: left;
}
.stitch-btn span.stitch-price {
display: block;
font-size: 11px;
font-weight: 400;
letter-spacing: 0.04em;
color: var(--charcoal);
margin-top: 3px;
}
.stitch-btn.selected {
background: #111;
color: #fff !important;
border-color: #111;
}
.stitch-btn.selected span.stitch-price { color: rgba(255,255,255,0.8); }
/* Size selector (shown only for Stitched / Custom) */
.pdp-size-section {
display: none;
margin-bottom: 16px;
}
.pdp-size-section.visible { display: block; }
.pdp-size-label {
font-size: 10px;
font-weight: 700;
letter-spacing: 0.18em;
text-transform: uppercase;
color: var(--black);
margin-bottom: 10px;
display: flex;
justify-content: space-between;
align-items: center;
}
.btn-size-guide {
font-size: 9px;
font-weight: 600;
letter-spacing: 0.1em;
text-transform: uppercase;
color: var(--gold);
background: none;
border: none;
border-bottom: 1px solid var(--gold);
cursor: pointer;
padding: 0;
line-height: 1.2;
transition: color 0.2s, border-color 0.2s;
}
.btn-size-guide:hover {
color: var(--black);
border-color: var(--black);
}
.size-chart-modal-backdrop {
display: none;
position: fixed;
inset: 0;
background: rgba(0,0,0,0.8);
z-index: 2000;
align-items: center;
justify-content: center;
padding: 20px;
}
.size-chart-modal-backdrop.open {
display: flex;
}
.size-chart-modal {
background: #fff;
max-width: 900px;
max-height: 90vh;
width: 100%;
position: relative;
padding: 40px 20px 20px;
overflow-y: auto;
text-align: center;
}
.size-chart-modal img {
max-width: 100%;
height: auto;
}
.size-chart-close {
position: absolute;
top: 10px;
right: 15px;
font-size: 24px;
cursor: pointer;
color: #333;
background: none;
border: none;
}
.pdp-size-grid {
display: flex;
flex-wrap: wrap;
gap: 8px;
}
.size-btn {
min-width: 52px;
padding: 9px 12px;
font-size: 10px;
font-weight: 600;
letter-spacing: 0.12em;
text-transform: uppercase;
color: var(--charcoal);
background: var(--white);
border: 1px solid var(--mid-gray);
cursor: pointer;
transition: background 0.2s, color 0.2s, border-color 0.2s;
text-align: center;
}
.size-btn:hover, .size-btn.selected {
background: #111;
color: #fff !important;
border-color: #111;
}
.pdp-total-note {
font-size: 10px;
letter-spacing: 0.08em;
color: var(--charcoal);
margin-top: 12px;
margin-bottom: 8px;
}
/* Custom measurements modal */
.measure-modal-backdrop {
display: none;
position: fixed;
inset: 0;
background: rgba(0,0,0,0.55);
z-index: 1000;
align-items: flex-start;
justify-content: center;
padding: 60px 16px 60px;
overflow-y: auto;
}
.measure-modal-backdrop.open { display: flex; }
.measure-modal {
background: var(--white);
width: 660px;
max-width: 100%;
position: relative;
padding: 44px 40px 36px;
margin-bottom: 40px;
}
.measure-modal-close {
position: absolute;
top: 14px;
right: 18px;
background: none;
border: none;
font-size: 26px;
cursor: pointer;
color: var(--charcoal);
line-height: 1;
}
.measure-modal-close:hover { color: var(--black); }
.measure-modal-title {
font-size: 10px;
font-weight: 700;
letter-spacing: 0.22em;
text-transform: uppercase;
color: var(--black);
margin-bottom: 22px;
}
.measure-unit-toggle {
display: flex;
gap: 0;
margin-bottom: 20px;
}
.unit-btn {
padding: 7px 22px;
font-size: 9.5px;
font-weight: 600;
letter-spacing: 0.12em;
text-transform: uppercase;
border: 1px solid var(--mid-gray);
background: var(--white);
color: var(--charcoal);
cursor: pointer;
transition: all 0.2s;
}
.unit-btn.active { background: var(--black); color: var(--white); border-color: var(--black); }
.measure-section-title {
font-size: 9px;
font-weight: 700;
letter-spacing: 0.2em;
text-transform: uppercase;
color: var(--gold);
border-bottom: 1px solid var(--mid-gray);
padding-bottom: 8px;
margin: 22px 0 14px;
}
.measure-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 12px 20px;
margin-bottom: 8px;
}
.measure-field {
display: flex;
flex-direction: column;
gap: 5px;
}
.measure-field label {
font-size: 9px;
font-weight: 600;
letter-spacing: 0.14em;
text-transform: uppercase;
color: var(--charcoal);
}
.measure-field input,
.measure-field select {
font-size: 11px;
color: var(--black);
background: var(--white);
border: 1px solid var(--mid-gray);
padding: 8px 10px;
outline: none;
transition: border-color 0.2s;
width: 100%;
box-sizing: border-box;
}
.measure-field input:focus, .measure-field select:focus { border-color: var(--gold); }
.measure-field input::placeholder { color: #bbb; }
.measure-waist-toggle {
display: flex;
gap: 8px;
}
.waist-btn {
flex: 1;
padding: 8px 4px;
font-size: 9px;
font-weight: 600;
letter-spacing: 0.1em;
text-transform: uppercase;
border: 1px solid var(--mid-gray);
background: var(--white);
color: var(--charcoal);
cursor: pointer;
text-align: center;
transition: all 0.2s;
}
.waist-btn.active { background: #111; color: #fff !important; border-color: #111; }
.measure-full-row { grid-column: 1 / -1; }
.measure-note {
font-size: 9.5px;
letter-spacing: 0.04em;
color: var(--charcoal);
line-height: 1.6;
margin: 18px 0;
padding: 12px 14px;
background: var(--warm-gray);
border-left: 2px solid var(--gold);
}
.measure-submit-btn {
width: 100%;
padding: 14px;
font-size: 11px;
font-weight: 700;
letter-spacing: 0.22em;
text-transform: uppercase;
background: #111;
color: #fff !important;
border: none;
cursor: pointer;
margin-top: 8px;
transition: background 0.2s;
}
.measure-submit-btn:hover { background: #333; }
/* Neck Pattern visual selector */
.neck-pattern-card {
width: 80px;
cursor: pointer;
border: 1px solid var(--mid-gray);
padding: 5px;
text-align: center;
transition: all 0.2s;
background: var(--white);
}
.neck-pattern-card:hover {
border-color: #999;
}
.neck-pattern-card.active {
border-color: var(--gold);
box-shadow: 0 0 5px rgba(201, 169, 110, 0.4);
}
.neck-pattern-card img {
width: 100%;
height: 80px;
object-fit: contain;
margin-bottom: 5px;
display: block;
background: #fafafa;
}
.neck-pattern-card span {
display: block;
font-size: 8px;
font-weight: 600;
color: var(--charcoal);
line-height: 1.2;
}
.neck-pattern-card.active span {
color: var(--black);
}
/* CTA buttons */
.pdp-cta-group {
display: flex;
flex-direction: column;
gap: 10px;
margin-bottom: 20px;
}
.btn-primary-pdp {
width: 100%;
padding: 16px 20px;
font-size: 11px;
font-weight: 700;
letter-spacing: 0.24em;
text-transform: uppercase;
background: #111;
color: #fff !important;
border: none;
cursor: pointer;
transition: background 0.25s, letter-spacing 0.25s;
display: flex;
align-items: center;
justify-content: center;
gap: 10px;
box-shadow: 0 4px 12px rgba(0,0,0,0.1);
}
.btn-primary-pdp:hover { background: #000; letter-spacing: 0.28em; box-shadow: 0 6px 16px rgba(0,0,0,0.15); transform: translateY(-1px); }
.btn-secondary-pdp {
width: 100%;
padding: 14px 20px;
font-size: 11px;
font-weight: 600;
letter-spacing: 0.18em;
text-transform: uppercase;
background: transparent;
color: var(--charcoal);
border: 1px solid var(--mid-gray);
cursor: pointer;
transition: border-color 0.25s, color 0.25s;
display: flex;
align-items: center;
justify-content: center;
gap: 10px;
}
.btn-secondary-pdp:hover { border-color: var(--black); color: var(--black); }
/* Trust strip */
.pdp-trust-strip {
display: flex;
gap: 0;
border: 1px solid var(--mid-gray);
margin-bottom: 20px;
}
.pdp-trust-item {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 4px;
padding: 12px 8px;
border-right: 1px solid var(--mid-gray);
text-align: center;
}
.pdp-trust-item:last-child { border-right: none; }
.pdp-trust-item i { color: var(--gold); font-size: 14px; }
.pdp-trust-item span {
font-size: 8.5px;
letter-spacing: 0.1em;
text-transform: uppercase;
color: var(--charcoal);
line-height: 1.3;
}
/* Dispatch info */
.pdp-dispatch-row {
display: flex;
align-items: flex-start;
gap: 12px;
font-size: 10.5px;
letter-spacing: 0.06em;
color: var(--charcoal);
padding: 12px 0;
border-bottom: 1px solid var(--mid-gray);
}
.pdp-dispatch-row:first-of-type { border-top: 1px solid var(--mid-gray); }
.pdp-dispatch-row i { color: var(--gold); font-size: 15px; margin-top: 1px; flex-shrink: 0; }
@media (max-width: 1024px) {
.pdp-layout { grid-template-columns: 1fr 400px; gap: 40px; }
}
@media (max-width: 768px) {
.pdp-layout { grid-template-columns: 1fr; }
.pdp-info { position: static; }
}
/* โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
RELATED PRODUCTS SECTION
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ */
.related-section {
max-width: 1300px;
margin: 0 auto 60px;
padding: 0 24px;
}
.related-section-head {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 32px;
padding-bottom: 16px;
border-bottom: 1px solid #ede8df;
}
.related-section-head h2 {
font-size: 14px;
font-weight: 600;
letter-spacing: 0.22em;
text-transform: uppercase;
color: #1a1a1a;
margin: 0;
}
.related-section-head h2 span {
display: block;
font-size: 11px;
font-weight: 400;
letter-spacing: 0.08em;
color: #c9a96e;
margin-top: 4px;
text-transform: none;
}
.related-view-all {
font-size: 11px;
font-weight: 600;
letter-spacing: 0.14em;
text-transform: uppercase;
color: #1a1a1a;
text-decoration: none;
border-bottom: 1.5px solid #c9a96e;
padding-bottom: 2px;
transition: color 0.2s;
white-space: nowrap;
flex-shrink: 0;
}
.related-view-all:hover { color: #c9a96e; }
.related-grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 24px;
}
.related-card {
position: relative;
background: #fff;
cursor: pointer;
group: true;
}
.related-card-img {
position: relative;
overflow: hidden;
aspect-ratio: 3/4;
background: #f5f0e8;
}
.related-card-img img {
width: 100%;
height: 100%;
object-fit: cover;
display: block;
transition: transform 0.5s cubic-bezier(0.4,0,0.2,1);
}
.related-card:hover .related-card-img img {
transform: scale(1.06);
}
.related-card-badge {
position: absolute;
top: 12px;
left: 12px;
background: #1a1a1a;
color: #c9a96e;
font-size: 8.5px;
font-weight: 700;
letter-spacing: 0.18em;
text-transform: uppercase;
padding: 4px 10px;
z-index: 2;
}
.related-card-actions {
position: absolute;
bottom: 0;
left: 0;
right: 0;
display: flex;
flex-direction: column;
gap: 6px;
padding: 12px;
background: linear-gradient(to top, rgba(0,0,0,0.72) 0%, transparent 100%);
opacity: 0;
transform: translateY(6px);
transition: opacity 0.3s ease, transform 0.3s ease;
z-index: 3;
}
.related-card:hover .related-card-actions {
opacity: 1;
transform: translateY(0);
}
.related-btn-bag {
width: 100%;
padding: 10px 12px;
font-size: 9.5px;
font-weight: 700;
letter-spacing: 0.16em;
text-transform: uppercase;
background: #c9a96e;
color: #fff;
border: none;
cursor: pointer;
transition: background 0.2s;
display: flex;
align-items: center;
justify-content: center;
gap: 7px;
}
.related-btn-bag:hover { background: #b8956a; }
.related-card-info {
padding: 14px 4px 4px;
}
.related-card-cat {
font-size: 9px;
letter-spacing: 0.14em;
text-transform: uppercase;
color: #c9a96e;
margin-bottom: 5px;
}
.related-card-name {
font-size: 13px;
font-weight: 400;
color: #1a1a1a;
margin-bottom: 6px;
line-height: 1.3;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.related-card-price {
font-size: 14px;
font-weight: 600;
color: #1a1a1a;
letter-spacing: 0.04em;
}
.related-card-link {
position: absolute;
inset: 0;
z-index: 1;
}
/* โโ RESPONSIVE DESIGN โโ */
@media (max-width: 1024px) {
.related-grid { grid-template-columns: repeat(3, 1fr); }
.pdp-layout { gap: 24px; grid-template-columns: 400px 1fr; }
}
@media (max-width: 900px) {
.pdp-layout {
grid-template-columns: 1fr;
gap: 32px;
}
.pdp-info {
position: static;
}
.pdp-main-media {
max-height: 600px; /* limit height on mobile */
}
.pdp-main-media img, .pdp-main-media video {
object-fit: contain;
max-height: 600px;
}
}
@media (max-width: 768px) {
.related-section-head {
flex-direction: column;
align-items: flex-start;
gap: 12px;
margin-bottom: 24px;
padding-bottom: 12px;
}
.related-grid { grid-template-columns: repeat(2, 1fr); gap: 16px; }
.related-card-actions { opacity: 1; transform: none; }
}
@media (max-width: 600px) {
.measure-modal-backdrop { padding: 20px 8px 40px !important; }
.measure-modal { padding: 30px 12px 25px !important; }
.measure-modal-title { font-size: 9.5px !important; margin-bottom: 20px !important; }
.measure-grid { grid-template-columns: 1fr !important; gap: 15px !important; }
.measure-submit-btn { padding: 13px !important; font-size: 10px !important; }
.measure-modal-close { top: 12px; right: 12px; font-size: 24px; }
.pdp-wrapper { padding: 15px 12px 40px !important; }
.pdp-name { font-size: 20px; }
.pdp-price { font-size: 19px; }
}
@media (max-width: 500px) {
.related-grid { grid-template-columns: 1fr; gap: 32px; }
.related-section { padding: 0 20px; }
.related-card-info { text-align: left; padding: 18px 5px; }
.related-card-name { font-size: 15px; }
.related-card-price { font-size: 14px; }
.related-btn-bag { padding: 12px; font-size: 11px; }
}
</style>
</head>
<body>
<!-- HEADER -->
<?php include 'inc/header.php'; ?>
<!-- PRODUCT DETAIL -->
<div class="pdp-wrapper">
<!-- Breadcrumb -->
<nav class="pdp-breadcrumb" aria-label="Breadcrumb">
<a href="index.php">Home</a>
<span class="sep"><i class="fas fa-chevron-right"></i></span>
<a href="shop.php">Shop All</a>
<span class="sep"><i class="fas fa-chevron-right"></i></span>
<?php if ($product['category_name']): ?>
<a href="shop.php?cat=<?= htmlspecialchars(current(explode(',', $product['category_id']))) ?>"><?= htmlspecialchars($product['category_name']) ?></a>
<span class="sep"><i class="fas fa-chevron-right"></i></span>
<?php endif; ?>
<span class="current"><?= htmlspecialchars($product['name']) ?></span>
</nav>
<div class="pdp-layout">
<!-- GALLERY -->
<div class="pdp-gallery">
<div class="pdp-main-media" id="pdpMainMedia">
<button id="pdpZoomBtn" class="pdp-zoom-btn" aria-label="Zoom Image" style="<?= $mainVid ? 'display:none;' : 'display:flex;' ?>">
<i class="fas fa-expand-arrows-alt"></i>
</button>
<img src="<?= htmlspecialchars($mainImg) ?>" alt="<?= htmlspecialchars($product['name']) ?>" id="pdpMainImgEl" style="<?= $mainVid ? 'display:none;' : '' ?>" />
<video id="pdpMainVidEl" src="<?= htmlspecialchars($mainVid) ?>" controls autoplay muted loop playsinline style="<?= $mainVid ? 'display:block; width:100%; height:auto;' : 'display:none;' ?>"></video>
</div>
<!-- Gallery Thumbnails (Images + Videos) -->
<div id="pdpSwatchGallery" style="display: flex; gap: 10px; margin-top: 15px; justify-content: center; flex-wrap: wrap;">
<?php
$initialThumb = $swatches[0]['thumb'] ?? $swatches[0]['src'] ?? '';
$initialGallery = $swatches[0]['gallery'] ?? [];
$initialVideos = $swatches[0]['videos'] ?? [];
if ($initialThumb) {
// Ensure thumb is first in gallery
array_unshift($initialGallery, $initialThumb);
$initialGallery = array_values(array_unique($initialGallery));
}
// Render Images
foreach ($initialGallery as $index => $gImg):
?>
<div class="gallery-thumb <?= $index === 0 ? 'active' : '' ?>" style="width: 50px; height: 65px; cursor: pointer; border: 1px solid #eee; overflow: hidden; opacity: <?= $index === 0 ? '1' : '0.6' ?>;" onclick="switchMainImage('<?= htmlspecialchars($gImg) ?>', this)">
<img src="<?= htmlspecialchars($gImg) ?>" style="width: 100%; height: 100%; object-fit: cover;" />
</div>
<?php endforeach; ?>
<?php
// Render Videos
foreach ($initialVideos as $vIndex => $vFile):
?>
<div class="gallery-thumb gallery-video-thumb <?= (empty($initialGallery) && $vIndex === 0) ? 'active' : '' ?>" style="width: 50px; height: 65px; cursor: pointer; border: 1px solid #eee; overflow: hidden; opacity: <?= (empty($initialGallery) && $vIndex === 0) ? '1' : '0.6' ?>; background: #000; position: relative;" onclick="switchMainVideo('<?= htmlspecialchars($vFile) ?>', this)">
<video src="<?= htmlspecialchars($vFile) ?>" style="width: 100%; height: 100%; object-fit: cover;" muted></video>
<div style="position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; color: #fff; font-size: 10px; background: rgba(0,0,0,0.2);">
<i class="fas fa-play"></i>
</div>
</div>
<?php endforeach; ?>
</div>
</div>
<!-- PRODUCT INFO -->
<div class="pdp-info">
<?php if ($product['badge_text']): ?>
<span class="pdp-badge" style="border-color: <?= htmlspecialchars($product['badge_color'] ?? 'var(--gold)') ?>; color: <?= htmlspecialchars($product['badge_color'] ?? 'var(--gold)') ?>;">
<?= htmlspecialchars($product['badge_text']) ?>
</span>
<?php endif; ?>
<h1 class="pdp-name" style="margin-bottom:4px;"><?= htmlspecialchars($product['name']) ?></h1>
<?php if (!empty($product['sku'])): ?>
<p class="pdp-name" style="margin-bottom:16px; font-size: 0.9rem;">Catalog Name: <?= htmlspecialchars($product['sku']) ?></p>
<?php endif; ?>
<p class="pdp-price" id="pdpPrice" data-base-price="<?= $basePrice ?>">USD <?= number_format($basePrice, 2) ?></p>
<?php if ($product['shipping_note']): ?>
<p class="pdp-shipping-note"><i class="fas fa-truck"></i> <?= htmlspecialchars($product['shipping_note']) ?></p>
<?php endif; ?>
<!-- Stock Display -->
<?php
$initialStock = $swatches[0]['stock_status'] ?? 'in';
$stockText = ($initialStock == 'in') ? 'In Stock' : 'Out of Stock';
$stockColor = ($initialStock == 'in') ? '#2e7d32' : '#c0392b';
?>
<p id="pdpStock" style="font-size: 11px; margin-bottom: 20px; color: <?= $stockColor ?>; font-weight: 700; text-transform: uppercase; letter-spacing: 0.1em;">
Status: <span id="pdpStockVal"><?= $stockText ?></span>
</p>
<div class="pdp-divider"></div>
<!-- Fabric Details -->
<?php if (!empty($fabricSpecs)): ?>
<div class="pdp-spec-list">
<?php foreach ($fabricSpecs as $spec): ?>
<span class="pdp-spec-label"><?= htmlspecialchars($spec['label']) ?></span>
<span class="pdp-spec-value"><?= htmlspecialchars($spec['value']) ?></span>
<?php endforeach; ?>
</div>
<div class="pdp-divider"></div>
<?php endif; ?>
<!-- Design Selector -->
<?php if (!empty($swatches)): ?>
<p class="pdp-design-label">Select Design</p>
<div class="pdp-design-grid" id="pdpDesignGrid">
<?php foreach ($swatches as $i => $swatch):
$sThumb = $swatch['thumb'] ?? $swatch['src'] ?? 'assets/placeholder-product.jpg';
$sVid = (!empty($swatch['videos'])) ? $swatch['videos'][0] : '';
$gallery = $swatch['gallery'] ?? [];
if ($sThumb && $sThumb != 'assets/placeholder-product.jpg') {
array_unshift($gallery, $sThumb);
$gallery = array_values(array_unique($gallery));
}
if (empty($gallery) && !$sVid) $gallery = ['assets/placeholder-product.jpg'];
?>
<div class="design-swatch <?= $i === 0 ? 'active' : '' ?>"
data-src="<?= htmlspecialchars($sThumb) ?>"
data-gallery='<?= json_encode($gallery) ?>'
data-videos='<?= json_encode($swatch['videos'] ?? []) ?>'
data-stock="<?= htmlspecialchars($swatch['stock_status'] ?? 'in') ?>"
data-design-code="<?= htmlspecialchars($swatch['design_code'] ?? '') ?>">
<?php if ($sThumb && $sThumb != 'assets/placeholder-product.jpg'): ?>
<img src="<?= htmlspecialchars($sThumb) ?>" alt="<?= htmlspecialchars($swatch['label'] ?? '') ?>" />
<?php elseif ($sVid): ?>
<video src="<?= htmlspecialchars($sVid) ?>" muted></video>
<?php else: ?>
<img src="assets/placeholder-product.jpg" alt="<?= htmlspecialchars($swatch['label'] ?? '') ?>" />
<?php endif; ?>
<span><?= htmlspecialchars($swatch['label'] ?? '') ?></span>
</div>
<?php endforeach; ?>
</div>
<div class="pdp-divider"></div>
<?php endif; ?>
<!-- Stitching Options -->
<?php if (!empty($stitchOpts)): ?>
<p class="pdp-stitch-label">Stitching</p>
<div class="pdp-stitch-grid" id="pdpStitchGrid">
<?php foreach ($stitchOpts as $i => $opt):
$price = (float)$opt['price'];
?>
<button class="stitch-btn <?= $i === 0 ? 'selected' : '' ?>" data-price="<?= $price ?>" data-type="<?= htmlspecialchars($opt['type']) ?>">
<?= htmlspecialchars($opt['label']) ?>
<span class="stitch-price"><?= $price == 0 ? 'USD 0.00' : "+ USD " . number_format($price, 2) ?></span>
</button>
<?php endforeach; ?>
</div>
<?php endif; ?>
<!-- Extra Add-ons -->
<?php if (!empty($extraAddons)): ?>
<p class="pdp-stitch-label" style="margin-top:20px;">Extra Add-ons</p>
<div class="pdp-addon-list" id="pdpAddonList" style="margin-bottom:20px;">
<?php foreach ($extraAddons as $ad):
$adPrice = (float)($ad['price'] ?? 0);
?>
<label class="addon-checkbox-label" style="display: flex; align-items: center; gap: 10px; margin-bottom: 8px; cursor: pointer; background: #fff; padding: 10px; border: 1px solid #eee; border-radius: 4px; transition: 0.2s;">
<input type="checkbox" class="addon-checkbox" data-price="<?= $adPrice ?>" data-label="<?= htmlspecialchars($ad['label']) ?>" style="width: 18px; height: 18px; accent-color: #c9a96e;" />
<span style="font-size: 14px; color: #333; flex: 1;">
<?= htmlspecialchars($ad['label']) ?>
</span>
<?php if ($adPrice > 0): ?>
<span style="color: #c9a96e; font-weight: 600; font-size: 14px;">+ USD <?= number_format($adPrice, 2) ?></span>
<?php endif; ?>
</label>
<?php endforeach; ?>
</div>
<?php endif; ?>
<!-- Size (shown only for Stitched / Custom) -->
<?php if (!empty($sizes)): ?>
<div class="pdp-size-section <?= (empty($stitchOpts) && !empty($sizes)) ? 'visible' : '' ?>" id="pdpSizeSection">
<div class="pdp-size-label">
<span>Standard Size</span>
<?php if (!empty($product['category_size_chart'])): ?>
<button class="btn-size-guide" id="openSizeChart">Size Guide</button>
<?php endif; ?>
</div>
<div class="pdp-size-grid" id="pdpSizeGrid">
<?php foreach ($sizes as $size): ?>
<button class="size-btn" data-size="<?= htmlspecialchars($size) ?>"><?= htmlspecialchars($size) ?></button>
<?php endforeach; ?>
</div>
</div>
<?php endif; ?>
<p class="pdp-total-note" id="pdpTotalNote">Base price: USD <?= number_format($basePrice, 2) ?></p>
<div class="pdp-divider"></div>
<!-- CTA -->
<div class="pdp-cta-group">
<button class="btn-primary-pdp" id="pdpAddToCart">
<i class="fas fa-shopping-bag"></i> Add to Bag
</button>
<button class="btn-secondary-pdp" id="pdpAddToWishlist">
<i class="far fa-heart"></i> Wishlist
</button>
</div>
<!-- Trust Strip -->
<?php if (!empty($trustStrip)): ?>
<div class="pdp-trust-strip">
<?php foreach ($trustStrip as $trust): ?>
<div class="pdp-trust-item">
<i class="<?= htmlspecialchars($trust['icon']) ?>"></i>
<span><?= nl2br(htmlspecialchars($trust['label'])) ?></span>
</div>
<?php endforeach; ?>
</div>
<?php endif; ?>
<!-- Dispatch & Returns -->
<?php if ($product['dispatch_days']): ?>
<div class="pdp-dispatch-row">
<i class="fas fa-calendar-check"></i>
<span>Dispatches in <strong><?= htmlspecialchars($product['dispatch_days']) ?></strong></span>
</div>
<?php endif; ?>
<?php if ($product['dispatch_note']): ?>
<div class="pdp-dispatch-row">
<i class="fas fa-shipping-fast"></i>
<span><?= htmlspecialchars($product['dispatch_note']) ?></span>
</div>
<?php endif; ?>
</div>
<!-- End product info -->
</div>
<!-- End pdp-layout -->
</div>
<!-- End pdp-wrapper -->
<!-- โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
RELATED PRODUCTS
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ -->
<?php if (!empty($relatedProducts)): ?>
<section class="related-section">
<div class="related-section-head">
<h2>
<?php if ($isFallbackRel): ?>
Trending Designs
<span>Selected just for you</span>
<?php else: ?>
You May Also Like
<span>From <?= htmlspecialchars($product['category_name'] ?? 'this collection') ?></span>
<?php endif; ?>
</h2>
<a href="shop.php<?= !$isFallbackRel ? '?cat='.htmlspecialchars(current(explode(',', $product['category_id']))) : '' ?>" class="related-view-all">View All →</a>
</div>
<div class="related-grid">
<?php foreach ($relatedProducts as $rp):
$relSwatches = json_decode($rp['design_swatches'] ?? '[]', true) ?? [];
$relThumb = 'assets/placeholder-product.jpg';
$relVid = '';
if (!empty($relSwatches[0])) {
$sw = $relSwatches[0];
if (!empty($sw['thumb'])) $relThumb = $sw['thumb'];
elseif (!empty($sw['src'])) $relThumb = $sw['src'];
elseif (!empty($sw['gallery'][0])) $relThumb = $sw['gallery'][0];
// If still placeholder, check for videos
if ($relThumb === 'assets/placeholder-product.jpg' && !empty($sw['videos'][0])) {
$relVid = $sw['videos'][0];
}
}
$relPrice = number_format((float)$rp['price_usd'], 2);
?>
<div class="related-card">
<!-- Clickable overlay for navigation -->
<a href="product.php?id=<?= $rp['id'] ?>" class="related-card-link" aria-label="<?= htmlspecialchars($rp['name']) ?>"></a>
<div class="related-card-img">
<?php if ($relVid): ?>
<video src="<?= htmlspecialchars($relVid) ?>" autoplay muted loop playsinline style="width:100%; height:100%; object-fit:cover;"></video>
<?php else: ?>
<img
src="<?= htmlspecialchars($relThumb) ?>"
alt="<?= htmlspecialchars($rp['name']) ?>"
loading="lazy"
/>
<?php endif; ?>
<?php if (!empty($rp['badge_text'])): ?>
<div class="related-card-badge"><?= htmlspecialchars($rp['badge_text']) ?></div>
<?php endif; ?>
</div>
<div class="related-card-info">
<?php if (!empty($rp['category_name'])): ?>
<div class="related-card-cat"><?= htmlspecialchars($rp['category_name']) ?></div>
<?php endif; ?>
<div class="related-card-name"><?= htmlspecialchars($rp['name']) ?></div>
<div class="related-card-price">USD <?= $relPrice ?></div>
</div>
</div>
<?php endforeach; ?>
</div>
</section>
<?php endif; ?>
<!-- FOOTER -->
<!-- <footer class="site-footer">
<div class="container">
<div class="footer-top">
<div class="footer-brand">
<a href="index.php" class="logo footer-logo">Elegance of India</a>
<p>Premier destination for luxury designer fashion. Curating over 400 designers across clothing and accessories.</p>
<div class="social-links">
<a href="#" aria-label="Instagram"><i class="fab fa-instagram"></i></a>
<a href="#" aria-label="Facebook"><i class="fab fa-facebook-f"></i></a>
<a href="#" aria-label="Twitter"><i class="fab fa-twitter"></i></a>
<a href="#" aria-label="Pinterest"><i class="fab fa-pinterest-p"></i></a>
<a href="#" aria-label="YouTube"><i class="fab fa-youtube"></i></a>
</div>
</div>
<div class="footer-col">
<h5>Company</h5>
<ul>
<li><a href="#">About Us</a></li>
<li><a href="#">The Journal</a></li>
<li><a href="#">Career</a></li>
<li><a href="#">Press</a></li>
<li><a href="#">Contact Us</a></li>
</ul>
</div>
</div>
<div class="footer-bottom">
<p>© 2026 Elegance of India. All rights reserved.</p>
<div class="payment-icons">
<i class="fab fa-cc-visa"></i>
<i class="fab fa-cc-mastercard"></i>
<i class="fab fa-google-pay"></i>
</div>
</div>
</div>
</footer> -->
<?php include 'inc/footer.php'; ?>
<div class="footer-info-bar">
<div class="footer-info-bar__inner">
<a href="#">Shipping & Delivery</a>
<a href="#">Returns & Exchanges</a>
<a href="#">Privacy Policy</a>
<a href="#">Terms & Conditions</a>
<a href="#">FAQs</a>
</div>
</div>
<?php if (!empty($product['category_size_chart'])): ?>
<!-- Size Chart Modal -->
<div class="size-chart-modal-backdrop" id="sizeChartModal">
<div class="size-chart-modal">
<button class="size-chart-close" id="closeSizeChart">×</button>
<img src="assets/uploads/categories/<?= htmlspecialchars($product['category_size_chart']) ?>" alt="Size Chart" />
</div>
</div>
<?php endif; ?>
<button class="back-to-top" id="backToTop" aria-label="Back to top"><i class="fas fa-chevron-up"></i></button>
<!-- Custom Measurements Modal -->
<div class="measure-modal-backdrop" id="customMeasureModal">
<div class="measure-modal">
<button class="measure-modal-close" id="measureModalClose" aria-label="Close">×</button>
<p class="measure-modal-title">Custom Measurements — <?= htmlspecialchars($product['sku']) ?></p>
<?php
$mType = $product['measurement_type'] ?? 'None';
if ($mType === 'Saree') {
include 'includes/measurements/saree.php';
} elseif ($mType === 'Lehenga') {
include 'includes/measurements/lehenga.php';
} elseif ($mType === 'Salwar') {
include 'includes/measurements/salwar.php';
} else {
echo '<div style="padding: 20px 0; text-align: center; color: #666;">';
echo '<p>Custom measurement form for <strong>' . htmlspecialchars($product['category_name']) . '</strong> will be provided later.</p>';
echo '</div>';
}
?>
<p class="measure-note">Note: All measurements and styling options will be based on the above selection in the measurement form. Any change instructions given through emails, calls, or chats would not be executed.</p>
<button class="measure-submit-btn" id="measureSubmitBtn">Submit Measurements</button>
</div>
</div>
<script src="main.js"></script>
<script>
var basePriceElem = document.getElementById('pdpPrice');
var basePrice = parseFloat(basePriceElem.getAttribute('data-base-price')) || 0;
var stitchExtra = 0;
// Image Zoom Logic
const pdpMainMedia = document.getElementById('pdpMainMedia');
const pdpMainImgEl = document.getElementById('pdpMainImgEl');
if (pdpMainMedia && pdpMainImgEl) {
pdpMainMedia.addEventListener('mousemove', function(e) {
if (pdpMainImgEl.style.display !== 'none') {
const rect = this.getBoundingClientRect();
const x = ((e.clientX - rect.left) / rect.width) * 100;
const y = ((e.clientY - rect.top) / rect.height) * 100;
pdpMainImgEl.style.transformOrigin = `${x}% ${y}%`;
}
});
pdpMainMedia.addEventListener('mouseleave', function() {
if (pdpMainImgEl.style.display !== 'none') {
setTimeout(() => { pdpMainImgEl.style.transformOrigin = 'center center'; }, 300);
}
});
}
const pdpZoomBtn = document.getElementById('pdpZoomBtn');
if (pdpZoomBtn) {
pdpZoomBtn.addEventListener('click', function(e) {
e.stopPropagation();
if (pdpMainImgEl && pdpMainImgEl.style.display !== 'none') {
Swal.fire({
imageUrl: pdpMainImgEl.src,
imageAlt: 'Zoomed Image',
showConfirmButton: false,
showCloseButton: true,
customClass: {
popup: 'pdp-swal-zoom-popup',
image: 'pdp-swal-zoom-image'
},
backdrop: 'rgba(0,0,0,0.85)'
});
}
});
}
// Size Chart Modal Logic
const sizeChartModal = document.getElementById('sizeChartModal');
const openSizeChartBtn = document.getElementById('openSizeChart');
const closeSizeChartBtn = document.getElementById('closeSizeChart');
if (openSizeChartBtn && sizeChartModal) {
openSizeChartBtn.addEventListener('click', () => {
sizeChartModal.classList.add('open');
document.body.style.overflow = 'hidden';
});
}
if (closeSizeChartBtn && sizeChartModal) {
closeSizeChartBtn.addEventListener('click', () => {
sizeChartModal.classList.remove('open');
document.body.style.overflow = '';
});
sizeChartModal.addEventListener('click', (e) => {
if (e.target === sizeChartModal) {
sizeChartModal.classList.remove('open');
document.body.style.overflow = '';
}
});
}
// Design swatch selector
document.querySelectorAll('.design-swatch').forEach(function(swatch) {
swatch.addEventListener('click', function() {
document.querySelectorAll('.design-swatch').forEach(function(s) { s.classList.remove('active'); });
this.classList.add('active');
// Update stock status
var stock = this.dataset.stock;
var stockElem = document.getElementById('pdpStock');
var stockValElem = document.getElementById('pdpStockVal');
if (stockElem && stockValElem) {
stockValElem.textContent = (stock === 'in') ? 'In Stock' : 'Out of Stock';
stockElem.style.color = (stock === 'in') ? '#2e7d32' : '#c0392b';
}
// Update swatch gallery thumbnails (Images + Videos)
var galleryContainer = document.getElementById('pdpSwatchGallery');
if (galleryContainer) {
try {
var gallery = JSON.parse(this.dataset.gallery || '[]');
var videos = JSON.parse(this.dataset.videos || '[]');
galleryContainer.innerHTML = '';
// Add Images
if (gallery && gallery.length > 0) {
switchMainImage(gallery[0]);
gallery.forEach(function(imgUrl, index) {
var thumb = document.createElement('div');
thumb.className = 'gallery-thumb' + (index === 0 ? ' active' : '');
thumb.style = 'width: 50px; height: 65px; cursor: pointer; border: 1px solid #eee; overflow: hidden; opacity: ' + (index === 0 ? '1' : '0.6') + ';';
thumb.onclick = function() { switchMainImage(imgUrl, this); };
thumb.innerHTML = '<img src="' + imgUrl + '" style="width: 100%; height: 100%; object-fit: cover;" />';
galleryContainer.appendChild(thumb);
});
}
// Add Videos
if (videos && videos.length > 0) {
if (!gallery || gallery.length === 0) {
switchMainVideo(videos[0]);
}
videos.forEach(function(vFile, vIndex) {
var vThumb = document.createElement('div');
var isActive = ( (!gallery || gallery.length === 0) && vIndex === 0 );
vThumb.className = 'gallery-thumb gallery-video-thumb' + (isActive ? ' active' : '');
vThumb.style = 'width: 50px; height: 65px; cursor: pointer; border: 1px solid #eee; overflow: hidden; opacity: ' + (isActive ? '1' : '0.6') + '; background: #000; position: relative;';
vThumb.onclick = function() { switchMainVideo(vFile, this); };
vThumb.innerHTML = '<video src="' + vFile + '" style="width: 100%; height: 100%; object-fit: cover;" muted></video>' +
'<div style="position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; color: #fff; font-size: 10px; background: rgba(0,0,0,0.2);">' +
'<i class="fas fa-play"></i></div>';
galleryContainer.appendChild(vThumb);
});
}
} catch(e) {
console.error("Gallery/Video parse error", e);
}
}
});
});
// Function to switch main image from gallery
window.switchMainImage = function(imgUrl, el) {
var imgEl = document.getElementById('pdpMainImgEl');
var vidEl = document.getElementById('pdpMainVidEl');
var zBtn = document.getElementById('pdpZoomBtn');
imgEl.src = imgUrl;
imgEl.style.display = 'block';
vidEl.style.display = 'none';
if (zBtn) zBtn.style.display = 'flex';
vidEl.pause();
if (el) {
document.querySelectorAll('.gallery-thumb').forEach(function(t) {
t.classList.remove('active');
t.style.opacity = '0.6';
});
el.classList.add('active');
el.style.opacity = '1';
}
};
// Function to switch main video
window.switchMainVideo = function(vidUrl, el) {
var imgEl = document.getElementById('pdpMainImgEl');
var vidEl = document.getElementById('pdpMainVidEl');
var zBtn = document.getElementById('pdpZoomBtn');
vidEl.src = vidUrl;
vidEl.style.display = 'block';
imgEl.style.display = 'none';
if (zBtn) zBtn.style.display = 'none';
vidEl.play();
if (el) {
document.querySelectorAll('.gallery-thumb').forEach(function(t) {
t.classList.remove('active');
t.style.opacity = '0.6';
});
el.classList.add('active');
el.style.opacity = '1';
}
};
// Stitching selector (radio behaviour)
document.querySelectorAll('.stitch-btn').forEach(function(btn) {
btn.addEventListener('click', function() {
document.querySelectorAll('.stitch-btn').forEach(function(b) { b.classList.remove('selected'); });
this.classList.add('selected');
stitchExtra = parseInt(this.dataset.price, 10);
var type = this.dataset.type;
var sizeSection = document.getElementById('pdpSizeSection');
var modal = document.getElementById('customMeasureModal');
if (sizeSection) {
if (type === 'stitched') {
sizeSection.classList.add('visible');
modal.classList.remove('open');
} else if (type === 'custom') {
modal.classList.add('open');
sizeSection.classList.remove('visible');
document.querySelectorAll('.size-btn').forEach(function(b) { b.classList.remove('selected'); });
} else {
sizeSection.classList.remove('visible');
modal.classList.remove('open');
document.querySelectorAll('.size-btn').forEach(function(b) { b.classList.remove('selected'); });
}
} else if (type === 'custom') {
modal.classList.add('open');
} else {
modal.classList.remove('open');
}
updateTotal();
});
});
// Add-on checkboxes
document.querySelectorAll('.addon-checkbox').forEach(function(cb) {
cb.addEventListener('change', updateTotal);
});
// Modal close: ร button
var modalCloseBtn = document.getElementById('measureModalClose');
if (modalCloseBtn) {
modalCloseBtn.addEventListener('click', function() {
document.getElementById('customMeasureModal').classList.remove('open');
});
}
// Modal close: click backdrop
var measureModal = document.getElementById('customMeasureModal');
if (measureModal) {
measureModal.addEventListener('click', function(e) {
if (e.target === this) this.classList.remove('open');
});
}
// Unit toggle
document.querySelectorAll('.unit-btn').forEach(function(btn) {
btn.addEventListener('click', function() {
document.querySelectorAll('.unit-btn').forEach(function(b) { b.classList.remove('active'); });
this.classList.add('active');
var unit = this.dataset.unit;
// Update Bust options
var bustSelect = document.getElementById('mBust');
if (bustSelect) {
var options = (unit === 'inches') ? [32,33,34,35,36,37,38,40,42,44,46,48,50,52] : [81,84,86,89,91,94,97,102,107,112,117,122,127,132];
bustSelect.innerHTML = '<option value="">-- Select --</option>';
options.forEach(function(opt) {
var o = document.createElement('option');
o.value = opt; o.textContent = opt; bustSelect.appendChild(o);
});
}
// Update Body Height options
var heightSelect = document.getElementById('mBodyHeight');
if (heightSelect) {
var hOptions = (unit === 'inches') ?
['4 feet 8 inches','4 feet 9 inches','4 feet 10 inches','5 feet','5 feet 1 inches','5 feet 2 inches','5 feet 3 inches','5 feet 4 inches','5 feet 5 inches','5 feet 6 inches'] :
['142.50','145.00','147.50','150.00','152.50','155.00','157.50','160.50','163.00','165.50','168.00'];
heightSelect.innerHTML = '<option value="">-- Select --</option>';
hOptions.forEach(function(opt) {
var o = document.createElement('option');
o.value = opt; o.textContent = opt; heightSelect.appendChild(o);
});
}
// Update Natural Waist options
var waistSelect = document.getElementById('mNaturalWaist');
if (waistSelect) {
var wOptions = (unit === 'inches') ?
['20.00','21.00','22.00','23.00','24.00','25.00','26.00','27.00','28.00','29.00','30.00','31.00','32.00'] :
['58','61','64','66','69','71','74','76','79','81','84','86','89'];
waistSelect.innerHTML = '<option value="">-- Select --</option>';
wOptions.forEach(function(opt) {
var o = document.createElement('option');
o.value = opt; o.textContent = opt; waistSelect.appendChild(o);
});
}
// Update Shoulder options
var shoulderSelect = document.getElementById('mShoulder');
if (shoulderSelect) {
var sOptions = (unit === 'inches') ?
['11.50','12.00','12.50','13.00','14.00','14.50'] :
['30','32','33','34','36','37','38'];
shoulderSelect.innerHTML = '<option value="">-- Select --</option>';
sOptions.forEach(function(opt) {
var o = document.createElement('option');
o.value = opt; o.textContent = opt; shoulderSelect.appendChild(o);
});
}
// Update Arm Hole options
var armHoleSelect = document.getElementById('mArmHole');
if (armHoleSelect) {
var aOptions = (unit === 'inches') ?
['14.50','15.00','15.50','16.00','16.50','17.00','17.50'] :
['37','38','39','41','42','43','44'];
armHoleSelect.innerHTML = '<option value="">-- Select --</option>';
aOptions.forEach(function(opt) {
var o = document.createElement('option');
o.value = opt; o.textContent = opt; armHoleSelect.appendChild(o);
});
}
// Update Full Hip options
var fullHipSelect = document.getElementById('mFullHip');
if (fullHipSelect) {
var fhOptions = (unit === 'inches') ?
['31.00','32.00','33.00','34.00','35.00','36.00','37.00','38.00','39.00','40.00','41.00','42.00','43.00'] :
['79','81','84','86','89','91','94','97','99','102','104','107','109'];
fullHipSelect.innerHTML = '<option value="">-- Select --</option>';
fhOptions.forEach(function(opt) {
var o = document.createElement('option');
o.value = opt; o.textContent = opt; fullHipSelect.appendChild(o);
});
}
// Update Waist to Floor options
var waistFloorSelect = document.getElementById('mWaistFloor');
if (waistFloorSelect) {
var wfOptions = (unit === 'inches') ?
['32.50','33.00','33.50','34.00','34.50','35.00','36.00','36.50','37.00','37.50','38.00','38.50'] :
['86','88','89','90','91','93','94','95','97','98','99','100','102'];
waistFloorSelect.innerHTML = '<option value="">-- Select --</option>';
wfOptions.forEach(function(opt) {
var o = document.createElement('option');
o.value = opt; o.textContent = opt; waistFloorSelect.appendChild(o);
});
}
// Update Bottom Waist Circumference options
var bottomWaistSelect = document.getElementById('mBottomWaist');
if (bottomWaistSelect) {
var bwOptions = (unit === 'inches') ?
['25.00','26.00','27.00','28.00','29.00','30.00','31.00','32.00','33.00','34.00','35.00','36.00','37.00'] :
['66','69','71','74','76','79','81','84','86','89','91','94','97'];
bottomWaistSelect.innerHTML = '<option value="">-- Select --</option>';
bwOptions.forEach(function(opt) {
var o = document.createElement('option');
o.value = opt; o.textContent = opt; bottomWaistSelect.appendChild(o);
});
}
// Update Blouse Length options
var blouseLengthSelect = document.getElementById('mBlouseLength');
if (blouseLengthSelect) {
var blOptions = (unit === 'inches') ?
['13.00','13.50','14.00','14.50','15.00','15.50'] :
['33','34','36','37','38','39'];
blouseLengthSelect.innerHTML = '<option value="">-- Select --</option>';
blOptions.forEach(function(opt) {
var o = document.createElement('option');
o.value = opt; o.textContent = opt; blouseLengthSelect.appendChild(o);
});
}
// Update Front Neck Depth options
var frontNeckSelect = document.getElementById('mFrontNeck');
if (frontNeckSelect) {
var fnOptions = (unit === 'inches') ?
['High (2-4 Inches)','Medium (5-7 Inches)','Low (8-10 Inches)','Collar (Neck Round)','As shown in product image Low (8-10 Inches)'] :
['High (5.50-10 CM)','Medium (13-18 CM)','Low (20.5-25.5 Cm)','Collar (Neck Round)','As shown in product image Low (20.5-25.5 CM)'];
frontNeckSelect.innerHTML = '<option value="">-- Select Here --</option>';
fnOptions.forEach(function(opt) {
var o = document.createElement('option');
o.value = opt; o.textContent = opt; frontNeckSelect.appendChild(o);
});
}
// Update Back Neck Depth options
var backNeckSelect = document.getElementById('mBackNeck');
if (backNeckSelect) {
var bnOptions = (unit === 'inches') ?
['High (0โ4 Inches)','Medium (5โ7 Inches)','Low (8โ10 Inches)','Very Low (11โ13 Inches)','As shown in product image Very Low (11-13 Inches)'] :
['High (0โ10 cm)','Medium (13โ18 cm)','Low (20.5โ25.5 cm)','Very Low (28โ32.5 cm)','As shown in product image Very Low (28-32.5 cm)'];
backNeckSelect.innerHTML = '<option value="">-- Select Here --</option>';
bnOptions.forEach(function(opt) {
var o = document.createElement('option');
o.value = opt; o.textContent = opt; backNeckSelect.appendChild(o);
});
}
// Update Sleeve Style options
var sleeveStyleSelect = document.getElementById('mSleeveStyle');
if (sleeveStyleSelect) {
var ssOptions = (unit === 'inches') ?
['As shown in product image ( Half Sleeve 8.00 to 10.00 inch)','Sleeveless','Cap Sleeve(2.00 to 4.00 inch)','Short Sleeve(5.00 to 7.00 inch)','Half Sleeve(8.00 to 10.00 inch)'] :
['As shown in product image ( Half Sleeve 20.32 to 25.40 cm)','Sleeveless','Cap Sleeve(5.08 to 10.16 cm)','Short Sleeve(12.70 to 17.78 cm)','Half Sleeve(20.32 to 25.40 cm)'];
sleeveStyleSelect.innerHTML = '<option value="">--Select Here--</option>';
ssOptions.forEach(function(opt) {
var o = document.createElement('option');
o.value = opt; o.textContent = opt; sleeveStyleSelect.appendChild(o);
});
}
});
});
// Initialize dropdowns for the default active unit (Inches)
(function() {
var activeUnitBtn = document.querySelector('.unit-btn.active');
if (activeUnitBtn) activeUnitBtn.click();
})();
// Neck Pattern Selection Logic
var neckPatterns = {
'High': [
{ id: 'F3', label: 'Boat Neck(F3)', ext: '.jpg' },
{ id: 'F4', label: 'High Neck With Side Balls(F4)', ext: '.jpg' },
{ id: 'F20', label: 'High Neck With net pattern(F20)', ext: '.webp' },
{ id: 'F23', label: 'Peter Pan Collar(F23)', ext: '.jpg' },
{ id: 'F29', label: 'High neck(F29)', ext: '.jpg' }
],
'Medium': [
{ id: 'F1', label: 'Round Neck (F1)', ext: '.jpg' },
{ id: 'F2', label: 'Square Neck (F2)', ext: '.jpg' },
{ id: 'F5', label: 'Round V-Neck (F5)', ext: '.webp' },
{ id: 'F9', label: 'Round Sweetheart Neck (F9)', ext: '.jpg' },
{ id: 'F10', label: 'Square Sweetheart with Shoulder Cut or Patch (F10)', ext: '.jpg' },
{ id: 'F13', label: 'Round Neck With Shoulder Cut Design (F13)', ext: '.jpg' },
{ id: 'F12', label: 'Horse-shoe Neck (F12)', ext: '.jpg' },
{ id: 'F16', label: 'Halter-Round Neck (F16)', ext: '.jpg' },
{ id: 'F17', label: 'Halter-Pointed Sweetheart Neck (F17)', ext: '.jpg' },
{ id: 'F18', label: 'High Neck With Bra Pattern (F18)', ext: '.webp' },
{ id: 'F24', label: 'Boat Neck with V Hole Neck (F24)', ext: '.jpg' },
{ id: 'F26', label: 'Collar with Teardrop Shape (F26)', ext: '.jpg' },
{ id: 'F27', label: 'Collar with Slit (F27)', ext: '.jpg' },
{ id: 'F30', label: 'Round Neck with Button Keyhole (F30)', ext: '.jpg' },
{ id: 'F31', label: 'Round V Slit Open Neck (F31)', ext: '.webp' }
],
'Low': [
{ id: 'F1', label: 'Round Neck (F1)', ext: '.jpg' },
{ id: 'F2', label: 'Square Neck (F2)', ext: '.jpg' },
{ id: 'F5', label: 'Round V-Neck (F5)', ext: '.webp' },
{ id: 'F6', label: 'Fish-Tail Window (F6)', ext: '.jpg' },
{ id: 'F7', label: 'String-Style Neck (F7)', ext: '.jpg' },
{ id: 'F8', label: 'Curve Sweetheart Neck (F8)', ext: '.jpg' },
{ id: 'F9', label: 'Round Sweetheart Neck (F9)', ext: '.jpg' },
{ id: 'F10', label: 'Square Sweetheart with Shoulder Cut or Patch (F10)', ext: '.jpg' },
{ id: 'F11', label: 'Broad Lower Boat Neck (F11)', ext: '.webp' },
{ id: 'F12', label: 'Horse-shoe Neck (F12)', ext: '.jpg' },
{ id: 'F14', label: 'Wide Pointed Sweetheart Neck (F14)', ext: '.jpg' },
{ id: 'F15', label: 'Wide Pointed V-Neck with Shoulder Cut or Patch (F15)', ext: '.webp' },
{ id: 'F16', label: 'Halter-Round Neck (F16)', ext: '.jpg' },
{ id: 'F17', label: 'Halter-Pointed Sweetheart Neck (F17)', ext: '.jpg' },
{ id: 'F18', label: 'High Neck With Bra Pattern (F18)', ext: '.webp' },
{ id: 'F19', label: 'Strap with Sweetheart Neck (F19)', ext: '.webp' },
{ id: 'F21', label: 'Double Sweetheart Neck (F21)', ext: '.webp' },
{ id: 'F22', label: 'Round Pentagon Neck (F22)', ext: '.webp' },
{ id: 'F24', label: 'Boat Neck with V Hole Neck (F24)', ext: '.jpg' },
{ id: 'F26', label: 'Collar with Teardrop Shape (F26)', ext: '.jpg' },
{ id: 'F30', label: 'Round Neck with Button Keyhole (F30)', ext: '.jpg' },
{ id: 'F31', label: 'Round V Slit Open Neck (F31)', ext: '.webp' }
],
'Collar': [
{ id: 'F25', label: 'Mandarin Collar (F25)', ext: '.jpg' },
{ id: 'F28', label: 'Halter Neck with Collar (F28)', ext: '.jpg' }
]
};
var backNeckPatterns = {
'High': [
{ id: 'B24', label: 'High Neck with Centre Panel and Buttons (B24)', ext: '.jpg' },
{ id: 'B32', label: 'High Neck (B32)', ext: '.webp' },
{ id: 'B33', label: 'Boat Neck with Side Patti Balls (B33)', ext: '.jpg' }
],
'Medium': [
{ id: 'B1', label: 'Round Neck (B1)', ext: '.webp' },
{ id: 'B2', label: 'Square Neck (B2)', ext: '.webp' },
{ id: 'B3', label: 'Square Sweetheart Neck (B3)', ext: '.webp' },
{ id: 'B4', label: 'Curved Sweetheart Neck (B4)', ext: '.webp' },
{ id: 'B11', label: 'Round Neck With Sweetheart Patch (B11)', ext: '.webp' },
{ id: 'B26', label: 'High Neck with Net Round Cut (B26)', ext: '.webp' }
],
'Low': [
{ id: 'B1', label: 'Round Neck (B1)', ext: '.webp' },
{ id: 'B2', label: 'Square Neck (B2)', ext: '.webp' },
{ id: 'B3', label: 'Square Sweetheart Neck (B3)', ext: '.webp' },
{ id: 'B4', label: 'Curved Sweetheart Neck (B4)', ext: '.webp' },
{ id: 'B5', label: 'Horse-shoe Neck (B5)', ext: '.webp' },
{ id: 'B6', label: 'Overlap V neck with buttons (B6)', ext: '.webp' },
{ id: 'B7', label: 'Scalloped Neck side cut or Patch (B7)', ext: '.webp' },
{ id: 'B8', label: 'Fish-Tail Window (B8)', ext: '.webp' },
{ id: 'B9', label: 'Overlap V neck (B9)', ext: '.webp' },
{ id: 'B10', label: 'Round window with strings (B10)', ext: '.webp' },
{ id: 'B11', label: 'Round Neck With Sweetheart Patch (B11)', ext: '.webp' },
{ id: 'B14', label: 'Diamond window with strings (B14)', ext: '.webp' },
{ id: 'B15', label: 'Square Sweetheart with shoulder cut or Patch (B15)', ext: '.webp' },
{ id: 'B16', label: 'Square Sweetheart with double strings (B16)', ext: '.webp' },
{ id: 'B17', label: 'Broad Sweetheart in U (B17)', ext: '.webp' },
{ id: 'B19', label: 'Square Sweetheart with side cut or patch (B19)', ext: '.webp' },
{ id: 'B20', label: 'Boatneck with keyhole (B20)', ext: '.webp' },
{ id: 'B21', label: 'Semi-circular window (B21)', ext: '.webp' },
{ id: 'B32', label: 'High neck (B32)', ext: '.webp' }
],
'Very Low': [
{ id: 'B1', label: 'Round Neck (B1)', ext: '.webp' },
{ id: 'B2', label: 'Square Neck (B2)', ext: '.webp' },
{ id: 'B3', label: 'Square Sweetheart Neck (B3)', ext: '.webp' },
{ id: 'B5', label: 'Horse-shoe Neck (B5)', ext: '.webp' },
{ id: 'B6', label: 'Overlap V neck with buttons (B6)', ext: '.webp' },
{ id: 'B7', label: 'Scalloped Neck side cut or Patch (B7)', ext: '.webp' },
{ id: 'B8', label: 'Fish-Tail Window (B8)', ext: '.webp' },
{ id: 'B9', label: 'Overlap V neck (B9)', ext: '.webp' },
{ id: 'B10', label: 'Round window with strings (B10)', ext: '.webp' },
{ id: 'B12', label: 'Round V-neck with back bow (B12)', ext: '.webp' },
{ id: 'B13', label: 'Princess gathered with Brooch (B13)', ext: '.webp' },
{ id: 'B14', label: 'Diamond window with strings (B14)', ext: '.webp' },
{ id: 'B15', label: 'Square Sweetheart with shoulder cut or Patch (B15)', ext: '.webp' },
{ id: 'B16', label: 'Square Sweetheart with double strings (B16)', ext: '.webp' },
{ id: 'B17', label: 'Broad Sweetheart in U (B17)', ext: '.webp' },
{ id: 'B19', label: 'Square Sweetheart with side cut or patch (B19)', ext: '.webp' },
{ id: 'B20', label: 'Boatneck with keyhole (B20)', ext: '.webp' },
{ id: 'B21', label: 'Semi-circular window (B21)', ext: '.webp' },
{ id: 'B25', label: 'High Neck Band With Low Sweetheart Neck Cut (B25)', ext: '.webp' },
{ id: 'B28', label: 'Stripped Window Pattern (B28)', ext: '.webp' },
{ id: 'B34', label: 'Dimond shape with tieup (B34)', ext: '.webp' }
]
};
var sleeveStylePatterns = {
'Sleeveless': [
{ id: 'Sleeveless-1', label: 'Sleeveless', ext: '.webp' }
],
'Cap Sleeve': [
{ id: 'CapSleeves-1', label: 'Normal Cap Sleeve', ext: '.webp' },
{ id: 'CapSleeves-2', label: 'Cap sleeve with Scallop hem', ext: '.webp' },
{ id: 'CapSleeves-3', label: 'Puff Cap sleeve', ext: '.webp' },
{ id: 'CapSleeves-4', label: 'Band sleeve', ext: '.webp' },
{ id: 'CapSleeves-5', label: 'Petal sleeve', ext: '.webp' },
{ id: 'CapSleeves-6', label: 'Bell Cap sleeve', ext: '.webp' }
],
'Short Sleeve': [
{ id: 'ShortSleeves-1', label: 'Normal Short sleeve', ext: '.webp' },
{ id: 'ShortSleeves-2', label: 'Puff Short sleeve', ext: '.webp' },
{ id: 'ShortSleeves-3', label: 'Normal with flaired hem', ext: '.webp' },
{ id: 'ShortSleeves-4', label: 'Short sleeve with Scallop hem', ext: '.webp' },
{ id: 'ShortSleeves-5', label: 'Short sleeve with contrast slit', ext: '.webp' },
{ id: 'ShortSleeves-6', label: 'Short Bell sleeve', ext: '.webp' }
],
'Half Sleeve': [
{ id: 'HalfSleeves-1', label: 'Normal Half Sleeve', ext: '.webp' },
{ id: 'HalfSleeves-2', label: 'Puff Half sleeve', ext: '.webp' },
{ id: 'HalfSleeves-3', label: 'Normal Half Sleeve with frill', ext: '.webp' },
{ id: 'HalfSleeves-4', label: 'Normal Half Sleeve with slit', ext: '.jpg' }
]
};
var mFrontNeckSelect = document.getElementById('mFrontNeck');
var frontNeckVisualContainer = document.getElementById('frontNeckVisualContainer');
var frontNeckGrid = document.getElementById('frontNeckGrid');
var targetFrontNeckPattern = document.getElementById('mFrontNeckPattern');
if (mFrontNeckSelect && frontNeckVisualContainer) {
mFrontNeckSelect.addEventListener('change', function() {
var val = this.value;
var category = '';
if (val.indexOf('High') !== -1 && val.indexOf('As shown') === -1) category = 'High';
else if (val.indexOf('Medium') !== -1) category = 'Medium';
else if (val.indexOf('Low') !== -1 && val.indexOf('As shown') === -1) category = 'Low';
else if (val.indexOf('Collar') !== -1) category = 'Collar';
if (category && neckPatterns[category]) {
var html = '';
neckPatterns[category].forEach(function(item) {
html += '<div class="neck-pattern-card" data-id="' + item.id + '" data-label="' + item.label + '">';
html += ' <img src="assets/frontneckdepth/' + item.id + (item.ext || '.jpg') + '" alt="' + item.label + '" onerror="this.src=\'assets/images/placeholder.jpg\'" />';
html += ' <span>' + item.label + '</span>';
html += '</div>';
});
frontNeckGrid.innerHTML = html;
frontNeckVisualContainer.style.display = 'block';
targetFrontNeckPattern.value = ''; // Reset selection
// Add click events
frontNeckGrid.querySelectorAll('.neck-pattern-card').forEach(function(card) {
card.addEventListener('click', function() {
frontNeckGrid.querySelectorAll('.neck-pattern-card').forEach(function(c) { c.classList.remove('active'); });
this.classList.add('active');
targetFrontNeckPattern.value = this.getAttribute('data-label');
});
});
} else {
frontNeckVisualContainer.style.display = 'none';
frontNeckGrid.innerHTML = '';
targetFrontNeckPattern.value = '';
}
});
}
var mBackNeckSelect = document.getElementById('mBackNeck');
var backNeckVisualContainer = document.getElementById('backNeckVisualContainer');
var backNeckGrid = document.getElementById('backNeckGrid');
var targetBackNeckPattern = document.getElementById('mBackNeckPattern');
if (mBackNeckSelect && backNeckVisualContainer) {
mBackNeckSelect.addEventListener('change', function() {
var val = this.value;
var category = '';
if (val.indexOf('High') !== -1 && val.indexOf('As shown') === -1) category = 'High';
else if (val.indexOf('Medium') !== -1) category = 'Medium';
else if (val.indexOf('Very Low') !== -1 && val.indexOf('As shown') === -1) category = 'Very Low';
else if (val.indexOf('Low') !== -1 && val.indexOf('As shown') === -1) category = 'Low';
if (category && backNeckPatterns[category]) {
var html = '';
backNeckPatterns[category].forEach(function(item) {
html += '<div class="neck-pattern-card" data-id="' + item.id + '" data-label="' + item.label + '">';
html += ' <img src="assets/backneckdepth/' + item.id + (item.ext || '.webp') + '" alt="' + item.label + '" onerror="this.src=\'assets/images/placeholder.jpg\'" />';
html += ' <span>' + item.label + '</span>';
html += '</div>';
});
backNeckGrid.innerHTML = html;
backNeckVisualContainer.style.display = 'block';
targetBackNeckPattern.value = ''; // Reset selection
// Add click events
backNeckGrid.querySelectorAll('.neck-pattern-card').forEach(function(card) {
card.addEventListener('click', function() {
backNeckGrid.querySelectorAll('.neck-pattern-card').forEach(function(c) { c.classList.remove('active'); });
this.classList.add('active');
targetBackNeckPattern.value = this.getAttribute('data-label');
});
});
} else {
backNeckVisualContainer.style.display = 'none';
backNeckGrid.innerHTML = '';
targetBackNeckPattern.value = '';
}
});
}
// Sleeve Style Selection Logic
var mSleeveStyleSelect = document.getElementById('mSleeveStyle');
var sleeveStyleVisualContainer = document.getElementById('sleeveStyleVisualContainer');
var sleeveStyleGrid = document.getElementById('sleeveStyleGrid');
var targetSleevePattern = document.getElementById('mSleevePattern');
if (mSleeveStyleSelect && sleeveStyleVisualContainer) {
mSleeveStyleSelect.addEventListener('change', function() {
var val = this.value;
var category = '';
if (val.indexOf('Sleeveless') !== -1) category = 'Sleeveless';
else if (val.indexOf('Cap Sleeve') !== -1) category = 'Cap Sleeve';
else if (val.indexOf('Short Sleeve') !== -1) category = 'Short Sleeve';
else if (val.indexOf('Half Sleeve') !== -1) category = 'Half Sleeve';
if (category && sleeveStylePatterns[category]) {
var html = '';
sleeveStylePatterns[category].forEach(function(item) {
html += '<div class="neck-pattern-card" data-id="' + item.id + '" data-label="' + item.label + '">';
html += ' <img src="assets/sleevestyle/' + item.id + (item.ext || '.webp') + '" alt="' + item.label + '" onerror="this.src=\'assets/images/placeholder.jpg\'" />';
html += ' <span>' + item.label + '</span>';
html += '</div>';
});
sleeveStyleGrid.innerHTML = html;
sleeveStyleVisualContainer.style.display = 'block';
targetSleevePattern.value = ''; // Reset selection
// Add click events
sleeveStyleGrid.querySelectorAll('.neck-pattern-card').forEach(function(card) {
card.addEventListener('click', function() {
sleeveStyleGrid.querySelectorAll('.neck-pattern-card').forEach(function(c) { c.classList.remove('active'); });
this.classList.add('active');
targetSleevePattern.value = this.getAttribute('data-label');
});
});
} else {
sleeveStyleVisualContainer.style.display = 'none';
sleeveStyleGrid.innerHTML = '';
targetSleevePattern.value = '';
}
});
}
// Size selector
document.querySelectorAll('.size-btn').forEach(function(btn) {
btn.addEventListener('click', function() {
document.querySelectorAll('.size-btn').forEach(function(b) { b.classList.remove('selected'); });
this.classList.add('selected');
});
});
var measurementsSubmitted = false;
// Submit measurements โ close modal
var submitMeasureBtn = document.getElementById('measureSubmitBtn');
if(submitMeasureBtn) {
submitMeasureBtn.addEventListener('click', function() {
// Validate new Saree form if present
if (document.querySelector('.saree-measurement-container')) {
var reqs = document.querySelectorAll('.saree-req');
for (var i = 0; i < reqs.length; i++) {
if (!reqs[i].value.trim()) {
alert("Please fill out all required measurement fields (*).");
reqs[i].focus();
return;
}
}
}
// Validate new Lehenga form if present
if (document.getElementById('lehengaMeasurementForm')) {
var lReqs = document.querySelectorAll('.lehenga-req');
for (var j = 0; j < lReqs.length; j++) {
if (!lReqs[j].value.trim()) {
alert("Please fill out all required measurement fields (*).");
lReqs[j].focus();
return;
}
}
}
// Validate new Salwar Kameez form if present
if (document.getElementById('salwarMeasurementForm')) {
var salwarReqs = document.querySelectorAll('.salwar-req');
for (var k = 0; k < salwarReqs.length; k++) {
if (!salwarReqs[k].value.trim()) {
alert("Please fill out all required measurement fields (*).");
salwarReqs[k].focus();
return;
}
}
}
// Legacy visual pattern validation (safely skips if elements don't exist)
var mFrontNeckPattern = document.getElementById('mFrontNeckPattern');
var frontNeckVisualContainer = document.getElementById('frontNeckVisualContainer');
if (mFrontNeckPattern && frontNeckVisualContainer && frontNeckVisualContainer.style.display === 'block') {
if (!mFrontNeckPattern.value) {
alert("Please select a specific Front Neck Pattern from the images below the dropdown.");
return;
}
}
var mBackNeckPattern = document.getElementById('mBackNeckPattern');
var backNeckVisualContainer = document.getElementById('backNeckVisualContainer');
if (mBackNeckPattern && backNeckVisualContainer && backNeckVisualContainer.style.display === 'block') {
if (!mBackNeckPattern.value) {
alert("Please select a specific Back Neck Pattern from the images below the dropdown.");
return;
}
}
var mSleevePattern = document.getElementById('mSleevePattern');
var sleeveStyleVisualContainer = document.getElementById('sleeveStyleVisualContainer');
if (mSleevePattern && sleeveStyleVisualContainer && sleeveStyleVisualContainer.style.display === 'block') {
if (!mSleevePattern.value) {
alert("Please select a specific Sleeve Pattern from the images below the dropdown.");
return;
}
}
measurementsSubmitted = true;
document.getElementById('customMeasureModal').classList.remove('open');
Swal.fire({
title: 'Measurements Saved',
text: 'Your custom measurements have been captured successfully.',
icon: 'success',
timer: 2000,
showConfirmButton: false,
background: '#fff',
iconColor: '#2e7d32'
});
});
}
// โโ Add to Bag โโ
var addToCartBtn = document.getElementById('pdpAddToCart');
if (addToCartBtn) {
addToCartBtn.addEventListener('click', function() {
var activeStitchBtn = document.querySelector('.stitch-btn.selected');
var stitchType = activeStitchBtn ? activeStitchBtn.dataset.type : '';
var activeSizeBtn = document.querySelector('.size-btn.selected');
var sizeLabel = activeSizeBtn ? activeSizeBtn.dataset.size : '';
if (stitchType === 'stitched' || (!stitchType && document.getElementById('pdpSizeSection'))) {
if (!sizeLabel) {
Swal.fire({
title: 'Selection Required',
text: 'Please select a Standard Size before adding to bag.',
icon: 'warning',
confirmButtonColor: '#111'
});
return;
}
} else if (stitchType === 'custom') {
if (!measurementsSubmitted) {
Swal.fire({
title: 'Measurements Required',
text: 'Please submit your custom measurements before adding to bag.',
icon: 'info',
confirmButtonColor: '#111'
}).then(() => {
document.getElementById('customMeasureModal').classList.add('open');
});
return;
}
sizeLabel = 'Custom';
}
var cart = [];
try { cart = JSON.parse(localStorage.getItem('eoi_cart') || '[]'); } catch(e) {}
var activeSwatch = document.querySelector('.design-swatch.active');
var imgSrc = (activeSwatch && activeSwatch.getAttribute('data-src')) ? activeSwatch.getAttribute('data-src') : '<?= addslashes($mainImg) ?>';
var stitchLabel = activeStitchBtn ? activeStitchBtn.childNodes[0].textContent.trim() : '';
var currentPrice = parseFloat(document.getElementById('pdpPrice').textContent.replace('USD ', '')) || basePrice;
var customMeasurements = null;
if (stitchType === 'custom') {
customMeasurements = {};
if (document.querySelector('.saree-measurement-container')) {
// Saree specific data collection
var activeSareeUnit = document.querySelector('.saree-unit-radio:checked');
customMeasurements.unit = activeSareeUnit ? activeSareeUnit.value : 'Inches';
var activeSareeFit = document.querySelector('input[name="mFit"]:checked');
customMeasurements.fit = activeSareeFit ? activeSareeFit.value : 'Body Fit';
var fields = ['sBust', 'sAboveWaist', 'sShoulder', 'sArmHole', 'sSleeveLoose', 'sSleeveLength', 'sFrontNeck', 'sBackNeck', 'sBlouseLength', 'sBlouseType', 'sBlouseClosing', 'sSleeveLining'];
fields.forEach(function(f) {
var el = document.getElementById(f);
if (el) customMeasurements[f] = el.value;
});
var inst = document.getElementById('sInstructions');
if (inst) customMeasurements.sInstructions = inst.value.trim();
} else if (document.getElementById('lehengaMeasurementForm')) {
// Lehenga specific data collection
var activeLehengaUnit = document.querySelector('.lehenga-unit-radio:checked');
customMeasurements.unit = activeLehengaUnit ? activeLehengaUnit.value : 'Inches';
var lFields = ['lHeight', 'lBust', 'lUnderBust', 'lWaist', 'lCholiLength', 'lShoulder', 'lArmHole', 'lSleeveLoose', 'lSleeveLength', 'lSleeveLining', 'lFrontNeck', 'lBackNeck', 'lCholiClosing', 'lCholiType', 'lHips', 'lLowerWaist', 'lLehengaLength'];
lFields.forEach(function(f) {
var el = document.getElementById(f);
if (el) customMeasurements[f] = el.value;
});
var lInst = document.getElementById('lInstructions');
if (lInst) customMeasurements.lInstructions = lInst.value.trim();
} else if (document.getElementById('salwarMeasurementForm')) {
// Salwar specific data collection
var activeSalwarUnit = document.querySelector('.salwar-unit-radio:checked');
customMeasurements.unit = activeSalwarUnit ? activeSalwarUnit.value : 'Inches';
var activeSalwarFit = document.querySelector('input[name="salwarFit"]:checked');
customMeasurements.fit = activeSalwarFit ? activeSalwarFit.value : 'Regular';
var salwarFields = ['salwarFullName', 'salwarPhone', 'salwarEmail', 'salwarBust', 'salwarSleeveLength', 'salwarWaist', 'salwarSleeveStyle', 'salwarHips', 'salwarShoulder', 'salwarKameezLength', 'salwarNeckFront', 'salwarNeckBack', 'salwarBottomWaist', 'salwarBottomLength', 'salwarBottomHips', 'salwarBottomStyle', 'salwarBottomThigh'];
salwarFields.forEach(function(f) {
var el = document.getElementById(f);
if (el) customMeasurements[f] = el.value;
});
var salwarNotes = document.getElementById('salwarNotes');
if (salwarNotes) customMeasurements.notes = salwarNotes.value.trim();
} else {
// Legacy structure fallback
customMeasurements.unit = document.querySelector('.unit-btn.active') ? document.querySelector('.unit-btn.active').dataset.unit : 'inches';
customMeasurements.bust = document.getElementById('mBust') ? document.getElementById('mBust').value : '';
customMeasurements.bodyHeight = document.getElementById('mBodyHeight') ? document.getElementById('mBodyHeight').value : '';
customMeasurements.naturalWaist = document.getElementById('mNaturalWaist') ? document.getElementById('mNaturalWaist').value : '';
customMeasurements.shoulder = document.getElementById('mShoulder') ? document.getElementById('mShoulder').value : '';
customMeasurements.armHole = document.getElementById('mArmHole') ? document.getElementById('mArmHole').value : '';
customMeasurements.fullHip = document.getElementById('mFullHip') ? document.getElementById('mFullHip').value : '';
customMeasurements.waistFloor = document.getElementById('mWaistFloor') ? document.getElementById('mWaistFloor').value : '';
customMeasurements.bottomWaist = document.getElementById('mBottomWaist') ? document.getElementById('mBottomWaist').value : '';
customMeasurements.frontNeck = document.getElementById('mFrontNeck') ? document.getElementById('mFrontNeck').value : '';
customMeasurements.frontNeckPattern = document.getElementById('mFrontNeckPattern') ? document.getElementById('mFrontNeckPattern').value : '';
customMeasurements.backNeck = document.getElementById('mBackNeck') ? document.getElementById('mBackNeck').value : '';
customMeasurements.backNeckPattern = document.getElementById('mBackNeckPattern') ? document.getElementById('mBackNeckPattern').value : '';
customMeasurements.sleeveStyle = document.getElementById('mSleeveStyle') ? document.getElementById('mSleeveStyle').value : '';
customMeasurements.sleevePattern = document.getElementById('mSleevePattern') ? document.getElementById('mSleevePattern').value : '';
customMeasurements.blousePattern = document.getElementById('mBlousePattern') ? document.getElementById('mBlousePattern').value : '';
customMeasurements.blouseOpening = document.getElementById('mBlouseOpening') ? document.getElementById('mBlouseOpening').value : '';
customMeasurements.blouseLength = document.getElementById('mBlouseLength') ? document.getElementById('mBlouseLength').value : '';
}
}
var selectedAddons = [];
document.querySelectorAll('.addon-checkbox:checked').forEach(function(cb) {
selectedAddons.push({
label: cb.dataset.label,
price: parseFloat(cb.dataset.price)
});
});
var activeSwatch = document.querySelector('.design-swatch.active');
var designCode = (activeSwatch && activeSwatch.getAttribute('data-design-code')) ? activeSwatch.getAttribute('data-design-code') : '<?= addslashes($product['sku']) ?>';
var swatchLabel = (activeSwatch) ? activeSwatch.querySelector('span').textContent.trim() : '';
var item = {
id: '<?= $id ?>',
sku: designCode,
swatch: swatchLabel,
catalog_sku: '<?= addslashes($product['sku']) ?>',
name: '<?= addslashes($product['name']) ?>',
price: currentPrice,
image: imgSrc,
stitch: stitchLabel,
size: sizeLabel,
addons: selectedAddons,
qty: 1,
measurements: customMeasurements
};
// Check if same product+stitch+size already in cart
var existingIdx = cart.findIndex(function(c) {
return c.id === item.id && c.stitch === item.stitch && c.size === item.size;
});
if (existingIdx >= 0) {
cart[existingIdx].qty = (parseInt(cart[existingIdx].qty) || 1) + 1;
} else {
cart.push(item);
}
localStorage.setItem('eoi_cart', JSON.stringify(cart));
// Show feedback using SweetAlert2
Swal.fire({
title: 'Added to Bag!',
text: item.name + ' has been added to your shopping bag.',
icon: 'success',
showCancelButton: true,
confirmButtonText: 'Go to Cart',
cancelButtonText: 'Continue Shopping',
background: '#fff',
iconColor: '#2e7d32',
reverseButtons: true,
customClass: {
title: 'swal-title-custom',
popup: 'swal-popup-custom',
confirmButton: 'swal-confirm-custom',
cancelButton: 'swal-cancel-custom'
}
}).then((result) => {
if (result.isConfirmed) {
window.location.href = 'cart.php';
}
});
// Also update the button slightly for immediate feedback
var origText = addToCartBtn.innerHTML;
addToCartBtn.innerHTML = '<i class="fas fa-check"></i> Added!';
addToCartBtn.style.background = '#2e7d32';
setTimeout(function() {
addToCartBtn.innerHTML = origText;
addToCartBtn.style.background = '';
}, 2000);
});
}
// โโ Add to Wishlist โโ
var wishlistBtn = document.getElementById('pdpAddToWishlist');
if (wishlistBtn) {
wishlistBtn.addEventListener('click', function() {
var wl = [];
try { wl = JSON.parse(localStorage.getItem('eoi_wishlist') || '[]'); } catch(e) {}
var activeSwatch = document.querySelector('.design-swatch.active');
var imgSrc = (activeSwatch && activeSwatch.getAttribute('data-src')) ? activeSwatch.getAttribute('data-src') : '<?= addslashes($mainImg) ?>';
var item = {
id: '<?= $id ?>',
sku: '<?= addslashes($product['sku']) ?>',
name: '<?= addslashes($product['name']) ?>',
price: basePrice,
image: imgSrc
};
var alreadyIn = wl.some(function(w) { return w.id === item.id; });
if (!alreadyIn) {
wl.push(item);
localStorage.setItem('eoi_wishlist', JSON.stringify(wl));
if (typeof updateWishlistBadge === 'function') updateWishlistBadge();
Swal.fire({
title: 'Saved!',
text: item.name + ' has been added to your wishlist.',
icon: 'success',
timer: 2000,
showConfirmButton: false,
iconColor: '#c0392b'
});
wishlistBtn.innerHTML = '<i class="fas fa-heart"></i> Saved';
wishlistBtn.style.color = '#c0392b';
wishlistBtn.style.borderColor = '#c0392b';
} else {
Swal.fire({
title: 'Already Saved',
text: 'This item is already in your wishlist.',
icon: 'info',
timer: 2000,
showConfirmButton: false
});
}
setTimeout(function() {
wishlistBtn.innerHTML = '<i class="far fa-heart"></i> Wishlist';
wishlistBtn.style.color = '';
wishlistBtn.style.borderColor = '';
}, 2500);
});
}
function updateTotal() {
var addonExtra = 0;
document.querySelectorAll('.addon-checkbox:checked').forEach(function(cb) {
addonExtra += parseFloat(cb.dataset.price);
});
var total = basePrice + stitchExtra + addonExtra;
document.getElementById('pdpPrice').textContent = 'USD ' + total.toFixed(2);
var activeStitch = document.querySelector('.stitch-btn.selected');
var stitchName = activeStitch ? activeStitch.childNodes[0].textContent.trim() : 'Unstitch';
var pts = ['Base: USD ' + basePrice.toFixed(2)];
if (stitchExtra > 0) pts.push(stitchName + ': + USD ' + stitchExtra.toFixed(2));
if (addonExtra > 0) pts.push('Add-ons: + USD ' + addonExtra.toFixed(2));
document.getElementById('pdpTotalNote').textContent = pts.join(' ยท ');
}
// Auto-slider for gallery
var gallerySlideInterval;
function startGalleryAutoSlide() {
stopGalleryAutoSlide();
gallerySlideInterval = setInterval(function() {
var thumbs = document.querySelectorAll('#pdpSwatchGallery .gallery-thumb');
if (thumbs.length <= 1) return;
var activeIdx = -1;
thumbs.forEach(function(t, i) { if (t.classList.contains('active')) activeIdx = i; });
var nextIdx = (activeIdx + 1) % thumbs.length;
// Auto click next thumbnail
var thumbToClick = thumbs[nextIdx];
if (thumbToClick.classList.contains('gallery-video-thumb')) {
switchMainVideo(thumbToClick.querySelector('video').src, thumbToClick);
} else {
switchMainImage(thumbToClick.querySelector('img').src, thumbToClick);
}
}, 3500); // Change image every 3.5 seconds
}
function stopGalleryAutoSlide() {
if (gallerySlideInterval) clearInterval(gallerySlideInterval);
}
// Start auto slide on load
startGalleryAutoSlide();
// Pause auto slide on hover
var pdpGallery = document.querySelector('.pdp-gallery');
if (pdpGallery) {
pdpGallery.addEventListener('mouseenter', stopGalleryAutoSlide);
pdpGallery.addEventListener('mouseleave', startGalleryAutoSlide);
pdpGallery.addEventListener('touchstart', stopGalleryAutoSlide);
}
// Make sure initial total is shown immediately if default selected has extra cost
var initialSelectedStitch = document.querySelector('.stitch-btn.selected');
if(initialSelectedStitch) {
stitchExtra = parseInt(initialSelectedStitch.dataset.price, 10);
updateTotal();
}
</script>
</body>
</html>