From aeb4d2098c935737000dcc08a609158658f643bb Mon Sep 17 00:00:00 2001 From: Dicken Date: Mon, 25 May 2026 22:45:01 +0200 Subject: [PATCH] =?UTF-8?q?frontend/src/tools/kalkulator3d.jsx=20gel=C3=B6?= =?UTF-8?q?scht?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/tools/kalkulator3d.jsx | 319 ---------------------------- 1 file changed, 319 deletions(-) delete mode 100644 frontend/src/tools/kalkulator3d.jsx diff --git a/frontend/src/tools/kalkulator3d.jsx b/frontend/src/tools/kalkulator3d.jsx deleted file mode 100644 index ec8bfbc..0000000 --- a/frontend/src/tools/kalkulator3d.jsx +++ /dev/null @@ -1,319 +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}
} -

Kostenrechner

-
- {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 }} - /> - -
-
-
- ); -} - -// ── Kostenarchiv ───────────────────────────────────────────────────────────── -export function SavedList({ toast, mobile }) { - const [items, setItems] = useState([]); - const [loading, setLoading] = useState(true); - const [delId, setDelId] = useState(null); - const [editData, setEditData] = useState(null); - const [search, setSearch] = useState(''); - - 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); } - }; - - const filtered = search.trim() - ? items.filter(i => i.name.toLowerCase().includes(search.toLowerCase())) - : items; - - if (editData) return ( - { - setEditData(null); - api('/tools/kalkulator3d').then(setItems).catch(()=>{}); - }} /> - ); - - return ( -
-

Kostenarchiv

- - {/* Live-Suche */} -
- - setSearch(e.target.value)} - placeholder="Suchen…" - style={{ ...S.inp, paddingLeft:34, fontSize:15 }} - /> - {search && ( - - )} -
- -

- {filtered.length} von {items.length} Einträge{items.length !== 1 ? 'n' : ''} - {search && ` für „${search}"`} -

- - {loading &&
Lädt…
} - - {!loading && items.length===0 && ( -
-
-
Noch keine Berechnungen gespeichert.
-
- )} - - {!loading && search && filtered.length===0 && ( -
-
Keine Treffer für „{search}"
-
- )} - - {filtered.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? - - -
- ) : ( -
- - -
- )} -
- ))} -
- ); -}