feat(akquise): Archiv bearbeiten und wiederherstellen

Im Archiv setzte der Stift nur `editing` - das Formular stand dort nicht,
also passierte sichtbar nichts. Es wird jetzt auch im Archiv gezeigt,
aber nur beim Bearbeiten: eingetragen wird weiterhin im Eingang.

Dazu ein Weg zurueck. `POST /api/acquisitions/:id/restore` setzt
`found_at` auf heute und leert `converted_at` samt `opportunity_id` -
ohne Letzteres haelt die Uebernahme einen Rueckfaeller im Archiv fest,
gleich welches Datum er traegt. Eine Spalte "wiederhergestellt" gibt es
bewusst nicht; die Tabelle fuehrt keinen Zustand.

Der Pfeil erscheint nur im Archiv. Ein nie uebernommener Eintrag wird
ohne Rueckfrage zurueckgeholt, ein Rueckfaeller mit - dabei faellt der
Verweis auf die geloeschte Opportunity weg. Fuer diese Rueckfrage kennt
`ConfirmDialog` jetzt `tone="neutral"`: ein roter Knopf an einer
harmlosen Stelle nimmt der Farbe ihre Bedeutung.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Sascha Wolf
2026-09-03 09:35:15 +02:00
co-authored by Claude Opus 5
parent ea886e4d1b
commit f319b8207b
10 changed files with 205 additions and 16 deletions
@@ -25,6 +25,8 @@ interface AcquisitionTableProps {
onEdit: (entry: Acquisition) => void;
onDelete: (entry: Acquisition) => void;
onConvert: (entry: Acquisition) => void;
/** Nur im Archiv gesetzt - im Eingang gibt es nichts wiederherzustellen. */
onRestore?: (entry: Acquisition) => void;
}
const COLUMNS: { key: AcquisitionSortKey | null; label: string; className?: string }[] = [
@@ -116,6 +118,7 @@ export const AcquisitionTable: React.FC<AcquisitionTableProps> = ({
onEdit,
onDelete,
onConvert,
onRestore,
}) => (
<div className="overflow-hidden rounded-2xl border border-ink-200 bg-surface shadow-card">
<div className="scrollbar-slim overflow-x-auto">
@@ -227,6 +230,24 @@ export const AcquisitionTable: React.FC<AcquisitionTableProps> = ({
<td className="whitespace-nowrap px-4 py-3 text-right">
<div className="inline-flex gap-1">
{onRestore && (
<button
onClick={() => onRestore(entry)}
disabled={isBusy}
title="Zurück in die Akquise: der Eintrag bekommt das heutige Datum und steht wieder im Eingang."
aria-label={`${entry.title} wiederherstellen`}
className="rounded-lg p-2 text-ink-400 transition hover:bg-brand-50 hover:text-brand-700 disabled:opacity-50"
>
<svg className="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M3 10h10a5 5 0 010 10h-3M3 10l4-4M3 10l4 4"
/>
</svg>
</button>
)}
<button
onClick={() => onEdit(entry)}
title="Bearbeiten"