Files
EnvelopeGenerator/EnvelopeGenerator.ReceiverUI/EnvelopeGenerator.ReceiverUI.Client/Pages/Envelope/EnvelopePage.razor
OlgunR 93488ba83e Refactor envelope receiver auth flow and state handling
- Introduce IReceiverAuthService and ReceiverAuthService for all envelope receiver authentication and status API calls
- Add ReceiverAuthModel as a client-side DTO for API responses
- Refactor EnvelopeState to store all relevant fields and update via ApplyApiResponse
- Overhaul EnvelopePage.razor to use new service and state, with improved status handling and UI
- Enhance ApiResponse and ApiServiceBase to support structured error deserialization
- Register IReceiverAuthService in DI container
2026-03-23 15:57:20 +01:00

159 lines
5.0 KiB
Plaintext

@page "/envelope/{EnvelopeKey}"
@rendermode InteractiveAuto
@inject IReceiverAuthService ReceiverAuthService
@inject EnvelopeState State
@implements IDisposable
<PageTitle>Dokument</PageTitle>
@switch (State.Status)
{
case EnvelopePageStatus.Loading:
<LoadingIndicator Message="Dokument wird geladen..." />
break;
case EnvelopePageStatus.NotFound:
<StatusPage Type="not_found" />
break;
case EnvelopePageStatus.AlreadySigned:
<StatusPage Type="signed"
Title="@State.Title"
SenderEmail="@State.SenderEmail" />
break;
case EnvelopePageStatus.Rejected:
<StatusPage Type="rejected"
Title="@State.Title"
SenderEmail="@State.SenderEmail" />
break;
case EnvelopePageStatus.Expired:
<StatusPage Type="expired" />
break;
case EnvelopePageStatus.RequiresAccessCode:
<AccessCodeForm EnvelopeKey="@EnvelopeKey"
ErrorMessage="@State.ErrorMessage"
SenderEmail="@State.SenderEmail"
Title="@State.Title"
TfaEnabled="@State.TfaEnabled"
HasPhoneNumber="@State.HasPhoneNumber"
OnSubmit="HandleAccessCodeSubmit" />
break;
case EnvelopePageStatus.RequiresTwoFactor:
<TfaForm EnvelopeKey="@EnvelopeKey"
TfaType="@(State.TfaType ?? "authenticator")"
TfaExpiration="@State.TfaExpiration"
HasPhoneNumber="@State.HasPhoneNumber"
ErrorMessage="@State.ErrorMessage"
OnSubmit="HandleTfaSubmit" />
break;
case EnvelopePageStatus.ShowDocument:
@* Phase 4 (PSPDFKit) kommt später — vorerst Platzhalter *@
<div class="text-center mt-5">
<div class="status-icon signed">
<i class="bi bi-file-earmark-check"></i>
</div>
<h2>Dokument bereit</h2>
<p class="text-muted">
«@State.Title» — PDF-Viewer wird in Phase 4 integriert.
</p>
@if (State.ReadOnly)
{
<span class="badge bg-secondary">Nur Lesen</span>
}
</div>
break;
case EnvelopePageStatus.Error:
<ErrorDisplay Title="Fehler" Message="@State.ErrorMessage" />
break;
}
@code {
[Parameter] public string EnvelopeKey { get; set; } = default!;
protected override async Task OnInitializedAsync()
{
State.OnChange += StateHasChanged;
await LoadStatusAsync();
}
/// <summary>
/// Erster API-Call: Status prüfen.
/// Entspricht dem GET /Envelope/{key} im Web-Projekt.
/// Die API entscheidet, was passiert (AccessCode nötig? Bereits signiert? etc.)
/// </summary>
private async Task LoadStatusAsync()
{
State.SetLoading();
var result = await ReceiverAuthService.GetStatusAsync(EnvelopeKey);
if (result.IsSuccess && result.Data is not null)
{
State.ApplyApiResponse(result.Data);
}
else if (result.StatusCode == 404)
{
State.SetNotFound();
}
else
{
State.SetError(result.ErrorMessage ?? "Verbindung zum Server fehlgeschlagen.");
}
}
/// <summary>
/// Zweiter API-Call: AccessCode senden.
/// Wird von AccessCodeForm aufgerufen (OnSubmit-Callback).
/// Die API prüft den Code und antwortet mit dem nächsten Status.
/// </summary>
private async Task HandleAccessCodeSubmit((string Code, bool PreferSms) submission)
{
var result = await ReceiverAuthService.SubmitAccessCodeAsync(
EnvelopeKey, submission.Code, submission.PreferSms);
if (result.IsSuccess && result.Data is not null)
{
State.ApplyApiResponse(result.Data);
}
else if (result.Data is not null)
{
// 401 mit Body → falscher Code, API gibt trotzdem ReceiverAuthModel zurück
State.ApplyApiResponse(result.Data);
}
else
{
State.SetError(result.ErrorMessage ?? "Fehler bei der Code-Prüfung.");
}
}
/// <summary>
/// Dritter API-Call: TFA-Code senden.
/// Wird von TfaForm aufgerufen (OnSubmit-Callback).
/// </summary>
private async Task HandleTfaSubmit((string Code, string Type) submission)
{
var result = await ReceiverAuthService.SubmitTfaCodeAsync(
EnvelopeKey, submission.Code, submission.Type);
if (result.IsSuccess && result.Data is not null)
{
State.ApplyApiResponse(result.Data);
}
else if (result.Data is not null)
{
State.ApplyApiResponse(result.Data);
}
else
{
State.SetError(result.ErrorMessage ?? "Fehler bei der TFA-Prüfung.");
}
}
public void Dispose() => State.OnChange -= StateHasChanged;
}