update links page to use <a> tags to update search params

pull/3/head
TZGyn 2 years ago
parent 1675b9e12e
commit ab7c632e0e
Signed by: TZGyn
GPG Key ID: 122EAF77AE81FD4A

@ -19,7 +19,7 @@ export const load = (async (event) => {
let sortBy = event.url.searchParams.get('sortBy') let sortBy = event.url.searchParams.get('sortBy')
let page = parseInt(event.url.searchParams.get('page') ?? '1') let page = parseInt(event.url.searchParams.get('page') ?? '1')
let perPage = parseInt( let perPage = parseInt(
event.url.searchParams.get('perPage') ?? '10', event.url.searchParams.get('perPage') ?? '12',
) )
if (isNaN(page)) { if (isNaN(page)) {
@ -83,6 +83,21 @@ export const load = (async (event) => {
.offset(perPage * (page - 1)) .offset(perPage * (page - 1))
.limit(perPage) .limit(perPage)
const pagination = db
.select({
total: sql<number>`count(*)`.as('total'),
})
.from(shortener)
.where(
and(
eq(shortener.userId, user.id),
project_id ? eq(shortener.projectId, project_id) : undefined,
search
? ilike(shortener.link, `%${decodeURI(search)}%`)
: undefined,
),
)
if (sortBy === 'latest') { if (sortBy === 'latest') {
shorteners.orderBy(desc(shortener.createdAt)) shorteners.orderBy(desc(shortener.createdAt))
} else if (sortBy === 'oldest') { } else if (sortBy === 'oldest') {
@ -108,5 +123,6 @@ export const load = (async (event) => {
perPage, perPage,
search, search,
sortBy, sortBy,
pagination,
} }
}) satisfies PageServerLoad }) satisfies PageServerLoad

@ -80,36 +80,25 @@
qrDialogOpen = true qrDialogOpen = true
} }
let page: number = data.page
let perPage: any = { label: data.perPage, value: data.perPage }
let selectedProjectUUID: string | null
$: selectedProjectUUID = data.selected_project.value
let search: string | null = data.search let search: string | null = data.search
let searchUpdateTimeout: any let searchUpdateTimeout: any
let sortBy: any = { label: data.sortBy, value: data.sortBy }
$: browser && $: browser &&
updateUrl(selectedProjectUUID, page, perPage, search, sortBy) goto(updateSearchParam([{ name: 'search', value: search }]))
const updateUrl = ( const updateSearchParam = (
selectedProjectUUID: string | null, params: { name: string; value: any }[],
page: number,
perPage: any,
search: string | null,
sortBy: any,
) => { ) => {
let query = [`page=${page}`, `perPage=${perPage.value}`] const urlParams = new URLSearchParams(window.location.search)
if (selectedProjectUUID) { params.map(({ name, value }) => {
query.push(`project=${selectedProjectUUID}`) if (value) {
} urlParams.set(name, value)
if (search) { } else {
query.push(`search=${encodeURI(search)}`) urlParams.delete(name)
} }
if (sortBy) { })
query.push(`sortBy=${sortBy.value}`) const searchParams = urlParams.toString()
} return '/links?' + searchParams
goto(`/links?${query.join('&')}`)
} }
</script> </script>
@ -135,41 +124,61 @@
<Command.Input placeholder="Search project..." /> <Command.Input placeholder="Search project..." />
<Command.Empty>No project found.</Command.Empty> <Command.Empty>No project found.</Command.Empty>
<Command.Group> <Command.Group>
<Command.Item <a
onSelect={() => { href={updateSearchParam([
selectedProjectUUID = null {
page = 1 name: 'project',
open = false value: undefined,
}}> },
<Check {
class={cn( name: 'page',
'mr-2 h-4 w-4', value: 1,
data.selected_project.value !== null && },
'text-transparent', ])}>
)} />
All
</Command.Item>
{#each data.projects as project}
<Command.Item <Command.Item
onSelect={() => { onSelect={() => {
selectedProjectUUID = project.uuid
page = 1
open = false open = false
}}> }}>
<Check <Check
class={cn( class={cn(
'mr-2 h-4 w-4', 'mr-2 h-4 w-4',
data.selected_project.value !== project.uuid && data.selected_project.value !== null &&
'text-transparent', 'text-transparent',
)} /> )} />
{project.name} All
</Command.Item> </Command.Item>
</a>
{#each data.projects as project}
<a
href={updateSearchParam([
{
name: 'project',
value: project.uuid,
},
{
name: 'page',
value: 1,
},
])}>
<Command.Item
onSelect={() => {
open = false
}}>
<Check
class={cn(
'mr-2 h-4 w-4',
data.selected_project.value !== project.uuid &&
'text-transparent',
)} />
{project.name}
</Command.Item>
</a>
{/each} {/each}
</Command.Group> </Command.Group>
</Command.Root> </Command.Root>
</Popover.Content> </Popover.Content>
</Popover.Root> </Popover.Root>
<Select.Root bind:selected={sortBy}> <Select.Root selected={{ label: data.sortBy, value: data.sortBy }}>
<Select.Trigger class="w-[180px]" customIcon={SortDescIcon}> <Select.Trigger class="w-[180px]" customIcon={SortDescIcon}>
<Select.Value placeholder="Sort By" /> <Select.Value placeholder="Sort By" />
</Select.Trigger> </Select.Trigger>
@ -177,8 +186,15 @@
<Select.Group> <Select.Group>
<Select.Label>Sort By</Select.Label> <Select.Label>Sort By</Select.Label>
{#each ['latest', 'oldest', 'most_visited'] as sortBy} {#each ['latest', 'oldest', 'most_visited'] as sortBy}
<Select.Item value={sortBy} label={sortBy} <a
>{sortBy}</Select.Item> href={updateSearchParam([
{ name: 'sortBy', value: sortBy },
{ name: 'page', value: 1 },
])}>
<Select.Item value={sortBy} label={sortBy}>
{sortBy}
</Select.Item>
</a>
{/each} {/each}
</Select.Group> </Select.Group>
</Select.Content> </Select.Content>
@ -304,40 +320,91 @@
{/each} {/each}
</div> </div>
</ScrollArea> </ScrollArea>
<div class="flex items-center justify-between border-t p-4"> {:else}
<Select.Root bind:selected={perPage}> <div class="flex w-full flex-grow items-center justify-center">
<Select.Trigger class="w-[180px]"> <div class="flex flex-col items-center gap-12">
<Select.Value placeholder="Page Size" /> <div class="flex flex-col items-center gap-4">
</Select.Trigger> <div class="text-4xl font-bold">No Shortener Found</div>
<Select.Content> </div>
<Select.Group> <Button
<Select.Label>Page Size</Select.Label> on:click={() => {
{#each [10, 20, 50, 100] as pageSize} dialogOpen = true
}}
class="w-fit">Add Shortener</Button>
</div>
</div>
{/if}
{/await}
{#await data.pagination then pagination}
<div class="flex items-center justify-between border-t p-4">
<Select.Root
selected={{ label: data.perPage, value: data.perPage }}>
<Select.Trigger class="w-[180px]">
<Select.Value placeholder="Page Size" />
</Select.Trigger>
<Select.Content>
<Select.Group>
<Select.Label>Page Size</Select.Label>
{#each [12, 24, 48, 96] as pageSize}
<a
href={updateSearchParam([
{
name: 'perPage',
value: pageSize,
},
{
name: 'page',
value: 1,
},
])}>
<Select.Item <Select.Item
value={pageSize} value={pageSize}
label={pageSize.toString()}>{pageSize}</Select.Item> label={pageSize.toString()}>{pageSize}</Select.Item>
{/each} </a>
</Select.Group> {/each}
</Select.Content> </Select.Group>
<Select.Input name="favoriteFruit" /> </Select.Content>
</Select.Root> <Select.Input name="favoriteFruit" />
<Pagination.Root </Select.Root>
class="items-end " <Pagination.Root
count={shorteners[0].fullcount} class="items-end "
bind:page count={pagination[0].total}
perPage={perPage.value} page={data.page}
let:pages perPage={data.perPage}
let:currentPage> let:pages
<Pagination.Content> let:currentPage>
<Pagination.Content>
{#if data.page <= 1}
<Pagination.Item> <Pagination.Item>
<Pagination.PrevButton /> <Pagination.PrevButton />
</Pagination.Item> </Pagination.Item>
{#each pages as page (page.key)} {:else}
{#if page.type === 'ellipsis'} <a
<Pagination.Item> href={updateSearchParam([
<Pagination.Ellipsis /> {
</Pagination.Item> name: 'page',
{:else} value: data.page - 1,
},
])}>
<Pagination.Item>
<Pagination.PrevButton />
</Pagination.Item>
</a>
{/if}
{#each pages as page (page.key)}
{#if page.type === 'ellipsis'}
<Pagination.Item>
<Pagination.Ellipsis />
</Pagination.Item>
{:else}
<a
href={updateSearchParam([
{
name: 'page',
value: page.value,
},
])}>
<Pagination.Item isVisible={currentPage == page.value}> <Pagination.Item isVisible={currentPage == page.value}>
<Pagination.Link <Pagination.Link
{page} {page}
@ -345,28 +412,29 @@
{page.value} {page.value}
</Pagination.Link> </Pagination.Link>
</Pagination.Item> </Pagination.Item>
{/if} </a>
{/each} {/if}
{/each}
{#if data.page >= pagination[0].total / data.perPage}
<Pagination.Item> <Pagination.Item>
<Pagination.NextButton /> <Pagination.NextButton />
</Pagination.Item> </Pagination.Item>
</Pagination.Content> {:else}
</Pagination.Root> <a
</div> href={updateSearchParam([
{:else} {
<div class="flex h-full w-full items-center justify-center"> name: 'page',
<div class="flex flex-col items-center gap-12"> value: data.page + 1,
<div class="flex flex-col items-center gap-4"> },
<div class="text-4xl font-bold">No Shortener Found</div> ])}>
</div> <Pagination.Item>
<Button <Pagination.NextButton />
on:click={() => { </Pagination.Item>
dialogOpen = true </a>
}} {/if}
class="w-fit">Add Shortener</Button> </Pagination.Content>
</div> </Pagination.Root>
</div> </div>
{/if}
{/await} {/await}
<EditShortenerDialog <EditShortenerDialog

Loading…
Cancel
Save