102 lines
4.0 KiB
Plaintext
102 lines
4.0 KiB
Plaintext
package pagination
|
|
|
|
import "git.haelnorr.com/h/oslstats/internal/db"
|
|
import "fmt"
|
|
|
|
templ Pagination(opts db.PageOpts, total int) {
|
|
<div class="mt-6 flex flex-col gap-4">
|
|
<input type="hidden" name="page" id="pagination-page"/>
|
|
<input type="hidden" name="per_page" id="pagination-per-page"/>
|
|
<!-- Page info and per-page selector -->
|
|
<div class="flex flex-col sm:flex-row justify-between items-center gap-4 text-sm text-subtext0">
|
|
<div>
|
|
if total > 0 {
|
|
Showing { fmt.Sprintf("%d", opts.StartItem()) } - { fmt.Sprintf("%d", opts.EndItem(total)) } of { fmt.Sprintf("%d", total) } results
|
|
} else {
|
|
No results
|
|
}
|
|
</div>
|
|
<div class="flex items-center gap-2">
|
|
<label for="per-page-select">Per page:</label>
|
|
<select
|
|
id="per-page-select"
|
|
class="py-1 px-2 rounded-lg bg-surface0 border border-surface1 text-text focus:border-blue outline-none"
|
|
x-model.number="perPage"
|
|
@change="setPerPage(perPage)"
|
|
>
|
|
<option value="1">1</option>
|
|
<option value="10">10</option>
|
|
<option value="25">25</option>
|
|
<option value="50">50</option>
|
|
<option value="100">100</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
<!-- Pagination buttons -->
|
|
if total > 0 && opts.TotalPages(total) > 1 {
|
|
<div class="flex flex-wrap justify-center items-center gap-2">
|
|
<!-- First button -->
|
|
<button
|
|
type="button"
|
|
@click="goToPage(1)"
|
|
class="px-3 py-2 rounded-lg border transition border-surface1 text-text bg-mantle"
|
|
x-bind:disabled={ fmt.Sprintf("%t", !opts.HasPrevPage()) }
|
|
x-bind:class={ fmt.Sprintf("%t", !opts.HasPrevPage()) +
|
|
" ? 'text-subtext0 cursor-not-allowed opacity-50' : 'hover:bg-surface0 hover:border-blue cursor-pointer'" }
|
|
>
|
|
<span class="hidden sm:inline">First</span>
|
|
<span class="sm:hidden"><<</span>
|
|
</button>
|
|
<!-- Previous button -->
|
|
<button
|
|
type="button"
|
|
@click={ fmt.Sprintf("goToPage(%d)", opts.Page-1) }
|
|
class="px-3 py-2 rounded-lg border transition border-surface1 text-text bg-mantle"
|
|
x-bind:disabled={ fmt.Sprintf("%t", !opts.HasPrevPage()) }
|
|
x-bind:class={ fmt.Sprintf("%t", !opts.HasPrevPage()) +
|
|
" ? 'text-subtext0 cursor-not-allowed opacity-50' : 'hover:bg-surface0 hover:border-blue cursor-pointer'" }
|
|
>
|
|
<span class="hidden sm:inline">Previous</span>
|
|
<span class="sm:hidden"><</span>
|
|
</button>
|
|
<!-- Page numbers -->
|
|
for _, pageNum := range opts.GetPageRange(total, 7) {
|
|
<button
|
|
type="button"
|
|
@click={ fmt.Sprintf("goToPage(%d)", pageNum) }
|
|
class={ "px-3 py-2 rounded-lg border transition",
|
|
templ.KV("bg-blue border-blue text-mantle font-bold", pageNum == opts.Page),
|
|
templ.KV("bg-mantle border-surface1 text-text hover:bg-surface0 hover:border-blue cursor-pointer", pageNum != opts.Page) }
|
|
>
|
|
{ fmt.Sprintf("%d", pageNum) }
|
|
</button>
|
|
}
|
|
<!-- Next button -->
|
|
<button
|
|
type="button"
|
|
@click={ fmt.Sprintf("goToPage(%d)", opts.Page+1) }
|
|
class="px-3 py-2 rounded-lg border transition border-surface1 text-text bg-mantle"
|
|
x-bind:disabled={ fmt.Sprintf("%t", !opts.HasNextPage(total)) }
|
|
x-bind:class={ fmt.Sprintf("%t", !opts.HasNextPage(total)) +
|
|
" ? 'text-subtext0 cursor-not-allowed opacity-50' : 'hover:bg-surface0 hover:border-blue cursor-pointer'" }
|
|
>
|
|
<span class="hidden sm:inline">Next</span>
|
|
<span class="sm:hidden">></span>
|
|
</button>
|
|
<!-- Last button -->
|
|
<button
|
|
type="button"
|
|
@click={ fmt.Sprintf("goToPage(%d)", opts.TotalPages(total)) }
|
|
class="px-3 py-2 rounded-lg border transition border-surface1 text-text bg-mantle"
|
|
x-bind:disabled={ fmt.Sprintf("%t", !opts.HasNextPage(total)) }
|
|
x-bind:class={ fmt.Sprintf("%t", !opts.HasNextPage(total)) +
|
|
" ? 'text-subtext0 cursor-not-allowed opacity-50' : 'hover:bg-surface0 hover:border-blue cursor-pointer'" }
|
|
>
|
|
<span class="hidden sm:inline">Last</span>
|
|
<span class="sm:hidden">>></span>
|
|
</button>
|
|
</div>
|
|
}
|
|
</div>
|
|
}
|