namespace Bsevita.Library.Ui.Pages; public partial class Books { [SupplyParameterFromQuery(Name = "focus")] public string? Focus { get; set; } private List _books = []; private string _searchText = string.Empty; private string _searchFilter = "title"; private bool _isLoading = true; private bool _isSaving; private bool _showEditor; private Guid? _editingId; private SaveBookRequest _editModel = new(); private BookDto? _bookToDelete; private string? _errorMessage; private string? _successMessage; private bool HasSearchText => !string.IsNullOrWhiteSpace(_searchText); private bool ShouldFocusSearch => string.Equals(Focus, "search", StringComparison.OrdinalIgnoreCase); private string EditorTitle => _editingId is null ? "Neu anlegen" : "Bearbeiten"; private string SaveButtonText => _isSaving ? "Speichert ..." : "Speichern"; private string DeleteMessage => _bookToDelete is null ? string.Empty : $"Soll '{_bookToDelete.Title}' wirklich gelöscht werden? Ausgeliehene Bücher können nicht gelöscht werden."; protected override Task OnInitializedAsync() => LoadAsync(); private async Task LoadAsync() { _isLoading = true; try { _books = (await BooksApi.GetAllAsync()).ToList(); } catch (Exception exception) { _errorMessage = Error(exception); _books = []; } finally { _isLoading = false; } } private async Task SearchAsync() { if (string.IsNullOrWhiteSpace(_searchText)) { await LoadAsync(); return; } _isLoading = true; try { var searchText = _searchText.Trim(); if (_searchFilter == "number") { var book = await BooksApi.GetByNumberAsync(searchText); _books = [book]; } else { _books = (await BooksApi.SearchAsync(_searchFilter, searchText)).ToList(); } } catch (Exception exception) { _errorMessage = Error(exception); _books = []; } finally { _isLoading = false; } } private async Task ResetSearchAsync() { _searchText = string.Empty; await LoadAsync(); } private async Task HandleSearchKey(KeyboardEventArgs args) { if (args.Key == "Enter") { await SearchAsync(); } } private void OpenCreate() { _editingId = null; _editModel = new SaveBookRequest(); _showEditor = true; ClearMessages(); } private async Task OpenEditAsync(Guid id) { ClearMessages(); try { var book = await BooksApi.GetByIdAsync(id); _editingId = book.Id; _editModel = new SaveBookRequest { BookNumber = book.BookNumber, Isbn = book.Isbn, Title = book.Title, Author = book.Author, Subject = book.Subject, Publisher = book.Publisher, PublicationYear = book.PublicationYear }; _showEditor = true; } catch (Exception exception) { _errorMessage = Error(exception); } } private void CloseEditor() { if (!_isSaving) { _showEditor = false; } } private async Task SaveAsync() { _isSaving = true; try { if (_editingId is Guid id) { await BooksApi.UpdateAsync(id, _editModel); } else { await BooksApi.CreateAsync(_editModel); } _showEditor = false; _successMessage = _editingId is null ? "Buch wurde angelegt." : "Buch wurde gespeichert."; await LoadAsync(); } catch (Exception exception) { _errorMessage = Error(exception); } finally { _isSaving = false; } } private void AskDelete(BookDto book) => _bookToDelete = book; private void CancelDelete() => _bookToDelete = null; private async Task DeleteAsync() { if (_bookToDelete is null) { return; } try { await BooksApi.DeleteBookAsync(_bookToDelete.Id); _successMessage = $"'{_bookToDelete.Title}' wurde gelöscht."; _bookToDelete = null; await LoadAsync(); } catch (Exception exception) { _errorMessage = Error(exception); _bookToDelete = null; } } private void ClearMessages() { _errorMessage = null; _successMessage = null; } private static bool HasIsbn(BookDto book) => !string.IsNullOrWhiteSpace(book.Isbn); private static string Error(Exception exception) => exception is ApiProblemException api ? api.Message : "Die Buchdaten konnten nicht verarbeitet werden."; }