download
raw
6.79 kB
import React, { useState } from 'react';
import {
Box,
Typography,
TextField,
Button,
Divider,
List,
ListItem,
ListItemText,
Alert,
CircularProgress,
} from '@mui/material';
import { ViewInAr as CubeIcon } from '@mui/icons-material';
import { api } from '../services/api';
import { GeometryInfo } from '../types';
interface GeometryPanelProps {
onGeometryCreated: (geometryId: string) => void;
}
const GeometryPanel: React.FC<GeometryPanelProps> = ({ onGeometryCreated }) => {
const [primitive, setPrimitive] = useState<'box' | 'cylinder' | 'sphere'>('box');
const [loading, setLoading] = useState(false);
const [error, setError] = useState<string | null>(null);
const [geometryInfo, setGeometryInfo] = useState<GeometryInfo | null>(null);
const [boxParams, setBoxParams] = useState({ length: 100, width: 100, height: 100 });
const [cylinderParams, setCylinderParams] = useState({ radius: 50, height: 100 });
const [sphereParams, setSphereParams] = useState({ radius: 50 });
const handleCreateBox = async () => {
setLoading(true);
setError(null);
try {
const info = await api.createBox(
boxParams.length / 1000,
boxParams.width / 1000,
boxParams.height / 1000
);
setGeometryInfo(info);
onGeometryCreated(info.id);
} catch (err: any) {
setError(err.message || 'Erreur lors de la création');
} finally {
setLoading(false);
}
};
const handleCreateCylinder = async () => {
setLoading(true);
setError(null);
try {
const info = await api.createCylinder(
cylinderParams.radius / 1000,
cylinderParams.height / 1000
);
setGeometryInfo(info);
onGeometryCreated(info.id);
} catch (err: any) {
setError(err.message || 'Erreur lors de la création');
} finally {
setLoading(false);
}
};
const handleCreateSphere = async () => {
setLoading(true);
setError(null);
try {
const info = await api.createSphere(sphereParams.radius / 1000);
setGeometryInfo(info);
onGeometryCreated(info.id);
} catch (err: any) {
setError(err.message || 'Erreur lors de la création');
} finally {
setLoading(false);
}
};
return (
<Box sx={{ p: 2 }}>
<Typography variant="subtitle2" color="primary" sx={{ mb: 2 }}>
Primitives 3D
</Typography>
<List dense disablePadding>
<ListItem
button
selected={primitive === 'box'}
onClick={() => setPrimitive('box')}
>
<ListItemText primary="Boîte" />
</ListItem>
<ListItem
button
selected={primitive === 'cylinder'}
onClick={() => setPrimitive('cylinder')}
>
<ListItemText primary="Cylindre" />
</ListItem>
<ListItem
button
selected={primitive === 'sphere'}
onClick={() => setPrimitive('sphere')}
>
<ListItemText primary="Sphère" />
</ListItem>
</List>
<Divider sx={{ my: 2 }} />
{primitive === 'box' && (
<Box>
<Typography variant="caption" color="textSecondary">
Dimensions (mm)
</Typography>
<TextField
fullWidth
size="small"
label="Longueur"
type="number"
value={boxParams.length}
onChange={(e) => setBoxParams({ ...boxParams, length: Number(e.target.value) })}
sx={{ mt: 1 }}
/>
<TextField
fullWidth
size="small"
label="Largeur"
type="number"
value={boxParams.width}
onChange={(e) => setBoxParams({ ...boxParams, width: Number(e.target.value) })}
sx={{ mt: 1 }}
/>
<TextField
fullWidth
size="small"
label="Hauteur"
type="number"
value={boxParams.height}
onChange={(e) => setBoxParams({ ...boxParams, height: Number(e.target.value) })}
sx={{ mt: 1 }}
/>
<Button
fullWidth
variant="contained"
startIcon={loading ? <CircularProgress size={16} /> : <CubeIcon />}
onClick={handleCreateBox}
disabled={loading}
sx={{ mt: 2 }}
>
Créer
</Button>
</Box>
)}
{primitive === 'cylinder' && (
<Box>
<Typography variant="caption" color="textSecondary">
Dimensions (mm)
</Typography>
<TextField
fullWidth
size="small"
label="Rayon"
type="number"
value={cylinderParams.radius}
onChange={(e) => setCylinderParams({ ...cylinderParams, radius: Number(e.target.value) })}
sx={{ mt: 1 }}
/>
<TextField
fullWidth
size="small"
label="Hauteur"
type="number"
value={cylinderParams.height}
onChange={(e) => setCylinderParams({ ...cylinderParams, height: Number(e.target.value) })}
sx={{ mt: 1 }}
/>
<Button
fullWidth
variant="contained"
startIcon={loading ? <CircularProgress size={16} /> : <CubeIcon />}
onClick={handleCreateCylinder}
disabled={loading}
sx={{ mt: 2 }}
>
Créer
</Button>
</Box>
)}
{primitive === 'sphere' && (
<Box>
<Typography variant="caption" color="textSecondary">
Dimensions (mm)
</Typography>
<TextField
fullWidth
size="small"
label="Rayon"
type="number"
value={sphereParams.radius}
onChange={(e) => setSphereParams({ ...sphereParams, radius: Number(e.target.value) })}
sx={{ mt: 1 }}
/>
<Button
fullWidth
variant="contained"
startIcon={loading ? <CircularProgress size={16} /> : <CubeIcon />}
onClick={handleCreateSphere}
disabled={loading}
sx={{ mt: 2 }}
>
Créer
</Button>
</Box>
)}
{error && (
<Alert severity="error" sx={{ mt: 2 }}>
{error}
</Alert>
)}
{geometryInfo && (
<Alert severity="success" sx={{ mt: 2 }}>
Géométrie créée : {geometryInfo.type}
<br />
Volume : {geometryInfo.volume.toExponential(3)} m³
</Alert>
)}
</Box>
);
};
export default GeometryPanel;

Xet Storage Details

Size:
6.79 kB
·
Xet hash:
1c87d3c52f5518d5e152c24768bfeb01fb9e8e4fed078872381cda5a53c84602

Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.