/** * Tischlerei Staffenberger - Main JavaScript * Handles navigation active state, gallery filtering, and lightbox on Bilder page. */ (function () { 'use strict'; /** * Set active state on the current page's nav link based on URL pathname. */ function setActiveNav() { var navLinks = document.querySelectorAll('.main-nav a'); var path = window.location.pathname; var page = path.split('/').pop() || 'index.html'; navLinks.forEach(function (link) { var href = link.getAttribute('href'); if (!href) return; var linkPage = href.split('/').pop() || 'index.html'; if (linkPage === page || (page === '' && linkPage === 'index.html')) { link.classList.add('active'); } else { link.classList.remove('active'); } }); } /** * Gallery filter: show/hide items by data-category. */ function initGalleryFilter() { var filters = document.querySelectorAll('.gallery-filters button'); var items = document.querySelectorAll('.gallery-item'); if (!filters.length || !items.length) return; filters.forEach(function (btn) { btn.addEventListener('click', function () { var category = this.getAttribute('data-filter'); // Update active button filters.forEach(function (b) { b.classList.toggle('active', b === btn); }); // Show/hide items items.forEach(function (item) { var itemCategory = item.getAttribute('data-category'); var show = category === 'all' || itemCategory === category; item.style.display = show ? '' : 'none'; }); }); }); } /** * Lightbox on Bilder page: open on gallery image click, navigate with swipe / arrow * keys / prev+next buttons, close via X, backdrop or ESC. * Respects the active gallery filter – only visible items are part of the sequence. */ function initLightbox() { var lightbox = document.getElementById('lightbox'); var lightboxImg = document.getElementById('lightbox-img'); if (!lightbox || !lightboxImg) return; var closeBtn = lightbox.querySelector('.lightbox-close'); var backdrop = lightbox.querySelector('.lightbox-backdrop'); var prevBtn = lightbox.querySelector('.lightbox-prev'); var nextBtn = lightbox.querySelector('.lightbox-next'); var currentIndex = 0; var sequence = []; // visible gallery links at the time the lightbox was opened function getVisibleLinks() { return Array.from(document.querySelectorAll('.gallery-item')) .filter(function (item) { return item.style.display !== 'none'; }) .map(function (item) { return item.querySelector('.gallery-image-link'); }) .filter(Boolean); } function showImage(index) { var link = sequence[index]; if (!link) return; currentIndex = index; lightboxImg.src = link.getAttribute('data-lightbox-src') || link.getAttribute('href'); lightboxImg.alt = link.getAttribute('data-lightbox-alt') || ''; var multiple = sequence.length > 1; if (prevBtn) prevBtn.hidden = !multiple; if (nextBtn) nextBtn.hidden = !multiple; } function navigate(dir) { showImage((currentIndex + dir + sequence.length) % sequence.length); } function openLightbox(index) { sequence = getVisibleLinks(); showImage(index); lightbox.classList.add('is-open'); document.addEventListener('keydown', onKeydown); } function closeLightbox() { lightbox.classList.remove('is-open'); document.removeEventListener('keydown', onKeydown); } function onKeydown(e) { if (e.key === 'Escape') closeLightbox(); if (e.key === 'ArrowRight') navigate(1); if (e.key === 'ArrowLeft') navigate(-1); } // Touch swipe var touchStartX = 0; lightbox.addEventListener('touchstart', function (e) { touchStartX = e.changedTouches[0].clientX; }, { passive: true }); lightbox.addEventListener('touchend', function (e) { var dx = e.changedTouches[0].clientX - touchStartX; if (Math.abs(dx) > 50) navigate(dx < 0 ? 1 : -1); }, { passive: true }); // Open on gallery click document.querySelectorAll('.gallery-image-link').forEach(function (link) { link.addEventListener('click', function (e) { e.preventDefault(); var visibles = getVisibleLinks(); var idx = visibles.indexOf(link); openLightbox(idx >= 0 ? idx : 0); }); }); if (prevBtn) prevBtn.addEventListener('click', function () { navigate(-1); }); if (nextBtn) nextBtn.addEventListener('click', function () { navigate(1); }); if (closeBtn) closeBtn.addEventListener('click', closeLightbox); if (backdrop) backdrop.addEventListener('click', closeLightbox); } /** * "Request" buttons on shop page – open mailto with product name in subject. */ function initShopRequests() { var requestBtns = document.querySelectorAll('.product-card .btn[data-product]'); requestBtns.forEach(function (btn) { btn.addEventListener('click', function (e) { var product = this.getAttribute('data-product'); if (product) { // Open mail with subject line (no real checkout) – replace email with your address var mailto = 'mailto:info@tischlerei-staffenberger.example?subject=Anfrage%20Produkt%3A%20' + encodeURIComponent(product); window.location.href = mailto; } }); }); } /** * Shop empty state: show message when no products are present. */ function initShopEmptyState() { var emptyMsg = document.getElementById('shop-empty-message'); var grid = document.getElementById('shop-grid'); if (!emptyMsg || !grid) return; var hasCards = grid.querySelectorAll('.product-card').length > 0; emptyMsg.hidden = hasCards; } /** * Run on DOM ready. */ function init() { setActiveNav(); initGalleryFilter(); initLightbox(); initShopRequests(); initShopEmptyState(); } if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', init); } else { init(); } })();