import React from 'react'; import { Container, Typography, Box, Chip, Stack, AppBar, Toolbar, Button } from '@mui/material'; import Footer from './components/Footer.js'; import { Logo } from './components/header/index.js'; import ProductImage from './components/ProductImage.js'; // Utility function to clean product names by removing trailing number in parentheses const cleanProductName = (name) => { if (!name) return ""; // Remove patterns like " (1)", " (3)", " (10)" at the end of the string return name.replace(/\s*\(\d+\)\s*$/, "").trim(); }; class PrerenderProduct extends React.Component { render() { const { productData } = this.props; if (!productData) { return React.createElement( Box, { sx: { p: 4, textAlign: "center" } }, React.createElement( Typography, { variant: 'h5', gutterBottom: true }, 'Produkt nicht gefunden' ), React.createElement( Typography, null, 'Das gesuchte Produkt existiert nicht oder wurde entfernt.' ) ); } const product = productData.product; const attributes = productData.attributes || []; // Format price with tax const priceWithTax = new Intl.NumberFormat("de-DE", { style: "currency", currency: "EUR", }).format(product.price); return React.createElement( Box, { sx: { display: 'flex', flexDirection: 'column', minHeight: '100vh', mb: 0, pb: 0, bgcolor: 'background.default' } }, React.createElement( AppBar, { position: 'sticky', color: 'primary', elevation: 0, sx: { zIndex: 1100 } }, React.createElement( Toolbar, { sx: { minHeight: 64, py: { xs: 0.5, sm: 0 } } }, React.createElement( Container, { maxWidth: 'lg', sx: { display: 'flex', alignItems: 'center', px: { xs: 0, sm: 3 } } }, // Desktop: simple layout, Mobile: column layout with SearchBar space React.createElement( Box, { sx: { display: 'flex', alignItems: 'center', width: '100%', flexDirection: { xs: 'column', sm: 'row' } } }, // First row: Logo and invisible placeholders to match SPA layout React.createElement( Box, { sx: { display: 'flex', alignItems: 'center', width: '100%', justifyContent: { xs: 'space-between', sm: 'flex-start' }, // Match SPA layout minHeight: { xs: 52, sm: 'auto' }, px: { xs: 0, sm: 0 } } }, React.createElement(Logo), // Invisible SearchBar placeholder on desktop to match SPA spacing React.createElement( Box, { sx: { display: { xs: 'none', sm: 'block' }, flexGrow: 1, mx: { xs: 0, sm: 2, md: 4 }, visibility: 'hidden', height: 40 // Match SearchBar height } } ), // Invisible ButtonGroup placeholder to match SPA spacing React.createElement( Box, { sx: { display: { xs: 'flex', sm: 'flex' }, alignItems: { xs: 'flex-end', sm: 'center' }, transform: { xs: 'translateY(4px) translateX(9px)', sm: 'none' }, ml: { xs: 0, sm: 0 }, visibility: 'hidden', width: { xs: 'auto', sm: '120px' }, // Approximate ButtonGroup width height: 40 } } ) ), // Second row: SearchBar placeholder only on mobile React.createElement( Box, { sx: { display: { xs: 'block', sm: 'none' }, width: '100%', mt: { xs: 1, sm: 0 }, mb: { xs: 0.5, sm: 0 }, px: { xs: 0, sm: 0 }, height: 41, // Small TextField height visibility: 'hidden' } } ) ) ) ) ), React.createElement( Box, { sx: { flexGrow: 1 } }, React.createElement( Container, { maxWidth: "lg", sx: { p: { xs: 2, md: 2 }, pb: { xs: 4, md: 8 }, flexGrow: 1 } }, // Back button (breadcrumbs section) React.createElement( Box, { sx: { mb: 2, position: ["-webkit-sticky", "sticky"], top: { xs: "80px", sm: "80px", md: "80px", lg: "80px", }, left: 0, width: "100%", display: "flex", zIndex: 999, // Just below the AppBar py: 0, px: 2, } }, React.createElement( Box, { sx: { ml: { xs: 0, md: 0 }, display: "inline-flex", px: 0, py: 1, backgroundColor: "#2e7d32", // primary dark green borderRadius: 1, } }, React.createElement( Typography, { variant: "body2", color: "text.secondary" }, React.createElement( 'a', { href: "#", onClick: (e) => { e.preventDefault(); if (window.history.length > 1) { window.history.back(); } else { window.location.href = '/'; } }, style: { paddingLeft: 16, paddingRight: 16, paddingTop: 8, paddingBottom: 8, textDecoration: "none", color: "#fff", fontWeight: "bold", cursor: "pointer" } }, this.props.t ? this.props.t('common.back') : 'Zurück' ) ) ) ), React.createElement( Box, { sx: { display: "flex", flexDirection: { xs: "column", md: "row" }, gap: 4, background: "#fff", borderRadius: 2, boxShadow: "0 2px 8px rgba(0,0,0,0.08)", } }, // Product Image Section React.createElement( ProductImage, { product: product, socket: null, socketB: null, fullscreenOpen: false, onOpenFullscreen: null, onCloseFullscreen: null } ), // Product Details Section React.createElement( Box, { sx: { flex: "1 1 60%", p: { xs: 2, md: 4 }, display: "flex", flexDirection: "column", } }, // Product identifiers React.createElement( Box, { sx: { mb: 1 } }, React.createElement( Typography, { variant: 'body2', color: 'text.secondary' }, (this.props.t ? this.props.t('product.articleNumber') : 'Artikelnummer')+': '+product.articleNumber+' '+(product.gtin ? ` | GTIN: ${product.gtin}` : "") ) ), // Product title React.createElement( Typography, { variant: 'h4', component: 'h1', gutterBottom: true, sx: { fontWeight: 600, color: "#333" } }, cleanProductName(product.name) ), // Manufacturer if available - exact match to SPA: only render Box if manufacturer exists product.manufacturer && React.createElement( Box, { sx: { display: "flex", alignItems: "center", mb: 2 } }, React.createElement( Typography, { variant: 'body2', sx: { fontStyle: "italic" } }, (this.props.t ? this.props.t('product.manufacturer') : 'Hersteller')+': '+product.manufacturer ) ), // Attribute images and chips with action buttons section - exact replica of SPA version // SPA condition: (attributes.some(attr => attributeImages[attr.kMerkmalWert]) || attributes.some(attr => !attributeImages[attr.kMerkmalWert])) // This essentially means "if there are any attributes at all" // For products with no attributes (like Vakuumbeutel), this section should NOT render (attributes.length > 0) && React.createElement( Box, { sx: { display: "flex", justifyContent: "space-between", alignItems: "flex-start", mb: 2, gap: 2 } }, // Left side - attributes React.createElement( Stack, { direction: 'row', spacing: 2, sx: { flexWrap: "wrap", gap: 1, flex: 1 } }, // In prerender: attributes.filter(attribute => attributeImages[attribute.kMerkmalWert]) = [] (empty) // Then: attributes.filter(attribute => !attributeImages[attribute.kMerkmalWert]) = all attributes as Chips ...attributes.map((attribute, index) => React.createElement( Chip, { key: attribute.kMerkmalWert || index, label: attribute.cWert, disabled: true, sx: { mb: 1 } } ) ) ), // Right side - action buttons (exact replica with invisible versions) React.createElement( Stack, { direction: 'column', spacing: 1, sx: { flexShrink: 0 } }, // "Frage zum Artikel" button - exact replica but invisible React.createElement( Button, { variant: "outlined", size: "small", sx: { fontSize: "0.75rem", px: 1.5, py: 0.5, minWidth: "auto", whiteSpace: "nowrap", visibility: "hidden", pointerEvents: "none" } }, "Frage zum Artikel" ), // "Artikel Bewerten" button - exact replica but invisible React.createElement( Button, { variant: "outlined", size: "small", sx: { fontSize: "0.75rem", px: 1.5, py: 0.5, minWidth: "auto", whiteSpace: "nowrap", visibility: "hidden", pointerEvents: "none" } }, "Artikel Bewerten" ), // "Verfügbarkeit anfragen" button - conditional, exact replica but invisible (product.available !== 1 && product.availableSupplier !== 1) && React.createElement( Button, { variant: "outlined", size: "small", sx: { fontSize: "0.75rem", px: 1.5, py: 0.5, minWidth: "auto", whiteSpace: "nowrap", borderColor: "warning.main", color: "warning.main", "&:hover": { borderColor: "warning.dark", backgroundColor: "warning.light" }, visibility: "hidden", pointerEvents: "none" } }, "Verfügbarkeit anfragen" ) ) ), // Weight (product.weight && product.weight > 0) ? React.createElement( Box, { sx: { mb: 2 } }, React.createElement( Typography, { variant: 'body2', color: 'text.secondary' }, (this.props.t ? this.props.t('product.weight', { weight: product.weight.toFixed(1).replace(".", ",") }) : `Gewicht: ${product.weight.toFixed(1).replace(".", ",")} kg`) ) ) : null, // Price and availability section React.createElement( Box, { sx: { mt: "auto", transform: "translateY(-1px)", // Move 1px up p: 3, background: "#f9f9f9", borderRadius: 2, } }, React.createElement( Box, { sx: { display: "flex", flexDirection: { xs: "column", sm: "row" }, justifyContent: "space-between", alignItems: { xs: "flex-start", sm: "flex-start" }, gap: 2, } }, // Left side - Price information (exact match to SPA) React.createElement( Box, null, React.createElement( Typography, { variant: "h4", color: "primary", sx: { fontWeight: "bold" } }, priceWithTax ), // VAT info (exact match to SPA - direct Typography, no wrapper) React.createElement( Typography, { variant: 'body2', color: 'text.secondary' }, (this.props.t ? this.props.t('product.inclVat', { vat: product.vat }) : `inkl. ${product.vat}% MwSt.`) + (product.cGrundEinheit && product.fGrundPreis ? `; ${new Intl.NumberFormat('de-DE', {style: 'currency', currency: 'EUR'}).format(product.fGrundPreis)}/${product.cGrundEinheit}` : "") ), // Shipping class (exact match to SPA - direct Typography, conditional render) product.versandklasse && product.versandklasse != "standard" && product.versandklasse != "kostenlos" && React.createElement( Typography, { variant: 'body2', color: 'text.secondary' }, product.versandklasse ) ), // Right side - Complex cart button area structure (matching SPA exactly) React.createElement( Box, { sx: { display: "flex", flexDirection: { xs: "column", sm: "row" }, gap: 2, alignItems: "flex-start", } }, // Empty steckling column placeholder - maintains flex positioning React.createElement( Box, { sx: { display: "flex", flexDirection: "column" } } // Empty - no steckling for this product ), // Main cart button column (exact match to SPA structure) React.createElement( Box, { sx: { display: "flex", flexDirection: "column", } }, // AddToCartButton placeholder - invisible button that reserves exact space React.createElement( Button, { variant: "contained", size: "large", sx: { visibility: "hidden", pointerEvents: "none", height: "36px", width: "140px", minWidth: "140px", maxWidth: "140px" } }, "In den Warenkorb" ), // Delivery time Typography (exact match to SPA) React.createElement( Typography, { variant: 'caption', sx: { fontStyle: "italic", color: "text.secondary", textAlign: "center", mt: 1 } }, product.id && product.id.toString().endsWith("steckling") ? (this.props.t ? this.props.t('delivery.times.cutting14Days') : "Lieferzeit: 14 Tage") : product.available == 1 ? (this.props.t ? this.props.t('delivery.times.standard2to3Days') : "Lieferzeit: 2-3 Tage") : product.availableSupplier == 1 ? (this.props.t ? this.props.t('delivery.times.supplier7to9Days') : "Lieferzeit: 7-9 Tage") : "" ) ) ) ) ) ) ), // Product full description - separate card product.description && React.createElement( Box, { sx: { mt: 4, p: 4, background: "#fff", borderRadius: 2, boxShadow: "0 2px 8px rgba(0,0,0,0.08)", } }, React.createElement( Box, { sx: { mt: 2, lineHeight: 1.7, "& p": { mt: 0, mb: 2 }, "& strong": { fontWeight: 600 }, } }, React.createElement( 'div', { dangerouslySetInnerHTML: { __html: product.description }, style: { fontFamily: '"Roboto","Helvetica","Arial",sans-serif', fontSize: '1rem', lineHeight: '1.7', color: '#333' } } ) ) ) ) ), React.createElement(Footer) ); } } export default PrerenderProduct;