feat: introduce ProductImage component to streamline image handling in PrerenderProduct and ProductDetailPage

This commit is contained in:
sebseb7
2025-07-20 01:12:50 +02:00
parent a21efab9d2
commit ea488982a7
3 changed files with 111 additions and 75 deletions

View File

@@ -13,6 +13,7 @@ const {
} = require('@mui/material');
const Footer = require('./components/Footer.js').default;
const { Logo } = require('./components/header/index.js');
const ProductImage = require('./components/ProductImage.js').default;
// Utility function to clean product names by removing trailing number in parentheses
const cleanProductName = (name) => {
@@ -170,50 +171,11 @@ class PrerenderProduct extends React.Component {
},
// Product Image Section
React.createElement(
Box,
ProductImage,
{
sx: {
width: { xs: "100%", sm: "555px" },
maxWidth: "100%",
minHeight: "400px",
background: "#f8f8f8",
display: "flex",
flexDirection: "column",
alignItems: "center",
justifyContent: "center",
}
},
!product.pictureList && React.createElement(
CardMedia,
{
component: 'img',
height: '400',
image: '/assets/images/nopicture.jpg',
alt: product.name,
sx: { objectFit: 'cover' }
}
),
product.pictureList && React.createElement(
Box,
{ sx: { position: 'relative', display: 'inline-block' } },
React.createElement(
CardMedia,
{
component: 'img',
height: '400',
image: mainImage,
alt: product.name,
sx: {
objectFit: 'contain',
cursor: 'pointer',
transition: 'transform 0.2s ease-in-out',
'&:hover': {
transform: 'scale(1.02)'
}
}
}
)
)
product: product,
isPrerender: true
}
),
// Product Details Section
React.createElement(

View File

@@ -4,6 +4,7 @@ import { Link } from "react-router-dom";
import parse from "html-react-parser";
import AddToCartButton from "./AddToCartButton.js";
import Images from "./Images.js";
import ProductImage from "./ProductImage.js";
import { withI18n } from "../i18n/withTranslation.js";
import ArticleQuestionForm from "./ArticleQuestionForm.js";
import ArticleRatingForm from "./ArticleRatingForm.js";
@@ -669,38 +670,15 @@ class ProductDetailPage extends Component {
boxShadow: "0 2px 8px rgba(0,0,0,0.08)",
}}
>
<Box
sx={{
width: { xs: "100%", sm: "555px" },
maxWidth: "100%",
minHeight: "400px",
background: "#f8f8f8",
display: "flex",
flexDirection: "column",
alignItems: "center",
justifyContent: "center",
}}
>
{!product.pictureList && (
<CardMedia
component="img"
height="400"
image="/assets/images/nopicture.jpg"
alt={product.name}
sx={{ objectFit: "cover" }}
/>
)}
{product.pictureList && (
<Images
socket={this.props.socket}
socketB={this.props.socketB}
pictureList={product.pictureList}
fullscreenOpen={this.state.imageDialogOpen}
onOpenFullscreen={this.handleOpenDialog}
onCloseFullscreen={this.handleCloseDialog}
/>
)}
</Box>
<ProductImage
product={product}
socket={this.props.socket}
socketB={this.props.socketB}
fullscreenOpen={this.state.imageDialogOpen}
onOpenFullscreen={this.handleOpenDialog}
onCloseFullscreen={this.handleCloseDialog}
isPrerender={false}
/>
{/* Product Details */}
<Box

View File

@@ -0,0 +1,96 @@
import React from 'react';
import Box from '@mui/material/Box';
import CardMedia from '@mui/material/CardMedia';
import Images from './Images.js';
const ProductImage = ({
product,
socket,
socketB,
fullscreenOpen,
onOpenFullscreen,
onCloseFullscreen,
isPrerender = false
}) => {
// For prerender, use static image path
const getImagePath = (pictureList) => {
if (!pictureList || !pictureList.trim()) {
return '/assets/images/nopicture.jpg';
}
return `/assets/images/prod${pictureList.split(',')[0].trim()}.jpg`;
};
// Container styling - same for both versions
const containerSx = {
width: { xs: "100%", sm: "555px" },
maxWidth: "100%",
minHeight: "400px",
background: "#f8f8f8",
display: "flex",
flexDirection: "column",
alignItems: "center",
justifyContent: "center",
};
if (isPrerender) {
// Prerender version - use CardMedia with static paths
return (
<Box sx={containerSx}>
{!product.pictureList && (
<CardMedia
component="img"
height="400"
image="/assets/images/nopicture.jpg"
alt={product.name}
sx={{ objectFit: "cover" }}
/>
)}
{product.pictureList && (
<Box sx={{ position: 'relative', display: 'inline-block' }}>
<CardMedia
component="img"
height="400"
image={getImagePath(product.pictureList)}
alt={product.name}
sx={{
objectFit: 'contain',
cursor: 'pointer',
transition: 'transform 0.2s ease-in-out',
'&:hover': {
transform: 'scale(1.02)'
}
}}
/>
</Box>
)}
</Box>
);
}
// SPA version - use existing Images component
return (
<Box sx={containerSx}>
{!product.pictureList && (
<CardMedia
component="img"
height="400"
image="/assets/images/nopicture.jpg"
alt={product.name}
sx={{ objectFit: "cover" }}
/>
)}
{product.pictureList && (
<Images
socket={socket}
socketB={socketB}
pictureList={product.pictureList}
fullscreenOpen={fullscreenOpen}
onOpenFullscreen={onOpenFullscreen}
onCloseFullscreen={onCloseFullscreen}
/>
)}
</Box>
);
};
export default ProductImage;