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 page = parseInt(event.url.searchParams.get('page') ?? '1')
let perPage = parseInt(
event.url.searchParams.get('perPage') ?? '10',
event.url.searchParams.get('perPage') ?? '12',
)
if (isNaN(page)) {
@ -83,6 +83,21 @@ export const load = (async (event) => {
.offset(perPage * (page - 1))
.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') {
shorteners.orderBy(desc(shortener.createdAt))
} else if (sortBy === 'oldest') {
@ -108,5 +123,6 @@ export const load = (async (event) => {
perPage,
search,
sortBy,
pagination,
}
}) satisfies PageServerLoad

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

Loading…
Cancel
Save