feat(i18n): enhance data fetching and caching with language support
- Update data-fetching functions to include language and translation request parameters for improved internationalization. - Modify caching logic in Content and GrowTentKonfigurator components to utilize language-aware cache keys. - Ensure ProductDetailPage retrieves cached data based on the current language, enhancing user experience across different locales. - Integrate language handling in various components to maintain consistency in data management and rendering.
This commit is contained in:
@@ -37,9 +37,15 @@ const fetchCategoryProducts = (socket, categoryId) => {
|
|||||||
reject(new Error(`Timeout fetching products for category ${categoryId}`));
|
reject(new Error(`Timeout fetching products for category ${categoryId}`));
|
||||||
}, 5000);
|
}, 5000);
|
||||||
|
|
||||||
|
// Prerender system fetches German version by default
|
||||||
socket.emit(
|
socket.emit(
|
||||||
"getCategoryProducts",
|
"getCategoryProducts",
|
||||||
{ full:true, categoryId: categoryId === "neu" ? "neu" : parseInt(categoryId) },
|
{
|
||||||
|
full: true,
|
||||||
|
categoryId: categoryId === "neu" ? "neu" : parseInt(categoryId),
|
||||||
|
language: 'de',
|
||||||
|
requestTranslation: false
|
||||||
|
},
|
||||||
(response) => {
|
(response) => {
|
||||||
clearTimeout(timeout);
|
clearTimeout(timeout);
|
||||||
if (response && response.products !== undefined) {
|
if (response && response.products !== undefined) {
|
||||||
@@ -68,7 +74,13 @@ const fetchProductDetails = (socket, productSeoName) => {
|
|||||||
);
|
);
|
||||||
}, 5000);
|
}, 5000);
|
||||||
|
|
||||||
socket.emit("getProductView", { seoName: productSeoName, nocount: true }, (response) => {
|
// Prerender system fetches German version by default
|
||||||
|
socket.emit("getProductView", {
|
||||||
|
seoName: productSeoName,
|
||||||
|
nocount: true,
|
||||||
|
language: 'de',
|
||||||
|
requestTranslation: false
|
||||||
|
}, (response) => {
|
||||||
clearTimeout(timeout);
|
clearTimeout(timeout);
|
||||||
if (response && response.product) {
|
if (response && response.product) {
|
||||||
response.product.seoName = productSeoName;
|
response.product.seoName = productSeoName;
|
||||||
|
|||||||
@@ -193,14 +193,17 @@ const renderPage = (
|
|||||||
let productDetailCacheScript = '';
|
let productDetailCacheScript = '';
|
||||||
if (productData && productData.product) {
|
if (productData && productData.product) {
|
||||||
// Cache the entire response object (includes product, attributes, etc.)
|
// Cache the entire response object (includes product, attributes, etc.)
|
||||||
|
// Use language-aware cache key (prerender defaults to German)
|
||||||
const productDetailCacheData = JSON.stringify(productData);
|
const productDetailCacheData = JSON.stringify(productData);
|
||||||
|
const language = 'de'; // Prerender system caches German version
|
||||||
|
const cacheKey = `product_${productData.product.seoName}_${language}`;
|
||||||
productDetailCacheScript = `
|
productDetailCacheScript = `
|
||||||
<script>
|
<script>
|
||||||
// Populate window.productDetailCache with complete product data for SPA hydration
|
// Populate window.productDetailCache with complete product data for SPA hydration
|
||||||
if (!window.productDetailCache) {
|
if (!window.productDetailCache) {
|
||||||
window.productDetailCache = {};
|
window.productDetailCache = {};
|
||||||
}
|
}
|
||||||
window.productDetailCache['${productData.product.seoName}'] = ${productDetailCacheData};
|
window.productDetailCache['${cacheKey}'] = ${productDetailCacheData};
|
||||||
</script>
|
</script>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -176,7 +176,8 @@ function setCachedCategoryData(categoryId, data, language = 'de') {
|
|||||||
try {
|
try {
|
||||||
const cacheKey = `categoryProducts_${categoryId}_${language}`;
|
const cacheKey = `categoryProducts_${categoryId}_${language}`;
|
||||||
if(data.products) for(const product of data.products) {
|
if(data.products) for(const product of data.products) {
|
||||||
window.productDetailCache[product.id] = product;
|
const productCacheKey = `product_${product.id}_${language}`;
|
||||||
|
window.productDetailCache[productCacheKey] = product;
|
||||||
}
|
}
|
||||||
window.productCache[cacheKey] = {
|
window.productCache[cacheKey] = {
|
||||||
...data,
|
...data,
|
||||||
|
|||||||
@@ -34,16 +34,20 @@ class ProductDetailPage extends Component {
|
|||||||
let cachedData = null;
|
let cachedData = null;
|
||||||
let partialProduct = null;
|
let partialProduct = null;
|
||||||
let isUpgrading = false;
|
let isUpgrading = false;
|
||||||
|
|
||||||
if (window.productDetailCache && window.productDetailCache[this.props.seoName]) {
|
// Get current language for cache key
|
||||||
cachedData = window.productDetailCache[this.props.seoName];
|
const currentLanguage = this.props.i18n?.language || 'de';
|
||||||
|
const cacheKey = `product_${this.props.seoName}_${currentLanguage}`;
|
||||||
|
|
||||||
|
if (window.productDetailCache && window.productDetailCache[cacheKey]) {
|
||||||
|
cachedData = window.productDetailCache[cacheKey];
|
||||||
} else if (window.productDetailCache) {
|
} else if (window.productDetailCache) {
|
||||||
// If not found by seoName, search for partial data by checking all cached products
|
// If not found by seoName, search for partial data by checking all cached products
|
||||||
// Look for a product where the seoName matches this.props.seoName
|
// Look for a product where the seoName matches this.props.seoName
|
||||||
for (const key in window.productDetailCache) {
|
for (const key in window.productDetailCache) {
|
||||||
const cached = window.productDetailCache[key];
|
const cached = window.productDetailCache[key];
|
||||||
if (cached && cached.seoName === this.props.seoName) {
|
if (cached && cached.product && cached.product.seoName === this.props.seoName) {
|
||||||
partialProduct = cached;
|
partialProduct = cached.product;
|
||||||
isUpgrading = true;
|
isUpgrading = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -296,9 +300,12 @@ class ProductDetailPage extends Component {
|
|||||||
window.productDetailCache = {};
|
window.productDetailCache = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const currentLanguage = this.props.languageContext?.currentLanguage || this.props.i18n?.language || 'de';
|
||||||
|
const cacheKey = `product_${id}_${currentLanguage}`;
|
||||||
|
|
||||||
// Check if this komponent is already cached
|
// Check if this komponent is already cached
|
||||||
if (window.productDetailCache[id]) {
|
if (window.productDetailCache[cacheKey]) {
|
||||||
const cachedProduct = window.productDetailCache[id];
|
const cachedProduct = window.productDetailCache[cacheKey];
|
||||||
|
|
||||||
// Load komponent image if available
|
// Load komponent image if available
|
||||||
if (cachedProduct.pictureList) {
|
if (cachedProduct.pictureList) {
|
||||||
@@ -367,9 +374,7 @@ class ProductDetailPage extends Component {
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
console.log('loadKomponent', id, count);
|
console.log('loadKomponent', id, count);
|
||||||
const currentLanguage = this.props.languageContext?.currentLanguage
|
|
||||||
const currentLanguage2 = this.props.i18n?.language || 'de';
|
|
||||||
console.log('debuglanguage', currentLanguage, currentLanguage2);
|
|
||||||
window.socketManager.emit(
|
window.socketManager.emit(
|
||||||
"getProductView",
|
"getProductView",
|
||||||
{ articleId: id, language: currentLanguage, requestTranslation: currentLanguage === "de" ? false : true},
|
{ articleId: id, language: currentLanguage, requestTranslation: currentLanguage === "de" ? false : true},
|
||||||
@@ -377,9 +382,9 @@ class ProductDetailPage extends Component {
|
|||||||
if (res.success) {
|
if (res.success) {
|
||||||
// Use translated product if available, otherwise use original product
|
// Use translated product if available, otherwise use original product
|
||||||
const productData = res.translatedProduct || res.product;
|
const productData = res.translatedProduct || res.product;
|
||||||
|
|
||||||
// Cache the successful response
|
// Cache the successful response
|
||||||
window.productDetailCache[id] = productData;
|
window.productDetailCache[cacheKey] = productData;
|
||||||
|
|
||||||
// Load komponent image if available
|
// Load komponent image if available
|
||||||
if (productData.pictureList) {
|
if (productData.pictureList) {
|
||||||
@@ -556,6 +561,9 @@ class ProductDetailPage extends Component {
|
|||||||
console.log('loadProductData', this.props.seoName);
|
console.log('loadProductData', this.props.seoName);
|
||||||
const currentLanguage = this.props.languageContext?.currentLanguage || this.props.i18n?.language || 'de';
|
const currentLanguage = this.props.languageContext?.currentLanguage || this.props.i18n?.language || 'de';
|
||||||
console.log('debuglanguage', currentLanguage);
|
console.log('debuglanguage', currentLanguage);
|
||||||
|
|
||||||
|
const cacheKey = `product_${this.props.seoName}_${currentLanguage}`;
|
||||||
|
|
||||||
window.socketManager.emit(
|
window.socketManager.emit(
|
||||||
"getProductView",
|
"getProductView",
|
||||||
{ seoName: this.props.seoName, language: currentLanguage, requestTranslation: currentLanguage === "de" ? false : true},
|
{ seoName: this.props.seoName, language: currentLanguage, requestTranslation: currentLanguage === "de" ? false : true},
|
||||||
@@ -564,15 +572,15 @@ class ProductDetailPage extends Component {
|
|||||||
// Use translated product if available, otherwise use original product
|
// Use translated product if available, otherwise use original product
|
||||||
const productData = res.translatedProduct || res.product;
|
const productData = res.translatedProduct || res.product;
|
||||||
productData.seoName = this.props.seoName;
|
productData.seoName = this.props.seoName;
|
||||||
|
|
||||||
// Initialize cache if it doesn't exist
|
// Initialize cache if it doesn't exist
|
||||||
if (!window.productDetailCache) {
|
if (!window.productDetailCache) {
|
||||||
window.productDetailCache = {};
|
window.productDetailCache = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cache the complete response data (product + attributes) - cache the response with translated product
|
// Cache the complete response data (product + attributes) - cache the response with translated product
|
||||||
const cacheData = { ...res, product: productData };
|
const cacheData = { ...res, product: productData };
|
||||||
window.productDetailCache[this.props.seoName] = cacheData;
|
window.productDetailCache[cacheKey] = cacheData;
|
||||||
|
|
||||||
// Clean up prerender fallback since we now have real data
|
// Clean up prerender fallback since we now have real data
|
||||||
if (typeof window !== "undefined" && window.__PRERENDER_FALLBACK__) {
|
if (typeof window !== "undefined" && window.__PRERENDER_FALLBACK__) {
|
||||||
@@ -1317,8 +1325,16 @@ class ProductDetailPage extends Component {
|
|||||||
>
|
>
|
||||||
{product.description ? (() => {
|
{product.description ? (() => {
|
||||||
try {
|
try {
|
||||||
// Sanitize HTML to remove invalid tags
|
// Sanitize HTML to remove invalid tags, but preserve style attributes
|
||||||
return parse(sanitizeHtml(product.description));
|
return parse(sanitizeHtml(product.description, {
|
||||||
|
allowedTags: sanitizeHtml.defaults.allowedTags.concat(['img']),
|
||||||
|
allowedAttributes: {
|
||||||
|
'*': ['class', 'style'],
|
||||||
|
'a': ['href', 'title'],
|
||||||
|
'img': ['src', 'alt', 'width', 'height']
|
||||||
|
},
|
||||||
|
disallowedTagsMode: 'discard'
|
||||||
|
}));
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.warn('Failed to parse product description HTML:', error);
|
console.warn('Failed to parse product description HTML:', error);
|
||||||
// Fallback to rendering as plain text if HTML parsing fails
|
// Fallback to rendering as plain text if HTML parsing fails
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ import { Link } from 'react-router-dom';
|
|||||||
import IconButton from '@mui/material/IconButton';
|
import IconButton from '@mui/material/IconButton';
|
||||||
import ZoomInIcon from '@mui/icons-material/ZoomIn';
|
import ZoomInIcon from '@mui/icons-material/ZoomIn';
|
||||||
|
|
||||||
function setCachedCategoryData(categoryId, data) {
|
function setCachedCategoryData(categoryId, data, language = 'de') {
|
||||||
if (!window.productCache) {
|
if (!window.productCache) {
|
||||||
window.productCache = {};
|
window.productCache = {};
|
||||||
}
|
}
|
||||||
@@ -31,9 +31,10 @@ function setCachedCategoryData(categoryId, data) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const cacheKey = `categoryProducts_${categoryId}`;
|
const cacheKey = `categoryProducts_${categoryId}_${language}`;
|
||||||
if(data.products) for(const product of data.products) {
|
if(data.products) for(const product of data.products) {
|
||||||
window.productDetailCache[product.id] = product;
|
const productCacheKey = `product_${product.id}_${language}`;
|
||||||
|
window.productDetailCache[productCacheKey] = product;
|
||||||
}
|
}
|
||||||
window.productCache[cacheKey] = {
|
window.productCache[cacheKey] = {
|
||||||
...data,
|
...data,
|
||||||
@@ -43,13 +44,13 @@ function setCachedCategoryData(categoryId, data) {
|
|||||||
console.error('Error writing to cache:', err);
|
console.error('Error writing to cache:', err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
function getCachedCategoryData(categoryId) {
|
function getCachedCategoryData(categoryId, language = 'de') {
|
||||||
if (!window.productCache) {
|
if (!window.productCache) {
|
||||||
window.productCache = {};
|
window.productCache = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const cacheKey = `categoryProducts_${categoryId}`;
|
const cacheKey = `categoryProducts_${categoryId}_${language}`;
|
||||||
const cachedData = window.productCache[cacheKey];
|
const cachedData = window.productCache[cacheKey];
|
||||||
|
|
||||||
if (cachedData) {
|
if (cachedData) {
|
||||||
@@ -167,7 +168,8 @@ class GrowTentKonfigurator extends Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
fetchCategoryData(categoryId) {
|
fetchCategoryData(categoryId) {
|
||||||
const cachedData = getCachedCategoryData(categoryId);
|
const currentLanguage = this.props.languageContext?.currentLanguage || this.props.i18n?.language || 'de';
|
||||||
|
const cachedData = getCachedCategoryData(categoryId, currentLanguage);
|
||||||
if (cachedData) {
|
if (cachedData) {
|
||||||
this.setState(prevState => ({
|
this.setState(prevState => ({
|
||||||
categoryLoadStatus: {
|
categoryLoadStatus: {
|
||||||
@@ -183,7 +185,7 @@ class GrowTentKonfigurator extends Component {
|
|||||||
window.socketManager.off(`productList:${categoryId}`);
|
window.socketManager.off(`productList:${categoryId}`);
|
||||||
|
|
||||||
window.socketManager.on(`productList:${categoryId}`,(response) => {
|
window.socketManager.on(`productList:${categoryId}`,(response) => {
|
||||||
setCachedCategoryData(categoryId, response);
|
setCachedCategoryData(categoryId, response, currentLanguage);
|
||||||
this.setState(prevState => ({
|
this.setState(prevState => ({
|
||||||
categoryLoadStatus: {
|
categoryLoadStatus: {
|
||||||
...prevState.categoryLoadStatus,
|
...prevState.categoryLoadStatus,
|
||||||
@@ -191,8 +193,6 @@ class GrowTentKonfigurator extends Component {
|
|||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
|
|
||||||
const currentLanguage = this.props.languageContext?.currentLanguage || this.props.i18n?.language || 'de';
|
|
||||||
window.socketManager.emit(
|
window.socketManager.emit(
|
||||||
"getCategoryProducts",
|
"getCategoryProducts",
|
||||||
{ categoryId: categoryId, language: currentLanguage, requestTranslation: currentLanguage === 'de' ? false : true },
|
{ categoryId: categoryId, language: currentLanguage, requestTranslation: currentLanguage === 'de' ? false : true },
|
||||||
@@ -202,10 +202,11 @@ class GrowTentKonfigurator extends Component {
|
|||||||
|
|
||||||
checkCacheValidity() {
|
checkCacheValidity() {
|
||||||
const categories = ["Zelte", "Lampen", "Abluft-sets", "Set-zubehoer"];
|
const categories = ["Zelte", "Lampen", "Abluft-sets", "Set-zubehoer"];
|
||||||
|
const currentLanguage = this.props.languageContext?.currentLanguage || this.props.i18n?.language || 'de';
|
||||||
let needsUpdate = false;
|
let needsUpdate = false;
|
||||||
const newStatus = { ...this.state.categoryLoadStatus };
|
const newStatus = { ...this.state.categoryLoadStatus };
|
||||||
for (const categoryId of categories) {
|
for (const categoryId of categories) {
|
||||||
if (newStatus[categoryId] && !getCachedCategoryData(categoryId)) {
|
if (newStatus[categoryId] && !getCachedCategoryData(categoryId, currentLanguage)) {
|
||||||
console.log(`Refetching ${categoryId} due to cache miss/expiry`);
|
console.log(`Refetching ${categoryId} due to cache miss/expiry`);
|
||||||
newStatus[categoryId] = false;
|
newStatus[categoryId] = false;
|
||||||
needsUpdate = true;
|
needsUpdate = true;
|
||||||
@@ -275,7 +276,8 @@ class GrowTentKonfigurator extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Extras
|
// Extras
|
||||||
const extrasData = getCachedCategoryData('Set-zubehoer');
|
const currentLanguage = this.props.languageContext?.currentLanguage || this.props.i18n?.language || 'de';
|
||||||
|
const extrasData = getCachedCategoryData('Set-zubehoer', currentLanguage);
|
||||||
if (extrasData && Array.isArray(extrasData.products)) {
|
if (extrasData && Array.isArray(extrasData.products)) {
|
||||||
this.state.selectedExtras.forEach(extraId => {
|
this.state.selectedExtras.forEach(extraId => {
|
||||||
const extra = extrasData.products.find(e => e.id === extraId);
|
const extra = extrasData.products.find(e => e.id === extraId);
|
||||||
@@ -398,7 +400,8 @@ class GrowTentKonfigurator extends Component {
|
|||||||
|
|
||||||
// Get lamps for selected tent shape
|
// Get lamps for selected tent shape
|
||||||
getLampsForTentShape(shapeId) {
|
getLampsForTentShape(shapeId) {
|
||||||
const cachedData = getCachedCategoryData('Lampen');
|
const currentLanguage = this.props.languageContext?.currentLanguage || this.props.i18n?.language || 'de';
|
||||||
|
const cachedData = getCachedCategoryData('Lampen', currentLanguage);
|
||||||
if (!cachedData || !cachedData.products || !cachedData.attributes) {
|
if (!cachedData || !cachedData.products || !cachedData.attributes) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
@@ -408,7 +411,8 @@ class GrowTentKonfigurator extends Component {
|
|||||||
|
|
||||||
// Get ventilation products for selected tent shape
|
// Get ventilation products for selected tent shape
|
||||||
getVentilationForTentShape(shapeId) {
|
getVentilationForTentShape(shapeId) {
|
||||||
const cachedData = getCachedCategoryData('Abluft-sets');
|
const currentLanguage = this.props.languageContext?.currentLanguage || this.props.i18n?.language || 'de';
|
||||||
|
const cachedData = getCachedCategoryData('Abluft-sets', currentLanguage);
|
||||||
if (!cachedData || !cachedData.products || !cachedData.attributes) {
|
if (!cachedData || !cachedData.products || !cachedData.attributes) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
@@ -523,7 +527,8 @@ class GrowTentKonfigurator extends Component {
|
|||||||
|
|
||||||
// Get real tent products for the selected shape
|
// Get real tent products for the selected shape
|
||||||
getTentsForShape(shapeId) {
|
getTentsForShape(shapeId) {
|
||||||
const cachedData = getCachedCategoryData('Zelte');
|
const currentLanguage = this.props.languageContext?.currentLanguage || this.props.i18n?.language || 'de';
|
||||||
|
const cachedData = getCachedCategoryData('Zelte', currentLanguage);
|
||||||
if (!cachedData || !cachedData.products || !cachedData.attributes) {
|
if (!cachedData || !cachedData.products || !cachedData.attributes) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
@@ -572,8 +577,9 @@ class GrowTentKonfigurator extends Component {
|
|||||||
itemCount++;
|
itemCount++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const extrasData = getCachedCategoryData('Set-zubehoer');
|
const currentLanguage = this.props.languageContext?.currentLanguage || this.props.i18n?.language || 'de';
|
||||||
|
const extrasData = getCachedCategoryData('Set-zubehoer', currentLanguage);
|
||||||
if (!extrasData || !Array.isArray(extrasData.products)) {
|
if (!extrasData || !Array.isArray(extrasData.products)) {
|
||||||
console.warn('Extras data not available; skipping extras price in total calculation');
|
console.warn('Extras data not available; skipping extras price in total calculation');
|
||||||
} else {
|
} else {
|
||||||
@@ -650,8 +656,9 @@ class GrowTentKonfigurator extends Component {
|
|||||||
itemCount++;
|
itemCount++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const extrasData = getCachedCategoryData('Set-zubehoer');
|
const currentLanguage = this.props.languageContext?.currentLanguage || this.props.i18n?.language || 'de';
|
||||||
|
const extrasData = getCachedCategoryData('Set-zubehoer', currentLanguage);
|
||||||
if (!extrasData || !Array.isArray(extrasData.products)) {
|
if (!extrasData || !Array.isArray(extrasData.products)) {
|
||||||
console.warn('Extras data not available; skipping extras in savings calculation');
|
console.warn('Extras data not available; skipping extras in savings calculation');
|
||||||
} else {
|
} else {
|
||||||
@@ -1156,7 +1163,8 @@ class GrowTentKonfigurator extends Component {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const extrasData = getCachedCategoryData('Set-zubehoer');
|
const currentLanguage = this.props.languageContext?.currentLanguage || this.props.i18n?.language || 'de';
|
||||||
|
const extrasData = getCachedCategoryData('Set-zubehoer', currentLanguage);
|
||||||
|
|
||||||
if (!extrasData) {
|
if (!extrasData) {
|
||||||
return (
|
return (
|
||||||
@@ -1212,7 +1220,8 @@ class GrowTentKonfigurator extends Component {
|
|||||||
const selectedLight = availableLamps.find(l => l.id === selectedLightType);
|
const selectedLight = availableLamps.find(l => l.id === selectedLightType);
|
||||||
const availableVentilation = this.state.selectedTentShape ? this.getVentilationForTentShape(this.state.selectedTentShape) : [];
|
const availableVentilation = this.state.selectedTentShape ? this.getVentilationForTentShape(this.state.selectedTentShape) : [];
|
||||||
const selectedVentilation = availableVentilation.find(v => v.id === selectedVentilationType && v.isDeliverable);
|
const selectedVentilation = availableVentilation.find(v => v.id === selectedVentilationType && v.isDeliverable);
|
||||||
const extrasData = getCachedCategoryData('Set-zubehoer');
|
const currentLanguage = this.props.languageContext?.currentLanguage || this.props.i18n?.language || 'de';
|
||||||
|
const extrasData = getCachedCategoryData('Set-zubehoer', currentLanguage);
|
||||||
const selectedExtrasItems = Array.isArray(extrasData?.products)
|
const selectedExtrasItems = Array.isArray(extrasData?.products)
|
||||||
? extrasData.products.filter(e => selectedExtras.includes(e.id))
|
? extrasData.products.filter(e => selectedExtras.includes(e.id))
|
||||||
: [];
|
: [];
|
||||||
|
|||||||
Reference in New Issue
Block a user