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:
@@ -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();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user