feat: improve ventilation selection logic in GrowTentKonfigurator

- Added functionality to reset ventilation selection when the tent shape changes and the current selection is not deliverable.
- Updated product filtering to include all size-matching products while marking their availability status.
- Enhanced UI to visually indicate non-deliverable ventilation options, improving user experience and clarity in selection.
- Adjusted price calculations to consider only deliverable ventilation products.
This commit is contained in:
sebseb7
2025-09-04 07:07:21 +02:00
parent 8862f0c6b8
commit 3660f80277

View File

@@ -116,6 +116,15 @@ class GrowTentKonfigurator extends Component {
if (prevState.selectedTentShape !== this.state.selectedTentShape && this.state.selectedTentShape !== prevState.selectedTentShape) {
this.setState({ selectedTentSize: '' });
}
// Reset ventilation selection if current selection is not deliverable for new tent shape
if (prevState.selectedTentShape !== this.state.selectedTentShape && this.state.selectedVentilationType) {
const availableVentilation = this.getVentilationForTentShape(this.state.selectedTentShape);
const currentVentilation = availableVentilation.find(v => v.id === this.state.selectedVentilationType);
if (!currentVentilation || !currentVentilation.isDeliverable) {
this.setState({ selectedVentilationType: '' });
}
}
// Recalculate total price when selections change
if (
@@ -341,6 +350,7 @@ class GrowTentKonfigurator extends Component {
});
// Filter products by matching tent size in "passend für Zelt" attribute
// Include all size-matching products, but mark availability status
const matchingProducts = products.filter(product => {
const attrs = attributesByProduct[product.id];
if (!attrs) return false;
@@ -349,18 +359,22 @@ class GrowTentKonfigurator extends Component {
const tentSizeAttr = attrs['passend für Zelt'];
if (!tentSizeAttr) return false;
// Check if tent size matches
// Only filter by tent size match, not by availability
const sizeMatch = tentSizeAttr === tentShape;
// Check availability - only show products that are available for delivery
console.log(`Ventilation Product ${product.id}: tentSize=${tentSizeAttr}, match=${sizeMatch}`);
return sizeMatch;
}).map(product => {
// Add availability flag to each product for UI rendering
const isAvailable = (product.available > 0) || (product.availableSupplier === 1);
console.log(`Ventilation Product ${product.id}: tentSize=${tentSizeAttr}, match=${sizeMatch}, available=${isAvailable}`);
return sizeMatch && isAvailable;
return {
...product,
isDeliverable: isAvailable
};
});
console.log('Filtered ventilation:', matchingProducts.length);
console.log('Filtered ventilation (including non-deliverable):', matchingProducts.length);
return matchingProducts;
}
@@ -477,7 +491,7 @@ class GrowTentKonfigurator extends Component {
if (selectedVentilationType) {
const availableVentilation = this.getVentilationForTentShape(this.state.selectedTentShape);
const ventilation = availableVentilation.find(v => v.id === selectedVentilationType);
if (ventilation && ventilation.price) {
if (ventilation && ventilation.price && ventilation.isDeliverable) {
total += ventilation.price;
itemCount++;
}
@@ -550,7 +564,7 @@ class GrowTentKonfigurator extends Component {
if (selectedVentilationType) {
const availableVentilation = this.getVentilationForTentShape(this.state.selectedTentShape);
const ventilation = availableVentilation.find(v => v.id === selectedVentilationType);
if (ventilation && ventilation.price) {
if (ventilation && ventilation.price && ventilation.isDeliverable) {
originalTotal += ventilation.price;
itemCount++;
}
@@ -915,18 +929,53 @@ class GrowTentKonfigurator extends Component {
flexDirection: 'column',
borderRadius: '8px',
overflow: 'hidden',
cursor: 'pointer',
cursor: ventilation.isDeliverable ? 'pointer' : 'not-allowed',
border: '2px solid',
borderColor: selectedVentilationType === ventilation.id ? '#2e7d32' : '#e0e0e0',
backgroundColor: selectedVentilationType === ventilation.id ? '#f1f8e9' : '#ffffff',
'&:hover': {
opacity: ventilation.isDeliverable ? 1 : 0.5,
filter: ventilation.isDeliverable ? 'none' : 'grayscale(50%)',
'&:hover': ventilation.isDeliverable ? {
boxShadow: 6,
borderColor: '#2e7d32'
},
transition: 'all 0.3s ease'
} : {},
transition: 'all 0.3s ease',
position: 'relative'
}}
onClick={() => {
if (ventilation.isDeliverable) {
this.handleVentilationSelect(ventilation.id);
}
}}
onClick={() => this.handleVentilationSelect(ventilation.id)}
>
{/* Non-deliverable overlay */}
{!ventilation.isDeliverable && (
<Box sx={{
position: 'absolute',
top: 0,
left: 0,
right: 0,
bottom: 0,
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
backgroundColor: 'rgba(255, 255, 255, 0.8)',
zIndex: 1,
flexDirection: 'column'
}}>
<Typography variant="h6" sx={{
color: '#d32f2f',
fontWeight: 'bold',
textAlign: 'center',
backgroundColor: 'rgba(255, 255, 255, 0.9)',
p: 1,
borderRadius: 1
}}>
Nicht lieferbar
</Typography>
</Box>
)}
{/* Image */}
<Box sx={{ height: 200, display: 'flex', alignItems: 'center', justifyContent: 'center', overflow: 'hidden' }}>
{this.renderTentImage(ventilation)}
@@ -935,13 +984,16 @@ class GrowTentKonfigurator extends Component {
{/* Content */}
<Box sx={{ p: 2, flexGrow: 1, display: 'flex', flexDirection: 'column' }}>
{/* Name */}
<Typography variant="h6" gutterBottom sx={{ fontWeight: 'bold' }}>
<Typography variant="h6" gutterBottom sx={{
fontWeight: 'bold',
color: ventilation.isDeliverable ? 'inherit' : '#999'
}}>
{ventilation.name}
</Typography>
{/* Price with VAT */}
<Typography variant="h6" sx={{
color: '#2e7d32',
color: ventilation.isDeliverable ? '#2e7d32' : '#999',
fontWeight: 'bold',
mt: 2,
display: 'flex',
@@ -954,14 +1006,14 @@ class GrowTentKonfigurator extends Component {
currency: 'EUR'
}).format(ventilation.price) : 'Kein Preis'}</span>
{ventilation.vat && (
<small style={{ color: '#77aa77', fontSize: '0.6em' }}>
<small style={{ color: ventilation.isDeliverable ? '#77aa77' : '#999', fontSize: '0.6em' }}>
(incl. {ventilation.vat}% MwSt.,*)
</small>
)}
</Typography>
{/* Selection Indicator */}
{selectedVentilationType === ventilation.id && (
{selectedVentilationType === ventilation.id && ventilation.isDeliverable && (
<Typography variant="body2" sx={{
color: '#2e7d32',
fontWeight: 'bold',
@@ -1009,7 +1061,7 @@ class GrowTentKonfigurator extends Component {
const availableLamps = this.state.selectedTentShape ? this.getLampsForTentShape(this.state.selectedTentShape) : [];
const selectedLight = availableLamps.find(l => l.id === selectedLightType);
const availableVentilation = this.state.selectedTentShape ? this.getVentilationForTentShape(this.state.selectedTentShape) : [];
const selectedVentilation = availableVentilation.find(v => v.id === selectedVentilationType);
const selectedVentilation = availableVentilation.find(v => v.id === selectedVentilationType && v.isDeliverable);
const selectedExtrasItems = extras.filter(e => selectedExtras.includes(e.id));
const savingsInfo = this.calculateSavings();