feat(GrowTentKonfigurator): add periodic cache validity checking
Implement interval-based cache monitoring every 60 seconds to detect misses or expirations across categories (Zelte, Lampen, Abluft-sets, Set-zubehoer). Update per-category load status tracking to conditionally render sections independently, improving UX by avoiding global loading delays and ensuring timely refetches. Clear interval on unmount to prevent memory leaks.
This commit is contained in:
@@ -92,8 +92,7 @@ class GrowTentKonfigurator extends Component {
|
||||
this.handleExtraToggle = this.handleExtraToggle.bind(this);
|
||||
this.calculateTotalPrice = this.calculateTotalPrice.bind(this);
|
||||
this.saveStateToWindow = this.saveStateToWindow.bind(this);
|
||||
|
||||
|
||||
this.checkCacheValidity = this.checkCacheValidity.bind(this);
|
||||
}
|
||||
|
||||
saveStateToWindow() {
|
||||
@@ -116,6 +115,7 @@ class GrowTentKonfigurator extends Component {
|
||||
this.fetchCategoryData("Lampen");
|
||||
this.fetchCategoryData("Abluft-sets");
|
||||
this.fetchCategoryData("Set-zubehoer");
|
||||
this.cacheCheckInterval = setInterval(this.checkCacheValidity, 60000);
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps, prevState) {
|
||||
@@ -156,12 +156,25 @@ class GrowTentKonfigurator extends Component {
|
||||
}
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
if (this.cacheCheckInterval) {
|
||||
clearInterval(this.cacheCheckInterval);
|
||||
}
|
||||
}
|
||||
fetchCategoryData(categoryId) {
|
||||
const cachedData = getCachedCategoryData(categoryId);
|
||||
if (cachedData) {
|
||||
this.setState(prevState => ({
|
||||
categoryLoadStatus: {
|
||||
...prevState.categoryLoadStatus,
|
||||
[categoryId]: true
|
||||
}
|
||||
}));
|
||||
return;
|
||||
}
|
||||
|
||||
console.log(`Cache miss for category ${categoryId}, fetching...`);
|
||||
|
||||
window.socketManager.off(`productList:${categoryId}`);
|
||||
|
||||
window.socketManager.on(`productList:${categoryId}`,(response) => {
|
||||
@@ -182,6 +195,23 @@ class GrowTentKonfigurator extends Component {
|
||||
);
|
||||
}
|
||||
|
||||
checkCacheValidity() {
|
||||
const categories = ["Zelte", "Lampen", "Abluft-sets", "Set-zubehoer"];
|
||||
let needsUpdate = false;
|
||||
const newStatus = { ...this.state.categoryLoadStatus };
|
||||
for (const categoryId of categories) {
|
||||
if (newStatus[categoryId] && !getCachedCategoryData(categoryId)) {
|
||||
console.log(`Refetching ${categoryId} due to cache miss/expiry`);
|
||||
newStatus[categoryId] = false;
|
||||
needsUpdate = true;
|
||||
this.fetchCategoryData(categoryId);
|
||||
}
|
||||
}
|
||||
if (needsUpdate) {
|
||||
this.setState({ categoryLoadStatus: newStatus });
|
||||
}
|
||||
}
|
||||
|
||||
handleTentShapeSelect(shapeId) {
|
||||
this.setState({ selectedTentShape: shapeId });
|
||||
}
|
||||
@@ -600,22 +630,20 @@ class GrowTentKonfigurator extends Component {
|
||||
return null; // Don't show tent sizes until shape is selected
|
||||
}
|
||||
|
||||
if (!this.state.categoryLoadStatus["Zelte"]) {
|
||||
return (
|
||||
<Box sx={{ textAlign: 'center', py: 4 }}>
|
||||
<Typography variant="h6" color="text.secondary">
|
||||
Lade Growbox-Produkte...
|
||||
</Typography>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
// Get real filtered tent products for the selected shape
|
||||
const filteredTents = this.getTentsForShape(selectedTentShape);
|
||||
|
||||
// Show loading state if data is not yet available
|
||||
if (filteredTents.length === 0) {
|
||||
const cachedData = getCachedCategoryData('Zelte');
|
||||
if (!cachedData) {
|
||||
return (
|
||||
<Box sx={{ textAlign: 'center', py: 4 }}>
|
||||
<Typography variant="h6" color="text.secondary">
|
||||
Lade Growbox-Produkte...
|
||||
</Typography>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
// If we have cached data but no filtered tents, show empty state
|
||||
return (
|
||||
<Box sx={{ textAlign: 'center', py: 4 }}>
|
||||
<Typography variant="h6" color="text.secondary">
|
||||
@@ -624,18 +652,6 @@ class GrowTentKonfigurator extends Component {
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
if (filteredTents.length === 0) {
|
||||
return (
|
||||
<Box sx={{ textAlign: 'center', py: 4 }}>
|
||||
<Typography variant="h6" color="text.secondary">
|
||||
Keine Produkte verfügbar
|
||||
</Typography>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Box sx={{ mb: 4 }}>
|
||||
<Typography variant="h2" component="h2" gutterBottom sx={{ color: '#2e7d32', fontWeight: 'bold' }}>
|
||||
@@ -743,11 +759,7 @@ class GrowTentKonfigurator extends Component {
|
||||
);
|
||||
}
|
||||
|
||||
// Get real lamps for selected tent shape
|
||||
const availableLamps = this.getLampsForTentShape(selectedTentShape);
|
||||
const cachedData = getCachedCategoryData('Lampen');
|
||||
|
||||
if (!cachedData) {
|
||||
if (!this.state.categoryLoadStatus["Lampen"]) {
|
||||
return (
|
||||
<Box sx={{ mt: 4 }}>
|
||||
<Typography variant="h2" component="h2" gutterBottom sx={{ color: '#2e7d32', fontWeight: 'bold' }}>
|
||||
@@ -760,6 +772,8 @@ class GrowTentKonfigurator extends Component {
|
||||
);
|
||||
}
|
||||
|
||||
const availableLamps = this.getLampsForTentShape(selectedTentShape);
|
||||
|
||||
if (availableLamps.length === 0) {
|
||||
return (
|
||||
<Box sx={{ mt: 4 }}>
|
||||
@@ -872,11 +886,7 @@ class GrowTentKonfigurator extends Component {
|
||||
);
|
||||
}
|
||||
|
||||
// Get real ventilation products for selected tent shape
|
||||
const availableVentilation = this.getVentilationForTentShape(selectedTentShape);
|
||||
const cachedData = getCachedCategoryData('Abluft-sets');
|
||||
|
||||
if (!cachedData) {
|
||||
if (!this.state.categoryLoadStatus["Abluft-sets"]) {
|
||||
return (
|
||||
<Box sx={{ mt: 4 }}>
|
||||
<Typography variant="h2" component="h2" gutterBottom sx={{ color: '#2e7d32', fontWeight: 'bold' }}>
|
||||
@@ -889,6 +899,8 @@ class GrowTentKonfigurator extends Component {
|
||||
);
|
||||
}
|
||||
|
||||
const availableVentilation = this.getVentilationForTentShape(selectedTentShape);
|
||||
|
||||
if (availableVentilation.length === 0) {
|
||||
return (
|
||||
<Box sx={{ mt: 4 }}>
|
||||
@@ -1025,6 +1037,19 @@ class GrowTentKonfigurator extends Component {
|
||||
|
||||
renderExtrasSection() {
|
||||
const { selectedExtras } = this.state;
|
||||
if (!this.state.categoryLoadStatus["Set-zubehoer"]) {
|
||||
return (
|
||||
<Box sx={{ mb: 4 }}>
|
||||
<Typography variant="h2" component="h2" gutterBottom sx={{ color: '#2e7d32', fontWeight: 'bold' }}>
|
||||
5. Extras hinzufügen (optional)
|
||||
</Typography>
|
||||
<Typography variant="body1" color="text.secondary" sx={{ mb: 3 }}>
|
||||
Lade Extras...
|
||||
</Typography>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
const extrasData = getCachedCategoryData('Set-zubehoer');
|
||||
|
||||
if (!extrasData) {
|
||||
@@ -1034,7 +1059,7 @@ class GrowTentKonfigurator extends Component {
|
||||
5. Extras hinzufügen (optional)
|
||||
</Typography>
|
||||
<Typography variant="body1" color="text.secondary" sx={{ mb: 3 }}>
|
||||
Lade Extras...
|
||||
Keine Extras verfügbar
|
||||
</Typography>
|
||||
</Box>
|
||||
);
|
||||
@@ -1225,14 +1250,6 @@ class GrowTentKonfigurator extends Component {
|
||||
|
||||
|
||||
render() {
|
||||
// Check if all 4 category data sections have loaded
|
||||
const tentsData = getCachedCategoryData('Zelte');
|
||||
const lampsData = getCachedCategoryData('Lampen');
|
||||
const ventilationData = getCachedCategoryData('Abluft-sets');
|
||||
const extrasData = getCachedCategoryData('Set-zubehoer');
|
||||
|
||||
const allDataLoaded = tentsData && lampsData && ventilationData && extrasData;
|
||||
|
||||
return (
|
||||
<Container maxWidth="lg" sx={{ py: 4 }}>
|
||||
<Paper elevation={2} sx={{ p: 4, borderRadius: 2 }}>
|
||||
@@ -1297,11 +1314,6 @@ class GrowTentKonfigurator extends Component {
|
||||
|
||||
{this.renderTentShapeSection()}
|
||||
<Divider sx={{ my: 4 }} />
|
||||
|
||||
{allDataLoaded && (
|
||||
<>
|
||||
|
||||
|
||||
{this.renderTentSizeSection()}
|
||||
{this.state.selectedTentShape && <Divider sx={{ my: 4 }} />}
|
||||
|
||||
@@ -1315,9 +1327,6 @@ class GrowTentKonfigurator extends Component {
|
||||
|
||||
{/* Inline summary section - expands when scrolling to bottom */}
|
||||
{this.renderInlineSummary()}
|
||||
</>
|
||||
)}
|
||||
|
||||
</Paper>
|
||||
</Container>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user