2024-08-26 09:09:46 +08:00

480 lines
12 KiB
Vue

<script setup>
definePageMeta({
title: "Dashboard",
middleware: ["auth"],
requiresAuth: true,
});
const data1 = ref([]);
const data2 = ref([]);
const data3 = ref([]);
const data4 = ref([]);
var sparkline1Data = [47, 45, 54, 38, 56, 24, 65];
var sparkline2Data = [61, 35, 66, 41, 59, 25, 32];
var sparkline3Data = [25, 18, 36, 41, 43, 35, 14];
var sparkline4Data = [8, 16, 22, 41, 43, 35, 14];
const changeKey = ref(0);
const customers = [
{
name: "Iqmal",
age: "25",
city: "Kuala Lumpur",
country: "Malaysia",
totalPurchase: 1524,
purchase: 23,
},
{
name: "Adi",
age: "45",
city: "Pulau Pinang",
country: "Malaysia",
totalPurchase: 643,
purchase: 14,
},
{
name: "Raziq",
age: "21",
city: "Kelantan",
country: "Malaysia",
totalPurchase: 543,
purchase: 12,
},
{
name: "Haqeem",
age: "19",
city: "Negeri Sembilan",
country: "Malaysia",
totalPurchase: 258,
purchase: 6,
},
];
const randomizeArray = function (arg) {
var array = arg.slice();
var currentIndex = array.length,
temporaryValue,
randomIndex;
while (0 !== currentIndex) {
randomIndex = Math.floor(Math.random() * currentIndex);
currentIndex -= 1;
temporaryValue = array[currentIndex];
array[currentIndex] = array[randomIndex];
array[randomIndex] = temporaryValue;
}
return array;
};
data1.value.push({
name: "Revenues",
data: randomizeArray(sparkline1Data),
});
data2.value.push({
name: "Users",
data: randomizeArray(sparkline2Data),
});
data3.value.push({
name: "Products",
data: randomizeArray(sparkline3Data),
});
data4.value.push({
name: "Viewers",
data: randomizeArray(sparkline4Data),
});
const chartOptions = computed(() => ({
chart: {
type: "area",
sparkline: {
enabled: true,
},
},
stroke: {
curve: "smooth",
},
fill: {
opacity: 1,
},
labels: [...Array(7).keys()].map((n) => `2022-06-0${n + 1}`),
xaxis: {
type: "datetime",
},
}));
// Radial Chart
const radialData = ref([44, 55, 67, 83]);
const chartOptionsRadial = computed(() => ({
chart: {
height: 350,
type: "radialBar",
},
plotOptions: {
radialBar: {
dataLabels: {
style: {
colors: "#9CA3AF",
},
name: {
offsetY: 30,
fontSize: "18px",
},
value: {
offsetY: -15,
fontSize: "30px",
},
total: {
show: true,
label: "Total",
formatter: function (w) {
// By default this function returns the average of all series. The below is just an example to show the use of custom formatter function
return 249;
},
},
},
},
},
labels: ["Product A", "Product B", "Product C", "Product D"],
stroke: {
lineCap: "round",
},
}));
// Transaction Graph
const transactionData = ref([
{
name: "Bill A",
data: [...Array(12).keys()].map((n) => Math.round(Math.random() * 100)),
},
{
name: "Bill B",
data: [...Array(12).keys()].map((n) => Math.round(Math.random() * 100)),
},
]);
const chartOptionsTransaction = computed(() => ({
chart: {
height: 350,
type: "area",
toolbar: {
show: false,
},
},
dataLabels: {
enabled: false,
},
stroke: {
curve: "smooth",
},
colors: ["#6366F1", "#F97316"],
yaxis: {
labels: {
style: {
colors: "#9CA3AF",
fontSize: "12px",
},
},
},
xaxis: {
type: "datetime",
categories: [
"2022-01-01",
"2022-02-01",
"2022-03-01",
"2022-04-01",
"2022-05-01",
"2022-06-01",
"2022-07-01",
"2022-08-01",
"2022-09-01",
"2022-10-01",
"2022-11-01",
"2022-12-01",
],
labels: {
style: {
colors: "#9CA3AF",
fontSize: "14px",
fontWeight: 400,
},
datetimeFormatter: {
month: "MMM",
},
},
},
legend: {
position: "top",
horizontalAlign: "left",
labels: {
colors: "#9CA3AF",
useSeriesColors: false,
},
},
tooltip: {
x: {
format: "MMMM",
},
},
}));
onMounted(() => {
setTimeout(() => {
changeKey.value++;
}, 500);
});
</script>
<template>
<div>
<LayoutsBreadcrumb />
<!-- First Row -->
<div class="grid grid-cols-1 lg:grid-cols-2 xl:grid-cols-4 gap-x-6">
<!-- Summary Card #1 -->
<rs-card>
<div class="summary-1 pt-5 pb-3 px-5 flex items-center gap-4">
<div
class="p-5 flex justify-center items-center bg-primary/20 rounded-2xl"
>
<Icon class="text-primary" name="ic:outline-attach-money"></Icon>
</div>
<div class="flex-1 truncate">
<span class="block font-semibold text-xl leading-tight">
RM 100,000</span
>
<span class="text-base font-semibold text-gray-500"
>Total Revenues</span
>
</div>
</div>
<client-only>
<VueApexCharts
:key="changeKey"
width="100%"
height="53"
:options="{
...chartOptions,
colors: ['#F43F5E'],
yaxis: {
min: 0,
max: Math.max(...data1[0].data) + 10,
},
}"
:series="data1"
></VueApexCharts>
</client-only>
</rs-card>
<!-- Summary Card #2 -->
<rs-card>
<div class="summary-2 pt-5 pb-3 px-5 flex items-center gap-4">
<div
class="p-5 flex justify-center items-center bg-indigo-100 rounded-2xl"
>
<Icon
class="text-indigo-500"
name="ic:outline-account-circle"
></Icon>
</div>
<div class="flex-1 truncate">
<span class="block font-semibold text-xl leading-tight"> 512</span>
<span class="text-base font-semibold text-gray-500"
>Total Users</span
>
</div>
</div>
<client-only>
<VueApexCharts
:key="changeKey"
width="100%"
height="53"
:options="{
...chartOptions,
colors: ['#6366F1'],
yaxis: {
min: 0,
max: Math.max(...data2[0].data) + 10,
},
}"
:series="data2"
></VueApexCharts>
</client-only>
</rs-card>
<!-- Summary Card #3 -->
<rs-card>
<div class="summary-3 pt-5 pb-3 px-5 flex items-center gap-4">
<div
class="p-5 flex justify-center items-center bg-orange-100 rounded-2xl"
>
<Icon class="text-orange-500" name="ic:outline-shopping-bag"></Icon>
</div>
<div class="flex-1 truncate">
<span class="block font-semibold text-xl leading-tight"> 20</span>
<span class="text-base font-semibold text-gray-500"
>Total Products</span
>
</div>
</div>
<client-only>
<VueApexCharts
:key="changeKey"
width="100%"
height="53"
:options="{
...chartOptions,
colors: ['#F97316'],
yaxis: {
min: 0,
max: Math.max(...data3[0].data) + 10,
},
}"
:series="data3"
></VueApexCharts>
</client-only>
</rs-card>
<!-- Summary Card #4 -->
<rs-card>
<div class="summary-4 pt-5 pb-3 px-5 flex items-center gap-4">
<div
class="p-5 flex justify-center items-center bg-blue-100 rounded-2xl"
>
<Icon class="text-blue-500" name="ic:outline-remove-red-eye"></Icon>
</div>
<div class="flex-1 truncate">
<span class="block font-semibold text-xl leading-tight">
2,452</span
>
<span class="text-base font-semibold text-gray-500"
>Total Viewers</span
>
</div>
</div>
<client-only>
<VueApexCharts
:key="changeKey"
width="100%"
height="53"
:options="{
...chartOptions,
colors: ['#3B82F6'],
yaxis: {
min: 0,
max: Math.max(...data4[0].data) + 10,
},
}"
:series="data4"
></VueApexCharts>
</client-only>
</rs-card>
</div>
<div class="flex flex-col md:flex-row gap-x-6">
<div class="w-12/2 md:w-8/12 flex flex-col">
<!-- Graph -->
<rs-card class="flex-1">
<template #header> Transaction </template>
<template #body>
<client-only>
<VueApexCharts
:key="changeKey"
width="100%"
height="300"
name="area"
:options="chartOptionsTransaction"
:series="transactionData"
></VueApexCharts
></client-only>
</template>
</rs-card>
<rs-card class="flex-1">
<template #header> Referral</template>
<template #body>
<div
v-for="(val, index) in customers"
:key="index"
class="flex justify-between items-center rounded-lg bg-[rgb(var(--bg-1))] p-5 first:mt-0 mt-3"
>
<div class="flex items-center gap-x-4">
<img
src="@/assets/img/avatar/user.webp"
class="h-10 w-10 rounded-lg"
/>
<div class="flex-1">
<div class="flex flex-col">
<span
class="text-gray-900 dark:text-white font-semibold text-lg"
>
{{ val.name }}
</span>
<span class="text-gray-600 dark:text-gray-50 text-sm">
RM{{ parseFloat(val.totalPurchase).toFixed(2) }} |
{{ val.purchase }} sold
</span>
</div>
</div>
</div>
<div>
<button
class="flex items-center p-4 rounded-full bg-[rgb(var(--bg-2))] hover:bg-[rgb(var(--bg-2))]/10 shadow-md"
>
<Icon size="20px" name="ic:baseline-mail-outline"></Icon>
</button>
</div>
</div>
</template>
</rs-card>
</div>
<div class="w-12/2 md:w-4/12 flex flex-col">
<!-- Monthly Target Radial -->
<rs-card class="flex-1">
<template #header> Monthly Target </template>
<template #body>
<client-only>
<VueApexCharts
:key="changeKey"
width="100%"
height="300"
name="radialBar"
:options="chartOptionsRadial"
:series="radialData"
></VueApexCharts>
</client-only>
<hr class="my-4" />
<p class="text-xl py-5 font-medium">Products</p>
<div
class="flex item-center gap-x-4"
:class="{
'mt-0': index === 0,
'mt-3': index !== 0,
}"
v-for="(val, index) in ['A', 'B', 'C', 'D', 'E']"
:key="index"
>
<img
src="@/assets/img/default-thumbnail.jpg"
class="h-20 w-20 object-cover rounded-lg"
/>
<div class="flex-1 flex items-center">
<div>
<span class="font-semibold text-lg leading-tight"
>Product {{ val }}</span
>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
</p>
</div>
</div>
</div>
</template>
</rs-card>
</div>
</div>
</div>
</template>