Skip to content

Commit

Permalink
feat(dashboard): Arranging home and link stats
Browse files Browse the repository at this point in the history
Signed-off-by: Binyamin Yawitz <316103+byawitz@users.noreply.github.com>
  • Loading branch information
byawitz committed Apr 11, 2024
1 parent 8866338 commit a44d332
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 249 deletions.
3 changes: 2 additions & 1 deletion apps/dashboard/src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import Footer from '@/components/view/Footer.vue';
import PageWrapper from '@/components/layouts/PageWrapper.vue';
import { isRTL, type SystemLang } from '@/locale/I18n';
import { useI18n } from 'vue-i18n';
import DomHelper from '@/heplers/DomHelper';
const isPageLoading = ref(true);
const store = useAppStore();
Expand All @@ -35,7 +36,7 @@ const i18n = useI18n();
function setTheme(theme: SystemTheme) {
if (theme === 'system') {
theme = window.matchMedia?.('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
theme = DomHelper.getTheme();
}
document.querySelector('body')?.setAttribute('data-bs-theme', theme);
Expand Down
4 changes: 4 additions & 0 deletions apps/dashboard/src/heplers/DomHelper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,8 @@ export default class DomHelper {
public static removeClassFromID(id: string, ...classNames: string[]) {
document.querySelector(`#${id}`)?.classList.remove(...classNames);
}

static getTheme() {
return window.matchMedia?.('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
}
}
3 changes: 1 addition & 2 deletions apps/dashboard/src/heplers/NetworkHelper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,7 @@ export default class NetworkHelper {
}

public static baseUrl(appendUrl = '') {
const base = import.meta.env.MODE === 'development' ? 'http://localhost:8081/v1/api' : `${window.location.origin}/v1/api`;
const base = import.meta.env.MODE === 'development' ? 'http://localhost/v1/api' : `${window.location.origin}/v1/api`;
return `${base}${appendUrl}`;
}

}
34 changes: 28 additions & 6 deletions apps/dashboard/src/views/HomeView.vue
Original file line number Diff line number Diff line change
@@ -1,10 +1,32 @@
<script setup lang="ts">
import PageHeader from '@/components/layouts/PageHeader.vue';
import StillInWork from '@/components/view/StillInWork.vue';
</script>

<template>
<PageHeader :title="$t('Linkos')" />

<StillInWork />
<div class="page-body">
<Container>
<div class="row row-cards">
<div class="col-12">
<div class="row row-cards">
<NumberOf :title="$t('Links')" number="10" :sub-title="$t('Shorts')" icon-type="bg-cyan" :icon="IconLink" />
<NumberOf :title="$t('Campaigns')" number="10" :icon="IconMist" />
<NumberOf :title="$t('Tags')" number="10" :icon="IconLink" />
<NumberOf :title="$t('Clicks')" number="10" :sub-title="$t('All links')" :icon="IconLink" />

<TopTen :title="$t('Countries')" :categories="['iphone', 'android']" :series="[1, 2]" />
<TopTen :title="$t('Links')" :categories="['iphone', 'android']" :series="[1, 2]" />
<TopTen :title="$t('Devices')" :categories="['iphone', 'android']" :series="[1, 2]" />
<TopTen :title="$t('Referrers')" :categories="['iphone', 'android']" :series="[1, 2]" />
</div>
</div>
</div>
</Container>
</div>
</template>

<script setup lang="ts">
import PageHeader from '@/components/layouts/PageHeader.vue';
import NumberOf from '@/components/stats/NumberOf.vue';
import Container from '@/components/layouts/Container.vue';
import { IconLink, IconMist } from '@tabler/icons-vue';
import TopTen from '@/components/stats/TopTen.vue';
</script>
279 changes: 39 additions & 240 deletions apps/dashboard/src/views/LinkView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -87,100 +87,41 @@
</div>

<template v-else>
<div class="col-md-6 col-xl-4 col-12">
<Card class="mt-4">
<CardBody>
<div class="d-flex">
<h3 class="card-title">{{ $t('Clicks') }}</h3>
</div>

<div class="row">
<div class="col">
<div id="clicks-chart" class="chart-lg"></div>
</div>
</div>
</CardBody>
</Card>
</div>

<div class="col-md-6 col-xl-4 col-12">
<Card class="mt-4">
<CardBody>
<div class="d-flex">
<h3 class="card-title">{{ $t('Device Type') }}</h3>
</div>

<div class="row">
<div class="col">
<div id="device-type-chart" class="chart-lg"></div>
</div>
</div>
</CardBody>
</Card>
</div>

<div class="col-md-6 col-xl-4 col-12">
<Card class="mt-4">
<CardBody>
<div class="d-flex">
<h3 class="card-title">{{ $t('Device Brand') }}</h3>
</div>

<div class="row">
<div class="col">
<div id="device-brand-chart" class="chart-lg"></div>
</div>
</div>
</CardBody>
</Card>
</div>

<div class="col-md-6 col-xl-4 col-12">
<Card class="mt-4">
<CardBody>
<div class="d-flex">
<h3 class="card-title">{{ $t('Countries') }}</h3>
</div>

<div class="row">
<div class="col">
<div id="countries-chart"></div>
</div>
</div>
</CardBody>
</Card>
</div>

<div class="col-md-6 col-xl-4 col-12">
<Card class="mt-4">
<CardBody>
<div class="d-flex">
<h3 class="card-title">{{ $t('Cities') }}</h3>
</div>
<div class="row">
<div class="col">
<div id="cities-chart"></div>
</div>
</div>
</CardBody>
</Card>
</div>

<div class="col-md-6 col-xl-4 col-12">
<Card class="mt-4">
<CardBody>
<div class="d-flex">
<h3 class="card-title">{{ $t('Referrers') }}</h3>
</div>

<div class="row">
<div class="col">
<div id="referrers-chart"></div>
</div>
</div>
</CardBody>
</Card>
</div>
<AreaStats
class="mt-4"
:title="$t('Clicks')"
:categories="clicks"
:series="[
{ name: t('Direct'), data: directs },
{ name: 'QR', data: qrs }
]"
/>

<AreaStats
class="mt-4"
:title="$t('Device Type')"
:categories="clicks"
:series="[
{ name: t('Other'), data: unknownType },
{ name: t('Mobile'), data: mobile },
{ name: t('Desktop'), data: desktop }
]"
/>

