added sorting to links page

pull/3/head
TZGyn 2 years ago
parent 5878a18bfa
commit 5b3336142c
Signed by: TZGyn
GPG Key ID: 122EAF77AE81FD4A

@ -7,6 +7,7 @@
type $$Events = SelectPrimitive.TriggerEvents
let className: $$Props['class'] = undefined
export let customIcon: any
export { className as class }
</script>
@ -21,6 +22,12 @@
on:keydown>
<slot {builder} />
<div>
<ChevronDown class="h-4 w-4 opacity-50" />
{#if customIcon}
<svelte:component
this={customIcon}
class="h-4 w-4 opacity-50" />
{:else}
<ChevronDown class="h-4 w-4 opacity-50" />
{/if}
</div>
</SelectPrimitive.Trigger>

@ -1,12 +1,22 @@
import { db } from '$lib/db'
import { sql } from 'drizzle-orm'
import {
and,
asc,
desc,
eq,
getTableColumns,
ilike,
sql,
} from 'drizzle-orm'
import type { PageServerLoad } from './$types'
import { project, shortener, visitor } from '$lib/db/schema'
export const load = (async (event) => {
const user = event.locals.userObject
const project_uuid = event.url.searchParams.get('project')
const search = event.url.searchParams.get('search')
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',
@ -20,6 +30,14 @@ export const load = (async (event) => {
perPage = 10
}
if (
sortBy !== 'latest' &&
sortBy !== 'oldest' &&
sortBy !== 'most_visited'
) {
sortBy = 'latest'
}
let project_id: number | undefined
let selected_project: { value: null | string; label: string } = {
value: null,
@ -41,16 +59,16 @@ export const load = (async (event) => {
}
}
const shorteners = db.query.shortener.findMany({
extras: {
const shortenerColumns = getTableColumns(shortener)
const shorteners = db
.select({
...shortenerColumns,
projectName: project.name,
fullcount: sql<number>`count(*) over()`.as('fullcount'),
},
with: {
visitor: true,
project: true,
},
orderBy: (shortener, { desc }) => [desc(shortener.createdAt)],
where: (shortener, { eq, and, ilike }) =>
visitorCount: sql<number>`count(${visitor.id})`,
})
.from(shortener)
.where(
and(
eq(shortener.userId, user.id),
project_id ? eq(shortener.projectId, project_id) : undefined,
@ -58,9 +76,20 @@ export const load = (async (event) => {
? ilike(shortener.link, `%${decodeURI(search)}%`)
: undefined,
),
offset: perPage * (page - 1),
limit: perPage,
})
)
.leftJoin(visitor, eq(shortener.id, visitor.shortenerId))
.leftJoin(project, eq(shortener.projectId, project.id))
.groupBy(shortener.id, project.id)
.offset(perPage * (page - 1))
.limit(perPage)
if (sortBy === 'latest') {
shorteners.orderBy(desc(shortener.createdAt))
} else if (sortBy === 'oldest') {
shorteners.orderBy(asc(shortener.createdAt))
} else if (sortBy === 'most_visited') {
shorteners.orderBy(sql`count(${visitor.id}) desc`)
}
const projects = db.query.project.findMany({
where: (project, { eq }) => eq(project.userId, user.id),
@ -78,5 +107,6 @@ export const load = (async (event) => {
page,
perPage,
search,
sortBy,
}
}) satisfies PageServerLoad

@ -24,6 +24,7 @@
QrCode,
Check,
ChevronsUpDown,
SortDescIcon,
} from 'lucide-svelte'
import Qr from '$lib/components/QR.svelte'
@ -85,14 +86,17 @@
$: 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)
$: browser &&
updateUrl(selectedProjectUUID, page, perPage, search, sortBy)
const updateUrl = (
selectedProjectUUID: string | null,
page: number,
perPage: any,
search: string | null,
sortBy: any,
) => {
let query = [`page=${page}`, `perPage=${perPage.value}`]
if (selectedProjectUUID) {
@ -101,6 +105,9 @@
if (search) {
query.push(`search=${encodeURI(search)}`)
}
if (sortBy) {
query.push(`sortBy=${sortBy.value}`)
}
goto(`/links?${query.join('&')}`)
}
@ -162,6 +169,21 @@
</Command.Root>
</Popover.Content>
</Popover.Root>
<Select.Root bind:selected={sortBy}>
<Select.Trigger class="w-[180px]" customIcon={SortDescIcon}>
<Select.Value placeholder="Sort By" />
</Select.Trigger>
<Select.Content>
<Select.Group>
<Select.Label>Sort By</Select.Label>
{#each ['latest', 'oldest', 'most_visited'] as sortBy}
<Select.Item value={sortBy} label={sortBy}
>{sortBy}</Select.Item>
{/each}
</Select.Group>
</Select.Content>
<Select.Input name="favoriteFruit" />
</Select.Root>
<Input
type="text"
placeholder="search"
@ -212,9 +234,9 @@
<ExternalLink size={16} />
</div>
<div class="flex gap-4">
{#if shortener.project}
{#if shortener.projectName}
<Badge variant="secondary"
>{shortener.project.name}</Badge>
>{shortener.projectName}</Badge>
{/if}
<Badge variant="outline" class="flex gap-2">
{#if shortener.active}
@ -241,7 +263,7 @@
class="flex h-8 items-center justify-center gap-1 rounded bg-secondary text-sm">
<BarChart size={20} />
<div>
{shortener.visitor.length} visits
{shortener.visitorCount} visits
</div>
</Button>
<Button

Loading…
Cancel
Save