// Lernmaterial-Verwaltung (Anlegen, Bearbeiten, Löschen)
function LernmaterialCreateDialog({ accent, onClose, onSave }) {
const kategorien = (window.CONSTANTS && window.CONSTANTS.LERNMATERIAL_KATEGORIEN) || [];
const [name, setName] = React.useState('');
const [kategorie, setKategorie] = React.useState(kategorien[0] || '');
const [preis, setPreis] = React.useState('');
const [bestand, setBestand] = React.useState('');
const valid = name.trim() && kategorie && preis;
const fieldStyle = {
width: '100%', padding: '8px 11px',
border: '1px solid #e2e8f0', borderRadius: 7,
fontSize: 13.5, fontFamily: 'inherit', color: '#0f172a',
background: '#fff', outline: 'none',
};
const labelStyle = { fontSize: 11.5, color: '#475569', fontWeight: 500, marginBottom: 5, display: 'block' };
return (
Lernmaterial anlegen
Neues Material in den Bestand aufnehmen.
Abbrechen
onSave({ name, kategorie, preis, bestand })}>
Anlegen
);
}
function LernmaterialEditDialog({ accent, item, onClose, onSave }) {
const kategorien = (window.CONSTANTS && window.CONSTANTS.LERNMATERIAL_KATEGORIEN) || [];
const [name, setName] = React.useState(item.name || '');
const [kategorie, setKategorie] = React.useState(item.kategorie || (kategorien[0] || ''));
const [preis, setPreis] = React.useState(item.preis_cents ? (item.preis_cents / 100).toFixed(2) : '');
const [bestand, setBestand] = React.useState(item.bestand_gesamt != null ? String(item.bestand_gesamt) : '');
const valid = name.trim() && kategorie && preis;
const fieldStyle = {
width: '100%', padding: '8px 11px',
border: '1px solid #e2e8f0', borderRadius: 7,
fontSize: 13.5, fontFamily: 'inherit', color: '#0f172a',
background: '#fff', outline: 'none',
};
const labelStyle = { fontSize: 11.5, color: '#475569', fontWeight: 500, marginBottom: 5, display: 'block' };
return (
Lernmaterial bearbeiten
{item.id}
Abbrechen
onSave({ name, kategorie, preis, bestand })}>
Speichern
);
}
window.LernmaterialListe = function LernmaterialListe({ accent }) {
const [items, setItems] = React.useState([]);
const [total, setTotal] = React.useState(0);
const [query, setQuery] = React.useState('');
const [showCreate, setShowCreate] = React.useState(false);
const [editingItem, setEditingItem] = React.useState(null);
const [confirmDelete, setConfirmDelete] = React.useState(null);
function fetchAll() {
window.api.lernmaterial.list({ q: query }).then(res => {
setItems(res.items || []);
setTotal(res.total || 0);
}).catch(err => {
console.error(err);
setItems([]);
setTotal(0);
});
}
React.useEffect(() => { fetchAll(); }, [query]);
function addItem(data) {
window.api.lernmaterial.create({
name: data.name,
kategorie: data.kategorie,
preis_cents: Math.round(parseFloat(data.preis) * 100),
bestand_gesamt: parseInt(data.bestand, 10) || 0,
}).then(() => {
setShowCreate(false);
fetchAll();
window.showToast('success', `„${data.name}" wurde angelegt.`);
}).catch(err => {
console.error(err);
window.showToast('error', err.message || 'Fehler beim Anlegen.');
});
}
function saveItem(id, data) {
window.api.lernmaterial.update(id, {
name: data.name,
kategorie: data.kategorie,
preis_cents: Math.round(parseFloat(data.preis) * 100),
bestand_gesamt: parseInt(data.bestand, 10) || 0,
}).then(() => {
setEditingItem(null);
fetchAll();
window.showToast('success', `„${data.name}" wurde aktualisiert.`);
}).catch(err => {
console.error(err);
window.showToast('error', err.message || 'Fehler beim Speichern.');
});
}
function removeItem(id) {
const name = confirmDelete ? confirmDelete.name : 'Material';
window.api.lernmaterial.remove(id).then(() => {
setConfirmDelete(null);
fetchAll();
window.showToast('success', `„${name}" wurde entfernt.`);
}).catch(err => {
console.error(err);
window.showToast('error', err.message || 'Fehler beim Entfernen.');
});
}
const KATEGORIE_FARBEN = {
'Hefter': 210,
'Taschenrechner': 160,
'Formelsammlung': 280,
'Lineal': 40,
'Zirkel': 20,
'Tintenkiller': 330,
'Sonstiges': 0,
};
function kategorieHue(kat) {
return (KATEGORIE_FARBEN[kat] != null ? KATEGORIE_FARBEN[kat] : (kat.charCodeAt(0) * 7) % 360);
}
return (
Lernmaterial
{total} Artikel im Bestand
setShowCreate(true)}>Material anlegen
Bezeichnung
Kategorie
Preis
Bestand
{items.length === 0 ? (
{query ? 'Keine passenden Artikel gefunden.' : 'Noch kein Lernmaterial angelegt.'}
) : items.map((item, index) => {
const hue = kategorieHue(item.kategorie);
return (
{item.kategorie}
{(item.preis_cents / 100).toFixed(2).replace('.', ',')} €
{item.bestand_frei}/{item.bestand_gesamt}
);
})}
{showCreate && (
setShowCreate(false)} onSave={addItem} />
)}
{editingItem && (
setEditingItem(null)} onSave={(data) => saveItem(editingItem.id, data)} />
)}
{confirmDelete && (
Möchten Sie {confirmDelete.name} ({confirmDelete.id}) wirklich entfernen?}
confirmLabel="Endgültig entfernen"
accent={accent}
onCancel={() => setConfirmDelete(null)}
onConfirm={() => removeItem(confirmDelete.id)}
/>
)}
);
};