<AreaStats
class="mt-4"
:title="$t('Device Brand')"
:categories="clicks"
:series="[
{ name: t('Other'), data: unknownBrand },
{ name: t('Android'), data: android },
{ name: t('Apple'), data: apple }
]"
/>

<TopTen class="mt-4" :title="$t('Countries')" :categories="countryNames" :series="countryCount" />
<TopTen class="mt-4" :title="$t('Cities')" :categories="cityNames" :series="countryCount" />
<TopTen class="mt-4" :title="$t('Referrers')" :categories="refererNames" :series="refererCount" />
</template>
</template>
</div>
Expand All @@ -204,6 +145,8 @@ import { IconCopy, IconExternalLink } from '@tabler/icons-vue';
import { useAppStore } from '@/stores/user';
import ApexCharts from 'apexcharts';
import { useI18n } from 'vue-i18n';
import TopTen from '@/components/stats/TopTen.vue';
import AreaStats from '@/components/stats/AreaStats.vue';

const router = useRouter();
const { t } = useI18n();
Expand All @@ -212,7 +155,7 @@ const id = router.currentRoute.value.params.id;

const days = ref(30);
const loading = ref(true);
const loadingAnalytics = ref(false);
const loadingAnalytics = ref(true);
const link = ref(new LinkModel());
const title = computed(() => (link.value.title !== '' ? link.value.title : t('View link')));
const store = useAppStore();
Expand Down Expand Up @@ -256,150 +199,6 @@ function getShort(link: LinkModel) {
return `${store.server.host}/${link.short}`;
}

