chore: install prettier
This commit is contained in:
@@ -1,17 +1,18 @@
|
||||
<template>
|
||||
<div
|
||||
class="fs-13 font-semibold mx-0 px-0 is-flex is-justify-content-center is-align-items-center is-flex-shrink-0 rounded-full size-10"
|
||||
<template>
|
||||
<div
|
||||
class="fs-13 font-semibold mx-0 px-0 is-flex is-justify-content-center is-align-items-center is-flex-shrink-0 rounded-full size-10"
|
||||
style="border: 1px solid var(--bulma-grey-80)"
|
||||
:style="image && 'border: none'">
|
||||
:style="image && 'border: none'"
|
||||
>
|
||||
<div>
|
||||
<span>{{text}}</span>
|
||||
<span>{{ text }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
props: ['text', 'image', 'type', 'size']
|
||||
}
|
||||
export default {
|
||||
props: ["text", "image", "type", "size"],
|
||||
};
|
||||
</script>
|
||||
<style>
|
||||
.cbox {
|
||||
|
||||
@@ -1,72 +1,72 @@
|
||||
<script setup>
|
||||
import DashboardHighlightCard from '@/components/dashboard/DashboardHighlightCard.vue';
|
||||
import Delivery from '@/components/dashboard/Delivery.vue';
|
||||
import OrderStatus from '@/components/dashboard/OrderStatus.vue';
|
||||
import RevenueChart from '@/components/dashboard/RevenueChart.vue';
|
||||
import TopCustomers from '@/components/dashboard/TopCustomers.vue';
|
||||
import TopProducts from '@/components/dashboard/TopProducts.vue';
|
||||
import Warnings from '@/components/dashboard/Warnings.vue';
|
||||
import DashboardHighlightCard from "@/components/dashboard/DashboardHighlightCard.vue";
|
||||
import Delivery from "@/components/dashboard/Delivery.vue";
|
||||
import OrderStatus from "@/components/dashboard/OrderStatus.vue";
|
||||
import RevenueChart from "@/components/dashboard/RevenueChart.vue";
|
||||
import TopCustomers from "@/components/dashboard/TopCustomers.vue";
|
||||
import TopProducts from "@/components/dashboard/TopProducts.vue";
|
||||
import Warnings from "@/components/dashboard/Warnings.vue";
|
||||
|
||||
const highlights = [
|
||||
{
|
||||
name: 'Doanh thu hôm nay',
|
||||
value: '72.5M',
|
||||
color: 'blue',
|
||||
icon: 'material-symbols:attach-money-rounded',
|
||||
subheader: {
|
||||
value: '+12.5%',
|
||||
fluctuation: 'up',
|
||||
}
|
||||
name: "Doanh thu hôm nay",
|
||||
value: "72.5M",
|
||||
color: "blue",
|
||||
icon: "material-symbols:attach-money-rounded",
|
||||
subheader: {
|
||||
value: "+12.5%",
|
||||
fluctuation: "up",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'Số đơn hàng',
|
||||
value: '73',
|
||||
color: 'purple',
|
||||
icon: 'material-symbols:shopping-cart-outline-rounded',
|
||||
subheader: {
|
||||
value: '+8 đơn',
|
||||
fluctuation: 'up',
|
||||
}
|
||||
name: "Số đơn hàng",
|
||||
value: "73",
|
||||
color: "purple",
|
||||
icon: "material-symbols:shopping-cart-outline-rounded",
|
||||
subheader: {
|
||||
value: "+8 đơn",
|
||||
fluctuation: "up",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'Đơn đang giao',
|
||||
value: '8',
|
||||
color: 'orange',
|
||||
icon: 'material-symbols:delivery-truck-speed-outline-rounded',
|
||||
name: "Đơn đang giao",
|
||||
value: "8",
|
||||
color: "orange",
|
||||
icon: "material-symbols:delivery-truck-speed-outline-rounded",
|
||||
},
|
||||
{
|
||||
name: 'Đơn hoàn thành',
|
||||
value: '38',
|
||||
color: 'green',
|
||||
icon: 'material-symbols:check-circle-outline-rounded',
|
||||
name: "Đơn hoàn thành",
|
||||
value: "38",
|
||||
color: "green",
|
||||
icon: "material-symbols:check-circle-outline-rounded",
|
||||
},
|
||||
{
|
||||
name: 'Công nợ phải thu',
|
||||
value: '245M',
|
||||
color: 'red',
|
||||
icon: 'material-symbols:universal-currency-alt-outline-rounded',
|
||||
subheader: {
|
||||
value: '+15M',
|
||||
fluctuation: 'down',
|
||||
}
|
||||
name: "Công nợ phải thu",
|
||||
value: "245M",
|
||||
color: "red",
|
||||
icon: "material-symbols:universal-currency-alt-outline-rounded",
|
||||
subheader: {
|
||||
value: "+15M",
|
||||
fluctuation: "down",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'Tồn kho',
|
||||
value: '1,250',
|
||||
color: 'cyan',
|
||||
icon: 'material-symbols:box-outline-rounded',
|
||||
subheader: {
|
||||
value: '-45 SP',
|
||||
fluctuation: 'down',
|
||||
}
|
||||
name: "Tồn kho",
|
||||
value: "1,250",
|
||||
color: "cyan",
|
||||
icon: "material-symbols:box-outline-rounded",
|
||||
subheader: {
|
||||
value: "-45 SP",
|
||||
fluctuation: "down",
|
||||
},
|
||||
},
|
||||
]
|
||||
];
|
||||
</script>
|
||||
<template>
|
||||
<div>
|
||||
<div class="fixed-grid has-2-cols has-3-cols-tablet has-6-cols-desktop">
|
||||
<div class="grid">
|
||||
<DashboardHighlightCard
|
||||
<DashboardHighlightCard
|
||||
v-for="highlight in highlights"
|
||||
:key="highlight.name"
|
||||
v-bind="highlight"
|
||||
@@ -88,4 +88,4 @@ const highlights = [
|
||||
<Delivery />
|
||||
<Warnings />
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
@@ -4,8 +4,8 @@ const props = defineProps({
|
||||
value: String,
|
||||
color: String,
|
||||
icon: String,
|
||||
subheader: Object
|
||||
})
|
||||
subheader: Object,
|
||||
});
|
||||
</script>
|
||||
<template>
|
||||
<div class="cell">
|
||||
@@ -14,14 +14,19 @@ const props = defineProps({
|
||||
<div>
|
||||
<p class="fs-14 has-text-grey mb-1">{{ name }}</p>
|
||||
<p class="fsb-26 mb-1 has-text-black">{{ value }}</p>
|
||||
<div v-if="subheader"
|
||||
<div
|
||||
v-if="subheader"
|
||||
:class="[
|
||||
'is-flex is-gap-0.5 is-align-items-center',
|
||||
subheader.fluctuation === 'up' ? 'has-text-green-40' : 'has-text-red-40'
|
||||
subheader.fluctuation === 'up' ? 'has-text-green-40' : 'has-text-red-40',
|
||||
]"
|
||||
>
|
||||
<Icon
|
||||
:name="subheader.fluctuation === 'up' ? 'material-symbols:arrow-upward-rounded' :'material-symbols:arrow-downward-rounded'"
|
||||
:name="
|
||||
subheader.fluctuation === 'up'
|
||||
? 'material-symbols:arrow-upward-rounded'
|
||||
: 'material-symbols:arrow-downward-rounded'
|
||||
"
|
||||
color="inherit"
|
||||
/>
|
||||
<p class="fs-14">{{ subheader.value }}</p>
|
||||
@@ -30,12 +35,15 @@ const props = defineProps({
|
||||
<div
|
||||
:class="[
|
||||
'rounded-lg size-12 is-flex-shrink-0 is-flex is-justify-content-center is-align-items-center',
|
||||
`has-background-${color}-soft has-text-${color}-40`
|
||||
`has-background-${color}-soft has-text-${color}-40`,
|
||||
]"
|
||||
">
|
||||
<Icon :name="icon" :size="28" />
|
||||
>
|
||||
<Icon
|
||||
:name="icon"
|
||||
:size="28"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
@@ -1,33 +1,33 @@
|
||||
<script setup>
|
||||
import DeliveryInteractive from '@/components/dashboard/DeliveryInteractive.vue';
|
||||
import Driver from '@/components/dashboard/Driver.vue';
|
||||
import DeliveryInteractive from "@/components/dashboard/DeliveryInteractive.vue";
|
||||
import Driver from "@/components/dashboard/Driver.vue";
|
||||
|
||||
const drivers = [
|
||||
{
|
||||
name: 'Nguyễn Văn A',
|
||||
status: 'Đang giao',
|
||||
name: "Nguyễn Văn A",
|
||||
status: "Đang giao",
|
||||
deliveries: 3,
|
||||
deliveries_completed: 2,
|
||||
},
|
||||
{
|
||||
name: 'Trần Văn B',
|
||||
status: 'Đang giao',
|
||||
name: "Trần Văn B",
|
||||
status: "Đang giao",
|
||||
deliveries: 2,
|
||||
deliveries_completed: 1,
|
||||
},
|
||||
{
|
||||
name: 'Lê Thị C',
|
||||
status: 'Hoàn thành',
|
||||
name: "Lê Thị C",
|
||||
status: "Hoàn thành",
|
||||
deliveries: 4,
|
||||
deliveries_completed: 4,
|
||||
},
|
||||
{
|
||||
name: 'Phạm Văn D',
|
||||
status: 'Đang giao',
|
||||
name: "Phạm Văn D",
|
||||
status: "Đang giao",
|
||||
deliveries: 1,
|
||||
deliveries_completed: 0,
|
||||
},
|
||||
]
|
||||
];
|
||||
</script>
|
||||
<template>
|
||||
<div class="card">
|
||||
@@ -51,4 +51,4 @@ const drivers = [
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
@@ -3,7 +3,47 @@
|
||||
class="relative w-full has-background-blue-95 rounded-lg is-clipped"
|
||||
style="height: 360px"
|
||||
>
|
||||
<div class="absolute inset-0 w-full h-full opacity-20"><div class="absolute w-full border-t border-gray-300" style="top: 20%;"></div><div class="absolute w-full border-t border-gray-300" style="top: 40%;"></div><div class="absolute w-full border-t border-gray-300" style="top: 60%;"></div><div class="absolute w-full border-t border-gray-300" style="top: 80%;"></div><div class="absolute w-full border-t border-gray-300" style="top: 100%;"></div><div class="absolute h-full border-l border-gray-300" style="left: 20%;"></div><div class="absolute h-full border-l border-gray-300" style="left: 40%;"></div><div class="absolute h-full border-l border-gray-300" style="left: 60%;"></div><div class="absolute h-full border-l border-gray-300" style="left: 80%;"></div><div class="absolute h-full border-l border-gray-300" style="left: 100%;"></div>
|
||||
<div class="absolute inset-0 w-full h-full opacity-20">
|
||||
<div
|
||||
class="absolute w-full border-t border-gray-300"
|
||||
style="top: 20%"
|
||||
></div>
|
||||
<div
|
||||
class="absolute w-full border-t border-gray-300"
|
||||
style="top: 40%"
|
||||
></div>
|
||||
<div
|
||||
class="absolute w-full border-t border-gray-300"
|
||||
style="top: 60%"
|
||||
></div>
|
||||
<div
|
||||
class="absolute w-full border-t border-gray-300"
|
||||
style="top: 80%"
|
||||
></div>
|
||||
<div
|
||||
class="absolute w-full border-t border-gray-300"
|
||||
style="top: 100%"
|
||||
></div>
|
||||
<div
|
||||
class="absolute h-full border-l border-gray-300"
|
||||
style="left: 20%"
|
||||
></div>
|
||||
<div
|
||||
class="absolute h-full border-l border-gray-300"
|
||||
style="left: 40%"
|
||||
></div>
|
||||
<div
|
||||
class="absolute h-full border-l border-gray-300"
|
||||
style="left: 60%"
|
||||
></div>
|
||||
<div
|
||||
class="absolute h-full border-l border-gray-300"
|
||||
style="left: 80%"
|
||||
></div>
|
||||
<div
|
||||
class="absolute h-full border-l border-gray-300"
|
||||
style="left: 100%"
|
||||
></div>
|
||||
</div>
|
||||
<div>
|
||||
<div
|
||||
@@ -25,7 +65,11 @@
|
||||
<path
|
||||
d="M20 10c0 4.993-5.539 10.193-7.399 11.799a1 1 0 0 1-1.202 0C9.539 20.193 4 14.993 4 10a8 8 0 0 1 16 0"
|
||||
></path>
|
||||
<circle cx="12" cy="10" r="3"></circle>
|
||||
<circle
|
||||
cx="12"
|
||||
cy="10"
|
||||
r="3"
|
||||
></circle>
|
||||
</svg>
|
||||
</div>
|
||||
<div
|
||||
@@ -47,7 +91,11 @@
|
||||
<path
|
||||
d="M20 10c0 4.993-5.539 10.193-7.399 11.799a1 1 0 0 1-1.202 0C9.539 20.193 4 14.993 4 10a8 8 0 0 1 16 0"
|
||||
></path>
|
||||
<circle cx="12" cy="10" r="3"></circle>
|
||||
<circle
|
||||
cx="12"
|
||||
cy="10"
|
||||
r="3"
|
||||
></circle>
|
||||
</svg>
|
||||
</div>
|
||||
<div
|
||||
@@ -69,7 +117,11 @@
|
||||
<path
|
||||
d="M20 10c0 4.993-5.539 10.193-7.399 11.799a1 1 0 0 1-1.202 0C9.539 20.193 4 14.993 4 10a8 8 0 0 1 16 0"
|
||||
></path>
|
||||
<circle cx="12" cy="10" r="3"></circle>
|
||||
<circle
|
||||
cx="12"
|
||||
cy="10"
|
||||
r="3"
|
||||
></circle>
|
||||
</svg>
|
||||
</div>
|
||||
<div
|
||||
@@ -91,7 +143,11 @@
|
||||
<path
|
||||
d="M20 10c0 4.993-5.539 10.193-7.399 11.799a1 1 0 0 1-1.202 0C9.539 20.193 4 14.993 4 10a8 8 0 0 1 16 0"
|
||||
></path>
|
||||
<circle cx="12" cy="10" r="3"></circle>
|
||||
<circle
|
||||
cx="12"
|
||||
cy="10"
|
||||
r="3"
|
||||
></circle>
|
||||
</svg>
|
||||
</div>
|
||||
<div
|
||||
@@ -113,7 +169,11 @@
|
||||
<path
|
||||
d="M20 10c0 4.993-5.539 10.193-7.399 11.799a1 1 0 0 1-1.202 0C9.539 20.193 4 14.993 4 10a8 8 0 0 1 16 0"
|
||||
></path>
|
||||
<circle cx="12" cy="10" r="3"></circle>
|
||||
<circle
|
||||
cx="12"
|
||||
cy="10"
|
||||
r="3"
|
||||
></circle>
|
||||
</svg>
|
||||
</div>
|
||||
<div
|
||||
@@ -139,9 +199,7 @@
|
||||
<polygon points="3 11 22 2 13 21 11 13 3 11"></polygon>
|
||||
</svg>
|
||||
</div>
|
||||
<div
|
||||
class="absolute -inset-1 rounded-full has-background-blue-60 animate-ping opacity-40"
|
||||
></div>
|
||||
<div class="absolute -inset-1 rounded-full has-background-blue-60 animate-ping opacity-40"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
@@ -167,9 +225,7 @@
|
||||
<polygon points="3 11 22 2 13 21 11 13 3 11"></polygon>
|
||||
</svg>
|
||||
</div>
|
||||
<div
|
||||
class="absolute -inset-1 rounded-full has-background-blue-60 animate-ping opacity-40"
|
||||
></div>
|
||||
<div class="absolute -inset-1 rounded-full has-background-blue-60 animate-ping opacity-40"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
@@ -220,9 +276,7 @@
|
||||
<polygon points="3 11 22 2 13 21 11 13 3 11"></polygon>
|
||||
</svg>
|
||||
</div>
|
||||
<div
|
||||
class="absolute -inset-1 rounded-full has-background-blue-60 animate-ping opacity-40"
|
||||
></div>
|
||||
<div class="absolute -inset-1 rounded-full has-background-blue-60 animate-ping opacity-40"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
@@ -244,7 +298,12 @@
|
||||
<path
|
||||
d="M20 10c0 4.993-5.539 10.193-7.399 11.799a1 1 0 0 1-1.202 0C9.539 20.193 4 14.993 4 10a8 8 0 0 1 16 0"
|
||||
></path>
|
||||
<circle cx="12" cy="10" r="3"></circle></svg>Hà Nội
|
||||
<circle
|
||||
cx="12"
|
||||
cy="10"
|
||||
r="3"
|
||||
></circle></svg
|
||||
>Hà Nội
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -314,7 +373,7 @@
|
||||
transform: var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,);
|
||||
}
|
||||
.animate-ping {
|
||||
animation: ping 1s cubic-bezier(0,0,0.2,1) infinite;
|
||||
animation: ping 1s cubic-bezier(0, 0, 0.2, 1) infinite;
|
||||
}
|
||||
@keyframes ping {
|
||||
0% {
|
||||
@@ -339,67 +398,67 @@
|
||||
|
||||
@keyframes move-random-1 {
|
||||
0% {
|
||||
transform: translateX(0) translateY(0)
|
||||
transform: translateX(0) translateY(0);
|
||||
}
|
||||
|
||||
33% {
|
||||
transform: translateX(30px) translateY(24px)
|
||||
transform: translateX(30px) translateY(24px);
|
||||
}
|
||||
|
||||
66% {
|
||||
transform: translateX(60px) translateY(12px)
|
||||
transform: translateX(60px) translateY(12px);
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: translateX(0) translateY(0)
|
||||
transform: translateX(0) translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes move-random-2 {
|
||||
0% {
|
||||
transform: translateX(0) translateY(0)
|
||||
transform: translateX(0) translateY(0);
|
||||
}
|
||||
|
||||
23% {
|
||||
transform: translateX(-20px) translateY(-36px)
|
||||
transform: translateX(-20px) translateY(-36px);
|
||||
}
|
||||
|
||||
46% {
|
||||
transform: translateX(0) translateY(22px)
|
||||
transform: translateX(0) translateY(22px);
|
||||
}
|
||||
|
||||
75% {
|
||||
transform: translateX(30px) translateY(-12px)
|
||||
transform: translateX(30px) translateY(-12px);
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: translateX(0) translateY(0)
|
||||
transform: translateX(0) translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes move-random-3 {
|
||||
0% {
|
||||
transform: translateX(0) translateY(0)
|
||||
transform: translateX(0) translateY(0);
|
||||
}
|
||||
|
||||
10% {
|
||||
transform: translateX(-30px) translateY(-15px)
|
||||
transform: translateX(-30px) translateY(-15px);
|
||||
}
|
||||
|
||||
30% {
|
||||
transform: translateX(-10px) translateY(26px)
|
||||
transform: translateX(-10px) translateY(26px);
|
||||
}
|
||||
|
||||
50% {
|
||||
transform: translateX(48px) translateY(-28px)
|
||||
transform: translateX(48px) translateY(-28px);
|
||||
}
|
||||
|
||||
80% {
|
||||
transform: translateX(17px) translateY(10px)
|
||||
transform: translateX(17px) translateY(10px);
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: translateX(0) translateY(0)
|
||||
transform: translateX(0) translateY(0);
|
||||
}
|
||||
}
|
||||
.border-2 {
|
||||
@@ -442,13 +501,20 @@
|
||||
opacity: 40%;
|
||||
}
|
||||
.shadow {
|
||||
--tw-shadow: 0 1px 3px 0 var(--tw-shadow-color, rgb(0 0 0 / 0.1)), 0 1px 2px -1px var(--tw-shadow-color, rgb(0 0 0 / 0.1));
|
||||
box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
|
||||
--tw-shadow:
|
||||
0 1px 3px 0 var(--tw-shadow-color, rgb(0 0 0 / 0.1)), 0 1px 2px -1px var(--tw-shadow-color, rgb(0 0 0 / 0.1));
|
||||
box-shadow:
|
||||
var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow),
|
||||
var(--tw-shadow);
|
||||
}
|
||||
.backdrop-blur {
|
||||
--tw-backdrop-blur: blur(8px);
|
||||
-webkit-backdrop-filter: var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);
|
||||
backdrop-filter: var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);
|
||||
-webkit-backdrop-filter: var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,)
|
||||
var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,)
|
||||
var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);
|
||||
backdrop-filter: var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,)
|
||||
var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,)
|
||||
var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);
|
||||
}
|
||||
.transition-all {
|
||||
transition-property: all;
|
||||
@@ -474,4 +540,4 @@
|
||||
.border-gray-300 {
|
||||
border-color: var(--bulma-grey-85);
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
<script setup>
|
||||
import AvatarBox from '@/components/dashboard/AvatarBox.vue';
|
||||
import AvatarBox from "@/components/dashboard/AvatarBox.vue";
|
||||
|
||||
const props = defineProps({
|
||||
name: String,
|
||||
status: String,
|
||||
deliveries: Number,
|
||||
deliveries_completed: Number,
|
||||
})
|
||||
});
|
||||
</script>
|
||||
<template>
|
||||
<div
|
||||
<div
|
||||
class="is-flex is-gap-2 fs-14 p-3 rounded-lg"
|
||||
:style="{
|
||||
border: '1px solid var(--bulma-grey-80)',
|
||||
@@ -22,14 +22,13 @@ const props = defineProps({
|
||||
<span :class="['tag', status === 'Đang giao' ? 'is-warning' : 'is-success']">{{ status }}</span>
|
||||
</div>
|
||||
<p class="fs-13 has-text-grey">Đơn: {{ deliveries_completed }}/{{ deliveries }}</p>
|
||||
<progress
|
||||
<progress
|
||||
v-if="deliveries !== deliveries_completed"
|
||||
class="progress is-small is-primary mt-2"
|
||||
style="--bulma-size-small: 0.4rem;"
|
||||
style="--bulma-size-small: 0.4rem"
|
||||
:value="deliveries_completed"
|
||||
:max="deliveries"
|
||||
>
|
||||
</progress>
|
||||
></progress>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -1,40 +1,40 @@
|
||||
<script setup>
|
||||
import OrderStatusCard from '@/components/dashboard/OrderStatusCard.vue';
|
||||
import OrderStatusCard from "@/components/dashboard/OrderStatusCard.vue";
|
||||
|
||||
const statuses = [
|
||||
{
|
||||
id: 1,
|
||||
code: 'pending',
|
||||
name: 'Chờ xử lý',
|
||||
code: "pending",
|
||||
name: "Chờ xử lý",
|
||||
value: 12,
|
||||
color: 'orange',
|
||||
icon: 'material-symbols:clock-loader-40'
|
||||
color: "orange",
|
||||
icon: "material-symbols:clock-loader-40",
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
code: 'delivering',
|
||||
name: 'Đang giao',
|
||||
code: "delivering",
|
||||
name: "Đang giao",
|
||||
value: 8,
|
||||
color: 'blue',
|
||||
icon: 'material-symbols:delivery-truck-speed-outline-rounded'
|
||||
color: "blue",
|
||||
icon: "material-symbols:delivery-truck-speed-outline-rounded",
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
code: 'delivered',
|
||||
name: 'Đã giao',
|
||||
code: "delivered",
|
||||
name: "Đã giao",
|
||||
value: 15,
|
||||
color: 'purple',
|
||||
icon: 'material-symbols:bucket-check-outline-rounded'
|
||||
color: "purple",
|
||||
icon: "material-symbols:bucket-check-outline-rounded",
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
code: 'completed',
|
||||
name: 'Hoàn thành',
|
||||
code: "completed",
|
||||
name: "Hoàn thành",
|
||||
value: 38,
|
||||
color: 'green',
|
||||
icon: 'material-symbols:check-circle-outline-rounded'
|
||||
color: "green",
|
||||
icon: "material-symbols:check-circle-outline-rounded",
|
||||
},
|
||||
]
|
||||
];
|
||||
</script>
|
||||
<template>
|
||||
<div class="card h-full">
|
||||
@@ -51,4 +51,4 @@ const statuses = [
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
@@ -6,18 +6,16 @@ const props = defineProps({
|
||||
value: Number,
|
||||
icon: String,
|
||||
color: String,
|
||||
})
|
||||
});
|
||||
</script>
|
||||
<template>
|
||||
<div class="cell">
|
||||
<div class="card" :style="{ border: `1px solid var(--bulma-${color}-70)` }">
|
||||
<div
|
||||
class="card"
|
||||
:style="{ border: `1px solid var(--bulma-${color}-70)` }"
|
||||
>
|
||||
<div class="card-content is-flex is-flex-direction-column is-align-items-center is-gap-1">
|
||||
<div
|
||||
:class="[
|
||||
'p-3 is-flex rounded-full',
|
||||
`has-background-${color}-90`,
|
||||
`has-text-${color}-40`,
|
||||
]" >
|
||||
<div :class="['p-3 is-flex rounded-full', `has-background-${color}-90`, `has-text-${color}-40`]">
|
||||
<Icon
|
||||
:name="icon"
|
||||
:size="24"
|
||||
@@ -30,4 +28,4 @@ const props = defineProps({
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
const { $shortenCurrency } = useNuxtApp();
|
||||
const revenueChartOptions = {
|
||||
chart: {
|
||||
type: 'spline'
|
||||
type: "spline",
|
||||
},
|
||||
credits: {
|
||||
enabled: false,
|
||||
@@ -11,38 +11,38 @@ const revenueChartOptions = {
|
||||
text: null,
|
||||
},
|
||||
xAxis: {
|
||||
categories: [
|
||||
'10/4', '11/4', '12/4', '13/4', '14/4', '15/4', '16/4', '17/4', '18/4'
|
||||
],
|
||||
categories: ["10/4", "11/4", "12/4", "13/4", "14/4", "15/4", "16/4", "17/4", "18/4"],
|
||||
accessibility: {
|
||||
description: 'Dates'
|
||||
}
|
||||
description: "Dates",
|
||||
},
|
||||
},
|
||||
yAxis: {
|
||||
title: {
|
||||
text: 'Doanh thu'
|
||||
text: "Doanh thu",
|
||||
},
|
||||
labels: {
|
||||
format: '{value}'
|
||||
}
|
||||
format: "{value}",
|
||||
},
|
||||
},
|
||||
tooltip: {
|
||||
crosshairs: true,
|
||||
shared: true,
|
||||
valueSuffix: ' VNĐ',
|
||||
valueSuffix: " VNĐ",
|
||||
},
|
||||
plotOptions: {
|
||||
spline: {
|
||||
marker: {
|
||||
enabled: false
|
||||
}
|
||||
}
|
||||
enabled: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
series: [{
|
||||
name: 'Doanh thu',
|
||||
data: [45000000, 52000000, 48000000, 51000000, 58000000, 61000000, 67500000, 72000000, 69000000],
|
||||
showInLegend: false,
|
||||
}]
|
||||
series: [
|
||||
{
|
||||
name: "Doanh thu",
|
||||
data: [45000000, 52000000, 48000000, 51000000, 58000000, 61000000, 67500000, 72000000, 69000000],
|
||||
showInLegend: false,
|
||||
},
|
||||
],
|
||||
};
|
||||
</script>
|
||||
<template>
|
||||
@@ -58,4 +58,4 @@ const revenueChartOptions = {
|
||||
<highcharts :options="revenueChartOptions" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
<script setup>
|
||||
import AvatarBox from '@/components/dashboard/AvatarBox.vue';
|
||||
import AvatarBox from "@/components/dashboard/AvatarBox.vue";
|
||||
|
||||
const props = defineProps({
|
||||
name: String,
|
||||
order_count: Number,
|
||||
paid: Number,
|
||||
})
|
||||
});
|
||||
|
||||
const { $shortenCurrency } = useNuxtApp();
|
||||
</script>
|
||||
@@ -20,4 +20,4 @@ const { $shortenCurrency } = useNuxtApp();
|
||||
</div>
|
||||
<p class="font-semibold">{{ $shortenCurrency(paid) }}</p>
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
@@ -1,35 +1,33 @@
|
||||
<script setup>
|
||||
import TopCustomer from '@/components/dashboard/TopCustomer.vue';
|
||||
|
||||
import TopCustomer from "@/components/dashboard/TopCustomer.vue";
|
||||
|
||||
const customers = [
|
||||
{
|
||||
name: 'Công ty TNHH ABC',
|
||||
name: "Công ty TNHH ABC",
|
||||
order_count: 45,
|
||||
paid: 125000000,
|
||||
},
|
||||
{
|
||||
name: 'Siêu thị XYZ',
|
||||
name: "Siêu thị XYZ",
|
||||
order_count: 38,
|
||||
paid: 98000000,
|
||||
},
|
||||
{
|
||||
name: 'Nhà hàng Đông Dương',
|
||||
name: "Nhà hàng Đông Dương",
|
||||
order_count: 32,
|
||||
paid: 87000000,
|
||||
},
|
||||
{
|
||||
name: 'Khách sạn Mường Thanh',
|
||||
name: "Khách sạn Mường Thanh",
|
||||
order_count: 28,
|
||||
paid: 76000000,
|
||||
},
|
||||
{
|
||||
name: 'Cửa hàng Bách Hoá',
|
||||
name: "Cửa hàng Bách Hoá",
|
||||
order_count: 24,
|
||||
paid: 64000000,
|
||||
},
|
||||
|
||||
]
|
||||
];
|
||||
</script>
|
||||
<template>
|
||||
<div class="card">
|
||||
@@ -44,4 +42,4 @@ const customers = [
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
@@ -17,7 +17,11 @@ const { $shortenCurrency } = useNuxtApp();
|
||||
</div>
|
||||
<p class="font-semibold">{{ $shortenCurrency(revenue) }}</p>
|
||||
</div>
|
||||
<progress class="progress is-small is-primary" :value="revenue" :max="topRevenue">
|
||||
<progress
|
||||
class="progress is-small is-primary"
|
||||
:value="revenue"
|
||||
:max="topRevenue"
|
||||
>
|
||||
15%
|
||||
</progress>
|
||||
</div>
|
||||
@@ -26,4 +30,4 @@ const { $shortenCurrency } = useNuxtApp();
|
||||
.progress {
|
||||
--bulma-size-small: 0.5rem;
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
||||
@@ -1,33 +1,33 @@
|
||||
<script setup>
|
||||
import TopProduct from '@/components/dashboard/TopProduct.vue';
|
||||
import TopProduct from "@/components/dashboard/TopProduct.vue";
|
||||
|
||||
const products = [
|
||||
{
|
||||
name: 'Gạo ST25 - Bao 5kg',
|
||||
name: "Gạo ST25 - Bao 5kg",
|
||||
sold_count: 1250,
|
||||
revenue: 156000000
|
||||
revenue: 156000000,
|
||||
},
|
||||
{
|
||||
name: 'Nước mắm Phú Quốc - Chai 500ml',
|
||||
name: "Nước mắm Phú Quốc - Chai 500ml",
|
||||
sold_count: 980,
|
||||
revenue: 132000000
|
||||
revenue: 132000000,
|
||||
},
|
||||
{
|
||||
name: 'Đường tinh luyện - Bao 1kg',
|
||||
name: "Đường tinh luyện - Bao 1kg",
|
||||
sold_count: 856,
|
||||
revenue: 98000000
|
||||
revenue: 98000000,
|
||||
},
|
||||
{
|
||||
name: 'Dầu ăn Neptune - Chai 1L',
|
||||
name: "Dầu ăn Neptune - Chai 1L",
|
||||
sold_count: 742,
|
||||
revenue: 87000000
|
||||
revenue: 87000000,
|
||||
},
|
||||
{
|
||||
name: 'Bột mì đa dụng - Bao 1kg',
|
||||
name: "Bột mì đa dụng - Bao 1kg",
|
||||
sold_count: 623,
|
||||
revenue: 72000000
|
||||
revenue: 72000000,
|
||||
},
|
||||
]
|
||||
];
|
||||
</script>
|
||||
<template>
|
||||
<div class="card">
|
||||
@@ -35,14 +35,14 @@ const products = [
|
||||
<p class="fs-17 font-semibold mb-4">Top sản phẩm</p>
|
||||
<div class="is-flex is-flex-direction-column is-gap-2">
|
||||
<TopProduct
|
||||
v-for="product in products"
|
||||
v-for="product in products"
|
||||
:key="product.name"
|
||||
v-bind="{
|
||||
...product,
|
||||
topRevenue: products[0].revenue
|
||||
topRevenue: products[0].revenue,
|
||||
}"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
@@ -3,17 +3,16 @@ const props = defineProps({
|
||||
name: String,
|
||||
details: String,
|
||||
level: Number,
|
||||
type: String
|
||||
})
|
||||
type: String,
|
||||
});
|
||||
|
||||
const color = computed(() => {
|
||||
if (props.level === 1) return 'yellow';
|
||||
if (props.level === 2) return 'orange';
|
||||
if (props.level === 3) return 'red';
|
||||
})
|
||||
if (props.level === 1) return "yellow";
|
||||
if (props.level === 2) return "orange";
|
||||
if (props.level === 3) return "red";
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
<template>
|
||||
<div
|
||||
:class="['card m-0', `has-background-${color}-95`]"
|
||||
@@ -22,7 +21,7 @@ const color = computed(() => {
|
||||
}"
|
||||
>
|
||||
<div class="card-content p-4 is-flex is-align-items-center is-gap-2">
|
||||
<Icon
|
||||
<Icon
|
||||
:name="type === 'time' ? 'material-symbols:clock-loader-40' : 'material-symbols:box-outline-rounded'"
|
||||
:size="20"
|
||||
:class="`has-text-${color}-45`"
|
||||
@@ -33,4 +32,4 @@ const color = computed(() => {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
@@ -1,26 +1,26 @@
|
||||
<script setup>
|
||||
import Warning from '@/components/dashboard/Warning.vue';
|
||||
import Warning from "@/components/dashboard/Warning.vue";
|
||||
|
||||
const warnings = [
|
||||
{
|
||||
name: 'Công nợ sắp đến hạn',
|
||||
details: 'Công ty TNHH ABC - 35.000.000đ - Hạn: 25/03/2026',
|
||||
name: "Công nợ sắp đến hạn",
|
||||
details: "Công ty TNHH ABC - 35.000.000đ - Hạn: 25/03/2026",
|
||||
level: 1,
|
||||
type: 'time',
|
||||
type: "time",
|
||||
},
|
||||
{
|
||||
name: 'Đơn giao trễ',
|
||||
details: 'Đơn hàng #DH-2156 - Đã trễ 2 giờ - Khách: Siêu thị XYZ',
|
||||
name: "Đơn giao trễ",
|
||||
details: "Đơn hàng #DH-2156 - Đã trễ 2 giờ - Khách: Siêu thị XYZ",
|
||||
level: 3,
|
||||
type: 'time',
|
||||
type: "time",
|
||||
},
|
||||
{
|
||||
name: 'Tồn kho thấp',
|
||||
details: 'Gạo ST25 - Chỉ còn 45 bao - Cần nhập thêm',
|
||||
name: "Tồn kho thấp",
|
||||
details: "Gạo ST25 - Chỉ còn 45 bao - Cần nhập thêm",
|
||||
level: 2,
|
||||
type: 'inventory'
|
||||
type: "inventory",
|
||||
},
|
||||
]
|
||||
];
|
||||
</script>
|
||||
<template>
|
||||
<div class="card">
|
||||
@@ -35,4 +35,4 @@ const warnings = [
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
Reference in New Issue
Block a user