// Schnelltexte tab — quick copy-to-clipboard text templates for WhatsApp/Kleinanzeigen. // Three panes: template list (with add/edit/delete) · rental picker · live preview with Kopieren. function DocsSchnelltexte({ rentals, equipment, company, docs, setDocs, initialRentalId }) { const t = useTheme(); const toast = useToast(); const [templates, setTemplates] = useLocal('rf-d-qtext-tpls-v1', QUICK_TEXT_TEMPLATES); const [selTplId, setSelTplId] = useState(templates[0] && templates[0].id); const [selRentalId, setSelRentalId] = useState(initialRentalId || (rentals[0] && rentals[0].id)); const [editingTpl, setEditingTpl] = useState(false); const [tplSnapshot, setTplSnapshot] = useState(null); // Snapshot taken when editor opens, used for „Verwerfen“ const [confirmDel, setConfirmDel] = useState(null); useEffect(() => { if (initialRentalId) setSelRentalId(initialRentalId); }, [initialRentalId]); const tpl = templates.find((x) => x.id === selTplId) || templates[0]; const r = rentals.find((x) => x.id === selRentalId); const eq = r && equipment.find((e) => e.id === r.equipmentId); const filled = useMemo(() => tpl && r ? fillQuickText(tpl.body, r, eq, company) : '', [tpl && tpl.id, tpl && tpl.body, r && r.id, eq && eq.id, company]); const [editedBody, setEditedBody] = useState(filled); useEffect(() => { setEditedBody(filled); }, [filled]); const copy = () => { if (!editedBody) return; try { navigator.clipboard.writeText(editedBody); toast('In die Zwischenablage kopiert'); } catch (err) { toast('Kopieren fehlgeschlagen'); } }; const saveToArchive = () => { if (!r || !tpl) return; const doc = { id: 'd-' + Date.now(), kind: tpl.kind || 'custom', format: 'text', title: tpl.name, rentalId: r.id, templateId: tpl.id, body: editedBody, createdISO: todayISO(), }; setDocs((prev) => [doc, ...prev]); toast('Im Archiv gespeichert'); }; const patchTpl = (patch) => setTemplates((prev) => prev.map((x) => x.id === tpl.id ? { ...x, ...patch } : x)); // Open editor: snapshot current template so we can restore on „Verwerfen“ const openEditor = () => { if (tpl) { setTplSnapshot({ ...tpl }); setEditingTpl(true); } }; const closeEditor = () => { setTplSnapshot(null); setEditingTpl(false); }; const discardTplEdits = () => { if (!tplSnapshot) return; setTemplates((prev) => prev.map((x) => x.id === tplSnapshot.id ? { ...tplSnapshot } : x)); toast('Änderungen verworfen'); }; const tplIsDirty = !!(tplSnapshot && tpl && ( tpl.name !== tplSnapshot.name || tpl.body !== tplSnapshot.body || tpl.icon !== tplSnapshot.icon || tpl.color !== tplSnapshot.color || tpl.desc !== tplSnapshot.desc )); // Built-in templates can be reset to their original definition const builtIn = tpl && QUICK_TEXT_TEMPLATES.find((x) => x.id === tpl.id); const tplDiffersFromBuiltIn = !!(builtIn && ( builtIn.name !== tpl.name || builtIn.body !== tpl.body || builtIn.icon !== tpl.icon || builtIn.color !== tpl.color || builtIn.desc !== tpl.desc )); const resetToBuiltIn = () => { if (!builtIn) return; setTemplates((prev) => prev.map((x) => x.id === builtIn.id ? { ...builtIn } : x)); toast('Auf Standard zurückgesetzt'); }; const addTpl = () => { const id = 'qt-' + Date.now(); const fresh = { id, name: 'Neue Vorlage', icon: '📝', color: '#5856D6', kind: 'custom', desc: 'Eigene Schnellnachricht', body: 'Hallo {{name}},\n\n…\n\nViele Grüße\n{{firma}}' }; setTemplates((prev) => [...prev, fresh]); setSelTplId(id); setEditingTpl(true); }; const delTpl = () => { setTemplates((prev) => prev.filter((x) => x.id !== tpl.id)); setSelTplId((templates.find((x) => x.id !== tpl.id) || templates[0] || { id: null }).id); setConfirmDel(null); setEditingTpl(false); toast('Vorlage gelöscht'); }; return (
{/* ── Sidebar: template list ── */}
Schnelltexte
Neu
{templates.map((d) => { const sel = selTplId === d.id; return ( setSelTplId(d.id)} scale={0.99} hoverBg={sel ? undefined : t.cardAlt}>
{d.icon || ( )}
{d.name}
{d.desc}
); })}
{/* ── Middle: rental picker ── */}
Mietvorgang wählen
{rentals.map((x) => { const e = equipment.find((q) => q.id === x.equipmentId); const sel = x.id === selRentalId; return ( setSelRentalId(x.id)} scale={0.99} hoverBg={sel ? undefined : t.card}>
{x.tenantName}
{e ? e.name : x.equipmentName}
); })}
{/* ── Right: preview / editor ── */}
{tpl ? (
{editingTpl ? ( <> patchTpl({ name: e.target.value })} placeholder="Name der Vorlage" style={{ width: '100%', fontSize: 22, fontWeight: 700, color: t.text, background: 'transparent', border: 'none', borderBottom: `1.5px solid ${t.accent}`, outline: 'none', letterSpacing: -0.5, boxSizing: 'border-box', padding: '2px 0' }}/> patchTpl({ desc: e.target.value })} placeholder="Kurze Beschreibung" style={{ width: '100%', fontSize: 13, color: t.textSec, background: 'transparent', border: 'none', borderBottom: `1px dashed ${t.sep}`, outline: 'none', boxSizing: 'border-box', padding: '4px 0', marginTop: 4 }}/> ) : ( <>
{tpl.name}
{tpl.desc} · für {r ? r.tenantName : '—'}
)}
{editingTpl && builtIn && } {editingTpl && } setConfirmDel(tpl)} title="Vorlage löschen"/>
{editingTpl && (
Symbol & Farbe
{tpl.icon || ( )}
Emoji
patchTpl({ icon: '' })} scale={0.9}>
{['📝','💬','📲','📧','📞','📅','✅','💰','🧾','📋','📦','🔑','⚡','⭐','🎉','⚠️'].map((e) => ( patchTpl({ icon: e })} scale={0.9}>
{e}
))} patchTpl({ icon: ev.target.value.slice(0, 4) })} maxLength={4} placeholder="…" style={{ width: 50, height: 30, borderRadius: 8, border: `1px solid ${t.inputBorder}`, background: t.inputBg, color: t.text, textAlign: 'center', fontSize: 14, outline: 'none', boxSizing: 'border-box' }}/>
Farbe
{['#007AFF','#34C759','#FF9500','#FF3B30','#AF52DE','#5856D6','#FF2D55','#8E8E93'].map((c) => ( patchTpl({ color: c })} scale={0.85}>
))}
Vorlagentext (mit Platzhaltern)