/* AccessoryScroll — vertical scroll-snap product viewer for accessories. Each product occupies one full-height slide. Product images float freely on the red background; a white info panel sits on the right with specs. */ /* ── Individual product slide ──────────────────────────────────────── */ const AccSlide = ({ lang, product, category, isActive }) => { const productName = lang === 'el' ? (product.name_el || product.code) : (product.name_en || product.code); const catName = lang === 'el' ? category.label_el : category.label_en; const images = product.images || [product.hero]; const specLabel = (s) => lang === 'el' ? (s.label_el || s.label) : (s.label_en || s.label); const specValue = (s) => lang === 'el' ? (s.value_el || s.value) : (s.value_en || s.value); // Replay the panel slide-in animation each time this slide becomes active const panelRef = React.useRef(null); React.useEffect(() => { const el = panelRef.current; if (!el || !isActive) return; el.classList.remove('acc-panel-animate'); void el.offsetWidth; // force reflow el.classList.add('acc-panel-animate'); }, [isActive]); const imgCount = Math.min(images.length, 3); return ( <> {/* Floating images — cover the red background area */}
{images.slice(0, 3).map((img, i) => (
{productName}
))}
{/* White info panel — right side */}
ENERGETICS {catName}

{productName}

{t('code_label', lang)} {product.code}
{product.specs.map((s, i) => (
{specLabel(s)} {specValue(s)}
))}
); }; /* ── Screen component ──────────────────────────────────────────────── */ const AccessoryScroll = ({ lang, categoryId }) => { const cat = window.CATALOG; const category = cat.categories[categoryId]; const allProducts = cat.getProductsByCategory(categoryId) || []; const products = allProducts.filter(p => !p.placeholder); const [currentIdx, setCurrentIdx] = React.useState(0); const containerRef = React.useRef(null); // Reset when category changes React.useEffect(() => { setCurrentIdx(0); const container = containerRef.current; if (container) container.scrollTop = 0; }, [categoryId]); // Scroll event — each slide is exactly clientHeight tall, so a simple // Math.round(scrollTop / clientHeight) gives the current index reliably. React.useEffect(() => { const container = containerRef.current; if (!container) return; const onScroll = () => { const h = container.clientHeight; if (!h) return; const idx = Math.min( Math.round(container.scrollTop / h), products.length - 1 ); setCurrentIdx(idx); }; container.addEventListener('scroll', onScroll, { passive: true }); return () => container.removeEventListener('scroll', onScroll); }, [products.length, categoryId]); const scrollTo = (idx) => { const container = containerRef.current; if (!container) return; container.scrollTo({ top: idx * container.clientHeight, behavior: 'smooth' }); }; // Placeholder state if (products.length === 0) { return (

{t('no_products', lang)}

{t('placeholder_text', lang)}

); } return (
{/* Snapping scroll container */}
{products.map((product, idx) => (
))}
{/* Dot navigation — right edge */} {products.length > 1 && ( )} {/* Scroll-down hint — disappears on last slide */} {currentIdx < products.length - 1 && ( )}
); }; window.AccessoryScroll = AccessoryScroll;