diff --git a/web/src/pages/Transactions.jsx b/web/src/pages/Transactions.jsx index c0f3a5d..5869602 100644 --- a/web/src/pages/Transactions.jsx +++ b/web/src/pages/Transactions.jsx @@ -13,7 +13,7 @@ import CategorySelect from "../components/CategorySelect"; import UebertragDialog from "../components/UebertragDialog"; import DataTable from "../components/DataTable"; import { gruppenFuer } from "../kategorien"; -import { centsToInput, parseAmountToCents, todayIso } from "../format"; +import { centsToInput, formatMoney, parseAmountToCents, todayIso } from "../format"; const TYPES = ["expense", "income", "transfer"]; @@ -256,7 +256,36 @@ export default function Transactions() { try { await api.deleteTransaction(tx.id); ladenBuchungen(); } catch (err) { toast(err.message, "error"); } } + // Ein verknüpftes Paar ist EINE Bewegung, keine zwei. Liegen beide Seiten in + // der Liste, wird die Zugangs-Seite ausgeblendet und die Abgangs-Seite zeigt + // „von → nach" – so wie ein echter Übertrag. Ist nur eine Seite geladen + // (etwa weil nach einem Konto gefiltert wird), bleibt sie einzeln stehen; + // dann trägt sie weiter die Marke mit dem Gegenkonto. + const { zeilen, paarZu } = useMemo(() => { + const vorhanden = new Set(txns.map((t) => t.id)); + const paare = {}; + const sichtbar = []; + for (const tx of txns) { + const link = links[String(tx.id)]; + const gegenseiteDa = link && vorhanden.has(link.other_id); + if (gegenseiteDa && link.richtung === "rein") continue; // von der anderen gezeigt + if (gegenseiteDa) paare[tx.id] = txns.find((x) => x.id === link.other_id); + sichtbar.push(tx); + } + return { zeilen: sichtbar, paarZu: paare }; + }, [txns, links]); + function rowLabel(tx) { + const gegen = paarZu[tx.id]; + if (gegen) { + const von = accountById[tx.account_id]?.name || "?"; + const nach = accountById[gegen.account_id]?.name || "?"; + return { + icon: "arrow-left-right", color: "#6b7480", + title: `${von} → ${nach}`, + sub: tx.payee || tx.description || t("transactions.transfer"), + }; + } if (tx.type === "transfer") { const from = accountById[tx.account_id]?.name || "?"; const to = accountById[tx.to_account_id]?.name || "?"; @@ -307,7 +336,9 @@ export default function Transactions() { {l.sub &&