Enhance product display in PrerenderProduct: Added a utility function to clean product names, improved layout with Box components for better styling, and formatted price display with tax. Updated product details section to include manufacturer, weight, and availability status, ensuring a more informative and visually appealing product presentation.

This commit is contained in:
sebseb7
2025-07-19 11:23:31 +02:00
parent b602444066
commit 5fb3e10598

View File

@@ -14,18 +14,30 @@ const {
const Footer = require('./components/Footer.js').default; const Footer = require('./components/Footer.js').default;
const { Logo } = require('./components/header/index.js'); const { Logo } = require('./components/header/index.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 { class PrerenderProduct extends React.Component {
render() { render() {
const { productData } = this.props; const { productData } = this.props;
if (!productData) { if (!productData) {
return React.createElement( return React.createElement(
Container, Box,
{ maxWidth: 'lg', sx: { py: 4 } }, { sx: { p: 4, textAlign: "center" } },
React.createElement( React.createElement(
Typography, Typography,
{ variant: 'h4', component: 'h1', gutterBottom: true }, { variant: 'h5', gutterBottom: true },
'Product not found' 'Produkt nicht gefunden'
),
React.createElement(
Typography,
null,
'Das gesuchte Produkt existiert nicht oder wurde entfernt.'
) )
); );
} }
@@ -36,6 +48,12 @@ class PrerenderProduct extends React.Component {
? `/assets/images/prod${product.pictureList.split(',')[0].trim()}.jpg` ? `/assets/images/prod${product.pictureList.split(',')[0].trim()}.jpg`
: '/assets/images/nopicture.jpg'; : '/assets/images/nopicture.jpg';
// Format price with tax
const priceWithTax = new Intl.NumberFormat("de-DE", {
style: "currency",
currency: "EUR",
}).format(product.price);
return React.createElement( return React.createElement(
Box, Box,
{ {
@@ -48,7 +66,7 @@ class PrerenderProduct extends React.Component {
bgcolor: 'background.default' bgcolor: 'background.default'
} }
}, },
React.createElement( React.createElement(
AppBar, AppBar,
{ position: 'sticky', color: 'primary', elevation: 0, sx: { zIndex: 1100 } }, { position: 'sticky', color: 'primary', elevation: 0, sx: { zIndex: 1100 } },
React.createElement( React.createElement(
@@ -62,18 +80,43 @@ class PrerenderProduct extends React.Component {
) )
), ),
React.createElement( React.createElement(
Container, Box,
{ maxWidth: 'lg', sx: { py: 4, flexGrow: 1 } }, {
sx: {
p: { xs: 2, md: 2 },
pb: { xs: 4, md: 8 },
maxWidth: "1400px",
mx: "auto",
flexGrow: 1
}
},
React.createElement( React.createElement(
Grid, Box,
{ container: true, spacing: 4 }, {
// Product Image sx: {
React.createElement( display: "flex",
Grid, flexDirection: { xs: "column", md: "row" },
{ item: true, xs: 12, md: 6 }, gap: 4,
background: "#fff",
borderRadius: 2,
boxShadow: "0 2px 8px rgba(0,0,0,0.08)",
}
},
// Product Image Section
React.createElement( React.createElement(
Card, Box,
{ sx: { height: '100%' } }, {
sx: {
width: { xs: "100%", sm: "555px" },
maxWidth: "100%",
minHeight: "400px",
background: "#f8f8f8",
display: "flex",
flexDirection: "column",
alignItems: "center",
justifyContent: "center",
}
},
React.createElement( React.createElement(
CardMedia, CardMedia,
{ {
@@ -84,108 +127,175 @@ class PrerenderProduct extends React.Component {
sx: { objectFit: 'contain', p: 2 } sx: { objectFit: 'contain', p: 2 }
} }
) )
) ),
), // Product Details Section
// Product Details
React.createElement(
Grid,
{ item: true, xs: 12, md: 6 },
React.createElement( React.createElement(
Stack, Box,
{ spacing: 3 }, {
React.createElement( sx: {
Typography, flex: "1 1 60%",
{ variant: 'h3', component: 'h1', gutterBottom: true }, p: { xs: 2, md: 4 },
product.name display: "flex",
), flexDirection: "column",
React.createElement( }
Typography, },
{ variant: 'h6', color: 'text.secondary' }, // Product identifiers
(this.props.t ? this.props.t('product.articleNumber') : 'Artikelnummer')+': '+product.articleNumber+' '+(product.gtin ? ` | GTIN: ${product.gtin}` : "")
),
React.createElement( React.createElement(
Box, Box,
{ sx: { mt: 1 } }, { sx: { mb: 1 } },
React.createElement( React.createElement(
Typography,
{ variant: 'h4', color: 'primary', fontWeight: 'bold' },
new Intl.NumberFormat('de-DE', {
style: 'currency',
currency: 'EUR'
}).format(product.price)
),
product.vat && React.createElement(
Typography, Typography,
{ variant: 'body2', color: 'text.secondary' }, { variant: 'body2', color: 'text.secondary' },
`inkl. ${product.vat}% MwSt.` (this.props.t ? this.props.t('product.articleNumber') : 'Artikelnummer')+': '+product.articleNumber+' '+(product.gtin ? ` | GTIN: ${product.gtin}` : "")
),
React.createElement(
Typography,
{
variant: 'body1',
color: product.available ? 'success.main' : 'error.main',
fontWeight: 'medium',
sx: { mt: 1 }
},
product.available ? '✅ Verfügbar' : '❌ Nicht verfügbar'
) )
), ),
product.description && React.createElement( // Product title
Box,
{ sx: { mt: 2 } },
React.createElement(
Typography,
{ variant: 'h6', gutterBottom: true },
'Beschreibung'
),
React.createElement(
'div',
{
dangerouslySetInnerHTML: { __html: product.description },
style: {
fontFamily: '"Roboto","Helvetica","Arial",sans-serif',
fontSize: '1rem',
lineHeight: '1.5',
color: '#33691E'
}
}
)
),
// Product specifications
React.createElement( React.createElement(
Typography,
{
variant: 'h4',
component: 'h1',
gutterBottom: true,
sx: { fontWeight: 600, color: "#333" }
},
cleanProductName(product.name)
),
// Manufacturer if available
product.manufacturer && React.createElement(
Box, Box,
{ sx: { mt: 2 } }, { sx: { display: "flex", alignItems: "center", mb: 2 } },
React.createElement( React.createElement(
Typography, Typography,
{ variant: 'h6', gutterBottom: true }, { variant: 'body2', sx: { fontStyle: "italic" } },
'Produktdetails' (this.props.t ? this.props.t('product.manufacturer') : 'Hersteller')+': '+product.manufacturer
), )
),
// Product specifications (attributes)
attributes.length > 0 && React.createElement(
Box,
{ sx: { mb: 2 } },
React.createElement( React.createElement(
Stack, Stack,
{ direction: 'row', spacing: 1, flexWrap: 'wrap', gap: 1 }, { direction: 'row', spacing: 1, flexWrap: 'wrap', gap: 1 },
product.manufacturer && React.createElement(
Chip,
{ label: `Hersteller: ${product.manufacturer}`, variant: 'outlined' }
),
product.weight && product.weight > 0 && React.createElement(
Chip,
{ label: `Gewicht: ${product.weight} kg`, variant: 'outlined' }
),
...attributes.map((attr, index) => ...attributes.map((attr, index) =>
React.createElement( React.createElement(
Chip, Chip,
{ {
key: index, key: index,
label: `${attr.cName}: ${attr.cWert}`, label: `${attr.cName}: ${attr.cWert}`,
variant: 'outlined', disabled: true,
color: 'primary' sx: { mb: 1 }
} }
) )
) )
) )
),
// 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`)
)
),
// Price and availability section
React.createElement(
Box,
{
sx: {
mt: "auto",
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,
}
},
React.createElement(
Box,
null,
React.createElement(
Typography,
{
variant: "h4",
color: "primary",
sx: { fontWeight: "bold" }
},
priceWithTax
),
product.vat && React.createElement(
Typography,
{ variant: 'body2', color: 'text.secondary' },
(this.props.t ? this.props.t('product.inclVat', { vat: product.vat }) : `inkl. ${product.vat}% MwSt.`)
),
product.versandklasse &&
product.versandklasse != "standard" &&
product.versandklasse != "kostenlos" && React.createElement(
Typography,
{ variant: 'body2', color: 'text.secondary' },
product.versandklasse
),
React.createElement(
Typography,
{
variant: 'body1',
color: product.available ? 'success.main' : 'error.main',
fontWeight: 'medium',
sx: { mt: 1 }
},
product.available ? '✅ Verfügbar' : '❌ Nicht verfügbar'
)
)
)
)
)
),
// Product full description
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) React.createElement(Footer)