75 lines
3.1 KiB
JavaScript
75 lines
3.1 KiB
JavaScript
|
|
// Product Color Variant Selector
|
||
|
|
// Dynamically adds color selection to product pages
|
||
|
|
|
||
|
|
(function() {
|
||
|
|
'use strict';
|
||
|
|
|
||
|
|
if (document.readyState === 'loading') {
|
||
|
|
document.addEventListener('DOMContentLoaded', init);
|
||
|
|
} else {
|
||
|
|
init();
|
||
|
|
}
|
||
|
|
|
||
|
|
function init() {
|
||
|
|
if (!window.location.pathname.includes('/shop/product/')) return;
|
||
|
|
|
||
|
|
// Wait a bit for page to fully load
|
||
|
|
setTimeout(() => {
|
||
|
|
const productId = window.location.pathname.split('/').pop();
|
||
|
|
if (productId) {
|
||
|
|
loadVariants(productId);
|
||
|
|
}
|
||
|
|
}, 500);
|
||
|
|
}
|
||
|
|
|
||
|
|
function loadVariants(productId) {
|
||
|
|
// Try to fetch variants data
|
||
|
|
fetch('/api/shop/product/' + productId + '/variants')
|
||
|
|
.then(res => res.json())
|
||
|
|
.then(variants => {
|
||
|
|
if (variants && variants.length > 0) {
|
||
|
|
renderVariants(variants);
|
||
|
|
}
|
||
|
|
})
|
||
|
|
.catch(() => {
|
||
|
|
// Silently fail if API doesn't exist
|
||
|
|
console.log('Variant API not available');
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
function renderVariants(variants) {
|
||
|
|
const actionsDiv = document.querySelector('.actions');
|
||
|
|
if (!actionsDiv || document.querySelector('.product-variants')) return;
|
||
|
|
|
||
|
|
const html = `
|
||
|
|
<div class="product-variants" style="margin-top: 1.5rem; padding-top: 1.5rem; border-top: 1px solid #eee;">
|
||
|
|
<h4 style="font-size: 0.95rem; font-weight: 600; margin-bottom: 0.75rem; color: #333;">
|
||
|
|
Color: <span id="selectedVariantName" style="color: #6B4E9B;">Choose a color</span>
|
||
|
|
</h4>
|
||
|
|
<div class="variant-swatches" style="display: flex; gap: 0.75rem; flex-wrap: wrap;">
|
||
|
|
${variants.map((v, i) => `
|
||
|
|
<div class="variant-swatch" data-index="${i}" style="cursor: pointer; text-align: center;">
|
||
|
|
<div style="width: 40px; height: 40px; border-radius: 50%; background: ${v.ColorHex};
|
||
|
|
border: 3px solid white; box-shadow: 0 0 0 2px #ddd; transition: all 0.2s;"></div>
|
||
|
|
<span style="font-size: 0.7rem; color: #666; display: block; margin-top: 0.25rem;">${v.ColorName}</span>
|
||
|
|
</div>
|
||
|
|
`).join('')}
|
||
|
|
</div>
|
||
|
|
<input type="hidden" id="selectedVariantData" value="" />
|
||
|
|
</div>
|
||
|
|
`;
|
||
|
|
|
||
|
|
actionsDiv.insertAdjacentHTML('beforebegin', html);
|
||
|
|
|
||
|
|
document.querySelectorAll('.variant-swatch').forEach((el, i) => {
|
||
|
|
el.onclick = () => {
|
||
|
|
document.getElementById('selectedVariantName').textContent = variants[i].ColorName;
|
||
|
|
document.getElementById('selectedVariantData').value = JSON.stringify(variants[i]);
|
||
|
|
document.querySelectorAll('.variant-swatch div').forEach((d, j) => {
|
||
|
|
d.style.boxShadow = i === j ? '0 0 0 2px ' + variants[i].ColorHex + ', 0 0 8px ' + variants[i].ColorHex : '0 0 0 2px #ddd';
|
||
|
|
});
|
||
|
|
};
|
||
|
|
});
|
||
|
|
}
|
||
|
|
})();
|