diff --git a/CutList.Web/Components/Shared/Pager.razor b/CutList.Web/Components/Shared/Pager.razor new file mode 100644 index 0000000..b7a90d7 --- /dev/null +++ b/CutList.Web/Components/Shared/Pager.razor @@ -0,0 +1,109 @@ +@if (TotalCount == 0) +{ + return; +} + +@{ + var totalPages = (int)Math.Ceiling((double)TotalCount / PageSize); + var start = (CurrentPage - 1) * PageSize + 1; + var end = Math.Min(CurrentPage * PageSize, TotalCount); +} + +
+ Showing @start–@end of @TotalCount + + @if (totalPages > 1) + { + + } +
+ +@code { + [Parameter, EditorRequired] + public int TotalCount { get; set; } + + [Parameter] + public int PageSize { get; set; } = 25; + + [Parameter] + public int CurrentPage { get; set; } = 1; + + [Parameter] + public EventCallback CurrentPageChanged { get; set; } + + private async Task SetPage(int page) + { + if (page < 1 || page > (int)Math.Ceiling((double)TotalCount / PageSize)) + return; + if (page == CurrentPage) + return; + + CurrentPage = page; + await CurrentPageChanged.InvokeAsync(page); + } + + private IEnumerable GetPageWindow(int totalPages) + { + const int maxVisible = 7; + + if (totalPages <= maxVisible) + { + for (var i = 1; i <= totalPages; i++) + yield return i; + yield break; + } + + // Always show first page + yield return 1; + + var windowStart = Math.Max(2, CurrentPage - 2); + var windowEnd = Math.Min(totalPages - 1, CurrentPage + 2); + + // Adjust window to show 5 middle pages when possible + if (windowEnd - windowStart < 4) + { + if (windowStart == 2) + windowEnd = Math.Min(totalPages - 1, windowStart + 4); + else + windowStart = Math.Max(2, windowEnd - 4); + } + + if (windowStart > 2) + yield return -1; // ellipsis + + for (var i = windowStart; i <= windowEnd; i++) + yield return i; + + if (windowEnd < totalPages - 1) + yield return -1; // ellipsis + + // Always show last page + yield return totalPages; + } +}