Files
certain/web/src/components/Modal.jsx
T
GuidoandClaude Opus 5 ee36dae34a feat: Zeigen, welche Buchungen in einem Ausgaben-Anteil stecken
Eine Zahl, die man nicht aufschluesseln kann, muss man glauben. Genau das
war der Streitpunkt: Die Karte nannte fuer Lebensmittel einen Betrag, und
es gab keine Moeglichkeit nachzusehen, welche Zahlungen darin einbezogen
sind und welche nicht.

Jetzt oeffnet ein Klick auf einen Anteil - in der Liste wie in der
Legende des Kreises - die Buchungen dahinter: Datum, Empfaenger, Konto,
Betrag. Die Liste kommt aus derselben Stelle, die auch die Summe bildet
(`budget.expense_rows`), sie kann also gar nicht etwas anderes zeigen als
das, was gezaehlt wurde. Ein Test haelt das fest.

Steht eine Buchung darin, obwohl ihr Datum ausserhalb des Zeitraums
liegt, traegt sie die Kalendermarke: Dann wurde ihr Budget-Monat von Hand
gesetzt, und das ist der Grund.

Nebenbei: Dialoge haengen jetzt am Seitenkoerper. Kacheln der Uebersicht
werden per `transform` positioniert - damit war die Kachel der
Bezugsrahmen fuer `position: fixed`, und der Dialog sass eingeklemmt
darin statt ueber der Seite.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-30 15:10:19 +02:00

40 lines
1.7 KiB
React
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { useRef } from "react";
import { createPortal } from "react-dom";
import Icon from "./Icon";
// Einfacher, gestalteter Dialog (nutzt die modal-Klassen der Vorlage).
export default function Modal({ title, onClose, children, footer, wide = false }) {
// Nur schliessen, wenn der Klick auch AUF dem Hintergrund begonnen hat.
// Markiert man Text in einem Feld und zieht dabei über den Rand hinaus,
// liegt das Mouseup auf dem Hintergrund; der Klick feuert dann auf dem
// gemeinsamen Elternelement und schloss den Dialog mitten im Markieren.
const startAussen = useRef(false);
// An den Seitenkoerper, nicht an die Stelle im Baum: Steht der Aufrufer in
// einem Element mit `transform` – jede Kachel der Uebersicht tut das –, waere
// das sonst der Bezugsrahmen fuer `position: fixed`, und der Dialog sitzt
// eingeklemmt in der Kachel statt ueber der Seite.
return createPortal(
<div
className="modal-backdrop"
onMouseDown={(e) => { startAussen.current = e.target === e.currentTarget; }}
onClick={(e) => {
if (e.target === e.currentTarget && startAussen.current) onClose();
startAussen.current = false;
}}
>
<div className="modal" role="dialog" aria-modal="true" style={{ maxWidth: wide ? 640 : 480 }}>
<div className="modal-head">
<h2 style={{ margin: 0 }}>{title}</h2>
<button className="btn-icon" style={{ marginLeft: "auto" }} onClick={onClose} title="Schließen">
<Icon name="close" size={18} />
</button>
</div>
<div className="modal-body">{children}</div>
{footer && <div className="btn-pair">{footer}</div>}
</div>
</div>,
document.body,
);
}