feat(frontend): add search to flags page, add pagination to profile flags page
This commit is contained in:
parent
35c5b520db
commit
1adb26e8b8
3 changed files with 85 additions and 24 deletions
|
@ -5,8 +5,11 @@
|
|||
currentPage: number;
|
||||
pageCount: number;
|
||||
center?: boolean;
|
||||
listAllPages?: boolean;
|
||||
};
|
||||
let { currentPage = $bindable(), pageCount, center }: Props = $props();
|
||||
let { currentPage = $bindable(), pageCount, center, listAllPages }: Props = $props();
|
||||
|
||||
let allPages = $derived(listAllPages === undefined || listAllPages);
|
||||
|
||||
let prevPage = $derived(currentPage > 0 ? currentPage - 1 : 0);
|
||||
let nextPage = $derived(currentPage < pageCount - 1 ? currentPage + 1 : pageCount - 1);
|
||||
|
@ -21,11 +24,27 @@
|
|||
<PaginationItem>
|
||||
<PaginationLink previous onclick={() => (currentPage = prevPage)} />
|
||||
</PaginationItem>
|
||||
{#if allPages}
|
||||
{#each new Array(pageCount) as _, page}
|
||||
<PaginationItem active={page === currentPage}>
|
||||
<PaginationLink onclick={() => (currentPage = page)}>{page + 1}</PaginationLink>
|
||||
</PaginationItem>
|
||||
{/each}
|
||||
{:else}
|
||||
{#if currentPage !== 0}
|
||||
<PaginationItem onclick={() => (currentPage = prevPage)}>
|
||||
<PaginationLink>{currentPage}</PaginationLink>
|
||||
</PaginationItem>
|
||||
{/if}
|
||||
<PaginationItem active>
|
||||
<PaginationLink>{currentPage + 1}</PaginationLink>
|
||||
</PaginationItem>
|
||||
{#if currentPage !== pageCount - 1}
|
||||
<PaginationItem onclick={() => (currentPage = nextPage)}>
|
||||
<PaginationLink>{currentPage + 2}</PaginationLink>
|
||||
</PaginationItem>
|
||||
{/if}
|
||||
{/if}
|
||||
<PaginationItem>
|
||||
<PaginationLink next onclick={() => (currentPage = nextPage)} />
|
||||
</PaginationItem>
|
||||
|
|
|
@ -4,23 +4,35 @@
|
|||
import Search from "svelte-bootstrap-icons/lib/Search.svelte";
|
||||
import FlagButton from "./FlagButton.svelte";
|
||||
import { t } from "$lib/i18n";
|
||||
import paginate from "$lib/paginate";
|
||||
import ClientPaginator from "$components/ClientPaginator.svelte";
|
||||
|
||||
type Props = { flags: PrideFlag[]; select(flag: PrideFlag): void };
|
||||
let { flags, select }: Props = $props();
|
||||
|
||||
const FLAGS_PER_PAGE = 5;
|
||||
let query = $state("");
|
||||
let filteredFlags = $derived(search(query));
|
||||
|
||||
let arr: PrideFlag[] = $state([]);
|
||||
let currentPage = $state(0);
|
||||
let pageCount = $state(0);
|
||||
|
||||
$effect(() => {
|
||||
const pages = paginate(filteredFlags, currentPage, FLAGS_PER_PAGE);
|
||||
arr = pages.data;
|
||||
pageCount = pages.pageCount;
|
||||
});
|
||||
|
||||
function search(q: string) {
|
||||
if (!q) return flags.slice(0, 20);
|
||||
return flags.filter((f) => f.name.toLowerCase().indexOf(q.toLowerCase()) !== -1).slice(0, 20);
|
||||
return flags.filter((f) => f.name.toLowerCase().indexOf(q.toLowerCase()) !== -1);
|
||||
}
|
||||
</script>
|
||||
|
||||
<input class="form-control" placeholder={$t("editor.flag-search-placeholder")} bind:value={query} />
|
||||
|
||||
<div class="mt-3">
|
||||
{#each filteredFlags as flag (flag.id)}
|
||||
{#each arr as flag (flag.id)}
|
||||
<FlagButton {flag} onclick={() => select(flag)} padding />
|
||||
{:else}
|
||||
<div class="text-secondary text-center">
|
||||
|
@ -36,6 +48,7 @@
|
|||
</p>
|
||||
</div>
|
||||
{/each}
|
||||
<ClientPaginator bind:currentPage {pageCount} listAllPages={false} />
|
||||
{#if flags.length > 0}
|
||||
<p class="text-secondary mt-2">
|
||||
<InfoCircleFill aria-hidden />
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
import ApiError from "$api/error";
|
||||
import log from "$lib/log";
|
||||
import FormStatusMarker from "$components/editor/FormStatusMarker.svelte";
|
||||
import Search from "svelte-bootstrap-icons/lib/Search.svelte";
|
||||
|
||||
type Props = { data: PageData; form: ActionData };
|
||||
let { data, form }: Props = $props();
|
||||
|
@ -26,13 +27,17 @@
|
|||
const FLAGS_PER_PAGE = 50;
|
||||
|
||||
$effect(() => {
|
||||
const pages = paginate(flags, currentPage, FLAGS_PER_PAGE);
|
||||
const filteredFlags = search
|
||||
? flags.filter((f) => f.name.toLocaleLowerCase().indexOf(search.toLocaleLowerCase()) !== -1)
|
||||
: flags;
|
||||
const pages = paginate(filteredFlags, currentPage, FLAGS_PER_PAGE);
|
||||
arr = pages.data;
|
||||
pageCount = pages.pageCount;
|
||||
});
|
||||
|
||||
let lastEditedFlag: string | null = $state(null);
|
||||
let ok: { ok: boolean; error: RawApiError | null } | null = $state(null);
|
||||
let search: string = $state("");
|
||||
|
||||
const update = async (
|
||||
id: string,
|
||||
|
@ -109,9 +114,32 @@
|
|||
})}
|
||||
</h4>
|
||||
|
||||
<div class="mb-3">
|
||||
<input
|
||||
class="form-control"
|
||||
type="text"
|
||||
bind:value={search}
|
||||
placeholder={$t("editor.flag-search-placeholder")}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<ClientPaginator center bind:currentPage {pageCount} />
|
||||
|
||||
<Accordion class="mb-3">
|
||||
{#if arr.length === 0}
|
||||
<div class="text-secondary text-center">
|
||||
<p>
|
||||
<Search class="no-flags-icon" height={64} width={64} aria-hidden />
|
||||
</p>
|
||||
<p>
|
||||
{#if search}
|
||||
{$t("editor.flag-search-no-flags")}
|
||||
{:else}
|
||||
{$t("editor.flag-search-no-account-flags")}
|
||||
{/if}
|
||||
</p>
|
||||
</div>
|
||||
{:else}
|
||||
<Accordion class="mb-3">
|
||||
{#each arr as flag (flag.id)}
|
||||
<AccordionItem>
|
||||
<span slot="header">
|
||||
|
@ -123,6 +151,7 @@
|
|||
<FlagEditor {flag} {update} {deleteFlag} />
|
||||
</AccordionItem>
|
||||
{/each}
|
||||
</Accordion>
|
||||
</Accordion>
|
||||
{/if}
|
||||
|
||||
<ClientPaginator center bind:currentPage {pageCount} />
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue