added browser data to visitors

pull/3/head
TZGyn 2 years ago
parent ba72a0a8b6
commit 6bb0e5578a
Signed by: TZGyn
GPG Key ID: 122EAF77AE81FD4A

Binary file not shown.

@ -19,7 +19,7 @@
"@types/qrcode": "^1.5.5",
"autoprefixer": "^10.4.14",
"bun-types": "^1.0.11",
"drizzle-kit": "latest",
"drizzle-kit": "^0.20.14",
"lucia": "^3.1.1",
"postcss": "^8.4.24",
"postcss-load-config": "^4.0.1",

@ -63,6 +63,7 @@ export const visitor = pgTable('visitor', {
deviceType: varchar('device_type', { length: 255 }),
deviceVendor: varchar('device_vendor', { length: 255 }),
os: varchar('os', { length: 255 }),
browser: varchar('browser', { length: 255 }),
})
export const session = pgTable('session', {

@ -75,6 +75,15 @@ export const load = (async (event) => {
.where(eq(visitorSchema.shortenerId, shortener.id))
.groupBy(visitorSchema.os)
const visitorByBrowser = await db
.select({
count: sql<number>`cast(count(*) as int)`,
browser: visitorSchema.browser,
})
.from(visitorSchema)
.where(eq(visitorSchema.shortenerId, shortener.id))
.groupBy(visitorSchema.browser)
const visitorByDeviceVendor = await db
.select({
count: sql<number>`cast(count(*) as int)`,
@ -101,6 +110,7 @@ export const load = (async (event) => {
visitorByCountry,
visitorByCity,
visitorByOS,
visitorByBrowser,
visitorByDeviceVendor,
visitorByDeviceType,
page_title,

@ -99,12 +99,13 @@
</script>
<div class="flex justify-between items-center p-4 min-h-[80px]">
<div class="text-3xl font-bold">{data.shortener.link}</div>
<div class="text-2xl font-bold">{data.shortener.link}</div>
</div>
<Separator />
<div class="flex overflow-y-scroll flex-wrap gap-4 p-4">
<Card.Root class="w-[700px]">
<div
class="grid grid-cols-[repeat(auto-fit,_minmax(600px,_1fr))] gap-4 overflow-y-scroll p-4">
<Card.Root>
<Card.Header>
<Card.Title>Clicks</Card.Title>
<Card.Description
@ -114,7 +115,8 @@
<div bind:this={container}></div>
</Card.Content>
</Card.Root>
<Card.Root class="min-h-[500px] w-[500px]">
<Card.Root class="min-h-[500px]">
<Tabs.Root value="country">
<Card.Header
class="flex flex-row justify-between items-center space-y-0 w-full">
@ -158,7 +160,7 @@
</Card.Content>
</Tabs.Root>
</Card.Root>
<Card.Root class="min-h-[500px] w-[500px]">
<Card.Root class="min-h-[500px]">
<Tabs.Root value="vendor">
<Card.Header
class="flex flex-row justify-between items-center space-y-0 w-full">
@ -170,6 +172,7 @@
<Tabs.Trigger value="vendor">Vendor</Tabs.Trigger>
<Tabs.Trigger value="type">Type</Tabs.Trigger>
<Tabs.Trigger value="os">OS</Tabs.Trigger>
<Tabs.Trigger value="browser">Browser</Tabs.Trigger>
</Tabs.List>
</Card.Header>
<Card.Content>
@ -224,6 +227,21 @@
{/each}
</div>
</Tabs.Content>
<Tabs.Content value="browser">
<div class="flex flex-col gap-6">
{#each data.visitorByBrowser as visitorByBrowser}
<div class="flex justify-between items-center">
<div class="flex gap-4 items-center">
<TabletSmartphone />
<div>
{visitorByBrowser.browser ?? 'Undefined Browser'}
</div>
</div>
<div>{visitorByBrowser.count}</div>
</div>
{/each}
</div>
</Tabs.Content>
</Card.Content>
</Tabs.Root>
</Card.Root>

@ -0,0 +1,30 @@
<script lang="ts">
import ThemeToggle from '$lib/components/theme-toggle.svelte'
import { Button } from '$lib/components/ui/button'
</script>
<div class="flex flex-col items-center w-screen h-screen">
<div class="flex justify-between py-4 px-8 w-full max-w-6xl">
<div class="flex gap-4 items-center">
<img src="/logo.png" alt="" class="h-8" />
<div>kon.sh</div>
</div>
<div class="flex gap-8 items-center">
<a href="/landing/docs">Docs</a>
<a href="/landing/pricing">Pricing</a>
</div>
<div class="flex gap-4 items-center">
<a
href="/login"
class="transition-all text-primary/80 hover:text-primary">
Login
</a>
<Button
href="/signup"
class="bg-orange-400 hover:bg-orange-300 w-fit"
>Get Started</Button>
<ThemeToggle />
</div>
</div>
<slot />
</div>

@ -0,0 +1,33 @@
<script lang="ts">
import { Button } from '$lib/components/ui/button'
</script>
<div class="flex flex-col items-center pt-24">
<div class="flex flex-col gap-24 max-w-6xl">
<div class="flex flex-col gap-4 items-center text-center">
<h1
class="text-6xl font-bold text-transparent bg-clip-text bg-gradient-to-r from-orange-300 to-orange-400">
Kon.sh
</h1>
<p class="max-w-sm text-xl font-semibold text-center">
Open Source Self-hostable Link Shortener With Analytics
</p>
<Button
href="/signup"
class="bg-orange-400 hover:bg-orange-300 w-fit">
Get Started
</Button>
</div>
<div class="flex flex-col gap-4 items-center text-center">
<h1 class="text-4xl font-bold">Why Kon.sh?</h1>
<p class="max-w-lg text-xl font-semibold text-center">
Kon.sh is completely self-hostable, open source, and free. No
vendor lock-in, can be hosted using docker/docker compose with
no limitations.
<a href="/landing/docs" class="text-orange-400 underline">
Learn More
</a>
</p>
</div>
</div>
</div>

@ -0,0 +1,6 @@
import type { PageServerLoad } from './$types'
import { redirect } from '@sveltejs/kit'
export const load = (async () => {
return redirect(300, '/landing')
}) satisfies PageServerLoad

@ -0,0 +1,15 @@
<script>
import { goto } from '$app/navigation'
import Button from '$lib/components/ui/button/button.svelte'
</script>
<div class="flex justify-center items-center w-full h-full">
<div class="flex flex-col gap-12 items-center">
<div class="flex flex-col gap-4 items-center">
<div class="text-4xl font-bold">404</div>
<div class="text-4xl font-bold">Page Not Found</div>
</div>
<Button on:click={() => goto('/landing')} class="w-fit"
>Return</Button>
</div>
</div>

@ -44,6 +44,7 @@ app.get(
city: geolocation.data.location.city.name as string,
device_type: ua_parser.getDevice().type,
device_vendor: ua_parser.getDevice().vendor,
browser: ua_parser.getBrowser().name,
os: ua_parser.getOS().name,
}

@ -39,6 +39,7 @@ export interface VisitorTable {
device_type: string | null
device_vendor: string | null
os: string | null
browser: string | null
created_at: ColumnType<Date, string | undefined, never>
}

Loading…
Cancel
Save