Files
reactShop/src/components/configurator/TentShapeSelector.js
2025-07-02 12:49:06 +02:00

241 lines
7.3 KiB
JavaScript

import React, { Component } from 'react';
import Grid from '@mui/material/Grid';
import Card from '@mui/material/Card';
import CardContent from '@mui/material/CardContent';
import Typography from '@mui/material/Typography';
import Box from '@mui/material/Box';
import Chip from '@mui/material/Chip';
class TentShapeSelector extends Component {
// Generate plant layout based on tent shape
generatePlantLayout(shapeId) {
const layouts = {
'60x60': [
{ x: 50, y: 50, size: 18 } // 1 large plant centered
],
'80x80': [
{ x: 35, y: 35, size: 12 }, // 2x2 = 4 plants
{ x: 65, y: 35, size: 12 },
{ x: 35, y: 65, size: 12 },
{ x: 65, y: 65, size: 12 }
],
'100x100': [
{ x: 22, y: 22, size: 10 }, // 3x3 = 9 plants
{ x: 50, y: 22, size: 10 },
{ x: 78, y: 22, size: 10 },
{ x: 22, y: 50, size: 10 },
{ x: 50, y: 50, size: 10 },
{ x: 78, y: 50, size: 10 },
{ x: 22, y: 78, size: 10 },
{ x: 50, y: 78, size: 10 },
{ x: 78, y: 78, size: 10 }
],
'120x60': [
{ x: 30, y: 50, size: 14 }, // 1x3 = 3 larger plants
{ x: 50, y: 50, size: 14 },
{ x: 70, y: 50, size: 14 }
]
};
return layouts[shapeId] || [];
}
renderShapeCard(shape) {
const { selectedShape, onShapeSelect } = this.props;
const isSelected = selectedShape === shape.id;
const plants = this.generatePlantLayout(shape.id);
// Make visual sizes proportional to actual dimensions
let visualWidth, visualHeight;
switch(shape.id) {
case '60x60':
visualWidth = 90;
visualHeight = 90;
break;
case '80x80':
visualWidth = 110;
visualHeight = 110;
break;
case '100x100':
visualWidth = 130;
visualHeight = 130;
break;
case '120x60':
visualWidth = 140;
visualHeight = 80;
break;
default:
visualWidth = 120;
visualHeight = 120;
}
return (
<Card
key={shape.id}
sx={{
cursor: 'pointer',
border: '3px solid',
borderColor: isSelected ? '#2e7d32' : '#e0e0e0',
backgroundColor: isSelected ? '#f1f8e9' : '#ffffff',
'&:hover': {
boxShadow: 8,
borderColor: isSelected ? '#2e7d32' : '#90caf9',
transform: 'translateY(-2px)'
},
transition: 'all 0.3s ease',
height: '100%',
minHeight: 300
}}
onClick={() => onShapeSelect(shape.id)}
>
<CardContent sx={{ textAlign: 'center', p: 3 }}>
<Typography variant="h5" gutterBottom sx={{ fontWeight: 'bold' }}>
{shape.name}
</Typography>
{/* Enhanced visual representation with plant layout */}
<Box sx={{
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
height: visualHeight,
mb: 2,
position: 'relative'
}}>
<Box
sx={{
width: `${visualWidth}px`,
height: `${visualHeight}px`,
border: '3px solid #2e7d32',
borderRadius: 2,
backgroundColor: isSelected ? '#e8f5e8' : '#f5f5f5',
position: 'relative',
boxShadow: '0 4px 12px rgba(0,0,0,0.15)',
overflow: 'hidden'
}}
>
{/* Grid pattern */}
<svg
width="100%"
height="100%"
style={{ position: 'absolute', top: 0, left: 0 }}
>
<defs>
<pattern id={`grid-${shape.id}`} width="10" height="10" patternUnits="userSpaceOnUse">
<path d="M 10 0 L 0 0 0 10" fill="none" stroke="#e0e0e0" strokeWidth="0.5"/>
</pattern>
</defs>
<rect width="100%" height="100%" fill={`url(#grid-${shape.id})`} />
{/* Plants */}
{plants.map((plant, index) => (
<circle
key={index}
cx={`${plant.x}%`}
cy={`${plant.y}%`}
r={plant.size}
fill="#4caf50"
fillOpacity="0.8"
stroke="#2e7d32"
strokeWidth="2"
/>
))}
</svg>
{/* Dimensions label */}
<Typography variant="caption" sx={{
position: 'absolute',
bottom: 4,
left: '50%',
transform: 'translateX(-50%)',
fontWeight: 'bold',
color: '#2e7d32',
backgroundColor: 'rgba(255,255,255,0.8)',
px: 1,
borderRadius: 1,
fontSize: '11px'
}}>
{shape.footprint}
</Typography>
{/* Plant count label */}
<Typography
variant="caption"
sx={{
position: 'absolute',
top: 4,
right: 4,
backgroundColor: 'rgba(46, 125, 50, 0.9)',
color: 'white',
px: 1,
borderRadius: 1,
fontSize: '10px',
fontWeight: 'bold'
}}
>
{plants.length} 🌱
</Typography>
</Box>
</Box>
<Typography variant="body2" color="text.secondary" gutterBottom>
{shape.description}
</Typography>
<Box sx={{ mt: 2 }}>
<Chip
label={`${shape.minPlants}-${shape.maxPlants} Pflanzen`}
size="small"
sx={{
bgcolor: isSelected ? '#2e7d32' : '#f0f0f0',
color: isSelected ? 'white' : 'inherit',
pointerEvents: 'none'
}}
/>
</Box>
<Box sx={{ mt: 2, height: 24, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
<Typography
variant="body2"
sx={{
color: '#2e7d32',
fontWeight: 'bold',
opacity: isSelected ? 1 : 0,
transition: 'opacity 0.3s ease'
}}
>
Ausgewählt
</Typography>
</Box>
</CardContent>
</Card>
);
}
render() {
const { tentShapes, title, subtitle } = this.props;
return (
<Box sx={{ mb: 4 }}>
<Typography variant="h5" gutterBottom sx={{ color: '#2e7d32', fontWeight: 'bold' }}>
{title}
</Typography>
{subtitle && (
<Typography variant="body1" color="text.secondary" sx={{ mb: 3 }}>
{subtitle}
</Typography>
)}
<Grid container spacing={3}>
{tentShapes.map(shape => (
<Grid item xs={12} sm={6} md={3} key={shape.id}>
{this.renderShapeCard(shape)}
</Grid>
))}
</Grid>
</Box>
);
}
}
export default TentShapeSelector;