clickable Herstellerkarousel part 1
This commit is contained in:
@@ -267,6 +267,11 @@ const AppContent = ({ currentTheme, dynamicTheme, onThemeChange }) => {
|
|||||||
path="/Kategorie/:categoryId"
|
path="/Kategorie/:categoryId"
|
||||||
element={<Content />}
|
element={<Content />}
|
||||||
/>
|
/>
|
||||||
|
{/* Manufacturer page - Render Content in parallel */}
|
||||||
|
<Route
|
||||||
|
path="/Hersteller/:categoryId"
|
||||||
|
element={<Content />}
|
||||||
|
/>
|
||||||
{/* Single product page */}
|
{/* Single product page */}
|
||||||
<Route
|
<Route
|
||||||
path="/Artikel/:seoName"
|
path="/Artikel/:seoName"
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import ProductList from './ProductList.js';
|
|||||||
import CategoryBoxGrid from './CategoryBoxGrid.js';
|
import CategoryBoxGrid from './CategoryBoxGrid.js';
|
||||||
import CategoryBox from './CategoryBox.js';
|
import CategoryBox from './CategoryBox.js';
|
||||||
|
|
||||||
import { useParams, useSearchParams } from 'react-router-dom';
|
import { useParams, useSearchParams, useLocation } from 'react-router-dom';
|
||||||
import { getAllSettingsWithPrefix } from '../utils/sessionStorage.js';
|
import { getAllSettingsWithPrefix } from '../utils/sessionStorage.js';
|
||||||
import { withI18n } from '../i18n/withTranslation.js';
|
import { withI18n } from '../i18n/withTranslation.js';
|
||||||
import { withCategory } from '../context/CategoryContext.js';
|
import { withCategory } from '../context/CategoryContext.js';
|
||||||
@@ -24,17 +24,19 @@ const withRouter = (ClassComponent) => {
|
|||||||
return (props) => {
|
return (props) => {
|
||||||
const params = useParams();
|
const params = useParams();
|
||||||
const [searchParams] = useSearchParams();
|
const [searchParams] = useSearchParams();
|
||||||
return <ClassComponent {...props} params={params} searchParams={searchParams} />;
|
const location = useLocation();
|
||||||
|
const isHersteller = location.pathname.startsWith('/Hersteller/');
|
||||||
|
return <ClassComponent {...props} params={params} searchParams={searchParams} isHersteller={isHersteller} />;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
function getCachedCategoryData(categoryId, language = 'de') {
|
function getCachedCategoryData(categoryId, language = 'de', isHersteller = false) {
|
||||||
if (!window.productCache) {
|
if (!window.productCache) {
|
||||||
window.productCache = {};
|
window.productCache = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const cacheKey = `categoryProducts_${categoryId}_${language}`;
|
const cacheKey = `${isHersteller ? 'manufacturer' : 'category'}Products_${categoryId}_${language}`;
|
||||||
const cachedData = window.productCache[cacheKey];
|
const cachedData = window.productCache[cacheKey];
|
||||||
|
|
||||||
if (cachedData) {
|
if (cachedData) {
|
||||||
@@ -166,7 +168,7 @@ function getFilteredProducts(unfilteredProducts, attributes, t) {
|
|||||||
|
|
||||||
return { filteredProducts, activeAttributeFilters: activeAttributeFiltersWithNames, activeManufacturerFilters: activeManufacturerFiltersWithNames, activeAvailabilityFilters };
|
return { filteredProducts, activeAttributeFilters: activeAttributeFiltersWithNames, activeManufacturerFilters: activeManufacturerFiltersWithNames, activeAvailabilityFilters };
|
||||||
}
|
}
|
||||||
function setCachedCategoryData(categoryId, data, language = 'de') {
|
function setCachedCategoryData(categoryId, data, language = 'de', isHersteller = false) {
|
||||||
if (!window.productCache) {
|
if (!window.productCache) {
|
||||||
window.productCache = {};
|
window.productCache = {};
|
||||||
}
|
}
|
||||||
@@ -175,7 +177,7 @@ function setCachedCategoryData(categoryId, data, language = 'de') {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const cacheKey = `categoryProducts_${categoryId}_${language}`;
|
const cacheKey = `${isHersteller ? 'manufacturer' : 'category'}Products_${categoryId}_${language}`;
|
||||||
if (data.products) for (const product of data.products) {
|
if (data.products) for (const product of data.products) {
|
||||||
const productCacheKey = `product_${product.id}_${language}`;
|
const productCacheKey = `product_${product.id}_${language}`;
|
||||||
window.productDetailCache[productCacheKey] = product;
|
window.productDetailCache[productCacheKey] = product;
|
||||||
@@ -221,9 +223,10 @@ class Content extends Component {
|
|||||||
componentDidUpdate(prevProps) {
|
componentDidUpdate(prevProps) {
|
||||||
const currentLanguage = this.props.i18n?.language || 'de';
|
const currentLanguage = this.props.i18n?.language || 'de';
|
||||||
const categoryChanged = this.props.params.categoryId && (prevProps.params.categoryId !== this.props.params.categoryId);
|
const categoryChanged = this.props.params.categoryId && (prevProps.params.categoryId !== this.props.params.categoryId);
|
||||||
|
const routeTypeChanged = !!prevProps.isHersteller !== !!this.props.isHersteller;
|
||||||
const searchChanged = this.props.searchParams?.get('q') && (prevProps.searchParams?.get('q') !== this.props.searchParams?.get('q'));
|
const searchChanged = this.props.searchParams?.get('q') && (prevProps.searchParams?.get('q') !== this.props.searchParams?.get('q'));
|
||||||
|
|
||||||
if (categoryChanged) {
|
if (categoryChanged || routeTypeChanged) {
|
||||||
// Clear context for new category loading
|
// Clear context for new category loading
|
||||||
if (this.props.categoryContext && this.props.categoryContext.setCurrentCategory) {
|
if (this.props.categoryContext && this.props.categoryContext.setCurrentCategory) {
|
||||||
this.props.categoryContext.setCurrentCategory(null);
|
this.props.categoryContext.setCurrentCategory(null);
|
||||||
@@ -233,7 +236,7 @@ class Content extends Component {
|
|||||||
this.setState({ loaded: false, unfilteredProducts: [], filteredProducts: [], attributes: [], categoryName: null, childCategories: [], lastFetchedLanguage: currentLanguage }, () => {
|
this.setState({ loaded: false, unfilteredProducts: [], filteredProducts: [], attributes: [], categoryName: null, childCategories: [], lastFetchedLanguage: currentLanguage }, () => {
|
||||||
this.fetchCategoryData(this.props.params.categoryId);
|
this.fetchCategoryData(this.props.params.categoryId);
|
||||||
});
|
});
|
||||||
return; // Don't check language change if category changed
|
return; // Don't check language change if category or route type changed
|
||||||
}
|
}
|
||||||
else if (searchChanged) {
|
else if (searchChanged) {
|
||||||
this.setState({ loaded: false, unfilteredProducts: [], filteredProducts: [], attributes: [], categoryName: null, childCategories: [], lastFetchedLanguage: currentLanguage }, () => {
|
this.setState({ loaded: false, unfilteredProducts: [], filteredProducts: [], attributes: [], categoryName: null, childCategories: [], lastFetchedLanguage: currentLanguage }, () => {
|
||||||
@@ -345,7 +348,8 @@ class Content extends Component {
|
|||||||
sessionStorage.setItem('filter_availability', '1');
|
sessionStorage.setItem('filter_availability', '1');
|
||||||
}
|
}
|
||||||
const currentLanguage = this.props.languageContext?.currentLanguage || this.props.i18n?.language || 'de';
|
const currentLanguage = this.props.languageContext?.currentLanguage || this.props.i18n?.language || 'de';
|
||||||
const cachedData = getCachedCategoryData(categoryId, currentLanguage);
|
const isHersteller = !!this.props.isHersteller;
|
||||||
|
const cachedData = getCachedCategoryData(categoryId, currentLanguage, isHersteller);
|
||||||
if (cachedData) {
|
if (cachedData) {
|
||||||
this.processDataWithCategoryTree(cachedData, categoryId);
|
this.processDataWithCategoryTree(cachedData, categoryId);
|
||||||
return;
|
return;
|
||||||
@@ -360,7 +364,7 @@ class Content extends Component {
|
|||||||
window.socketManager.on(`productList:${categoryId}`, (response) => {
|
window.socketManager.on(`productList:${categoryId}`, (response) => {
|
||||||
console.log("getCategoryProducts full response", response);
|
console.log("getCategoryProducts full response", response);
|
||||||
receivedFullResponse = true;
|
receivedFullResponse = true;
|
||||||
setCachedCategoryData(categoryId, response, currentLanguage);
|
setCachedCategoryData(categoryId, response, currentLanguage, isHersteller);
|
||||||
if (response && response.products !== undefined) {
|
if (response && response.products !== undefined) {
|
||||||
this.processDataWithCategoryTree(response, categoryId);
|
this.processDataWithCategoryTree(response, categoryId);
|
||||||
} else {
|
} else {
|
||||||
@@ -370,12 +374,17 @@ class Content extends Component {
|
|||||||
|
|
||||||
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,
|
||||||
|
isHersteller,
|
||||||
|
},
|
||||||
(response) => {
|
(response) => {
|
||||||
console.log("getCategoryProducts stub response", response);
|
console.log("getCategoryProducts stub response", response);
|
||||||
// Only process stub response if we haven't received the full response yet
|
// Only process stub response if we haven't received the full response yet
|
||||||
if (!receivedFullResponse) {
|
if (!receivedFullResponse) {
|
||||||
setCachedCategoryData(categoryId, response, currentLanguage);
|
setCachedCategoryData(categoryId, response, currentLanguage, isHersteller);
|
||||||
if (response && response.products !== undefined) {
|
if (response && response.products !== undefined) {
|
||||||
this.processDataWithCategoryTree(response, categoryId);
|
this.processDataWithCategoryTree(response, categoryId);
|
||||||
} else {
|
} else {
|
||||||
@@ -454,7 +463,7 @@ class Content extends Component {
|
|||||||
const n = typeof v === 'number' ? v : parseInt(String(v), 10);
|
const n = typeof v === 'number' ? v : parseInt(String(v), 10);
|
||||||
return Number.isFinite(n) && n > 0;
|
return Number.isFinite(n) && n > 0;
|
||||||
};
|
};
|
||||||
if (categoryId !== 'neu' && categoryId !== 'bald' && !isValidJtlCategoryId(enhancedResponse.dataParam)) {
|
if (!this.props.isHersteller && categoryId !== 'neu' && categoryId !== 'bald' && !isValidJtlCategoryId(enhancedResponse.dataParam)) {
|
||||||
try {
|
try {
|
||||||
const currentLanguage = this.props.languageContext?.currentLanguage || this.props.i18n?.language || 'de';
|
const currentLanguage = this.props.languageContext?.currentLanguage || this.props.i18n?.language || 'de';
|
||||||
const categoryTreeCache = window.categoryService.getSync(209, currentLanguage);
|
const categoryTreeCache = window.categoryService.getSync(209, currentLanguage);
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import { Link } from 'react-router-dom';
|
||||||
import Box from "@mui/material/Box";
|
import Box from "@mui/material/Box";
|
||||||
import Typography from "@mui/material/Typography";
|
import Typography from "@mui/material/Typography";
|
||||||
import { withTranslation } from 'react-i18next';
|
import { withTranslation } from 'react-i18next';
|
||||||
@@ -46,7 +47,12 @@ class ManufacturerCarousel extends React.Component {
|
|||||||
.filter(m => m.imageBuffer)
|
.filter(m => m.imageBuffer)
|
||||||
.map(m => {
|
.map(m => {
|
||||||
const blob = new Blob([m.imageBuffer], { type: 'image/avif' });
|
const blob = new Blob([m.imageBuffer], { type: 'image/avif' });
|
||||||
return { id: m.id, name: m.name || '', src: URL.createObjectURL(blob) };
|
return {
|
||||||
|
id: m.id,
|
||||||
|
name: m.name || '',
|
||||||
|
slug: m.slug || '',
|
||||||
|
src: URL.createObjectURL(blob),
|
||||||
|
};
|
||||||
})
|
})
|
||||||
.sort(() => Math.random() - 0.5);
|
.sort(() => Math.random() - 0.5);
|
||||||
|
|
||||||
@@ -151,8 +157,9 @@ class ManufacturerCarousel extends React.Component {
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{items.map((item, index) => (
|
{items.map((item, index) => (
|
||||||
<div
|
<Link
|
||||||
key={`${item.id}-${index}`}
|
key={`${item.id}-${index}`}
|
||||||
|
to={`/Hersteller/${encodeURIComponent(item.slug || '')}`}
|
||||||
style={{
|
style={{
|
||||||
flex: '0 0 140px',
|
flex: '0 0 140px',
|
||||||
width: '140px',
|
width: '140px',
|
||||||
@@ -162,7 +169,8 @@ class ManufacturerCarousel extends React.Component {
|
|||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
overflow: 'hidden',
|
overflow: 'hidden',
|
||||||
userSelect: 'none',
|
userSelect: 'none',
|
||||||
pointerEvents: 'none',
|
textDecoration: 'none',
|
||||||
|
cursor: 'pointer',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
@@ -176,7 +184,7 @@ class ManufacturerCarousel extends React.Component {
|
|||||||
display: 'block',
|
display: 'block',
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</Link>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user