function loadCharts() {
loadDeviceType();
loadDeviceBrands();
loadClicks();
loadCountries();
loadCities();
loadReferrers();
}

function loadClicks() {
new ApexCharts(document.querySelector('#clicks-chart'), {
theme: { mode: 'dark' /* TODO: by theme*/ },
series: [
{
name: t('Direct'),
data: directs.value
},
{
name: 'QR',
data: qrs.value
}
],
chart: {
background: 'transparent',
type: 'area',
toolbar: { show: false },

height: 240,
zoom: { enabled: false }
},
dataLabels: { enabled: false },
stroke: {
curve: 'straight'
},
labels: clicks.value,
yaxis: {
opposite: true
},
legend: {
horizontalAlign: 'left'
}
}).render();
}

function loadDeviceBrands() {
new ApexCharts(document.getElementById('device-brand-chart'), {
theme: { mode: 'dark' /* TODO: by theme*/ },
series: [
{ name: t('Other'), data: unknownBrand.value },
{ name: t('Android'), data: android.value },
{ name: t('Apple'), data: apple.value }
],
chart: { background: 'transparent', height: 240, type: 'area', toolbar: { show: false } },
dataLabels: { enabled: false },
stroke: { curve: 'smooth' },
xaxis: {
type: 'date',
categories: clicks.value
},
tooltip: { x: { format: t('dd/MM/yy') } }
}).render();
}

function loadDeviceType() {
new ApexCharts(document.getElementById('device-type-chart'), {
theme: { mode: 'dark' /* TODO: by theme*/ },
series: [
{ name: t('Other'), data: unknownType.value },
{ name: t('Mobile'), data: mobile.value },
{ name: t('Desktop'), data: desktop.value }
],
chart: { background: 'transparent', height: 240, type: 'area', toolbar: { show: false } },
dataLabels: { enabled: false },
stroke: { curve: 'smooth' },
xaxis: {
type: 'date',
categories: clicks.value
},
tooltip: { x: { format: t('dd/MM/yy') } }
}).render();
}

function loadCountries() {
new ApexCharts(document.querySelector('#countries-chart'), {
theme: { mode: 'dark' /* TODO: by theme*/ },
series: [{ data: countryCount.value }],
chart: {
background: 'transparent',
type: 'bar',
height: 240,
toolbar: { show: false }
},
plotOptions: {
bar: {
horizontal: true
}
},
dataLabels: {
enabled: true
},
xaxis: { categories: countryNames.value },
grid: { xaxis: { lines: { show: false } } },
yaxis: { axisTicks: { show: true } }
}).render();
}

function loadCities() {
new ApexCharts(document.querySelector('#cities-chart'), {
theme: { mode: 'dark' /* TODO: by theme*/ },
series: [{ data: citiesCount.value }],
chart: {
background: 'transparent',
type: 'bar',
height: 240,
toolbar: { show: false }
},
plotOptions: {
bar: {
borderRadius: 4,

horizontal: true
}
},
dataLabels: {
enabled: true
},
xaxis: { categories: cityNames.value }
}).render();
}

function loadReferrers() {
new ApexCharts(document.querySelector('#referrers-chart'), {
theme: { mode: 'dark' /* TODO: by theme*/ },
series: [{ data: refererCount.value }],

chart: { background: 'transparent', type: 'bar', height: 240, toolbar: { show: false } },
plotOptions: {
bar: { borderRadius: 4, horizontal: true }
},
dataLabels: { enabled: false },
xaxis: { categories: refererNames.value }
}).render();
}

async function loadAnalytics() {
const analytics = await NetworkHelper.get(`${NetworkHelper.linkStats}${id}/${days.value}`);
if (!analytics.success) {
Expand Down Expand Up @@ -478,7 +277,7 @@ async function loadAnalytics() {
refererCount.value = _refererCount;
}

loadCharts();
loadingAnalytics.value = false;
}

onMounted(async () => {
Expand Down

0 comments on commit a44d332

Please sign in to comment.