@page "/souhaits/{Id:int}/edition" @inject ServiceLivresApi Api @inject EtatReseau Reseau @inject NavigationManager Navigation @implements IDisposable @* Écran dédié plutôt qu'un formulaire déplié dans la liste : convention du projet depuis la fiche livre — le mode est dans l'ADRESSE, jamais dans un booléen interne. C'est ce qui rend le bouton « retour » du navigateur une sortie d'édition naturelle, et ce qui empêche de modifier une envie en faisant défiler sa liste. ⚠️ Cette page ne partage aucun paramètre avec une autre route : contrairement à la fiche livre ou à la fiche série, elle n'a pas besoin de s'abonner à LocationChanged. L'abonnement ci-dessous ne sert qu'à suivre l'état du réseau. *@ MaBibli — modifier une envie

Modifier une envie

@if (_erreur is not null) { } @if (_introuvable) { @* Hors-ligne, « supprimée » et « pas encore enregistrée ici » sont indiscernables : on ne tranche pas à la place de l'utilisateur. Même règle que pour une fiche livre absente. *@

@(Reseau.EnLigne ? "Cette envie n'existe plus dans votre liste." : "Cette envie n'est pas dans les données enregistrées sur cet appareil.")

} else if (_saisie is null) { } else {
@* Le champ de saisie garde la valeur nue : découper à la frappe se battrait avec le curseur. Les tirets sont une affaire d'affichage, pas de saisie. *@ @if (!Reseau.EnLigne) {

@EtatReseau.MotifHorsLigne

}
Annuler
} @code { [Parameter] public int Id { get; set; } private EnregistrementSouhait? _saisie; private bool _introuvable; private bool _enCours; private string? _erreur; protected override async Task OnInitializedAsync() { Reseau.Change += SurChangementReseau; await ChargerAsync(); } private void SurChangementReseau() => _ = InvokeAsync(StateHasChanged); public void Dispose() => Reseau.Change -= SurChangementReseau; private string? MotifBlocage => Reseau.EnLigne ? null : EtatReseau.MotifHorsLigne; /// /// Reprend l'envie depuis la liste, et non depuis un point d'entrée dédié. /// /// /// L'API n'expose pas GET /api/souhaits/{id}, et il n'y a pas lieu de l'ajouter : la /// liste entière est déjà chargée, déjà mise en instantané, et c'est ce qui rend cet écran /// consultable hors-ligne — même si l'enregistrement, lui, y est refusé. /// private async Task ChargerAsync() { var souhaits = await Api.ListerSouhaitsAsync(); var souhait = souhaits.FirstOrDefault(s => s.Id == Id); if (souhait is null) { _introuvable = true; return; } // ⚠️ La couverture n'est PAS reprise ici : elle n'a pas de champ de saisie, et le // service la conserve donc telle qu'elle est en base. La valeur portée par le DTO peut // en outre être déduite de l'ISBN — la figer serait écrire en base ce qui se calcule. _saisie = new EnregistrementSouhait { Titre = souhait.Titre, Auteur = souhait.Auteur, Editeur = souhait.Editeur, Annee = souhait.Annee, Isbn = souhait.Isbn, Note = souhait.Note, }; } private async Task EnregistrerAsync() { if (_saisie is null) { return; } _enCours = true; _erreur = null; var resultat = await Api.ModifierSouhaitAsync(Id, _saisie); _enCours = false; if (!resultat.EstOk) { // Le message vient de l'API : doublon d'une autre envie, ISBN invalide, ou hors // ligne. Aucun code HTTP brut n'arrive jusqu'ici. _erreur = resultat.Erreur; return; } Navigation.NavigateTo("souhaits"); } }