feat: 'Speichern & übersetzen' im Edit-Formular

Neuer Button im EditPairForm: speichert das Pair und öffnet direkt das
Übersetzen-&-Prüfen-Modal (handleSave({translateAfter}) → onSavedAndTranslate
→ handleTranslate). Bestehender Speichern-Button unverändert.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-05 21:39:08 +02:00
parent 350614d6e0
commit 840996fce9

View File

@@ -465,7 +465,7 @@ function PairForm({ objectId, allObjects, onPairSaved }) {
// ─── EditPairForm ───────────────────────────────────────────────────────────── // ─── EditPairForm ─────────────────────────────────────────────────────────────
function EditPairForm({ pair, allObjects, onSaved, onCancel, onDeleted }) { function EditPairForm({ pair, allObjects, onSaved, onCancel, onDeleted, onSavedAndTranslate }) {
const lang = getUserLang(); const lang = getUserLang();
const [loading, setLoading] = useState(true); const [loading, setLoading] = useState(true);
const [saving, setSaving] = useState(false); const [saving, setSaving] = useState(false);
@@ -592,7 +592,7 @@ function EditPairForm({ pair, allObjects, onSaved, onCancel, onDeleted }) {
finally { setCreatingWord(false); } finally { setCreatingWord(false); }
} }
async function handleSave() { async function handleSave({ translateAfter = false } = {}) {
setSaving(true); setSaving(true);
try { try {
const ph = t => withPlaceholders(t, wordMap, objectAssignments); const ph = t => withPlaceholders(t, wordMap, objectAssignments);
@@ -646,7 +646,8 @@ function EditPairForm({ pair, allObjects, onSaved, onCancel, onDeleted }) {
if (pair.answer_type !== type) patchPair.answer_type = type; if (pair.answer_type !== type) patchPair.answer_type = type;
if (pair.status !== pairStatus) patchPair.status = pairStatus; if (pair.status !== pairStatus) patchPair.status = pairStatus;
if (Object.keys(patchPair).length) await apiPatch('/pairs', pair.id, patchPair); if (Object.keys(patchPair).length) await apiPatch('/pairs', pair.id, patchPair);
onSaved(); if (translateAfter && onSavedAndTranslate) onSavedAndTranslate({ ...pair, answer_type: type });
else onSaved();
} catch (e) { alert('Fehler: ' + e.message); } } catch (e) { alert('Fehler: ' + e.message); }
finally { setSaving(false); } finally { setSaving(false); }
} }
@@ -837,10 +838,17 @@ function EditPairForm({ pair, allObjects, onSaved, onCancel, onDeleted }) {
<div className="pt-2 border-t border-amber-100 space-y-1.5"> <div className="pt-2 border-t border-amber-100 space-y-1.5">
<div className="flex gap-2"> <div className="flex gap-2">
<button onClick={onCancel} className="flex-1 py-1.5 text-xs font-medium rounded-lg border border-slate-300 text-slate-600 hover:bg-slate-50 transition-colors">Abbrechen</button> <button onClick={onCancel} className="flex-1 py-1.5 text-xs font-medium rounded-lg border border-slate-300 text-slate-600 hover:bg-slate-50 transition-colors">Abbrechen</button>
<button onClick={handleSave} disabled={saving} className="flex-1 py-1.5 text-xs font-medium rounded-lg bg-amber-500 hover:bg-amber-600 disabled:opacity-40 text-white transition-colors"> <button onClick={() => handleSave()} disabled={saving} className="flex-1 py-1.5 text-xs font-medium rounded-lg bg-amber-500 hover:bg-amber-600 disabled:opacity-40 text-white transition-colors">
{saving ? 'Speichern' : ' Speichern'} {saving ? 'Speichern' : ' Speichern'}
</button> </button>
</div> </div>
{onSavedAndTranslate && (
<button onClick={() => handleSave({ translateAfter: true })} disabled={saving}
className="w-full py-1.5 text-xs font-medium rounded-lg bg-emerald-600 hover:bg-emerald-500 disabled:opacity-40 text-white transition-colors"
title="Pair speichern und direkt das Übersetzen-&-Prüfen-Modal öffnen">
{saving ? 'Speichern' : '💾 Speichern & übersetzen'}
</button>
)}
{!confirmDelete ? ( {!confirmDelete ? (
<button onClick={() => setConfirmDelete(true)} <button onClick={() => setConfirmDelete(true)}
className="w-full py-1.5 text-xs font-medium rounded-lg border border-red-200 text-red-400 hover:bg-red-50 hover:text-red-600 hover:border-red-300 transition-colors"> className="w-full py-1.5 text-xs font-medium rounded-lg border border-red-200 text-red-400 hover:bg-red-50 hover:text-red-600 hover:border-red-300 transition-colors">
@@ -1228,7 +1236,8 @@ function PairsPanel({ selectedObject, allObjects, objectPairs, loadingPairs, onP
<EditPairForm pair={pair} allObjects={allObjects} <EditPairForm pair={pair} allObjects={allObjects}
onSaved={() => { setEditingId(null); onPairsReload(); }} onSaved={() => { setEditingId(null); onPairsReload(); }}
onCancel={() => setEditingId(null)} onCancel={() => setEditingId(null)}
onDeleted={id => { setEditingId(null); onPairsReload(); }} /> onDeleted={id => { setEditingId(null); onPairsReload(); }}
onSavedAndTranslate={(savedPair) => { setEditingId(null); onPairsReload(); handleTranslate(savedPair); }} />
) : ( ) : (
<div className="rounded-lg border border-slate-200 p-3 bg-slate-50 space-y-1.5"> <div className="rounded-lg border border-slate-200 p-3 bg-slate-50 space-y-1.5">
<div className="flex items-center gap-1.5 flex-wrap"> <div className="flex items-center gap-1.5 flex-wrap">