using EnvelopeGenerator.ReceiverUI.Client.Models; namespace EnvelopeGenerator.ReceiverUI.Client.State; /// /// Hält den aktuellen Zustand des geladenen Umschlags. /// /// WARUM ein eigenes State-Objekt? /// - Mehrere Komponenten auf einer Seite brauchen die gleichen Daten /// - Ohne State müsste jede Komponente die Daten selbst laden → doppelte API-Calls /// - StateHasChanged() informiert automatisch alle Subscriber /// /// PATTERN: "Observable State" — Services setzen den State, Komponenten reagieren darauf. /// /// Die Set-Methoden nehmen jetzt ein ReceiverAuthModel entgegen, /// damit alle Felder (Title, SenderEmail, TfaType etc.) zentral gespeichert werden. /// public class EnvelopeState { private EnvelopePageStatus _status = EnvelopePageStatus.Loading; /// Aktueller Seitenstatus public EnvelopePageStatus Status { get => _status; private set { _status = value; NotifyStateChanged(); } } // ── Felder aus ReceiverAuthModel ── /// Titel des Umschlags (z.B. "Vertragsdokument") public string? Title { get; private set; } /// Nachricht des Absenders public string? Message { get; private set; } /// E-Mail des Absenders (für Rückfragen-Hinweis) public string? SenderEmail { get; private set; } /// Ob TFA für diesen Umschlag aktiviert ist public bool TfaEnabled { get; private set; } /// Ob der Empfänger eine Telefonnummer hat (für SMS-TFA) public bool HasPhoneNumber { get; private set; } /// Ob das Dokument nur gelesen werden soll (ReadAndConfirm) public bool ReadOnly { get; private set; } /// TFA-Typ: "sms" oder "authenticator" public string? TfaType { get; private set; } /// Ablaufzeit des SMS-Codes (für Countdown-Timer) public DateTime? TfaExpiration { get; private set; } /// Fehlermeldung (z.B. "Falscher Zugangscode") public string? ErrorMessage { get; private set; } // ── Zustandsübergänge ── public void SetLoading() { ErrorMessage = null; Status = EnvelopePageStatus.Loading; } /// /// Setzt den State aus einer API-Antwort. /// Zentrale Methode — alle Endpunkte liefern ReceiverAuthModel, /// und diese Methode mappt den Status-String auf das richtige Enum. /// public void ApplyApiResponse(ReceiverAuthModel model) { // Gemeinsame Felder immer übernehmen Title = model.Title ?? Title; Message = model.Message ?? Message; SenderEmail = model.SenderEmail ?? SenderEmail; TfaEnabled = model.TfaEnabled; HasPhoneNumber = model.HasPhoneNumber; ReadOnly = model.ReadOnly; TfaType = model.TfaType ?? TfaType; TfaExpiration = model.TfaExpiration ?? TfaExpiration; ErrorMessage = model.ErrorMessage; // Status-String → Enum Status = model.Status switch { "requires_access_code" => EnvelopePageStatus.RequiresAccessCode, "requires_tfa" => EnvelopePageStatus.RequiresTwoFactor, "show_document" => EnvelopePageStatus.ShowDocument, "already_signed" => EnvelopePageStatus.AlreadySigned, "rejected" => EnvelopePageStatus.Rejected, "not_found" => EnvelopePageStatus.NotFound, "expired" => EnvelopePageStatus.Expired, "error" => EnvelopePageStatus.Error, _ => EnvelopePageStatus.Error }; } /// Setzt Fehler wenn der API-Call selbst fehlschlägt (Netzwerk etc.) public void SetError(string message) { ErrorMessage = message; Status = EnvelopePageStatus.Error; } /// Setzt NotFound (z.B. bei 404 ohne Body) public void SetNotFound() => Status = EnvelopePageStatus.NotFound; // ── Event ── public event Action? OnChange; private void NotifyStateChanged() => OnChange?.Invoke(); } /// Alle möglichen Zustände der Umschlag-Seite public enum EnvelopePageStatus { Loading, RequiresAccessCode, RequiresTwoFactor, ShowDocument, AlreadySigned, Rejected, NotFound, Expired, Error }