diff --git a/src/data/configuratorData.js b/src/data/configuratorData.js
index 4fec079..3b529fa 100644
--- a/src/data/configuratorData.js
+++ b/src/data/configuratorData.js
@@ -42,181 +42,6 @@ export const tentShapes = [
}
];
-export const tentSizes = [
- // 60x60 tents
- {
- id: 'tent_60x60x140',
- name: 'Basic 140cm',
- description: 'Einsteigermodell',
- price: 89.99,
- image: '/assets/images/nopicture.jpg',
- dimensions: '60x60x140cm',
- coverage: '1-2 Pflanzen',
- shapeId: '60x60',
- height: 140
- },
- {
- id: 'tent_60x60x160',
- name: 'Premium 160cm',
- description: 'Mehr Höhe für größere Pflanzen',
- price: 109.99,
- image: '/assets/images/nopicture.jpg',
- dimensions: '60x60x160cm',
- coverage: '1-2 Pflanzen',
- shapeId: '60x60',
- height: 160
- },
- // 80x80 tents
- {
- id: 'tent_80x80x160',
- name: 'Standard 160cm',
- description: 'Beliebtes Mittelklasse-Modell',
- price: 129.99,
- image: '/assets/images/nopicture.jpg',
- dimensions: '80x80x160cm',
- coverage: '2-4 Pflanzen',
- shapeId: '80x80',
- height: 160
- },
- {
- id: 'tent_80x80x180',
- name: 'Pro 180cm',
- description: 'Extra Höhe für optimales Wachstum',
- price: 149.99,
- image: '/assets/images/nopicture.jpg',
- dimensions: '80x80x180cm',
- coverage: '2-4 Pflanzen',
- shapeId: '80x80',
- height: 180
- },
- // 100x100 tents
- {
- id: 'tent_100x100x180',
- name: 'Professional 180cm',
- description: 'Für anspruchsvolle Projekte',
- price: 189.99,
- image: '/assets/images/nopicture.jpg',
- dimensions: '100x100x180cm',
- coverage: '4-6 Pflanzen',
- shapeId: '100x100',
- height: 180
- },
- {
- id: 'tent_100x100x200',
- name: 'Expert 200cm',
- description: 'Maximum an Wuchshöhe',
- price: 219.99,
- image: '/assets/images/nopicture.jpg',
- dimensions: '100x100x200cm',
- coverage: '4-6 Pflanzen',
- shapeId: '100x100',
- height: 200
- },
- // 120x60 tents
- {
- id: 'tent_120x60x160',
- name: 'Rectangular 160cm',
- description: 'Platzsparend und effizient',
- price: 139.99,
- image: '/assets/images/nopicture.jpg',
- dimensions: '120x60x160cm',
- coverage: '3-6 Pflanzen',
- shapeId: '120x60',
- height: 160
- },
- {
- id: 'tent_120x60x180',
- name: 'Rectangular Pro 180cm',
- description: 'Optimale Raumausnutzung',
- price: 169.99,
- image: '/assets/images/nopicture.jpg',
- dimensions: '120x60x180cm',
- coverage: '3-6 Pflanzen',
- shapeId: '120x60',
- height: 180
- }
-];
-
-export const lightTypes = [
- {
- id: 'led_quantum_board',
- name: 'LED Quantum Board',
- description: 'Energieeffizient, geringe Wärmeentwicklung',
- price: 159.99,
- image: '/assets/images/nopicture.jpg',
- wattage: '240W',
- coverage: 'Bis 100x100cm',
- spectrum: 'Vollspektrum',
- efficiency: 'Sehr hoch'
- },
- {
- id: 'led_cob',
- name: 'LED COB',
- description: 'Hochintensive COB-LEDs',
- price: 199.99,
- image: '/assets/images/nopicture.jpg',
- wattage: '300W',
- coverage: 'Bis 120x120cm',
- spectrum: 'Vollspektrum',
- efficiency: 'Hoch'
- },
- {
- id: 'hps_400w',
- name: 'HPS 400W',
- description: 'Bewährte Natriumdampflampe',
- price: 89.99,
- image: '/assets/images/nopicture.jpg',
- wattage: '400W',
- coverage: 'Bis 80x80cm',
- spectrum: 'Blüte-optimiert',
- efficiency: 'Mittel'
- },
- {
- id: 'cmh_315w',
- name: 'CMH 315W',
- description: 'Keramik-Metallhalogenid',
- price: 129.99,
- image: '/assets/images/nopicture.jpg',
- wattage: '315W',
- coverage: 'Bis 90x90cm',
- spectrum: 'Natürlich',
- efficiency: 'Hoch'
- }
-];
-
-export const ventilationTypes = [
- {
- id: 'basic_exhaust',
- name: 'Basic Abluft-Set',
- description: 'Lüfter + Aktivkohlefilter',
- price: 79.99,
- image: '/assets/images/nopicture.jpg',
- airflow: '187 m³/h',
- noiseLevel: '35 dB',
- includes: ['Rohrventilator', 'Aktivkohlefilter', 'Aluflexrohr']
- },
- {
- id: 'premium_ventilation',
- name: 'Premium Klima-Set',
- description: 'Komplette Klimakontrolle',
- price: 159.99,
- image: '/assets/images/nopicture.jpg',
- airflow: '280 m³/h',
- noiseLevel: '28 dB',
- includes: ['EC-Lüfter', 'Aktivkohlefilter', 'Thermostat', 'Feuchtigkeitsmesser']
- },
- {
- id: 'pro_climate',
- name: 'Profi Klima-System',
- description: 'Automatisierte Klimasteuerung',
- price: 299.99,
- image: '/assets/images/nopicture.jpg',
- airflow: '420 m³/h',
- noiseLevel: '25 dB',
- includes: ['Digitaler Controller', 'EC-Lüfter', 'Aktivkohlefilter', 'Zu-/Abluft']
- }
-];
-
export const extras = [
{
id: 'ph_tester',
diff --git a/src/pages/GrowTentKonfigurator.js b/src/pages/GrowTentKonfigurator.js
index d6485dd..94a36ae 100644
--- a/src/pages/GrowTentKonfigurator.js
+++ b/src/pages/GrowTentKonfigurator.js
@@ -15,8 +15,8 @@ import {
CircularProgress,
} from '@mui/material';
import ShoppingCartIcon from '@mui/icons-material/ShoppingCart';
-import { TentShapeSelector, ProductSelector, ExtrasSelector } from '../components/configurator/index.js';
-import { tentShapes, ventilationTypes, extras } from '../data/configuratorData.js';
+import { TentShapeSelector, ExtrasSelector } from '../components/configurator/index.js';
+import { tentShapes, extras } from '../data/configuratorData.js';
function setCachedCategoryData(categoryId, data) {
if (!window.productCache) {
@@ -312,6 +312,58 @@ class GrowTentKonfigurator extends Component {
return this.filterLampsByTentSize(shapeId, cachedData.products, cachedData.attributes);
}
+ // Get ventilation products for selected tent shape
+ getVentilationForTentShape(shapeId) {
+ const cachedData = getCachedCategoryData('Abluft-sets');
+ if (!cachedData || !cachedData.products || !cachedData.attributes) {
+ console.log('No cached ventilation data available');
+ return [];
+ }
+
+ return this.filterVentilationByTentSize(shapeId, cachedData.products, cachedData.attributes);
+ }
+
+ // Filter ventilation by tent size using "passend für Zelt" attribute
+ filterVentilationByTentSize(tentShape, products, attributes) {
+ if (!products || !attributes || !tentShape) return [];
+
+ console.log('Filtering ventilation for tent shape:', tentShape);
+ console.log('Available ventilation products:', products.length);
+ console.log('Available ventilation attributes:', attributes.length);
+
+ // Group attributes by product ID and attribute name
+ const attributesByProduct = {};
+ attributes.forEach(attr => {
+ if (!attributesByProduct[attr.kArtikel]) {
+ attributesByProduct[attr.kArtikel] = {};
+ }
+ attributesByProduct[attr.kArtikel][attr.cName] = attr.cWert;
+ });
+
+ // Filter products by matching tent size in "passend für Zelt" attribute
+ const matchingProducts = products.filter(product => {
+ const attrs = attributesByProduct[product.id];
+ if (!attrs) return false;
+
+ // Check "passend für Zelt" attribute
+ const tentSizeAttr = attrs['passend für Zelt'];
+ if (!tentSizeAttr) return false;
+
+ // Check if tent size matches
+ const sizeMatch = tentSizeAttr === tentShape;
+
+ // Check availability - only show products that are available for delivery
+ const isAvailable = (product.available > 0) || (product.availableSupplier === 1);
+
+ console.log(`Ventilation Product ${product.id}: tentSize=${tentSizeAttr}, match=${sizeMatch}, available=${isAvailable}`);
+
+ return sizeMatch && isAvailable;
+ });
+
+ console.log('Filtered ventilation:', matchingProducts.length);
+ return matchingProducts;
+ }
+
// Helper function to generate coverage descriptions
getCoverageDescription(width, depth) {
const area = width * depth;
@@ -423,8 +475,9 @@ class GrowTentKonfigurator extends Component {
// Add ventilation price
if (selectedVentilationType) {
- const ventilation = ventilationTypes.find(v => v.id === selectedVentilationType);
- if (ventilation) {
+ const availableVentilation = this.getVentilationForTentShape(this.state.selectedTentShape);
+ const ventilation = availableVentilation.find(v => v.id === selectedVentilationType);
+ if (ventilation && ventilation.price) {
total += ventilation.price;
itemCount++;
}
@@ -495,8 +548,9 @@ class GrowTentKonfigurator extends Component {
}
if (selectedVentilationType) {
- const ventilation = ventilationTypes.find(v => v.id === selectedVentilationType);
- if (ventilation) {
+ const availableVentilation = this.getVentilationForTentShape(this.state.selectedTentShape);
+ const ventilation = availableVentilation.find(v => v.id === selectedVentilationType);
+ if (ventilation && ventilation.price) {
originalTotal += ventilation.price;
itemCount++;
}
@@ -801,17 +855,128 @@ class GrowTentKonfigurator extends Component {
}
renderVentilationSection() {
- const { selectedVentilationType } = this.state;
+ const { selectedVentilationType, selectedTentShape } = this.state;
+ if (!selectedTentShape) {
+ return (
+
+
+ 4. Belüftung auswählen
+
+
+ Bitte wählen Sie zuerst eine Zeltgröße aus.
+
+
+ );
+ }
+
+ // Get real ventilation products for selected tent shape
+ const availableVentilation = this.getVentilationForTentShape(selectedTentShape);
+ const cachedData = getCachedCategoryData('Abluft-sets');
+
+ if (!cachedData) {
+ return (
+
+
+ 4. Belüftung auswählen - {selectedTentShape}
+
+
+ Lade Belüftungs-Produkte...
+
+
+ );
+ }
+
+ if (availableVentilation.length === 0) {
+ return (
+
+
+ 4. Belüftung auswählen - {selectedTentShape}
+
+
+ Keine passenden Belüftung für Zeltgröße {selectedTentShape} verfügbar.
+
+
+ );
+ }
+
return (
-
+
+
+ 4. Belüftung auswählen - {selectedTentShape}
+
+
+ {availableVentilation.map((ventilation) => (
+
+ this.handleVentilationSelect(ventilation.id)}
+ >
+ {/* Image */}
+
+ {this.renderTentImage(ventilation)}
+
+
+ {/* Content */}
+
+ {/* Name */}
+
+ {ventilation.name}
+
+
+ {/* Price with VAT */}
+
+ {ventilation.price ? new Intl.NumberFormat('de-DE', {
+ style: 'currency',
+ currency: 'EUR'
+ }).format(ventilation.price) : 'Kein Preis'}
+ {ventilation.vat && (
+
+ (incl. {ventilation.vat}% MwSt.,*)
+
+ )}
+
+
+ {/* Selection Indicator */}
+ {selectedVentilationType === ventilation.id && (
+
+ ✓ Ausgewählt
+
+ )}
+
+
+
+ ))}
+
+
);
}
@@ -843,7 +1008,8 @@ class GrowTentKonfigurator extends Component {
}
const availableLamps = this.state.selectedTentShape ? this.getLampsForTentShape(this.state.selectedTentShape) : [];
const selectedLight = availableLamps.find(l => l.id === selectedLightType);
- const selectedVentilation = ventilationTypes.find(v => v.id === selectedVentilationType);
+ const availableVentilation = this.state.selectedTentShape ? this.getVentilationForTentShape(this.state.selectedTentShape) : [];
+ const selectedVentilation = availableVentilation.find(v => v.id === selectedVentilationType);
const selectedExtrasItems = extras.filter(e => selectedExtras.includes(e.id));
const savingsInfo = this.calculateSavings();