Refactor PrerenderProduct layout: Introduced a back button for navigation, improved styling with Box components, and ensured consistent heights for product details and price sections. Enhanced product display with fixed height placeholders and updated availability messaging for better user experience.

This commit is contained in:
sebseb7
2025-07-19 11:30:37 +02:00
parent 5fb3e10598
commit dfb4f3e189

View File

@@ -90,6 +90,70 @@ class PrerenderProduct extends React.Component {
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,
{
@@ -110,6 +174,7 @@ class PrerenderProduct extends React.Component {
width: { xs: "100%", sm: "555px" },
maxWidth: "100%",
minHeight: "400px",
height: "400px", // Fixed height to prevent shifts
background: "#f8f8f8",
display: "flex",
flexDirection: "column",
@@ -124,7 +189,12 @@ class PrerenderProduct extends React.Component {
height: '400',
image: mainImage,
alt: product.name,
sx: { objectFit: 'contain', p: 2 }
sx: {
objectFit: 'contain',
p: 2,
width: '100%',
maxWidth: '100%'
}
}
)
),
@@ -137,44 +207,56 @@ class PrerenderProduct extends React.Component {
p: { xs: 2, md: 4 },
display: "flex",
flexDirection: "column",
minHeight: "400px", // Ensure consistent minimum height
}
},
// Product identifiers
// Product identifiers - fixed height to prevent shifts
React.createElement(
Box,
{ sx: { mb: 1 } },
{ sx: { mb: 1, minHeight: "24px" } },
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
// Product title - reserve space for 2 lines
React.createElement(
Box,
{ sx: { mb: 2, minHeight: "72px" } },
React.createElement(
Typography,
{
variant: 'h4',
component: 'h1',
gutterBottom: true,
sx: { fontWeight: 600, color: "#333" }
sx: {
fontWeight: 600,
color: "#333",
display: '-webkit-box',
WebkitLineClamp: 2,
WebkitBoxOrient: 'vertical',
overflow: 'hidden',
lineHeight: 1.2
}
},
cleanProductName(product.name)
)
),
// Manufacturer if available
product.manufacturer && React.createElement(
Box,
{ sx: { display: "flex", alignItems: "center", mb: 2 } },
// Manufacturer if available - fixed height placeholder
React.createElement(
Box,
{ sx: { display: "flex", alignItems: "center", mb: 2, minHeight: "28px" } },
product.manufacturer && React.createElement(
Typography,
{ variant: 'body2', sx: { fontStyle: "italic" } },
(this.props.t ? this.props.t('product.manufacturer') : 'Hersteller')+': '+product.manufacturer
)
),
// Product specifications (attributes)
attributes.length > 0 && React.createElement(
Box,
{ sx: { mb: 2 } },
// Product specifications (attributes) - fixed height container
React.createElement(
Box,
{ sx: { mb: 2, minHeight: attributes.length > 0 ? "auto" : "0px" } },
attributes.length > 0 && React.createElement(
Stack,
{ direction: 'row', spacing: 1, flexWrap: 'wrap', gap: 1 },
...attributes.map((attr, index) =>
@@ -184,23 +266,24 @@ class PrerenderProduct extends React.Component {
key: index,
label: `${attr.cName}: ${attr.cWert}`,
disabled: true,
size: "small",
sx: { mb: 1 }
}
)
)
)
),
// Weight
product.weight && product.weight > 0 && React.createElement(
Box,
{ sx: { mb: 2 } },
// Weight - fixed height placeholder
React.createElement(
Box,
{ sx: { mb: 2, minHeight: "28px" } },
product.weight && product.weight > 0 && 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
// Price and availability section - positioned at bottom
React.createElement(
Box,
{
@@ -209,6 +292,7 @@ class PrerenderProduct extends React.Component {
p: 3,
background: "#f9f9f9",
borderRadius: 2,
minHeight: "120px", // Fixed minimum height for price section
}
},
React.createElement(
@@ -222,46 +306,106 @@ class PrerenderProduct extends React.Component {
gap: 2,
}
},
// Left side - Price information
React.createElement(
Box,
null,
{ sx: { flex: 1 } },
React.createElement(
Typography,
{
variant: "h4",
color: "primary",
sx: { fontWeight: "bold" }
sx: { fontWeight: "bold", mb: 1 }
},
priceWithTax
),
// VAT info with fixed height
React.createElement(
Box,
{ sx: { minHeight: "20px", mb: 1 } },
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.`)
)
),
// Shipping class with fixed height
React.createElement(
Box,
{ sx: { minHeight: "20px", mb: 1 } },
product.versandklasse &&
product.versandklasse != "standard" &&
product.versandklasse != "kostenlos" && React.createElement(
Typography,
{ variant: 'body2', color: 'text.secondary' },
product.versandklasse
)
)
),
// Right side - Cart button area with availability info
React.createElement(
Box,
{
sx: {
display: "flex",
flexDirection: "column",
minWidth: { xs: "100%", sm: "200px" }
}
},
// Placeholder for AddToCartButton area
React.createElement(
Box,
{
sx: {
minHeight: "48px",
mb: 1,
display: "flex",
alignItems: "center",
justifyContent: "center",
backgroundColor: "#f0f0f0",
borderRadius: 2,
border: "1px dashed #ccc"
}
},
React.createElement(
Typography,
{
variant: 'body1',
color: product.available ? 'success.main' : 'error.main',
fontWeight: 'medium',
sx: { mt: 1 }
variant: 'body2',
color: 'text.secondary',
sx: { fontStyle: 'italic' }
},
product.available ? '✅ Verfügbar' : '❌ Nicht verfügbar'
'Add to Cart Button'
)
),
// Availability and delivery time info (matching ProductDetailPage)
React.createElement(
Typography,
{
variant: 'caption',
sx: {
fontStyle: "italic",
color: "text.secondary",
textAlign: "center",
minHeight: "28px",
display: "flex",
alignItems: "center",
justifyContent: "center"
}
},
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.available ? '✅ Verfügbar' : '❌ Nicht verfügbar')
)
)
)
)
)
),
// Product full description
// Product full description - separate card
product.description && React.createElement(
Box,
{
@@ -271,6 +415,7 @@ class PrerenderProduct extends React.Component {
background: "#fff",
borderRadius: 2,
boxShadow: "0 2px 8px rgba(0,0,0,0.08)",
minHeight: "100px" // Minimum height to prevent shifts
}
},
React.createElement(