(function(){
'use strict';
function parseJSON(raw, fallback){
if(!raw) return fallback;
try { return JSON.parse(raw); } catch (e){ return fallback; }}
function toFloat(value){
var num=parseFloat(String(value).replace(',', '.'));
return isNaN(num) ? 0:num;
}
function formatMoney(amount, symbol){
var value=Number(amount||0);
var formatted=value.toLocaleString('de-DE', {
minimumFractionDigits: 2,
maximumFractionDigits: 2
});
return formatted + ' ' + (symbol||'EUR');
}
function stageHtml(item){
if(!item||!item.type) return '';
if(item.type==='video'){
return '<video class="gco-stage-video" src="' + (item.url||'') + '" controls playsinline preload="metadata"></video>';
}
if(item.type==='youtube'){
var videoId=getYoutubeId(item.url||'');
if(videoId){
return '<iframe class="gco-stage-youtube" src="https://www.youtube-nocookie.com/embed/' + videoId + '" title="YouTube Video" loading="lazy" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>';
}}
return '<img class="gco-stage-image" src="' + (item.url||'') + '" alt="' + (item.title||'') + '" loading="lazy" />';
}
function getYoutubeId(url){
if(!url) return '';
var patterns=[
/youtu\.be\/([A-Za-z0-9_-]{6,})/i,
/youtube\.com\/watch\?v=([A-Za-z0-9_-]{6,})/i,
/youtube\.com\/embed\/([A-Za-z0-9_-]{6,})/i,
/youtube\.com\/shorts\/([A-Za-z0-9_-]{6,})/i
];
for (var i=0; i < patterns.length; i++){
var match=url.match(patterns[i]);
if(match&&match[1]) return match[1];
}
return '';
}
function renderResponse(target, type, message){
if(!target) return;
target.className='gco-form-response is-' + type;
target.textContent=message||'';
}
function initGallery(root){
var stage=root.querySelector('[data-role="stage"]');
if(!stage) return;
root.querySelectorAll('.gco-thumb').forEach(function(button){
button.addEventListener('click', function(){
var item=parseJSON(button.getAttribute('data-media'), null);
if(!item) return;
stage.innerHTML=stageHtml(item);
root.querySelectorAll('.gco-thumb').forEach(function(el){ el.classList.remove('is-active'); });
button.classList.add('is-active');
});
});
}
function getCurrencyData(root){
return parseJSON(root.getAttribute('data-currencies'), {});
}
function selectedCurrency(root){
var select=root.querySelector('.gco-currency');
return select ? String(select.value||'EUR'):'EUR';
}
function selectedQuantity(root){
var input=root.querySelector('.gco-quantity');
var qty=input ? parseInt(input.value, 10):1;
return !isNaN(qty)&&qty > 0 ? qty:1;
}
function optionLabel(field){
return String(field.getAttribute('data-option-label')||'').replace('*', '').trim();
}
function normalizePricingRule(type, value, contextLabel){
var normalizedType=String(type||'').toLowerCase();
var rawValue=String(value==null ? '':value).trim();
var normalizedValue=toFloat(rawValue);
var context=String(contextLabel||'');
if(!normalizedType&&rawValue.indexOf('%')!==-1){
normalizedType='percent';
}
if(normalizedType!=='percent') normalizedType='fixed';
if(normalizedType==='fixed'&&!normalizedValue&&/mwst|ustg|vat|tax|gewerb/i.test(context)){
var match=context.match(/([0-9]+(?:[.,][0-9]+)?)\s*%/i);
if(match){
normalizedType='percent';
normalizedValue=toFloat(match[1]);
}}
return {
type: normalizedType,
value: normalizedValue
};}
function selectedPricingRule(field){
var type=field.getAttribute('data-option-type');
var labelText=optionLabel(field);
if(type==='select'){
var select=field.querySelector('select');
if(!select||!select.options.length) return null;
var option=select.options[select.selectedIndex];
if(!option||!option.value) return null;
return normalizePricingRule(
option.getAttribute('data-price-type')||'',
option.getAttribute('data-price-value')||option.getAttribute('data-price')||'',
labelText + ' ' + (option.textContent||'')
);
}
if(type==='radio'){
var radio=field.querySelector('input[type="radio"]:checked');
if(!radio) return null;
return normalizePricingRule(
radio.getAttribute('data-price-type')||'',
radio.getAttribute('data-price-value')||radio.getAttribute('data-price')||'',
labelText + ' ' + (radio.getAttribute('data-label')||radio.value||'')
);
}
if(type==='checkbox'){
var checkbox=field.querySelector('input[type="checkbox"]');
if(!checkbox||!checkbox.checked) return null;
return normalizePricingRule(
checkbox.getAttribute('data-price-type')||'',
checkbox.getAttribute('data-price-value')||checkbox.getAttribute('data-price')||'',
labelText + ' ' + (checkbox.getAttribute('data-label')||'')
);
}
return null;
}
function optionDisplay(field){
var type=field.getAttribute('data-option-type');
var labelText=optionLabel(field);
if(type==='select'){
var select=field.querySelector('select');
if(!select||!select.value) return null;
var option=select.options[select.selectedIndex];
return {
label: labelText,
value: option ? option.textContent.trim():select.value
};}
if(type==='radio'){
var radio=field.querySelector('input[type="radio"]:checked');
if(!radio) return null;
return {
label: labelText,
value: String(radio.getAttribute('data-label')||radio.value||'').trim()
};}
if(type==='checkbox'){
var checkbox=field.querySelector('input[type="checkbox"]');
if(!checkbox||!checkbox.checked) return null;
return {
label: labelText||checkbox.getAttribute('data-label')||'Option',
value: 'Ja'
};}
var input=field.querySelector('input[type="text"], input[type="number"], textarea');
if(!input||!String(input.value||'').trim()) return null;
return {
label: labelText,
value: String(input.value||'').trim()
};}
function optionRawValue(field){
var type=field.getAttribute('data-option-type');
if(type==='select'){
var select=field.querySelector('select');
return select ? String(select.value||'').trim():'';
}
if(type==='radio'){
var radio=field.querySelector('input[type="radio"]:checked');
return radio ? String(radio.value||'').trim():'';
}
if(type==='checkbox'){
var checkbox=field.querySelector('input[type="checkbox"]');
return checkbox&&checkbox.checked ? '1':'';
}
if(type==='file'){
return '';
}
var input=field.querySelector('input[type="text"], input[type="number"], textarea');
return input ? String(input.value||'').trim():'';
}
function updateExternalOrderLink(root, totalEur, formatted){
var baseUrl=String(root.getAttribute('data-external-order-url')||'').trim();
var button=root.querySelector('.gco-open-order--external');
if(!baseUrl||!button||typeof URL==='undefined') return;
var url;
try {
url=new URL(baseUrl, window.location.origin);
} catch (e){
button.setAttribute('href', baseUrl);
return;
}
var params=url.searchParams;
params.set('gco_product', String(root.getAttribute('data-product-id')||''));
params.set('gco_currency', selectedCurrency(root));
params.set('gco_quantity', String(selectedQuantity(root)));
params.set('gco_total_eur', String((Number(totalEur||0)).toFixed(2)));
params.set('gco_display_total', String(formatted||''));
root.querySelectorAll('.gco-option-field').forEach(function(field){
var optionId=String(field.getAttribute('data-option-id')||'').trim();
if(!optionId) return;
var key='gco_prefill_option[' + optionId + ']';
params.delete(key);
var value=optionRawValue(field);
if(!value) return;
params.set(key, value);
});
button.setAttribute('href', url.toString());
}
function updateProductView(root){
var currencies=getCurrencyData(root);
var currencyCode=selectedCurrency(root);
var currency=currencies[currencyCode]||currencies.EUR||{ rate: 1, symbol: 'EUR' };
var basePrice=toFloat(root.getAttribute('data-base-price'));
var quantity=selectedQuantity(root);
var fixedDelta=0;
var percentRules=[];
root.querySelectorAll('.gco-option-field').forEach(function(field){
var rule=selectedPricingRule(field);
if(!rule) return;
if(rule.type==='percent'){
percentRules.push(rule);
return;
}
fixedDelta +=rule.value;
});
var subtotalEur=basePrice * quantity + fixedDelta;
var percentDelta=0;
percentRules.forEach(function(rule){
percentDelta +=subtotalEur * (rule.value / 100);
});
var totalEur=subtotalEur + percentDelta;
var displayTotal=totalEur * toFloat(currency.rate||1);
var formatted=formatMoney(displayTotal, currency.symbol||currencyCode);
var priceValue=root.querySelector('.gco-price-value');
if(priceValue) priceValue.textContent=formatted;
var modalTotal=root.querySelector('[data-role="modal-total"]');
if(modalTotal) modalTotal.textContent=formatted;
var displayTotalInput=root.querySelector('.gco-display-total-input');
if(displayTotalInput) displayTotalInput.value=formatted;
var totalEurInput=root.querySelector('.gco-total-eur-input');
if(totalEurInput) totalEurInput.value=String(totalEur.toFixed(2));
var chipBox=root.querySelector('[data-role="compact-summary"]');
if(chipBox){
chipBox.innerHTML='';
root.querySelectorAll('.gco-compact-fields .gco-option-field').forEach(function(field){
var display=optionDisplay(field);
if(!display) return;
var chip=document.createElement('span');
chip.className='gco-chip';
chip.textContent=display.label + ': ' + display.value;
chipBox.appendChild(chip);
});
}
updateExternalOrderLink(root, totalEur, formatted);
}
function scrollToOrder(root){
var section=root.querySelector('.gco-order-section');
if(!section) return;
if(typeof section.scrollIntoView==='function'){
section.scrollIntoView({ behavior: 'smooth', block: 'start' });
return;
}
window.location.hash=section.id||'';
}
function initProductView(root){
initGallery(root);
updateProductView(root);
root.querySelectorAll('.gco-order-input, .gco-currency, .gco-quantity').forEach(function(input){
input.addEventListener('change', function(){ updateProductView(root); });
input.addEventListener('input', function(){ updateProductView(root); });
});
var openButton=root.querySelector('.gco-open-order');
if(openButton){
openButton.addEventListener('click', function(event){
updateProductView(root);
if(openButton.classList.contains('gco-open-order--external')){
event.preventDefault();
var href=openButton.getAttribute('href');
if(href){
window.location.href=href;
}
return;
}
event.preventDefault();
scrollToOrder(root);
});
}
var form=root.querySelector('.gco-order-form');
if(!form) return;
form.addEventListener('submit', function(event){
event.preventDefault();
updateProductView(root);
var responseBox=root.querySelector('[data-role="response"]');
renderResponse(responseBox, 'info', (window.gcoFrontend&&gcoFrontend.strings&&gcoFrontend.strings.sending)||'Wird gesendet ...');
var submitButton=form.querySelector('button[type="submit"]');
if(submitButton) submitButton.disabled=true;
var formData=new FormData(form);
fetch((window.gcoFrontend&&gcoFrontend.ajaxUrl)||form.getAttribute('action')||'', {
method: 'POST',
body: formData,
credentials: 'same-origin'
})
.then(function(response){ return response.json(); })
.then(function(payload){
if(!payload||!payload.success){
var message=payload&&payload.data&&payload.data.message ? payload.data.message:((window.gcoFrontend&&gcoFrontend.strings&&gcoFrontend.strings.error)||'Fehler beim Senden.');
renderResponse(responseBox, 'error', message);
return;
}
var successMessage=payload.data&&payload.data.message ? payload.data.message:((window.gcoFrontend&&gcoFrontend.strings&&gcoFrontend.strings.success)||'Erfolgreich gesendet.');
renderResponse(responseBox, 'success', successMessage);
root.querySelectorAll('.gco-inline-success').forEach(function(node){ node.remove(); });
root.insertAdjacentHTML('afterbegin', '<div class="gco-inline-success">' + successMessage + '</div>');
form.reset();
updateProductView(root);
})
.catch(function(){
renderResponse(responseBox, 'error', (window.gcoFrontend&&gcoFrontend.strings&&gcoFrontend.strings.error)||'Fehler beim Senden.');
})
.finally(function(){
if(submitButton) submitButton.disabled=false;
});
});
}
function updateGridPrices(grid, currencyCode){
var currencies=parseJSON(grid.getAttribute('data-currencies'), {});
var currency=currencies[currencyCode]||currencies.EUR||{ rate: 1, symbol: 'EUR' };
grid.querySelectorAll('.gco-money').forEach(function(node){
var base=toFloat(node.getAttribute('data-base-price'));
node.textContent=formatMoney(base * toFloat(currency.rate||1), currency.symbol||currencyCode);
});
}
function cleanupThemeChrome(){
var isPluginRoute=document.body&&(document.body.classList.contains('gco-single-route')||document.body.classList.contains('gco-order-route'));
if(!isPluginRoute) return;
var selectors=[
'.page-header',
'.entry-header',
'.entry-hero',
'.hero-section',
'.breadcrumbs',
'.breadcrumb',
'.rank-math-breadcrumb',
'nav[aria-label="breadcrumb"]',
'.post-thumbnail',
'.featured-media',
'.page-title',
'.entry-title',
'.entry-subtitle',
'.post-excerpt',
'.inner-banner-wrap',
'.page-title-wrap',
'.single-post-thumb',
'.ast-breadcrumbs-wrapper',
'.brxe-post-title',
'.brxe-breadcrumbs',
'.brxe-post-excerpt',
'.elementor-widget-theme-post-title',
'.elementor-widget-breadcrumbs',
'.elementor-widget-theme-post-excerpt'
];
selectors.forEach(function(selector){
document.querySelectorAll(selector).forEach(function(node){
if(node.closest('.gco-product-view')||node.closest('.gco-standalone-order')) return;
node.style.display='none';
var parent=node.parentElement;
var depth=0;
while (parent&&depth < 2&&!parent.closest('.gco-product-view')&&!parent.closest('.gco-standalone-order')){
parent.style.minHeight='0';
if(parent.children.length <=1){
parent.style.paddingTop='0';
parent.style.paddingBottom='0';
parent.style.marginTop='0';
parent.style.marginBottom='0';
}
parent=parent.parentElement;
depth +=1;
}});
});
}
function initGridCurrency(){
document.querySelectorAll('.gco-card-grid').forEach(function(grid){
var toolbar=grid.previousElementSibling;
if(!toolbar) return;
var select=toolbar.querySelector('[data-role="currency-switcher"]');
if(!select) return;
updateGridPrices(grid, select.value||'EUR');
select.addEventListener('change', function(){
updateGridPrices(grid, select.value||'EUR');
});
});
}
document.addEventListener('DOMContentLoaded', function(){
cleanupThemeChrome();
document.querySelectorAll('.gco-product-view').forEach(initProductView);
initGridCurrency();
});
})();