@page "/ajout/isbn" @inject ServiceLivresApi Api @inject NavigationManager Navigation MaBibli — ajouter par ISBN

Ajouter par ISBN

@if (_etape == Etape.Saisie) {

Scannez le code-barres, ou saisissez l'ISBN imprimé sur le livre.

@* La saisie manuelle reste le recours quand le code-barres est abîmé, absent, ou que la caméra est indisponible : elle ne disparaît jamais derrière le scan. *@ Saisir à la main
} @if (_etape == Etape.Scan) { } @if (_erreur is not null) { } @foreach (var avertissement in _avertissements) {

@avertissement

} @if (_etape == Etape.Choix) { @* Décision actée dans CLAUDE.md : plusieurs notices pour un même ISBN (rééditions successives partageant l'ISBN), on ne choisit JAMAIS à la place de l'utilisateur. Les candidats partagent titre et auteur : ce sont l'éditeur et l'année qui départagent, donc ils sont mis en avant. *@

@_candidats.Count notices correspondent à cet ISBN. Elles se distinguent par l'éditeur et l'année.

} @if (_etape == Etape.Formulaire) {

Vérifiez et complétez la fiche : tout reste modifiable.

} @code { private enum Etape { Saisie, Scan, Choix, Formulaire } private Etape _etape = Etape.Saisie; private string _isbn = string.Empty; private bool _chargement; private bool _enregistrement; private string? _erreur; private string? _erreurFormulaire; private IReadOnlyList _candidats = []; private IReadOnlyList _avertissements = []; private EnregistrementLivre _saisie = new(); private void OuvrirScanner() { _erreur = null; _avertissements = []; _etape = Etape.Scan; } // Le scan enchaîne directement sur le flux de lookup existant : l'utilisateur // ne retape jamais ce qui vient d'être scanné. private async Task SurCodeDetecteAsync(string isbn) { _isbn = isbn; _etape = Etape.Saisie; await ChercherAsync(); } private async Task SurTouche(KeyboardEventArgs e) { if (e.Key == "Enter" && !string.IsNullOrWhiteSpace(_isbn)) { await ChercherAsync(); } } private async Task ChercherAsync() { _chargement = true; _erreur = null; _avertissements = []; try { var resultat = await Api.ChercherIsbnAsync(_isbn.Trim()); if (resultat is null) { _erreur = $"« {_isbn} » n'est pas un ISBN valide."; return; } _avertissements = resultat.Avertissements; _candidats = resultat.Candidats; if (_candidats.Count == 0) { // Aucune notice : on ne bloque pas, le formulaire manuel reste la porte de sortie. _erreur = "Aucune notice trouvée pour cet ISBN. Complétez la fiche à la main."; _saisie = new EnregistrementLivre { Isbn = resultat.IsbnDemande }; _etape = Etape.Formulaire; return; } if (_candidats.Count == 1) { Choisir(_candidats[0]); return; } _etape = Etape.Choix; } catch (Exception ex) { _erreur = $"La recherche a échoué : {ex.Message}"; } finally { _chargement = false; } } private void Choisir(CandidatLivre candidat) { _saisie = new EnregistrementLivre { Isbn = _isbn.Trim(), Titre = candidat.Titre, Auteur = candidat.Auteur, Editeur = candidat.Editeur, CoverUrl = candidat.CoverUrl, Format = Format.Physique, Statut = Statut.ALire, }; _erreur = null; _etape = Etape.Formulaire; } private void Recommencer() { _etape = Etape.Saisie; _erreur = null; _erreurFormulaire = null; _candidats = []; } private async Task EnregistrerAsync() { _enregistrement = true; _erreurFormulaire = null; var resultat = await Api.CreerAsync(_saisie); _enregistrement = false; if (!resultat.EstOk) { _erreurFormulaire = resultat.Erreur; return; } Navigation.NavigateTo("/"); } }