diff --git a/src/pages/GrowTentKonfigurator.js b/src/pages/GrowTentKonfigurator.js
index 744f3fe..d06e61b 100644
--- a/src/pages/GrowTentKonfigurator.js
+++ b/src/pages/GrowTentKonfigurator.js
@@ -10,10 +10,13 @@ import {
ListItem,
ListItemText,
ListItemSecondaryAction,
+ Grid,
+ CardMedia,
+ CircularProgress,
} from '@mui/material';
import ShoppingCartIcon from '@mui/icons-material/ShoppingCart';
import { TentShapeSelector, ProductSelector, ExtrasSelector } from '../components/configurator/index.js';
-import { tentShapes, tentSizes, lightTypes, ventilationTypes, extras } from '../data/configuratorData.js';
+import { tentShapes, lightTypes, ventilationTypes, extras } from '../data/configuratorData.js';
function setCachedCategoryData(categoryId, data) {
if (!window.productCache) {
@@ -143,12 +146,19 @@ class GrowTentKonfigurator extends Component {
return;
}
- console.log(`productList:${categoryId}`);
window.socketManager.off(`productList:${categoryId}`);
+ // Track if we've received the full response to ignore stub response if needed
+ let receivedFullResponse = false;
+
window.socketManager.on(`productList:${categoryId}`,(response) => {
- console.log("getCategoryProducts full response", response);
+ receivedFullResponse = true;
setCachedCategoryData(categoryId, response);
+
+ // Force re-render when data arrives
+ if (categoryId === 'Zelte') {
+ this.forceUpdate();
+ }
});
const currentLanguage = this.props.languageContext?.currentLanguage || this.props.i18n?.language || 'de';
@@ -156,7 +166,13 @@ class GrowTentKonfigurator extends Component {
"getCategoryProducts",
{ categoryId: categoryId, language: currentLanguage, requestTranslation: currentLanguage === 'de' ? false : true },
(response) => {
- console.log("getCategoryProducts stub response", response);
+ // Only process stub response if we haven't received the full response yet
+ if (!receivedFullResponse) {
+ setCachedCategoryData(categoryId, response);
+ if (categoryId === 'Zelte') {
+ this.forceUpdate();
+ }
+ }
}
);
}
@@ -188,6 +204,133 @@ class GrowTentKonfigurator extends Component {
+ // Helper function to filter real tent products by shape
+ filterTentsByShape(tentShape, products, attributes) {
+ if (!products || !attributes || !tentShape) {
+ return [];
+ }
+
+ // Parse the shape dimensions (e.g., '80x80' -> width: 80, depth: 80)
+ const [widthStr, depthStr] = tentShape.split('x');
+ const targetWidth = parseInt(widthStr);
+ const targetDepth = parseInt(depthStr);
+
+ // Group attributes by product for efficient lookup
+ const productAttributes = {};
+ attributes.forEach(attr => {
+ if (!productAttributes[attr.kArtikel]) {
+ productAttributes[attr.kArtikel] = {};
+ }
+ productAttributes[attr.kArtikel][attr.cName] = attr.cWert;
+ });
+
+ // Filter products that match the target dimensions
+ const matchingProducts = products.filter(product => {
+ const attrs = productAttributes[product.id];
+ if (!attrs) return false;
+
+ // Check width (Breite)
+ const widthAttr = attrs['Breite'];
+ if (!widthAttr) return false;
+ const widthMatch = widthAttr.match(/(\d+)cm breit/i);
+ if (!widthMatch) return false;
+ const productWidth = parseInt(widthMatch[1]);
+
+ // Check depth (Tiefe)
+ const depthAttr = attrs['Tiefe'];
+ if (!depthAttr) return false;
+ const depthMatch = depthAttr.match(/(\d+)cm tief/i);
+ if (!depthMatch) return false;
+ const productDepth = parseInt(depthMatch[1]);
+
+ // Check if dimensions match
+ return productWidth === targetWidth && productDepth === targetDepth;
+ });
+
+ return matchingProducts.map(product => {
+ // Convert to the format expected by the configurator
+ console.log('Raw product from backend:', product);
+ return product;
+ }); // No sorting needed
+ }
+
+ // Helper function to generate coverage descriptions
+ getCoverageDescription(width, depth) {
+ const area = width * depth;
+ if (area <= 3600) return '1-2 Pflanzen'; // 60x60
+ if (area <= 6400) return '2-4 Pflanzen'; // 80x80
+ if (area <= 10000) return '4-6 Pflanzen'; // 100x100
+ return '3-6 Pflanzen'; // 120x60 and larger
+ }
+
+ // Render tent image using working code from Product component
+ renderTentImage(product) {
+ if (!window.smallPicCache) {
+ window.smallPicCache = {};
+ }
+
+ const pictureList = product.pictureList;
+
+ if (!pictureList || pictureList.length === 0 || !pictureList.split(',').length) {
+ return (
+
+ );
+ }
+
+ const bildId = pictureList.split(',')[0];
+
+ if (window.smallPicCache[bildId]) {
+ return (
+
+ );
+ }
+
+ // Load image if not cached
+ if (!this.loadingImages) this.loadingImages = new Set();
+ if (!this.loadingImages.has(bildId)) {
+ this.loadingImages.add(bildId);
+ window.socketManager.emit('getPic', { bildId, size:'small' }, (res) => {
+ if (res.success) {
+ window.smallPicCache[bildId] = URL.createObjectURL(new Blob([res.imageBuffer], { type: 'image/jpeg' }));
+ this.forceUpdate();
+ }
+ this.loadingImages.delete(bildId);
+ });
+ }
+
+ return (
+
+ );
+ }
+
+ // Get real tent products for the selected shape
+ getTentsForShape(shapeId) {
+ const cachedData = getCachedCategoryData('Zelte');
+ if (!cachedData || !cachedData.products || !cachedData.attributes) {
+ return [];
+ }
+
+ return this.filterTentsByShape(shapeId, cachedData.products, cachedData.attributes);
+ }
+
calculateTotalPrice() {
let total = 0;
const { selectedTentSize, selectedLightType, selectedVentilationType, selectedExtras } = this.state;
@@ -195,9 +338,17 @@ class GrowTentKonfigurator extends Component {
// Add tent price
if (selectedTentSize) {
- const tent = tentSizes.find(t => t.id === selectedTentSize);
- if (tent) {
- total += tent.price;
+ // Find the selected tent from all available shapes
+ let selectedTent = null;
+ const allShapes = ['60x60', '80x80', '100x100', '120x60'];
+ for (const shape of allShapes) {
+ const tents = this.getTentsForShape(shape);
+ selectedTent = tents.find(t => t.id === selectedTentSize);
+ if (selectedTent) break;
+ }
+
+ if (selectedTent) {
+ total += selectedTent.price;
itemCount++;
}
}
@@ -260,9 +411,17 @@ class GrowTentKonfigurator extends Component {
// Calculate original total without discount
if (selectedTentSize) {
- const tent = tentSizes.find(t => t.id === selectedTentSize);
- if (tent) {
- originalTotal += tent.price;
+ // Find the selected tent from all available shapes
+ let selectedTent = null;
+ const allShapes = ['60x60', '80x80', '100x100', '120x60'];
+ for (const shape of allShapes) {
+ const tents = this.getTentsForShape(shape);
+ selectedTent = tents.find(t => t.id === selectedTentSize);
+ if (selectedTent) break;
+ }
+
+ if (selectedTent) {
+ originalTotal += selectedTent.price;
itemCount++;
}
}
@@ -321,25 +480,143 @@ class GrowTentKonfigurator extends Component {
}
renderTentSizeSection() {
- const { selectedTentSize, selectedTentShape } = this.state;
-
- // Filter tents by selected shape
- const filteredTents = tentSizes.filter(tent => tent.shapeId === selectedTentShape);
-
+ const { selectedTentShape } = this.state;
+
if (!selectedTentShape) {
return null; // Don't show tent sizes until shape is selected
}
-
+
+ // 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 (
+
+
+ Lade Growbox-Produkte...
+
+
+ );
+ }
+ // If we have cached data but no filtered tents, show empty state
+ return (
+
+
+ Keine Produkte für diese Größe verfügbar
+
+
+ );
+ }
+
+ console.log('Product display:', {
+ productsCount: filteredTents.length,
+ firstProduct: filteredTents[0] || null
+ });
+
+ if (filteredTents.length === 0) {
+ return (
+
+
+ Keine Produkte verfügbar
+
+
+ );
+ }
+
return (
-
+
+
+ 2. Growbox Produkt auswählen
+
+
+ Wähle das passende Produkt für deine {selectedTentShape} Growbox
+
+
+ {filteredTents.map((product, _index) => (
+
+ this.handleTentSizeSelect(product.id)}>
+ {/* Image */}
+
+ {this.renderTentImage(product)}
+
+
+ {/* Content */}
+
+ {/* Name */}
+
+{product.name}
+
+
+ {/* Price */}
+
+{product.price ? new Intl.NumberFormat('de-DE', {
+ style: 'currency',
+ currency: 'EUR'
+ }).format(product.price) : 'Kein Preis'}
+
+
+ {/* VAT */}
+
+ (incl. 19% MwSt.,*)
+
+
+ {/* Selection Indicator */}
+ {this.state.selectedTentSize === product.id && (
+
+
+ ✓ Ausgewählt
+
+
+ )}
+
+
+
+ ))}
+
+
);
}
@@ -391,7 +668,14 @@ class GrowTentKonfigurator extends Component {
renderInlineSummary() {
const { selectedTentSize, selectedLightType, selectedVentilationType, selectedExtras, totalPrice } = this.state;
- const selectedTent = tentSizes.find(t => t.id === selectedTentSize);
+ // Find the selected tent from all available shapes
+ let selectedTent = null;
+ const allShapes = ['60x60', '80x80', '100x100', '120x60'];
+ for (const shape of allShapes) {
+ const tents = this.getTentsForShape(shape);
+ selectedTent = tents.find(t => t.id === selectedTentSize);
+ if (selectedTent) break;
+ }
const selectedLight = lightTypes.find(l => l.id === selectedLightType);
const selectedVentilation = ventilationTypes.find(v => v.id === selectedVentilationType);
const selectedExtrasItems = extras.filter(e => selectedExtras.includes(e.id));