@* ConfirmDialog: Ersetzt SweetAlert2 aus dem Web-Projekt. Zeigt einen modalen Bestätigungsdialog mit Titel, Text und Ja/Nein-Buttons. Wird NICHT über Parameter gesteuert, sondern über eine Methode: var confirmed = await _dialog.ShowAsync("Titel", "Text"); WARUM eine Methode statt Parameter? - Ein Dialog ist ein "einmaliges Ereignis", kein dauerhafter Zustand - Die aufrufende Komponente will auf das Ergebnis WARTEN (await) - Mit Parametern müsste man den State manuell hin- und herschalten WARUM kein SweetAlert2? - SweetAlert2 ist eine JavaScript-Bibliothek - In Blazor können wir das nativ in C# lösen, ohne JS-Interop - Weniger Abhängigkeiten = weniger Wartung = weniger Fehlerquellen *@ @if (_isVisible) { @* Hintergrund-Overlay: Dunkler Hintergrund hinter dem Dialog. Im Web-Projekt macht SweetAlert2 das automatisch. Hier bauen wir es selbst mit CSS. *@ @* Modal-Dialog: Bootstrap 5 Modal-Markup. Normalerweise braucht Bootstrap-Modal JavaScript (bootstrap.js) um zu öffnen/schließen. Wir steuern die Sichtbarkeit stattdessen über die _isVisible-Variable — Blazor macht das DOM-Update. *@ } @code { // ── Interner State (NICHT Parameter — wird über ShowAsync gesetzt) ── private bool _isVisible; private string _title = string.Empty; private string _message = string.Empty; private string _confirmText = "Ja"; private string _cancelText = "Abbrechen"; private string _confirmColor = "primary"; /// /// TaskCompletionSource: Das Herzstück dieser Komponente. /// /// WAS IST DAS? /// Ein TaskCompletionSource erstellt einen Task, der erst dann /// "fertig" wird, wenn jemand SetResult() aufruft. /// /// WIE FUNKTIONIERT ES? /// 1. ShowAsync() erstellt ein neues TaskCompletionSource /// 2. ShowAsync() gibt dessen Task zurück → der Aufrufer wartet (await) /// 3. Der Benutzer klickt "Ja" → Confirm() ruft SetResult(true) auf /// 4. Der await in der aufrufenden Komponente kommt zurück mit true /// /// Das ist wie ein "Promise" in JavaScript, nur in C#. /// private TaskCompletionSource? _tcs; /// /// Zeigt den Dialog und wartet auf die Benutzer-Entscheidung. /// /// Beispiel-Aufruf: /// var confirmed = await _dialog.ShowAsync( /// "Unterschreiben", /// "Möchten Sie das Dokument wirklich unterschreiben?"); /// /// Dialog-Überschrift /// Beschreibungstext /// Text auf dem Bestätigen-Button (Standard: "Ja") /// Text auf dem Abbrechen-Button (Standard: "Abbrechen") /// Bootstrap-Farbe des Bestätigen-Buttons (Standard: "primary") /// true wenn bestätigt, false wenn abgebrochen public Task ShowAsync( string title, string message, string confirmText = "Ja", string cancelText = "Abbrechen", string confirmColor = "primary") { _title = title; _message = message; _confirmText = confirmText; _cancelText = cancelText; _confirmColor = confirmColor; _tcs = new TaskCompletionSource(); _isVisible = true; StateHasChanged(); return _tcs.Task; } private void Confirm() { _isVisible = false; _tcs?.TrySetResult(true); StateHasChanged(); } private void Cancel() { _isVisible = false; _tcs?.TrySetResult(false); StateHasChanged(); } }