Improved Subscribers Page with better table sizing, better mobile view and items per page dropdown

This commit is contained in:
Mia Rose Winter 2024-04-29 15:09:04 +02:00
parent acc2e02961
commit 5c7bf8be04
Signed by: miawinter
GPG key ID: 4B6F6A83178F595E
2 changed files with 41 additions and 18 deletions

View file

@ -42,7 +42,25 @@
<h1 class="text-3xl lg:text-5xl font-light mb-6 text-primary">@Localizer["Title"]</h1>
<div class="flex gap-2 mb-3">
<div class="flex flex-wrap gap-2 mb-3">
<details class="dropdown">
<summary class="btn btn-sm btn-accent">
@Items /
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="w-4 h-4" title="page">
<path d="M5.625 1.5c-1.036 0-1.875.84-1.875 1.875v17.25c0 1.035.84 1.875 1.875 1.875h12.75c1.035 0 1.875-.84 1.875-1.875V12.75A3.75 3.75 0 0 0 16.5 9h-1.875a1.875 1.875 0 0 1-1.875-1.875V5.25A3.75 3.75 0 0 0 9 1.5H5.625Z" />
<path d="M12.971 1.816A5.23 5.23 0 0 1 14.25 5.25v1.875c0 .207.168.375.375.375H16.5a5.23 5.23 0 0 1 3.434 1.279 9.768 9.768 0 0 0-6.963-6.963Z" />
</svg>
</summary>
<ul class="p-2 shadow-xl menu dropdown-content z-[1] bg-accent text-accent-content rounded-box w-52">
<li><a href="@($"/subscribers?page={Math.Floor(Items * Page / 5.0)}&items=5")">5</a></li>
<li><a href="@($"/subscribers?page={Math.Floor(Items * Page / 10.0)}")">10</a></li>
<li><a href="@($"/subscribers?page={Math.Floor(Items * Page / 25.0)}&items=25")">25</a></li>
<li><a href="@($"/subscribers?page={Math.Floor(Items * Page / 50.0)}&items=50")">50</a></li>
<li><a href="@($"/subscribers?page={Math.Floor(Items * Page / 100.0)}&items=100")">100</a></li>
<li><a href="@($"/subscribers?page={Math.Floor(Items * Page / 250.0)}&items=250")">250</a></li>
</ul>
</details>
<button class="btn btn-sm btn-primary" onclick="@(ModalId).showModal()">
@Localizer["AddSubscribers_Label"]
</button>
@ -53,29 +71,31 @@
<table class="table table-zebra">
<thead>
<tr>
<th>@Localizer["Header_Email"]</th>
<th>@Localizer["Header_Name"]</th>
<th>@Localizer["Header_LastReceived"]</th>
<th>@Localizer["Header_LastOpen"]</th>
<th>@Localizer["Header_UnsubscribeReason"]</th>
<th>@Localizer["Header_Subscribed"]</th>
<th class="text-center md:text-left md:w-48">@Localizer["Header_Email"]</th>
<th class="text-center md:text-left w-48 max-md:hidden">@Localizer["Header_Name"]</th>
<th class="text-center md:text-left w-24 max-md:hidden">@Localizer["Header_LastReceived"]</th>
<th class="text-center md:text-left w-24 max-md:hidden">@Localizer["Header_LastOpen"]</th>
<th class="text-center md:text-left w-24 max-md:hidden">@Localizer["Header_UnsubscribeReason"]</th>
<th class="text-center md:text-left md:w-8">@Localizer["Header_Subscribed"]</th>
</tr>
</thead>
<tbody>
<PageComponent Page="@Page" LoadCallback="LoadSubscribers" ItemsPerPage="ItemsPerPage">
<PageComponent Page="@Page" LoadCallback="LoadSubscribers" ItemsPerPage="@Items">
<tr>
<td>@context.Email</td>
<td>@context.Name</td>
<td>@context.LastMailReceived?.ToString("g")</td>
<td>@context.LastMailOpened?.ToString("g")</td>
<td>@context.UnsubscribeReason</td>
<td><input type="checkbox" class="checkbox" checked="@(!context.Unsubscribed)"/></td>
<td class="max-md:hidden">@context.Name</td>
<td class="max-md:hidden">@context.LastMailReceived?.ToString("g")</td>
<td class="max-md:hidden">@context.LastMailOpened?.ToString("g")</td>
<td class="max-md:hidden">@context.UnsubscribeReason</td>
<td class="text-center md:text-left"><input type="checkbox" class="checkbox no-animation" checked="@(!context.Unsubscribed)" disabled /></td>
</tr>
</PageComponent>
</tbody>
<tfoot>
<tr>
<td colspan="3">@Localizer["Newsletter_Footer_Timezone"] @TimeZoneInfo.Local</td>
<td colspan="6" class="max-md:hidden">
@Localizer["Newsletter_Footer_Timezone"] @TimeZoneInfo.Local
</td>
</tr>
</tfoot>
</table>
@ -90,7 +110,7 @@
</svg>
</button>
} else {
<a class="join-item btn" target="_top" href="@(Page < 2 ? "/subscribers" : $"/subscribers?page={Page - 1}")" title="@Localizer["Paging_Previous"]">
<a class="join-item btn" target="_top" href="@(Page < 2 ? $"/subscribers?items={Items}" : $"/subscribers?page={Page - 1}&items={Items}")" title="@Localizer["Paging_Previous"]">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="w-6 h-6">
<path fill-rule="evenodd" d="M7.72 12.53a.75.75 0 0 1 0-1.06l7.5-7.5a.75.75 0 1 1 1.06 1.06L9.31 12l6.97 6.97a.75.75 0 1 1-1.06 1.06l-7.5-7.5Z" clip-rule="evenodd"/>
</svg>
@ -104,7 +124,7 @@
</svg>
</button>
} else {
<a class="join-item btn" target="_top" href="/subscribers?page=@(Page + 1)" title="@Localizer["Paging_Next"]">
<a class="join-item btn" target="_top" href="@($"/subscribers?page={Page + 1}&items={Items}")" title="@Localizer["Paging_Next"]">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="w-6 h-6">
<path fill-rule="evenodd" d="M16.28 11.47a.75.75 0 0 1 0 1.06l-7.5 7.5a.75.75 0 0 1-1.06-1.06L14.69 12 7.72 5.03a.75.75 0 0 1 1.06-1.06l7.5 7.5Z" clip-rule="evenodd"/>
</svg>
@ -119,6 +139,8 @@
private string TitlePostfix { get; set; } = default!;
[SupplyParameterFromQuery]
public int Page { get; set; } = 0;
[SupplyParameterFromQuery]
public int Items { get; set; }
private const int ItemsPerPage = 10;
private int TotalPages { get; set; }
@ -128,9 +150,10 @@
private static string ModalId => "AddSubscribersDialog";
protected override async Task OnInitializedAsync() {
if (Items < 1) Items = 10;
await using var context = await ContextFactory.CreateDbContextAsync();
var query = context.Set<EmailSubscriber>();
TotalPages = (int)Math.Max(Math.Ceiling(await query.CountAsync() / (double)ItemsPerPage), 1);
TotalPages = (int)Math.Max(Math.Ceiling(await query.CountAsync() / (double)Items), 1);
}
private async ValueTask<IEnumerable<EmailSubscriber>> LoadSubscribers(int page, int count) {

File diff suppressed because one or more lines are too long