@page "/Borrowings/Manage" @using BlazorFrontend.Services @using LibraryManagement.Shared.Models @using Microsoft.AspNetCore.Authorization @inject LibraryApiClient ApiClient @inject IJSRuntime JS @attribute [Authorize(Roles = "Librarian")] Manage Borrowings

Manage All Borrowings

Monitor and process library loans across all members.

Total Active: @_borrowings.Count(m => m.Status == "Borrowed")
@if (_isLoading) {
} else {
@if (!_borrowings.Any()) { } @foreach (var loan in PaginatedBorrowings) { }
Book & Loan Info Member Details Loan Dates Status Fines Actions
No borrowing records found in the system.

@loan.BookTitle

ID: #@loan.Id

@loan.UserEmail

UID: #@loan.UserId

Out: @loan.BorrowDate.ToString("MMM dd, yyyy")
Due: @{ var isOverdue = loan.DueDate < DateTime.Now && loan.Status == "Borrowed"; } @loan.DueDate.ToString("MMM dd, yyyy")
@if (loan.ReturnDate.HasValue) {
Back: @loan.ReturnDate.Value.ToString("MMM dd, yyyy")
}
@(loan.Status == "PendingReturn" ? "Pending Approval" : loan.Status) @if (loan.FineAmount > 0) {
MMK @loan.FineAmount.ToString("N0") @if (loan.IsFinePaid) { Settled } else { Pending }
} else { No Fines }
@if (loan.Status == "PendingReturn") { } else if (loan.Status == "Borrowed") { } else {
}
@if (TotalPages > 1) {

Showing @((_currentPage - 1) * _pageSize + 1) to @(Math.Min(_currentPage * _pageSize, _borrowings.Count())) of @_borrowings.Count() records

Page @_currentPage of @TotalPages
}
} @code { private bool _isLoading = true; private IEnumerable _borrowings = Enumerable.Empty(); // Pagination private int _currentPage = 1; private int _pageSize = 10; private IEnumerable PaginatedBorrowings => _borrowings .OrderByDescending(l => l.BorrowDate) .Skip((_currentPage - 1) * _pageSize) .Take(_pageSize); private int TotalPages => (int)Math.Ceiling(_borrowings.Count() / (double)_pageSize); protected override async Task OnInitializedAsync() { await LoadDataAsync(); } private async Task LoadDataAsync() { _isLoading = true; try { _borrowings = await ApiClient.GetAllBorrowingsAsync(); _currentPage = 1; } catch (Exception ex) { Console.WriteLine($"Error loading all borrowings: {ex.Message}"); } finally { _isLoading = false; } } private async Task ApproveReturnAsync(BorrowingDto loan) { bool confirmed = await JS.InvokeAsync("confirm", $"Approve return for \"{loan.BookTitle}\" borrowed by {loan.UserEmail}?"); if (!confirmed) return; var result = await ApiClient.ReturnBookAsync(loan.Id); if (result != null) { await JS.InvokeVoidAsync("showToast", "Return approved successfully!", "success"); await LoadDataAsync(); } else { await JS.InvokeVoidAsync("showToast", "Failed to approve return.", "error"); } } private async Task ForceReturnAsync(BorrowingDto loan) { bool confirmed = await JS.InvokeAsync("confirm", $"Force process return for \"{loan.BookTitle}\" (Member: {loan.UserEmail})? Use this if the member returned the book in person."); if (!confirmed) return; var result = await ApiClient.ReturnBookAsync(loan.Id); if (result != null) { await JS.InvokeVoidAsync("showToast", "Book marked as returned!", "success"); await LoadDataAsync(); } else { await JS.InvokeVoidAsync("showToast", "Failed to process return.", "error"); } } }