main
vue 69 lines 2.1 KB
Raw
1 <template>
2 <n-spin :show="loading">
3 <div class="grid grid-cols-1 gap-6 @xl:grid-cols-2 @3xl:grid-cols-3">
4 <CardStats title="Total Alerts" :value="stats.total_alerts" clickable @click="routeAlertsList().navigate()">
5 <template #icon>
6 <Icon :name="ICONS.alerts" :size="24" class="text-error" />
7 </template>
8 </CardStats>
9
10 <CardStats title="Total Cases" :value="stats.total_cases" clickable @click="routeCasesList().navigate()">
11 <template #icon>
12 <Icon :name="ICONS.cases" :size="24" class="text-info" />
13 </template>
14 </CardStats>
15
16 <CardStats title="Total Agents" :value="stats.total_agents" clickable @click="routeAgentsList().navigate()">
17 <template #icon>
18 <Icon :name="ICONS.agents" :size="24" class="text-primary" />
19 </template>
20 </CardStats>
21 </div>
22 </n-spin>
23 </template>
24
25 <script setup lang="ts">
26 import type { ApiError } from "@/types/common"
27 import type { DashboardStats } from "@/types/portal"
28 import { NSpin, useMessage } from "naive-ui"
29 import { onBeforeMount, ref, watch } from "vue"
30 import Api from "@/api"
31 import CardStats from "@/components/common/cards/CardStats.vue"
32 import Icon from "@/components/common/Icon.vue"
33 import { useNavigation } from "@/composables/common/useNavigation"
34 import { ICONS } from "@/const"
35 import { useCustomerFilterStore } from "@/stores/customerFilter"
36 import { getApiErrorMessage } from "@/utils"
37
38 const { routeAlertsList, routeCasesList, routeAgentsList } = useNavigation()
39 const loading = ref(false)
40 const message = useMessage()
41 const customerFilterStore = useCustomerFilterStore()
42 const stats = ref<DashboardStats>({
43 total_alerts: 0,
44 total_cases: 0,
45 total_agents: 0
46 })
47
48 function fetchStats() {
49 loading.value = true
50 Api.portal
51 .dashboardStats(customerFilterStore.queryCustomerCodes)
52 .then(res => {
53 stats.value = res.data
54 })
55 .catch(err => {
56 message.error(getApiErrorMessage(err as ApiError))
57 })
58 .finally(() => {
59 loading.value = false
60 })
61 }
62
63 onBeforeMount(() => {
64 fetchStats()
65 })
66
67 // Refetch whenever the global customer filter changes.
68 watch(() => customerFilterStore.selectedCustomerCodes, fetchStats, { deep: true })
69 </script>