add favicon to shortener card + update shortener card ui

main
TZGyn 1 year ago
parent 3592673cef
commit 57cebc7330
Signed by: TZGyn
GPG Key ID: 122EAF77AE81FD4A

@ -4,8 +4,10 @@
import * as Tooltip from '$lib/components/ui/tooltip' import * as Tooltip from '$lib/components/ui/tooltip'
import * as Dialog from '$lib/components/ui/dialog' import * as Dialog from '$lib/components/ui/dialog'
import * as DropdownMenu from '$lib/components/ui/dropdown-menu' import * as DropdownMenu from '$lib/components/ui/dropdown-menu'
import * as Avatar from '$lib/components/ui/avatar'
import { Badge } from '$lib/components/ui/badge' import { Badge } from '$lib/components/ui/badge'
import { ScrollArea } from '$lib/components/ui/scroll-area' import { ScrollArea } from '$lib/components/ui/scroll-area'
import { Separator } from '$lib/components/ui/separator'
import type { Shortener } from '$lib/db/types' import type { Shortener } from '$lib/db/types'
import { import {
BarChart, BarChart,
@ -43,25 +45,10 @@
return '' return ''
} }
const showEditModal = async (e: MouseEvent) => {
if (innerWidth < 640) return
const { href } = e.currentTarget as HTMLAnchorElement
const result = await preloadData(href)
if (result.type === 'loaded' && result.status === 200) {
pushState(href, { editLink: result.data })
} else {
// something bad happened! try navigating
goto(href)
}
}
let editProjectLinkOpen = false let editProjectLinkOpen = false
let editData: typeof $page.state.editLink let editData: typeof $page.state.editLink
const showEditModalNew = async (code: string) => { const showEditModal = async (code: string) => {
const href = `/links/${code}/edit` const href = `/links/${code}/edit`
const result = await preloadData(href) const result = await preloadData(href)
@ -91,45 +78,27 @@
goto(href) goto(href)
} }
} }
const hostDomain = 'https://' + shortener.link.split('/')[2]
</script> </script>
<Card.Root class="w-full max-w-[500px]"> <Card.Root>
<Card.Header> <Card.Header>
<Card.Title class="flex items-center justify-between gap-2"> <Card.Title class="flex gap-4 justify-between items-center">
<div class="flex items-center gap-2"> <Avatar.Root>
<a <Avatar.Image
href={'https://' + shortener_url + '/' + shortener.code} src={hostDomain + '/favicon.ico'}
target="_blank" alt="favicon" />
class="hover:underline"> <Avatar.Fallback class="bg-opacity-0">
{shortener_url + '/' + shortener.code} <img src="/favicon.png" alt="favicon" />
</a> </Avatar.Fallback>
<ExternalLink size={16} /> </Avatar.Root>
</div>
<div class="flex gap-4"> <div class="flex flex-col flex-grow gap-2 items-start">
{#if shortener.projectName}
<Badge variant="secondary">{shortener.projectName}</Badge>
{/if}
<Badge variant="outline" class="flex gap-2">
{#if shortener.active}
<span
class="relative inline-flex h-2 w-2 rounded-full bg-green-400"
></span>
Active
{:else}
<span
class="relative inline-flex h-2 w-2 rounded-full bg-gray-600"
></span>
Inactive
{/if}
</Badge>
</div>
</Card.Title>
<Card.Description>
<div class="flex items-center gap-2">
<Tooltip.Root> <Tooltip.Root>
<Tooltip.Trigger> <Tooltip.Trigger>
<div <div
class="max-w-[200px] overflow-hidden overflow-ellipsis whitespace-nowrap"> class="whitespace-nowrap max-w-[250px] overflow-x-clip overflow-ellipsis">
{shortener.link} {shortener.link}
</div> </div>
</Tooltip.Trigger> </Tooltip.Trigger>
@ -137,6 +106,65 @@
<p>{shortener.link}</p> <p>{shortener.link}</p>
</Tooltip.Content> </Tooltip.Content>
</Tooltip.Root> </Tooltip.Root>
<div
class="flex gap-2 items-center text-sm text-muted-foreground">
<a
href={'https://' + shortener_url + '/' + shortener.code}
target="_blank"
class="hover:underline">
{shortener_url + '/' + shortener.code}
</a>
<ExternalLink size={16} />
</div>
</div>
<DropdownMenu.Root>
<DropdownMenu.Trigger>
<MoreVertical />
</DropdownMenu.Trigger>
<DropdownMenu.Content>
<DropdownMenu.Group>
<a
href={`/links/${shortener.code}/edit`}
on:click|preventDefault={() =>
showEditModal(shortener.code)}>
<DropdownMenu.Item class="flex gap-2 items-center">
<EditIcon size={16} />Edit
</DropdownMenu.Item>
</a>
<DropdownMenu.Item
on:click={() => openDeleteDialog(shortener.code)}
class="flex gap-2 items-center text-destructive data-[highlighted]:bg-destructive">
<TrashIcon size={16} />
Delete
</DropdownMenu.Item>
</DropdownMenu.Group>
</DropdownMenu.Content>
</DropdownMenu.Root>
</Card.Title>
</Card.Header>
<Card.Content>
<div class="flex justify-between items-center">
<div class="flex gap-2">
<Button
href={`/links/${shortener.code}`}
class="flex gap-1 justify-center items-center h-8 text-sm rounded bg-secondary">
<BarChart size={20} />
<div>
{shortener.visitorCount} visits
</div>
</Button>
<a
class={cn(
buttonVariants({ variant: 'default' }),
'flex h-8 items-center justify-center gap-1 rounded bg-secondary text-sm',
)}
href={`${getUrl()}/links/${shortener.code}/qr`}
on:click|preventDefault={showQRModal}>
<QrCode size={20} />
</a>
<Separator orientation="vertical" />
{#if shortener.ios} {#if shortener.ios}
<Tooltip.Root> <Tooltip.Root>
<Tooltip.Trigger> <Tooltip.Trigger>
@ -159,52 +187,24 @@
</Tooltip.Root> </Tooltip.Root>
{/if} {/if}
</div> </div>
</Card.Description> <div class="flex gap-4">
</Card.Header> {#if shortener.projectName}
<Card.Content> <Badge variant="secondary">{shortener.projectName}</Badge>
<div class="flex items-center justify-between"> {/if}
<div class="flex gap-2"> <Badge variant="outline" class="flex gap-2">
<Button {#if shortener.active}
href={`/links/${shortener.code}`} <span
class="bg-secondary flex h-8 items-center justify-center gap-1 rounded text-sm"> class="inline-flex relative w-2 h-2 bg-green-400 rounded-full"
<BarChart size={20} /> ></span>
<div> Active
{shortener.visitorCount} visits {:else}
</div> <span
</Button> class="inline-flex relative w-2 h-2 bg-gray-600 rounded-full"
<a ></span>
class={cn( Inactive
buttonVariants({ variant: 'default' }), {/if}
'bg-secondary flex h-8 items-center justify-center gap-1 rounded text-sm', </Badge>
)}
href={`${getUrl()}/links/${shortener.code}/qr`}
on:click|preventDefault={showQRModal}>
<QrCode size={20} />
</a>
</div> </div>
<DropdownMenu.Root>
<DropdownMenu.Trigger>
<MoreVertical />
</DropdownMenu.Trigger>
<DropdownMenu.Content>
<DropdownMenu.Group>
<a
href={`/links/${shortener.code}/edit`}
on:click|preventDefault={() =>
showEditModalNew(shortener.code)}>
<DropdownMenu.Item class="flex items-center gap-2">
<EditIcon size={16} />Edit
</DropdownMenu.Item>
</a>
<DropdownMenu.Item
on:click={() => openDeleteDialog(shortener.code)}
class="text-destructive data-[highlighted]:bg-destructive flex items-center gap-2">
<TrashIcon size={16} />
Delete
</DropdownMenu.Item>
</DropdownMenu.Group>
</DropdownMenu.Content>
</DropdownMenu.Root>
</div> </div>
</Card.Content> </Card.Content>
</Card.Root> </Card.Root>

@ -80,7 +80,7 @@
</script> </script>
<div <div
class="flex flex-wrap-reverse items-center justify-start gap-4 p-4"> class="flex flex-wrap-reverse gap-4 justify-start items-center p-4">
<Drawer.Root> <Drawer.Root>
<Drawer.Trigger class="md:hidden"> <Drawer.Trigger class="md:hidden">
<Button size="icon"><SortAscIcon /></Button> <Button size="icon"><SortAscIcon /></Button>
@ -124,10 +124,10 @@
class="justify-between"> class="justify-between">
{selectedProject} {selectedProject}
<ChevronsUpDown <ChevronsUpDown
class="ml-2 h-4 w-4 shrink-0 opacity-50" /> class="ml-2 w-4 h-4 opacity-50 shrink-0" />
</Button> </Button>
</Popover.Trigger> </Popover.Trigger>
<Popover.Content class="w-[200px] p-0"> <Popover.Content class="p-0 w-[200px]">
<Command.Root> <Command.Root>
<Command.Input placeholder="Search project..." /> <Command.Input placeholder="Search project..." />
<Command.Empty>No project found.</Command.Empty> <Command.Empty>No project found.</Command.Empty>
@ -186,7 +186,7 @@
</Command.Root> </Command.Root>
</Popover.Content> </Popover.Content>
</Popover.Root> </Popover.Root>
<div class="flex items-center gap-4"> <div class="flex gap-4 items-center">
<Input <Input
type="text" type="text"
placeholder="search" placeholder="search"
@ -208,7 +208,7 @@
</Drawer.Footer> </Drawer.Footer>
</Drawer.Content> </Drawer.Content>
</Drawer.Root> </Drawer.Root>
<div class="hidden items-center gap-4 md:flex"> <div class="hidden gap-4 items-center md:flex">
<Popover.Root bind:open> <Popover.Root bind:open>
<Popover.Trigger asChild let:builder> <Popover.Trigger asChild let:builder>
<Button <Button
@ -216,12 +216,12 @@
variant="outline" variant="outline"
role="combobox" role="combobox"
aria-expanded={open} aria-expanded={open}
class="w-[200px] justify-between"> class="justify-between w-[200px]">
{selectedProject} {selectedProject}
<ChevronsUpDown class="ml-2 h-4 w-4 shrink-0 opacity-50" /> <ChevronsUpDown class="ml-2 w-4 h-4 opacity-50 shrink-0" />
</Button> </Button>
</Popover.Trigger> </Popover.Trigger>
<Popover.Content class="w-[200px] p-0"> <Popover.Content class="p-0 w-[200px]">
<Command.Root> <Command.Root>
<Command.Input placeholder="Search project..." /> <Command.Input placeholder="Search project..." />
<Command.Empty>No project found.</Command.Empty> <Command.Empty>No project found.</Command.Empty>
@ -304,7 +304,7 @@
<Select.Input name="favoriteFruit" /> <Select.Input name="favoriteFruit" />
</Select.Root> </Select.Root>
</div> </div>
<div class="hidden items-center gap-4 sm:flex"> <div class="hidden gap-4 items-center sm:flex">
<Input <Input
type="text" type="text"
placeholder="search" placeholder="search"
@ -326,13 +326,14 @@
{#await data.shorteners} {#await data.shorteners}
<div class="flex flex-wrap gap-4 p-4"> <div class="flex flex-wrap gap-4 p-4">
{#each [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] as _} {#each [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] as _}
<Skeleton class="h-[150px] w-[500px] rounded-lg" /> <Skeleton class="rounded-lg h-[150px] w-[500px]" />
{/each} {/each}
</div> </div>
{:then shorteners} {:then shorteners}
{#if shorteners.length > 0} {#if shorteners.length > 0}
<ScrollArea class="flex-grow"> <ScrollArea class="flex-grow">
<div class="flex flex-wrap gap-4 p-4"> <div
class="grid grid-cols-[repeat(auto-fit,_minmax(500px,_1fr))] gap-4 p-4">
{#each shorteners as shortener} {#each shorteners as shortener}
<ShortenerCard <ShortenerCard
{shortener} {shortener}
@ -345,11 +346,11 @@
{:else} {:else}
<div class="flex flex-grow p-4"> <div class="flex flex-grow p-4">
<div <div
class="flex flex-1 items-center justify-center rounded-lg border border-dashed shadow-sm"> class="flex flex-1 justify-center items-center rounded-lg border border-dashed shadow-sm">
<div <div
class="flex w-full flex-grow items-center justify-center"> class="flex flex-grow justify-center items-center w-full">
<div class="flex flex-col items-center gap-8"> <div class="flex flex-col gap-8 items-center">
<div class="flex flex-col items-center gap-2"> <div class="flex flex-col gap-2 items-center">
<div class="text-4xl font-bold">No Shortener Found</div> <div class="text-4xl font-bold">No Shortener Found</div>
<p class="text-muted-foreground">Add a new shortener</p> <p class="text-muted-foreground">Add a new shortener</p>
</div> </div>
@ -366,7 +367,7 @@
{/await} {/await}
{#await data.pagination then pagination} {#await data.pagination then pagination}
<div class="flex items-center justify-between border-t p-4"> <div class="flex justify-between items-center p-4 border-t">
<Select.Root <Select.Root
selected={{ label: data.perPage, value: data.perPage }}> selected={{ label: data.perPage, value: data.perPage }}>
<Select.Trigger class="w-[180px]"> <Select.Trigger class="w-[180px]">

@ -4,8 +4,10 @@
import * as Dialog from '$lib/components/ui/dialog' import * as Dialog from '$lib/components/ui/dialog'
import * as DropdownMenu from '$lib/components/ui/dropdown-menu' import * as DropdownMenu from '$lib/components/ui/dropdown-menu'
import * as Tooltip from '$lib/components/ui/tooltip' import * as Tooltip from '$lib/components/ui/tooltip'
import * as Avatar from '$lib/components/ui/avatar'
import { Badge } from '$lib/components/ui/badge' import { Badge } from '$lib/components/ui/badge'
import { ScrollArea } from '$lib/components/ui/scroll-area' import { ScrollArea } from '$lib/components/ui/scroll-area'
import { Separator } from '$lib/components/ui/separator'
import type { Shortener, Project, Setting } from '$lib/db/types' import type { Shortener, Project, Setting } from '$lib/db/types'
import { import {
BarChart, BarChart,
@ -35,36 +37,10 @@
deleteDialogOpen = true deleteDialogOpen = true
} }
const showEditModal = async (e: MouseEvent) => {
// bail if opening a new tab, or we're on too small a screen
if (innerWidth < 640) return
// // prevent navigation
// e.preventDefault()
//
const { href } = e.currentTarget as HTMLAnchorElement
// run `load` functions (or rather, get the result of the `load` functions
// that are already running because of `data-sveltekit-preload-data`)
// const href = `/projects/${selected_project.uuid}/links/${shortener.code}/edit`
const result = await preloadData(href)
if (result.type === 'loaded' && result.status === 200) {
pushState(href, { editProjectLink: result.data })
} else {
// something bad happened! try navigating
goto(href)
}
}
let editProjectLinkOpen = false let editProjectLinkOpen = false
let editData: typeof $page.state.editProjectLink let editData: typeof $page.state.editProjectLink
const showEditModalNew = async ( const showEditModal = async (projectUuid: string, code: string) => {
projectUuid: string,
code: string,
) => {
const href = `/projects/${projectUuid}/links/${code}/edit` const href = `/projects/${projectUuid}/links/${code}/edit`
const result = await preloadData(href) const result = await preloadData(href)
@ -90,42 +66,26 @@
goto(href) goto(href)
} }
} }
const hostDomain = 'https://' + shortener.link.split('/')[2]
</script> </script>
<Card.Root class="w-full max-w-[500px]"> <Card.Root>
<Card.Header> <Card.Header>
<Card.Title class="flex items-center justify-between gap-2"> <Card.Title class="flex gap-4 justify-between items-center">
<div class="flex items-center gap-2"> <Avatar.Root>
<a <Avatar.Image
href={'https://' + shortener_url + '/' + shortener.code} src={hostDomain + '/favicon.ico'}
target="_blank" alt="favicon" />
class="hover:underline"> <Avatar.Fallback class="bg-opacity-0">
{shortener_url + '/' + shortener.code} <img src="/favicon.png" alt="favicon" />
</a> </Avatar.Fallback>
<ExternalLink size={16} /> </Avatar.Root>
</div> <div class="flex flex-col flex-grow gap-2 items-start">
<div class="flex gap-4">
<Badge variant="outline" class="flex gap-2">
{#if shortener.active}
<span
class="relative inline-flex h-2 w-2 rounded-full bg-green-400"
></span>
Active
{:else}
<span
class="relative inline-flex h-2 w-2 rounded-full bg-gray-600"
></span>
Inactive
{/if}
</Badge>
</div>
</Card.Title>
<Card.Description>
<div class="flex items-center gap-2">
<Tooltip.Root> <Tooltip.Root>
<Tooltip.Trigger> <Tooltip.Trigger>
<div <div
class="max-w-[200px] overflow-hidden overflow-ellipsis whitespace-nowrap"> class="whitespace-nowrap max-w-[250px] overflow-x-clip overflow-ellipsis">
{shortener.link} {shortener.link}
</div> </div>
</Tooltip.Trigger> </Tooltip.Trigger>
@ -133,51 +93,19 @@
<p>{shortener.link}</p> <p>{shortener.link}</p>
</Tooltip.Content> </Tooltip.Content>
</Tooltip.Root> </Tooltip.Root>
{#if shortener.ios}
<Tooltip.Root> <div
<Tooltip.Trigger> class="flex gap-2 items-center text-sm text-muted-foreground">
<Badge variant="outline" class="flex gap-2">iOS</Badge> <a
</Tooltip.Trigger> href={'https://' + shortener_url + '/' + shortener.code}
<Tooltip.Content> target="_blank"
<p>{shortener.ios_link}</p> class="hover:underline">
</Tooltip.Content> {shortener_url + '/' + shortener.code}
</Tooltip.Root> </a>
{/if} <ExternalLink size={16} />
{#if shortener.android} </div>
<Tooltip.Root>
<Tooltip.Trigger>
<Badge variant="outline" class="flex gap-2"
>Android</Badge>
</Tooltip.Trigger>
<Tooltip.Content>
<p>{shortener.android_link}</p>
</Tooltip.Content>
</Tooltip.Root>
{/if}
</div>
</Card.Description>
</Card.Header>
<Card.Content>
<div class="flex items-center justify-between">
<div class="flex gap-2">
<Button
href={`/links/${shortener.code}`}
class="bg-secondary flex h-8 items-center justify-center gap-1 rounded text-sm">
<BarChart size={20} />
<div>
{shortener.visitorCount} visits
</div>
</Button>
<a
class={cn(
buttonVariants({ variant: 'default' }),
'bg-secondary flex h-8 items-center justify-center gap-1 rounded text-sm',
)}
href={`/projects/${selected_project.uuid}/links/${shortener.code}/qr`}
on:click|preventDefault={showQRModal}>
<QrCode size={20} />
</a>
</div> </div>
<DropdownMenu.Root> <DropdownMenu.Root>
<DropdownMenu.Trigger> <DropdownMenu.Trigger>
<MoreVertical /> <MoreVertical />
@ -194,23 +122,85 @@
<a <a
href={`/projects/${selected_project.uuid}/links/${shortener.code}/edit`} href={`/projects/${selected_project.uuid}/links/${shortener.code}/edit`}
on:click|preventDefault={() => on:click|preventDefault={() =>
showEditModalNew( showEditModal(
selected_project.uuid || '', selected_project.uuid || '',
shortener.code, shortener.code,
)}> )}>
<DropdownMenu.Item class="flex items-center gap-2"> <DropdownMenu.Item class="flex gap-2 items-center">
<EditIcon size={16} />Edit <EditIcon size={16} />Edit
</DropdownMenu.Item> </DropdownMenu.Item>
</a> </a>
<DropdownMenu.Item <DropdownMenu.Item
on:click={() => openDeleteDialog(shortener.code)} on:click={() => openDeleteDialog(shortener.code)}
class="text-destructive data-[highlighted]:bg-destructive flex items-center gap-2"> class="flex gap-2 items-center text-destructive data-[highlighted]:bg-destructive">
<TrashIcon size={16} /> <TrashIcon size={16} />
Delete Delete
</DropdownMenu.Item> </DropdownMenu.Item>
</DropdownMenu.Group> </DropdownMenu.Group>
</DropdownMenu.Content> </DropdownMenu.Content>
</DropdownMenu.Root> </DropdownMenu.Root>
</Card.Title>
</Card.Header>
<Card.Content>
<div class="flex justify-between items-center">
<div class="flex gap-2">
<Button
href={`/links/${shortener.code}`}
class="flex gap-1 justify-center items-center h-8 text-sm rounded bg-secondary">
<BarChart size={20} />
<div>
{shortener.visitorCount} visits
</div>
</Button>
<a
class={cn(
buttonVariants({ variant: 'default' }),
'flex h-8 items-center justify-center gap-1 rounded bg-secondary text-sm',
)}
href={`/projects/${selected_project.uuid}/links/${shortener.code}/qr`}
on:click|preventDefault={showQRModal}>
<QrCode size={20} />
</a>
{#if shortener.ios}
<Tooltip.Root>
<Tooltip.Trigger>
<Badge variant="outline" class="flex gap-2">iOS</Badge>
</Tooltip.Trigger>
<Tooltip.Content>
<p>{shortener.ios_link}</p>
</Tooltip.Content>
</Tooltip.Root>
{/if}
{#if shortener.android}
<Tooltip.Root>
<Tooltip.Trigger>
<Badge variant="outline" class="flex gap-2"
>Android</Badge>
</Tooltip.Trigger>
<Tooltip.Content>
<p>{shortener.android_link}</p>
</Tooltip.Content>
</Tooltip.Root>
{/if}
</div>
<div class="flex gap-4">
{#if shortener.projectName}
<Badge variant="secondary">{shortener.projectName}</Badge>
{/if}
<Badge variant="outline" class="flex gap-2">
{#if shortener.active}
<span
class="inline-flex relative w-2 h-2 bg-green-400 rounded-full"
></span>
Active
{:else}
<span
class="inline-flex relative w-2 h-2 bg-gray-600 rounded-full"
></span>
Inactive
{/if}
</Badge>
</div>
</div> </div>
</Card.Content> </Card.Content>
</Card.Root> </Card.Root>

@ -64,7 +64,7 @@
</script> </script>
<div <div
class="flex flex-wrap-reverse items-center justify-start gap-4 px-4 py-4 md:px-10"> class="flex flex-wrap-reverse gap-4 justify-start items-center py-4 px-4 md:px-10">
<Drawer.Root> <Drawer.Root>
<Drawer.Trigger class="md:hidden"> <Drawer.Trigger class="md:hidden">
<Button size="icon"><SortAscIcon /></Button> <Button size="icon"><SortAscIcon /></Button>
@ -120,7 +120,7 @@
</Drawer.Footer> </Drawer.Footer>
</Drawer.Content> </Drawer.Content>
</Drawer.Root> </Drawer.Root>
<div class="hidden items-center gap-4 md:flex"> <div class="hidden gap-4 items-center md:flex">
<Select.Root <Select.Root
selected={{ label: data.sortBy, value: data.sortBy }}> selected={{ label: data.sortBy, value: data.sortBy }}>
<Select.Trigger class="w-[180px]" customIcon={SortDescIcon}> <Select.Trigger class="w-[180px]" customIcon={SortDescIcon}>
@ -145,7 +145,7 @@
<Select.Input name="favoriteFruit" /> <Select.Input name="favoriteFruit" />
</Select.Root> </Select.Root>
</div> </div>
<div class="hidden items-center gap-4 sm:flex"> <div class="hidden gap-4 items-center sm:flex">
<Input <Input
type="text" type="text"
placeholder="search" placeholder="search"
@ -165,15 +165,16 @@
</div> </div>
{#await data.shorteners} {#await data.shorteners}
<div class="flex flex-wrap gap-4 px-4 py-4 md:px-10"> <div class="flex flex-wrap gap-4 py-4 px-4 md:px-10">
{#each [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] as _} {#each [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] as _}
<Skeleton class="h-[150px] w-[500px] rounded-lg" /> <Skeleton class="rounded-lg h-[150px] w-[500px]" />
{/each} {/each}
</div> </div>
{:then shorteners} {:then shorteners}
{#if shorteners.length > 0} {#if shorteners.length > 0}
<ScrollArea class="flex-grow"> <ScrollArea class="flex-grow">
<div class="flex flex-wrap gap-4 px-4 py-4 md:px-10"> <div
class="grid grid-cols-[repeat(auto-fit,_minmax(500px,_1fr))] gap-4 px-4 py-4 md:px-10">
{#each shorteners as shortener} {#each shorteners as shortener}
<ShortenerCard <ShortenerCard
{shortener} {shortener}
@ -184,13 +185,13 @@
</div> </div>
</ScrollArea> </ScrollArea>
{:else} {:else}
<div class="flex flex-grow px-4 py-4 md:px-10"> <div class="flex flex-grow py-4 px-4 md:px-10">
<div <div
class="flex flex-1 items-center justify-center rounded-lg border border-dashed shadow-sm"> class="flex flex-1 justify-center items-center rounded-lg border border-dashed shadow-sm">
<div <div
class="flex w-full flex-grow items-center justify-center"> class="flex flex-grow justify-center items-center w-full">
<div class="flex flex-col items-center gap-8"> <div class="flex flex-col gap-8 items-center">
<div class="flex flex-col items-center gap-2"> <div class="flex flex-col gap-2 items-center">
<div class="text-4xl font-bold">No Shortener Found</div> <div class="text-4xl font-bold">No Shortener Found</div>
<p class="text-muted-foreground">Add a new shortener</p> <p class="text-muted-foreground">Add a new shortener</p>
</div> </div>
@ -207,7 +208,7 @@
{/await} {/await}
{#await data.pagination then pagination} {#await data.pagination then pagination}
<div class="flex items-center justify-between border-t p-4"> <div class="flex justify-between items-center p-4 border-t">
<Select.Root <Select.Root
selected={{ label: data.perPage, value: data.perPage }}> selected={{ label: data.perPage, value: data.perPage }}>
<Select.Trigger class="w-[180px]"> <Select.Trigger class="w-[180px]">

Loading…
Cancel
Save