This commit is contained in:
lejay
2026-02-13 00:21:53 +01:00
parent 81d2412835
commit 6923c319a1
85 changed files with 17836 additions and 0 deletions
+201
View File
@@ -0,0 +1,201 @@
import { useState, useEffect } from 'react';
import { createFormexMaterial, updateFormexMaterial } from '../api/client';
import styles from './MaterialModal.module.css';
export default function MaterialModal({ material, collections, onClose, onSave }) {
const isEditing = !!material;
const [formData, setFormData] = useState({
formex_code: '',
name: '',
collection: '',
width_mm: '',
height_mm: '',
thickness_mm: '',
formex_url: ''
});
const [error, setError] = useState('');
const [saving, setSaving] = useState(false);
useEffect(() => {
if (material) {
setFormData({
formex_code: material.formex_code || '',
name: material.name || '',
collection: material.collection || '',
width_mm: material.width_mm?.toString() || '',
height_mm: material.height_mm?.toString() || '',
thickness_mm: material.thickness_mm?.toString() || '',
formex_url: material.formex_url || ''
});
}
}, [material]);
const handleChange = (e) => {
const { name, value } = e.target;
setFormData(prev => ({ ...prev, [name]: value }));
};
const handleSubmit = async (e) => {
e.preventDefault();
setError('');
// Validation
if (!formData.formex_code.trim() || !formData.name.trim() || !formData.collection.trim()) {
setError('Le code, le nom et la collection sont requis.');
return;
}
setSaving(true);
try {
const payload = {
formex_code: formData.formex_code.trim(),
name: formData.name.trim(),
collection: formData.collection.trim(),
width_mm: formData.width_mm ? parseInt(formData.width_mm, 10) : null,
height_mm: formData.height_mm ? parseInt(formData.height_mm, 10) : null,
thickness_mm: formData.thickness_mm ? parseInt(formData.thickness_mm, 10) : null,
formex_url: formData.formex_url.trim() || null
};
if (isEditing) {
await updateFormexMaterial(material.id, payload);
} else {
await createFormexMaterial(payload);
}
onSave();
} catch (err) {
setError(err.message);
} finally {
setSaving(false);
}
};
const handleOverlayClick = (e) => {
if (e.target === e.currentTarget) {
onClose();
}
};
return (
<div className={styles.overlay} onClick={handleOverlayClick}>
<div className={styles.modal}>
<div className={styles.header}>
<h2>{isEditing ? 'Modifier le matériau' : 'Nouveau matériau'}</h2>
<button type="button" onClick={onClose} className={styles.closeBtn}>
&times;
</button>
</div>
<form onSubmit={handleSubmit} className={styles.form}>
{error && <p className={styles.error}>{error}</p>}
<div className={styles.field}>
<label htmlFor="formex_code">Code Formex *</label>
<input
type="text"
id="formex_code"
name="formex_code"
value={formData.formex_code}
onChange={handleChange}
placeholder="ex: 10000"
required
/>
</div>
<div className={styles.field}>
<label htmlFor="name">Nom *</label>
<input
type="text"
id="name"
name="name"
value={formData.name}
onChange={handleChange}
placeholder="ex: Panneaux mélaminés Duplex Plus 10000 Tilia"
required
/>
</div>
<div className={styles.field}>
<label htmlFor="collection">Collection *</label>
<input
type="text"
id="collection"
name="collection"
value={formData.collection}
onChange={handleChange}
list="collections-list"
placeholder="ex: Duplex Plus"
required
/>
<datalist id="collections-list">
{collections.map((c) => (
<option key={c} value={c} />
))}
</datalist>
</div>
<div className={styles.row}>
<div className={styles.field}>
<label htmlFor="width_mm">Largeur (mm)</label>
<input
type="number"
id="width_mm"
name="width_mm"
value={formData.width_mm}
onChange={handleChange}
placeholder="2800"
/>
</div>
<div className={styles.field}>
<label htmlFor="height_mm">Hauteur (mm)</label>
<input
type="number"
id="height_mm"
name="height_mm"
value={formData.height_mm}
onChange={handleChange}
placeholder="2070"
/>
</div>
<div className={styles.field}>
<label htmlFor="thickness_mm">Épaisseur (mm)</label>
<input
type="number"
id="thickness_mm"
name="thickness_mm"
value={formData.thickness_mm}
onChange={handleChange}
placeholder="19"
/>
</div>
</div>
<div className={styles.field}>
<label htmlFor="formex_url">URL Formex</label>
<input
type="url"
id="formex_url"
name="formex_url"
value={formData.formex_url}
onChange={handleChange}
placeholder="https://www.formex.ch/fr/shop/..."
/>
</div>
<div className={styles.actions}>
<button type="button" onClick={onClose} className={styles.cancelBtn}>
Annuler
</button>
<button type="submit" disabled={saving} className={styles.saveBtn}>
{saving ? 'Enregistrement…' : (isEditing ? 'Enregistrer' : 'Créer')}
</button>
</div>
</form>
</div>
</div>
);
}