feat(ui): add similar products section to ProductDetailPage
- Introduce a new section displaying similar products on the ProductDetailPage. - Update state management to include similar products data. - Enhance internationalization by adding translation keys for similar products in English, German, and Spanish.
This commit is contained in:
@@ -11,6 +11,7 @@ import { Link } from "react-router-dom";
|
||||
import parse from "html-react-parser";
|
||||
import AddToCartButton from "./AddToCartButton.js";
|
||||
import ProductImage from "./ProductImage.js";
|
||||
import Product from "./Product.js";
|
||||
import { withI18n } from "../i18n/withTranslation.js";
|
||||
import ArticleQuestionForm from "./ArticleQuestionForm.js";
|
||||
import ArticleRatingForm from "./ArticleRatingForm.js";
|
||||
@@ -97,7 +98,9 @@ class ProductDetailPage extends Component {
|
||||
// Snackbar state
|
||||
snackbarOpen: false,
|
||||
snackbarMessage: "",
|
||||
snackbarSeverity: "success"
|
||||
snackbarSeverity: "success",
|
||||
// Similar products
|
||||
similarProducts: cachedData.similarProducts || []
|
||||
};
|
||||
} else if (partialProduct && isUpgrading) {
|
||||
// Partial product data found - enter upgrading state
|
||||
@@ -144,7 +147,9 @@ class ProductDetailPage extends Component {
|
||||
// Snackbar state
|
||||
snackbarOpen: false,
|
||||
snackbarMessage: "",
|
||||
snackbarSeverity: "success"
|
||||
snackbarSeverity: "success",
|
||||
// Similar products
|
||||
similarProducts: []
|
||||
};
|
||||
} else {
|
||||
// No cached data found - full loading state
|
||||
@@ -173,7 +178,9 @@ class ProductDetailPage extends Component {
|
||||
// Snackbar state
|
||||
snackbarOpen: false,
|
||||
snackbarMessage: "",
|
||||
snackbarSeverity: "success"
|
||||
snackbarSeverity: "success",
|
||||
// Similar products
|
||||
similarProducts: []
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -196,7 +203,7 @@ class ProductDetailPage extends Component {
|
||||
// Check for seoName changes
|
||||
if (prevProps.seoName !== this.props.seoName) {
|
||||
this.setState(
|
||||
{ product: null, loading: true, upgrading: false, error: null, imageDialogOpen: false },
|
||||
{ product: null, loading: true, upgrading: false, error: null, imageDialogOpen: false, similarProducts: [] },
|
||||
this.loadProductData
|
||||
);
|
||||
return;
|
||||
@@ -225,7 +232,8 @@ class ProductDetailPage extends Component {
|
||||
komponentenData: {},
|
||||
komponentenLoaded: false,
|
||||
totalKomponentenPrice: 0,
|
||||
totalSavings: 0
|
||||
totalSavings: 0,
|
||||
similarProducts: []
|
||||
},
|
||||
this.loadProductData
|
||||
);
|
||||
@@ -514,7 +522,8 @@ class ProductDetailPage extends Component {
|
||||
imageDialogOpen: false,
|
||||
attributes: res.attributes,
|
||||
komponenten: komponenten,
|
||||
komponentenLoaded: komponenten.length === 0 // If no komponenten, mark as loaded
|
||||
komponentenLoaded: komponenten.length === 0, // If no komponenten, mark as loaded
|
||||
similarProducts: res.similarProducts || []
|
||||
}, () => {
|
||||
if(komponenten.length > 0) {
|
||||
for(const komponent of komponenten) {
|
||||
@@ -1599,6 +1608,57 @@ class ProductDetailPage extends Component {
|
||||
</Box>
|
||||
)}
|
||||
|
||||
{/* Similar Products Section */}
|
||||
{this.state.similarProducts && this.state.similarProducts.length > 0 && (
|
||||
<Box sx={{ mt: 4, p: 4, background: "#fff", borderRadius: 2, boxShadow: "0 2px 8px rgba(0,0,0,0.08)" }}>
|
||||
<Typography variant="h4" component="h2" gutterBottom sx={{ mb: 3 }}>
|
||||
{this.props.t ? this.props.t('product.similarProducts') : 'Ähnliche Produkte'}
|
||||
</Typography>
|
||||
<Box sx={{
|
||||
display: "grid",
|
||||
gridTemplateColumns: {
|
||||
xs: "1fr",
|
||||
sm: "repeat(2, 1fr)",
|
||||
md: "repeat(3, 1fr)",
|
||||
lg: "repeat(4, 1fr)"
|
||||
},
|
||||
gap: 2
|
||||
}}>
|
||||
{this.state.similarProducts.map((similarProductData, index) => {
|
||||
const product = similarProductData.product;
|
||||
return (
|
||||
<Box key={product.id} sx={{ display: 'flex', justifyContent: 'center' }}>
|
||||
<Product
|
||||
id={product.id}
|
||||
name={product.name}
|
||||
seoName={product.seoName}
|
||||
price={product.price}
|
||||
currency={product.currency}
|
||||
available={product.available}
|
||||
manufacturer={product.manufacturer}
|
||||
vat={product.vat}
|
||||
cGrundEinheit={product.cGrundEinheit}
|
||||
fGrundPreis={product.fGrundPreis}
|
||||
incoming={product.incomingDate}
|
||||
neu={product.neu}
|
||||
thc={product.thc}
|
||||
floweringWeeks={product.floweringWeeks}
|
||||
versandklasse={product.versandklasse}
|
||||
weight={product.weight}
|
||||
pictureList={product.pictureList}
|
||||
availableSupplier={product.availableSupplier}
|
||||
komponenten={product.komponenten}
|
||||
rebate={product.rebate}
|
||||
priority={index < 6 ? 'high' : 'auto'}
|
||||
t={this.props.t}
|
||||
/>
|
||||
</Box>
|
||||
);
|
||||
})}
|
||||
</Box>
|
||||
</Box>
|
||||
)}
|
||||
|
||||
{/* Snackbar for user feedback */}
|
||||
<Snackbar
|
||||
open={snackbarOpen}
|
||||
|
||||
@@ -28,6 +28,7 @@ export default {
|
||||
"individualPriceTotal": "Einzelpreis gesamt:",
|
||||
"setPrice": "Set-Preis:",
|
||||
"yourSavings": "Ihre Ersparnis:",
|
||||
"similarProducts": "Ähnliche Produkte",
|
||||
"countDisplay": {
|
||||
"noProducts": "0 Produkte",
|
||||
"oneProduct": "1 Produkt",
|
||||
|
||||
@@ -28,6 +28,7 @@ export default {
|
||||
"individualPriceTotal": "Total individual price:", // Einzelpreis gesamt:
|
||||
"setPrice": "Set price:", // Set-Preis:
|
||||
"yourSavings": "Your savings:", // Ihre Ersparnis:
|
||||
"similarProducts": "Similar Products", // Ähnliche Produkte
|
||||
"countDisplay": {
|
||||
"noProducts": "0 products", // 0 Produkte
|
||||
"oneProduct": "1 product", // 1 Produkt
|
||||
|
||||
@@ -28,6 +28,7 @@ export default {
|
||||
"individualPriceTotal": "Precio individual total:",
|
||||
"setPrice": "Precio del set:",
|
||||
"yourSavings": "Tus ahorros:",
|
||||
"similarProducts": "Productos Similares",
|
||||
"countDisplay": {
|
||||
"noProducts": "0 productos",
|
||||
"oneProduct": "1 producto",
|
||||
|
||||
Reference in New Issue
Block a user