diff --git a/frontend/src/tools/kalkulator3d.jsx b/frontend/src/tools/kalkulator3d.jsx
deleted file mode 100644
index fff437d..0000000
--- a/frontend/src/tools/kalkulator3d.jsx
+++ /dev/null
@@ -1,285 +0,0 @@
-import { useState, useMemo, useEffect } from 'react';
-import { api, S } from '../lib.js';
-
-const DEFAULTS = {
- materialpreis_pro_gramm: 0.01, stromverbrauch_kw: 0.15,
- strompreis_pro_kwh: 0.38, druckerpreis: 550,
- gesamtdruckstunden: 5000, verschleiss_pro_stunde: 0.06,
-};
-// Farbfaktor: jede weitere Farbe +0.1
-const getFarbFaktor = n => Math.round((1.0 + Math.max(0, n-1) * 0.1) * 100) / 100;
-const STUFEN = [
- { key:'f', emoji:'💖', label:'Freundschaft', mult:1.0, c:'#ff6b9d' },
- { key:'n', emoji:'🤝', label:'Normal', mult:1.5, c:'#4ecdc4' },
- { key:'a', emoji:'💼', label:'Auftrag', mult:2.5, c:'#ffe66d' },
-];
-
-// Stepper-Eingabe – kein Tippen nötig, gut für Mobile
-function Stepper({ label, value, onChange, step, unit, min=0, hint }) {
- const dec = () => onChange(Math.max(min, Math.round((value - step) * 10000) / 10000));
- const inc = () => onChange(Math.round((value + step) * 10000) / 10000);
- return (
-
-
- {label.toUpperCase()}{unit ? ` (${unit})` : ''}
-
-
-
- onChange(parseFloat(e.target.value) || 0)}
- style={{ flex:1, background:'transparent', border:'none', color:'#fff', fontSize:15, fontFamily:"'Space Mono',monospace", textAlign:'center', outline:'none', minWidth:0, padding:'10px 4px' }}
- />
-
-
- {hint &&
{hint}
}
-
- );
-}
-
-function SmallInput({ label, value, onChange, step=0.01 }) {
- return (
-
-
{label}
-
onChange(parseFloat(e.target.value)||0)}
- style={{ ...S.inp, padding:'7px 8px', fontSize:13 }}
- />
-
- );
-}
-
-export default function Kalkulator3D({ toast, editData, onEditDone, mobile }) {
- const [gramm, setGramm] = useState(editData?.gramm ?? 50);
- const [stunden, setStunden] = useState(editData?.stunden ?? 3);
- const [farben, setFarben] = useState(editData?.farben ?? 1);
- const [vars, setVars] = useState(editData ? {
- materialpreis_pro_gramm: editData.materialpreis_pro_gramm,
- stromverbrauch_kw: editData.stromverbrauch_kw,
- strompreis_pro_kwh: editData.strompreis_pro_kwh,
- druckerpreis: editData.druckerpreis,
- gesamtdruckstunden: editData.gesamtdruckstunden,
- verschleiss_pro_stunde: editData.verschleiss_pro_stunde,
- } : { ...DEFAULTS });
- const [showAdv, setShowAdv] = useState(false);
- const [name, setName] = useState(editData?.name ?? '');
- const [saving, setSaving] = useState(false);
- const sv = (k,v) => setVars(p => ({ ...p, [k]:v }));
-
- const calc = useMemo(() => {
- const f = getFarbFaktor(farben);
- const mat = gramm * vars.materialpreis_pro_gramm * f;
- const str = stunden * vars.stromverbrauch_kw * vars.strompreis_pro_kwh;
- const ver = stunden * vars.verschleiss_pro_stunde;
- return { mat, str, ver, grund: mat + str + ver };
- }, [gramm, stunden, farben, vars]);
-
- const save = async () => {
- if (!name.trim()) { toast('Bitte einen Namen eingeben','error'); return; }
- setSaving(true);
- try {
- const payload = { name, gramm, stunden, farben, ...vars,
- preis_freundschaft: calc.grund * 1.0,
- preis_normal: calc.grund * 1.5,
- preis_auftrag: calc.grund * 2.5 };
- if (editData?.id) {
- await api(`/tools/kalkulator3d/${editData.id}`, { method:'PUT', body:payload });
- toast('Aktualisiert ✓'); onEditDone?.();
- } else {
- await api('/tools/kalkulator3d', { body:payload });
- toast('Gespeichert ✓'); setName('');
- }
- } catch(e) { toast(e.message,'error'); } finally { setSaving(false); }
- };
-
- const pad = mobile ? '14px 14px 90px' : '36px 44px';
-
- return (
-
-
- {/* Header */}
-
-
- {editData &&
✎ {editData.name}
}
-
3D-Kalkulator
-
- {editData &&
}
-
-
- {/* Haupteingaben */}
-
-
-
-
-
-
-
setFarben(Math.max(1, Math.round(v)))}
- step={1} min={1}
- hint={`Farbfaktor: ×${getFarbFaktor(farben).toFixed(2)}`} />
-
- {/* Erweiterte Einstellungen */}
-
- {showAdv && (
-
-
- sv('materialpreis_pro_gramm',v)} step={0.001}/>
- sv('stromverbrauch_kw',v)} step={0.01}/>
- sv('strompreis_pro_kwh',v)} step={0.01}/>
- sv('druckerpreis',v)} step={10}/>
- sv('gesamtdruckstunden',v)} step={100}/>
- sv('verschleiss_pro_stunde',v)} step={0.01}/>
-
-
-
- )}
-
-
- {/* Ergebnis – kompakt */}
-
-
- {[['Material',calc.mat,'#a78bfa'],['Strom',calc.str,'#60a5fa'],['Verschleiß',calc.ver,'#f59e0b'],['Grundkosten',calc.grund,'#4ecdc4']].map(([l,v,c],i)=>(
-
-
{l.toUpperCase()}
-
- {v.toFixed(2)} €
-
-
- ))}
-
-
-
- {/* Preis-Cards */}
-
- {STUFEN.map((s,i) => (
-
-
{s.emoji}
-
{s.label}
-
- {(calc.grund*s.mult).toFixed(2)}€
-
-
×{s.mult}
-
- ))}
-
-
- {/* Speichern */}
-
-
- setName(e.target.value)}
- onKeyDown={e=>e.key==='Enter'&&save()}
- placeholder='Name z.B. "Halterung Müller"'
- style={{ ...S.inp, flex:1, fontSize:15 }}
- />
-
-
-
-
- );
-}
-
-// ── Gespeicherte Berechnungen ─────────────────────────────────────────────────
-export function SavedList({ toast, mobile }) {
- const [items, setItems] = useState([]);
- const [loading, setLoading] = useState(true);
- const [delId, setDelId] = useState(null);
- const [editData, setEditData] = useState(null);
-
- useEffect(() => {
- api('/tools/kalkulator3d').then(setItems).catch(e=>toast(e.message,'error')).finally(()=>setLoading(false));
- }, []);
-
- const del = async id => {
- try { await api(`/tools/kalkulator3d/${id}`,{method:'DELETE'}); setItems(p=>p.filter(i=>i.id!==id)); toast('Gelöscht'); }
- catch(e) { toast(e.message,'error'); } finally { setDelId(null); }
- };
-
- if (editData) return (
- {
- setEditData(null);
- api('/tools/kalkulator3d').then(setItems).catch(()=>{});
- }} />
- );
-
- return (
-
-
Gespeichert
-
{items.length} Einträge
-
- {loading &&
Lädt…
}
-
- {!loading && items.length===0 && (
-
-
◉
-
Noch keine Berechnungen.
-
- )}
-
- {items.map(item => (
-
- {/* Name + Datum */}
-
-
-
{item.name}
-
- {item.gramm}g · {item.stunden}h · {item.farben} Farbe{item.farben>1?'n':''}
-
-
-
- {new Date(item.created_at).toLocaleDateString('de-DE')}
-
-
-
- {/* Preise */}
-
- {[['💖',item.preis_freundschaft,'#ff6b9d'],['🤝',item.preis_normal,'#4ecdc4'],['💼',item.preis_auftrag,'#ffe66d']].map(([e,v,c])=>(
-
-
{e}
-
{v.toFixed(2)}€
-
- ))}
-
-
- {/* Aktionen */}
- {delId===item.id ? (
-
- Wirklich löschen?
-
-
-
- ) : (
-
-
-
-
- )}
-
- ))}
-
- );
-}