improve analytics page ui

main
TZGyn 1 year ago
parent 135577b0d6
commit 155623a444
Signed by: TZGyn
GPG Key ID: 122EAF77AE81FD4A

@ -109,10 +109,14 @@ declare global {
}
}
}
// prototype functions are declared in ./lib/utils
interface String {
removeUnderscores(): string
capitalize(): string
}
interface Number {
toDecimalPoint(decimal: number): Number
}
}
export {}

@ -70,6 +70,7 @@ export const flyAndScale = (
}
}
// type declaration are in ../app.d.ts
// this works because its imported in the root layout by other components
String.prototype.removeUnderscores = function () {
return this.replace(/_/g, ' ')
@ -78,3 +79,11 @@ String.prototype.removeUnderscores = function () {
String.prototype.capitalize = function () {
return this.charAt(0).toUpperCase() + this.slice(1)
}
Number.prototype.toDecimalPoint = function (decimal: number) {
const decimalInInt = Math.round(decimal)
const value = 10 ** decimalInInt
return Math.round(this.valueOf() * value) / value
}

@ -141,15 +141,25 @@
<Card.Content>
<Tabs.Content value="country">
{#each data.visitorByCountry as visitorByCountry}
<div class="flex flex-col gap-2">
<div
class="hover:bg-muted flex flex-col gap-2 border-b p-2 transition-colors">
<div class="flex items-center justify-between">
<div class="flex items-center gap-4">
<img
src={`https://flagsapi.com/${visitorByCountry.code}/flat/64.png`}
src={`https://flagsapi.com/${visitorByCountry.code}/flat/32.png`}
alt="" />
<div>{visitorByCountry.country}</div>
</div>
<div>{visitorByCountry.count}</div>
<div>
{visitorByCountry.count}
<span class="text-muted-foreground">
({(
(visitorByCountry.count /
data.visitorAllTime[0].count) *
100
).toDecimalPoint(2)} %)
</span>
</div>
</div>
<Progress
value={visitorByCountry.count}
@ -160,15 +170,25 @@
</Tabs.Content>
<Tabs.Content value="city">
{#each data.visitorByCity as visitorByCity}
<div class="flex flex-col gap-2">
<div
class="hover:bg-muted flex flex-col gap-2 border-b p-2 transition-colors">
<div class="flex items-center justify-between">
<div class="flex items-center gap-4">
<img
src={`https://flagsapi.com/${visitorByCity.code}/flat/64.png`}
src={`https://flagsapi.com/${visitorByCity.code}/flat/32.png`}
alt="" />
<div>{visitorByCity.city}</div>
</div>
<div>{visitorByCity.count}</div>
<div>
{visitorByCity.count}
<span class="text-muted-foreground">
({(
(visitorByCity.count /
data.visitorAllTime[0].count) *
100
).toDecimalPoint(2)} %)
</span>
</div>
</div>
<Progress
value={visitorByCity.count}
@ -195,52 +215,68 @@
</Card.Header>
<Card.Content>
<Tabs.Content value="vendor">
<div class="flex flex-col gap-6">
{#each data.visitorByDeviceVendor as visitorByDeviceVendor}
<div class="flex flex-col gap-2">
<div class="flex items-center justify-between">
<div class="flex items-center gap-4">
<TabletSmartphone />
<div>
{visitorByDeviceVendor.vendor ?? '(None)'}
</div>
{#each data.visitorByDeviceVendor as visitorByDeviceVendor}
<div
class="hover:bg-muted flex flex-col gap-2 border-b p-2 transition-colors">
<div class="flex items-center justify-between">
<div class="flex items-center gap-4">
<TabletSmartphone />
<div>
{visitorByDeviceVendor.vendor || '(None)'}
</div>
<div>{visitorByDeviceVendor.count}</div>
</div>
<Progress
value={visitorByDeviceVendor.count}
max={data.visitorAllTime[0].count}
class={'h-2'} />
<div>
{visitorByDeviceVendor.count}
<span class="text-muted-foreground">
({(
(visitorByDeviceVendor.count /
data.visitorAllTime[0].count) *
100
).toDecimalPoint(2)} %)
</span>
</div>
</div>
{/each}
</div>
<Progress
value={visitorByDeviceVendor.count}
max={data.visitorAllTime[0].count}
class={'h-2'} />
</div>
{/each}
</Tabs.Content>
<Tabs.Content value="type">
<div class="flex flex-col gap-6">
{#each data.visitorByDeviceType as visitorByDeviceType}
<div class="flex flex-col gap-2">
<div class="flex items-center justify-between">
<div class="flex items-center gap-4">
{#if visitorByDeviceType.type === 'mobile'}
<Smartphone />
{:else if visitorByDeviceType.type === 'tablet'}
<Tablet />
{:else}
<TabletSmartphone />
{/if}
<div>
{visitorByDeviceType.type ?? '(None)'}
</div>
{#each data.visitorByDeviceType as visitorByDeviceType}
<div
class="hover:bg-muted flex flex-col gap-2 border-b p-2 transition-colors">
<div class="flex items-center justify-between">
<div class="flex items-center gap-4">
{#if visitorByDeviceType.type === 'mobile'}
<Smartphone />
{:else if visitorByDeviceType.type === 'tablet'}
<Tablet />
{:else}
<TabletSmartphone />
{/if}
<div>
{visitorByDeviceType.type ?? '(None)'}
</div>
<div>{visitorByDeviceType.count}</div>
</div>
<Progress
value={visitorByDeviceType.count}
max={data.visitorAllTime[0].count}
class={'h-2'} />
<div>
{visitorByDeviceType.count}
<span class="text-muted-foreground">
({(
(visitorByDeviceType.count /
data.visitorAllTime[0].count) *
100
).toDecimalPoint(2)} %)
</span>
</div>
</div>
{/each}
</div>
<Progress
value={visitorByDeviceType.count}
max={data.visitorAllTime[0].count}
class={'h-2'} />
</div>
{/each}
</Tabs.Content>
</Card.Content>
</Tabs.Root>
@ -260,44 +296,60 @@
</Card.Header>
<Card.Content>
<Tabs.Content value="os">
<div class="flex flex-col gap-6">
{#each data.visitorByOS as visitorByOS}
<div class="flex flex-col gap-2">
<div class="flex items-center justify-between">
<div class="flex items-center gap-4">
<TabletSmartphone />
<div>{visitorByOS.os ?? '(None)'}</div>
</div>
<div>{visitorByOS.count}</div>
{#each data.visitorByOS as visitorByOS}
<div
class="hover:bg-muted flex flex-col gap-2 border-b p-2 transition-colors">
<div class="flex items-center justify-between">
<div class="flex items-center gap-4">
<TabletSmartphone />
<div>{visitorByOS.os ?? '(None)'}</div>
</div>
<div>
{visitorByOS.count}
<span class="text-muted-foreground">
({(
(visitorByOS.count /
data.visitorAllTime[0].count) *
100
).toDecimalPoint(2)} %)
</span>
</div>
<Progress
value={visitorByOS.count}
max={data.visitorAllTime[0].count}
class={'h-2'} />
</div>
{/each}
</div>
<Progress
value={visitorByOS.count}
max={data.visitorAllTime[0].count}
class={'h-2'} />
</div>
{/each}
</Tabs.Content>
<Tabs.Content value="browser">
<div class="flex flex-col gap-6">
{#each data.visitorByBrowser as visitorByBrowser}
<div class="flex flex-col gap-2">
<div class="flex items-center justify-between">
<div class="flex items-center gap-4">
<GlobeIcon />
<div>
{visitorByBrowser.browser ?? '(None)'}
</div>
{#each data.visitorByBrowser as visitorByBrowser}
<div
class="hover:bg-muted flex flex-col gap-2 border-b p-2 transition-colors">
<div class="flex items-center justify-between">
<div class="flex items-center gap-4">
<GlobeIcon />
<div>
{visitorByBrowser.browser ?? '(None)'}
</div>
<div>{visitorByBrowser.count}</div>
</div>
<Progress
value={visitorByBrowser.count}
max={data.visitorAllTime[0].count}
class={'h-2'} />
<div>
{visitorByBrowser.count}
<span class="text-muted-foreground">
({(
(visitorByBrowser.count /
data.visitorAllTime[0].count) *
100
).toDecimalPoint(2)} %)
</span>
</div>
</div>
{/each}
</div>
<Progress
value={visitorByBrowser.count}
max={data.visitorAllTime[0].count}
class={'h-2'} />
</div>
{/each}
</Tabs.Content>
</Card.Content>
</Tabs.Root>

Loading…
Cancel
Save