first commit
This commit is contained in:
110
resources/js/views/apps/logistics/LogisticsCardStatistics.vue
Normal file
110
resources/js/views/apps/logistics/LogisticsCardStatistics.vue
Normal file
@@ -0,0 +1,110 @@
|
||||
<script setup>
|
||||
const logisticData = ref([
|
||||
{
|
||||
icon: 'ri-car-line',
|
||||
color: 'primary',
|
||||
title: 'On route vehicles',
|
||||
value: 42,
|
||||
change: 18.2,
|
||||
isHover: false,
|
||||
},
|
||||
{
|
||||
icon: 'ri-alert-line',
|
||||
color: 'warning',
|
||||
title: 'Vehicles with errors',
|
||||
value: 8,
|
||||
change: -8.7,
|
||||
isHover: false,
|
||||
},
|
||||
{
|
||||
icon: 'ri-stackshare-line',
|
||||
color: 'error',
|
||||
title: 'Deviated from route',
|
||||
value: 27,
|
||||
change: 4.3,
|
||||
isHover: false,
|
||||
},
|
||||
{
|
||||
icon: 'ri-timer-line',
|
||||
color: 'info',
|
||||
title: 'Late vehicles',
|
||||
value: 13,
|
||||
change: -2.5,
|
||||
isHover: false,
|
||||
},
|
||||
])
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VRow>
|
||||
<VCol
|
||||
v-for="(data, index) in logisticData"
|
||||
:key="index"
|
||||
cols="12"
|
||||
md="3"
|
||||
sm="6"
|
||||
>
|
||||
<div>
|
||||
<VCard
|
||||
class="logistics-card-statistics cursor-pointer"
|
||||
:style="data.isHover ? `border-block-end-color: rgb(var(--v-theme-${data.color}))` : `border-block-end-color: rgba(var(--v-theme-${data.color}),0.7)`"
|
||||
@mouseenter="data.isHover = true"
|
||||
@mouseleave="data.isHover = false"
|
||||
>
|
||||
<VCardText>
|
||||
<div class="d-flex align-center gap-x-4 mb-2">
|
||||
<VAvatar
|
||||
variant="tonal"
|
||||
:color="data.color"
|
||||
rounded
|
||||
>
|
||||
<VIcon
|
||||
:icon="data.icon"
|
||||
size="24"
|
||||
/>
|
||||
</VAvatar>
|
||||
<h4 class="text-h4">
|
||||
{{ data.value }}
|
||||
</h4>
|
||||
</div>
|
||||
<h6 class="text-h6 font-weight-regular">
|
||||
{{ data.title }}
|
||||
</h6>
|
||||
<div class="d-flex align-center">
|
||||
<div class="text-body-1 font-weight-medium me-2">
|
||||
{{ data.change }}%
|
||||
</div>
|
||||
<span class="text-sm text-disabled">than last week</span>
|
||||
</div>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
</div>
|
||||
</VCol>
|
||||
</VRow>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@use "@core-scss/base/mixins" as mixins;
|
||||
|
||||
.logistics-card-statistics {
|
||||
border-block-end-style: solid;
|
||||
border-block-end-width: 2px;
|
||||
|
||||
&:hover {
|
||||
border-block-end-width: 3px;
|
||||
margin-block-end: -1px;
|
||||
|
||||
@include mixins.elevation(10);
|
||||
|
||||
transition: all 0.1s ease-out;
|
||||
}
|
||||
}
|
||||
|
||||
.skin--bordered{
|
||||
.logistics-card-statistics {
|
||||
&:hover {
|
||||
margin-block-end: -2px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
@@ -0,0 +1,115 @@
|
||||
<script setup>
|
||||
const chartColors = {
|
||||
donut: {
|
||||
series1: '#56ca00',
|
||||
series2: '#56ca00cc',
|
||||
series3: '#56ca0099',
|
||||
series4: '#56ca0066',
|
||||
},
|
||||
}
|
||||
|
||||
const headingColor = 'rgba(var(--v-theme-on-background), var(--v-high-emphasis-opacity))'
|
||||
const labelColor = 'rgba(var(--v-theme-on-background), var(--v-medium-emphasis-opacity))'
|
||||
|
||||
const deliveryExceptionsChartSeries = [
|
||||
13,
|
||||
25,
|
||||
22,
|
||||
40,
|
||||
]
|
||||
|
||||
const deliveryExceptionsChartConfig = {
|
||||
labels: [
|
||||
'Incorrect address',
|
||||
'Weather conditions',
|
||||
'Federal Holidays',
|
||||
'Damage during transit',
|
||||
],
|
||||
colors: [
|
||||
chartColors.donut.series1,
|
||||
chartColors.donut.series2,
|
||||
chartColors.donut.series3,
|
||||
chartColors.donut.series4,
|
||||
],
|
||||
stroke: { width: 0 },
|
||||
dataLabels: {
|
||||
enabled: false,
|
||||
formatter(val) {
|
||||
return `${ Number.parseInt(val) }%`
|
||||
},
|
||||
},
|
||||
legend: {
|
||||
show: true,
|
||||
position: 'bottom',
|
||||
offsetY: 10,
|
||||
markers: {
|
||||
width: 8,
|
||||
height: 8,
|
||||
offsetX: -3,
|
||||
},
|
||||
itemMargin: {
|
||||
horizontal: 15,
|
||||
vertical: 5,
|
||||
},
|
||||
fontSize: '13px',
|
||||
fontWeight: 400,
|
||||
labels: {
|
||||
colors: headingColor,
|
||||
useSeriesColors: false,
|
||||
},
|
||||
},
|
||||
tooltip: { theme: false },
|
||||
grid: { padding: { top: 15 } },
|
||||
plotOptions: {
|
||||
pie: {
|
||||
donut: {
|
||||
size: '75%',
|
||||
labels: {
|
||||
show: true,
|
||||
value: {
|
||||
fontSize: '26px',
|
||||
color: headingColor,
|
||||
fontWeight: 500,
|
||||
offsetY: -15,
|
||||
formatter(val) {
|
||||
return `${ Number.parseInt(val) }%`
|
||||
},
|
||||
},
|
||||
name: { offsetY: 30 },
|
||||
total: {
|
||||
show: true,
|
||||
fontSize: '1rem',
|
||||
label: 'AVG. Exceptions',
|
||||
color: labelColor,
|
||||
formatter() {
|
||||
return '30%'
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
responsive: [{
|
||||
breakpoint: 420,
|
||||
options: { chart: { height: 400 } },
|
||||
}],
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VCard>
|
||||
<VCardItem title="Delivery exceptions">
|
||||
<template #append>
|
||||
<MoreBtn />
|
||||
</template>
|
||||
</VCardItem>
|
||||
<VCardText>
|
||||
<VueApexCharts
|
||||
type="donut"
|
||||
height="400"
|
||||
:options="deliveryExceptionsChartConfig"
|
||||
:series="deliveryExceptionsChartSeries"
|
||||
/>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
</template>
|
@@ -0,0 +1,101 @@
|
||||
<script setup>
|
||||
const deliveryData = [
|
||||
{
|
||||
title: 'Packages in transit',
|
||||
value: '10k',
|
||||
change: 25.8,
|
||||
icon: 'ri-gift-line',
|
||||
color: 'primary',
|
||||
},
|
||||
{
|
||||
title: 'Packages out for delivery',
|
||||
value: '5k',
|
||||
change: 4.3,
|
||||
icon: 'ri-car-line',
|
||||
color: 'info',
|
||||
},
|
||||
{
|
||||
title: 'Packages delivered',
|
||||
value: '15k',
|
||||
change: -12.5,
|
||||
icon: 'ri-check-line',
|
||||
color: 'success',
|
||||
},
|
||||
{
|
||||
title: 'Delivery success rate',
|
||||
value: '95%',
|
||||
change: 35.6,
|
||||
icon: 'ri-home-line',
|
||||
color: 'warning',
|
||||
},
|
||||
{
|
||||
title: 'Average delivery time',
|
||||
value: '2.5 Days',
|
||||
change: -2.15,
|
||||
icon: 'ri-timer-line',
|
||||
color: 'secondary',
|
||||
},
|
||||
{
|
||||
title: 'Customer satisfaction',
|
||||
value: '4.5/5',
|
||||
change: 5.7,
|
||||
icon: 'ri-user-line',
|
||||
color: 'error',
|
||||
},
|
||||
]
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VCard>
|
||||
<VCardItem
|
||||
title="Delivery performance"
|
||||
subtitle="12% increase in this month"
|
||||
>
|
||||
<template #append>
|
||||
<MoreBtn class="mt-n5" />
|
||||
</template>
|
||||
</VCardItem>
|
||||
|
||||
<VCardText>
|
||||
<VList class="card-list">
|
||||
<VListItem
|
||||
v-for="(data, index) in deliveryData"
|
||||
:key="index"
|
||||
>
|
||||
<template #prepend>
|
||||
<VAvatar
|
||||
:color="data.color"
|
||||
variant="tonal"
|
||||
rounded
|
||||
size="42"
|
||||
>
|
||||
<VIcon
|
||||
:icon="data.icon"
|
||||
size="26"
|
||||
/>
|
||||
</VAvatar>
|
||||
</template>
|
||||
<VListItemTitle>{{ data.title }}</VListItemTitle>
|
||||
<VListItemSubtitle>
|
||||
<div
|
||||
:class="data.change > 0 ? 'text-success' : 'text-error'"
|
||||
class="d-flex align-center"
|
||||
>
|
||||
<VIcon
|
||||
:icon="data.change > 0 ? 'ri-arrow-up-s-line' : 'ri-arrow-down-s-line'"
|
||||
size="24"
|
||||
class="me-1"
|
||||
/>
|
||||
<span>{{ data.change }}%</span>
|
||||
</div>
|
||||
</VListItemSubtitle>
|
||||
<template #append>
|
||||
<span class="text-high-emphasis text-body-1 font-weight-medium">
|
||||
{{ data.value }}
|
||||
</span>
|
||||
</template>
|
||||
</VListItem>
|
||||
</VList>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
</template>
|
347
resources/js/views/apps/logistics/LogisticsOrderByCountries.vue
Normal file
347
resources/js/views/apps/logistics/LogisticsOrderByCountries.vue
Normal file
@@ -0,0 +1,347 @@
|
||||
<script setup>
|
||||
const currentTab = ref('New')
|
||||
|
||||
const tabsData = [
|
||||
'New',
|
||||
'Preparing',
|
||||
'Shipping',
|
||||
]
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VCard>
|
||||
<VCardItem
|
||||
title="Orders by countries"
|
||||
subtitle="62 deliveries in progress"
|
||||
>
|
||||
<template #append>
|
||||
<MoreBtn class="mt-n5" />
|
||||
</template>
|
||||
</VCardItem>
|
||||
|
||||
<VTabs
|
||||
v-model="currentTab"
|
||||
grow
|
||||
class="disable-tab-transition"
|
||||
>
|
||||
<VTab
|
||||
v-for="(tab, index) in tabsData"
|
||||
:key="index"
|
||||
>
|
||||
{{ tab }}
|
||||
</VTab>
|
||||
</VTabs>
|
||||
|
||||
<VCardText>
|
||||
<VWindow v-model="currentTab">
|
||||
<VWindowItem>
|
||||
<div>
|
||||
<VTimeline
|
||||
align="start"
|
||||
truncate-line="both"
|
||||
side="end"
|
||||
density="compact"
|
||||
line-thickness="1"
|
||||
class="v-timeline--variant-outlined"
|
||||
>
|
||||
<VTimelineItem
|
||||
icon="ri-checkbox-circle-line"
|
||||
dot-color="rgba(var(--v-theme-surface))"
|
||||
icon-color="success"
|
||||
fill-dot
|
||||
size="20"
|
||||
:elevation="0"
|
||||
>
|
||||
<div class="text-caption text-uppercase text-success">
|
||||
Sender
|
||||
</div>
|
||||
<div class="app-timeline-title">
|
||||
Myrtle Ullrich
|
||||
</div>
|
||||
<div class="text-body-2 mb-1">
|
||||
101 Boulder, California(CA), 95959
|
||||
</div>
|
||||
</VTimelineItem>
|
||||
|
||||
<VTimelineItem
|
||||
icon="ri-map-pin-line"
|
||||
dot-color="rgba(var(--v-theme-surface))"
|
||||
icon-color="primary"
|
||||
fill-dot
|
||||
size="20"
|
||||
:elevation="0"
|
||||
>
|
||||
<div class="text-caption text-primary text-uppercase">
|
||||
Receiver
|
||||
</div>
|
||||
<div class="app-timeline-title">
|
||||
Barry Schowalter
|
||||
</div>
|
||||
<div class="text-body-2">
|
||||
939 Orange, California(CA), 92118
|
||||
</div>
|
||||
</VTimelineItem>
|
||||
</VTimeline>
|
||||
|
||||
<VDivider
|
||||
class="my-4"
|
||||
style="border-style: dashed;"
|
||||
/>
|
||||
|
||||
<VTimeline
|
||||
align="start"
|
||||
truncate-line="both"
|
||||
side="end"
|
||||
density="compact"
|
||||
line-thickness="1"
|
||||
class="v-timeline--variant-outlined"
|
||||
>
|
||||
<VTimelineItem
|
||||
icon="ri-checkbox-circle-line"
|
||||
dot-color="rgba(var(--v-theme-surface))"
|
||||
icon-color="success"
|
||||
fill-dot
|
||||
size="20"
|
||||
:elevation="0"
|
||||
>
|
||||
<div class="text-caption text-uppercase text-success">
|
||||
Sender
|
||||
</div>
|
||||
<div class="app-timeline-title">
|
||||
Veronica Herman
|
||||
</div>
|
||||
<div class="text-body-2 mb-1">
|
||||
162 Windsor, California(CA), 95492
|
||||
</div>
|
||||
</VTimelineItem>
|
||||
|
||||
<VTimelineItem
|
||||
icon="ri-map-pin-line"
|
||||
dot-color="rgba(var(--v-theme-surface))"
|
||||
icon-color="primary"
|
||||
fill-dot
|
||||
size="20"
|
||||
:elevation="0"
|
||||
>
|
||||
<div class="text-caption text-primary text-uppercase">
|
||||
Receiver
|
||||
</div>
|
||||
<div class="app-timeline-title">
|
||||
Helen Jacobs
|
||||
</div>
|
||||
<div class="text-body-2">
|
||||
487 Sunset, California(CA), 94043
|
||||
</div>
|
||||
</VTimelineItem>
|
||||
</VTimeline>
|
||||
</div>
|
||||
</VWindowItem>
|
||||
|
||||
<VWindowItem>
|
||||
<div>
|
||||
<VTimeline
|
||||
align="start"
|
||||
truncate-line="both"
|
||||
side="end"
|
||||
density="compact"
|
||||
line-thickness="1"
|
||||
class="v-timeline--variant-outlined"
|
||||
>
|
||||
<VTimelineItem
|
||||
icon="ri-checkbox-circle-line"
|
||||
dot-color="rgba(var(--v-theme-surface))"
|
||||
icon-color="success"
|
||||
fill-dot
|
||||
size="20"
|
||||
:elevation="0"
|
||||
>
|
||||
<div class="text-caption text-uppercase text-success">
|
||||
Sender
|
||||
</div>
|
||||
<div class="app-timeline-title">
|
||||
Barry Schowalter
|
||||
</div>
|
||||
<div class="text-body-2">
|
||||
939 Orange, California(CA), 92118
|
||||
</div>
|
||||
</VTimelineItem>
|
||||
|
||||
<VTimelineItem
|
||||
icon="ri-map-pin-line"
|
||||
dot-color="rgba(var(--v-theme-surface))"
|
||||
icon-color="primary"
|
||||
fill-dot
|
||||
size="20"
|
||||
:elevation="0"
|
||||
>
|
||||
<div class="text-caption text-primary text-uppercase">
|
||||
Receiver
|
||||
</div>
|
||||
<div class="app-timeline-title">
|
||||
Myrtle Ullrich
|
||||
</div>
|
||||
<div class="text-body-2">
|
||||
101 Boulder, California(CA), 95959
|
||||
</div>
|
||||
</VTimelineItem>
|
||||
</VTimeline>
|
||||
|
||||
<VDivider
|
||||
class="my-4"
|
||||
style="border-style: dashed;"
|
||||
/>
|
||||
|
||||
<VTimeline
|
||||
align="start"
|
||||
truncate-line="both"
|
||||
side="end"
|
||||
density="compact"
|
||||
line-thickness="1"
|
||||
class="v-timeline--variant-outlined"
|
||||
>
|
||||
<VTimelineItem
|
||||
icon="ri-checkbox-circle-line"
|
||||
dot-color="rgba(var(--v-theme-surface))"
|
||||
icon-color="success"
|
||||
fill-dot
|
||||
size="20"
|
||||
:elevation="0"
|
||||
>
|
||||
<div class="text-caption text-uppercase text-success">
|
||||
Sender
|
||||
</div>
|
||||
<div class="app-timeline-title">
|
||||
Veronica Herman
|
||||
</div>
|
||||
<div class="text-body-2">
|
||||
162 Windsor, California(CA), 95492
|
||||
</div>
|
||||
</VTimelineItem>
|
||||
|
||||
<VTimelineItem
|
||||
icon="ri-map-pin-line"
|
||||
dot-color="rgba(var(--v-theme-surface))"
|
||||
icon-color="primary"
|
||||
fill-dot
|
||||
size="20"
|
||||
:elevation="0"
|
||||
>
|
||||
<div class="text-caption text-primary text-uppercase">
|
||||
Receiver
|
||||
</div>
|
||||
<div class="app-timeline-title">
|
||||
Helen Jacobs
|
||||
</div>
|
||||
<div class="text-body-2">
|
||||
487 Sunset, California(CA), 94043
|
||||
</div>
|
||||
</VTimelineItem>
|
||||
</VTimeline>
|
||||
</div>
|
||||
</VWindowItem>
|
||||
|
||||
<VWindowItem>
|
||||
<div>
|
||||
<VTimeline
|
||||
align="start"
|
||||
truncate-line="both"
|
||||
side="end"
|
||||
density="compact"
|
||||
line-thickness="1"
|
||||
class="v-timeline--variant-outlined"
|
||||
>
|
||||
<VTimelineItem
|
||||
icon="ri-checkbox-circle-line"
|
||||
dot-color="rgba(var(--v-theme-surface))"
|
||||
icon-color="success"
|
||||
fill-dot
|
||||
size="20"
|
||||
:elevation="0"
|
||||
>
|
||||
<div class="text-caption text-uppercase text-success">
|
||||
Sender
|
||||
</div>
|
||||
<div class="app-timeline-title">
|
||||
Myrtle Ullrich
|
||||
</div>
|
||||
<div class="text-body-2">
|
||||
101 Boulder, California(CA), 95959
|
||||
</div>
|
||||
</VTimelineItem>
|
||||
<VTimelineItem
|
||||
icon="ri-map-pin-line"
|
||||
dot-color="rgba(var(--v-theme-surface))"
|
||||
icon-color="primary"
|
||||
fill-dot
|
||||
size="20"
|
||||
:elevation="0"
|
||||
>
|
||||
<div class="text-caption text-primary text-uppercase">
|
||||
Receiver
|
||||
</div>
|
||||
<div class="app-timeline-title">
|
||||
Barry Schowalter
|
||||
</div>
|
||||
<div class="text-body-2">
|
||||
939 Orange, California(CA), 92118
|
||||
</div>
|
||||
</VTimelineItem>
|
||||
</VTimeline>
|
||||
|
||||
<VDivider
|
||||
class="my-4"
|
||||
style="border-style: dashed;"
|
||||
/>
|
||||
|
||||
<VTimeline
|
||||
align="start"
|
||||
truncate-line="both"
|
||||
side="end"
|
||||
density="compact"
|
||||
line-thickness="1"
|
||||
class="v-timeline--variant-outlined"
|
||||
>
|
||||
<VTimelineItem
|
||||
icon="ri-checkbox-circle-line"
|
||||
dot-color="rgba(var(--v-theme-surface))"
|
||||
icon-color="success"
|
||||
fill-dot
|
||||
size="20"
|
||||
:elevation="0"
|
||||
>
|
||||
<div class="text-caption text-uppercase text-success">
|
||||
Sender
|
||||
</div>
|
||||
<div class="app-timeline-title">
|
||||
Veronica Herman
|
||||
</div>
|
||||
<div class="text-body-2">
|
||||
162 Windsor, California(CA), 95492
|
||||
</div>
|
||||
</VTimelineItem>
|
||||
|
||||
<VTimelineItem
|
||||
icon="ri-map-pin-line"
|
||||
dot-color="rgba(var(--v-theme-surface))"
|
||||
icon-color="primary"
|
||||
fill-dot
|
||||
size="20"
|
||||
:elevation="0"
|
||||
>
|
||||
<div class="text-caption text-primary text-uppercase">
|
||||
Receiver
|
||||
</div>
|
||||
<div class="app-timeline-title">
|
||||
Helen Jacobs
|
||||
</div>
|
||||
<div class="text-body-2">
|
||||
487 Sunset, California(CA), 94043
|
||||
</div>
|
||||
</VTimelineItem>
|
||||
</VTimeline>
|
||||
</div>
|
||||
</VWindowItem>
|
||||
</VWindow>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
</template>
|
187
resources/js/views/apps/logistics/LogisticsOverviewTable.vue
Normal file
187
resources/js/views/apps/logistics/LogisticsOverviewTable.vue
Normal file
@@ -0,0 +1,187 @@
|
||||
<script setup>
|
||||
const itemsPerPage = ref(5)
|
||||
const page = ref(1)
|
||||
const sortBy = ref()
|
||||
const orderBy = ref()
|
||||
|
||||
const updateOptions = options => {
|
||||
page.value = options.page
|
||||
sortBy.value = options.sortBy[0]?.key
|
||||
orderBy.value = options.sortBy[0]?.order
|
||||
}
|
||||
|
||||
const { data: vehiclesData } = await useApi(createUrl('/apps/logistics/vehicles', {
|
||||
query: {
|
||||
page,
|
||||
itemsPerPage,
|
||||
sortBy,
|
||||
orderBy,
|
||||
},
|
||||
}))
|
||||
|
||||
const vehicles = computed(() => vehiclesData.value.vehicles)
|
||||
const totalVehicles = computed(() => vehiclesData.value.totalVehicles)
|
||||
|
||||
const headers = [
|
||||
{
|
||||
title: 'LOCATION',
|
||||
key: 'location',
|
||||
},
|
||||
{
|
||||
title: 'STARTING ROUTE',
|
||||
key: 'startRoute',
|
||||
},
|
||||
{
|
||||
title: 'ENDING ROUTE',
|
||||
key: 'endRoute',
|
||||
},
|
||||
{
|
||||
title: 'WARNINGS',
|
||||
key: 'warnings',
|
||||
},
|
||||
{
|
||||
title: 'PROGRESS',
|
||||
key: 'progress',
|
||||
},
|
||||
]
|
||||
|
||||
const resolveChipColor = warning => {
|
||||
if (warning === 'No Warnings')
|
||||
return 'success'
|
||||
if (warning === 'fuel problems')
|
||||
return 'primary'
|
||||
if (warning === 'Temperature Not Optimal')
|
||||
return 'warning'
|
||||
if (warning === 'Ecu Not Responding')
|
||||
return 'error'
|
||||
if (warning === 'Oil Leakage')
|
||||
return 'info'
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VCard>
|
||||
<VCardItem title="On Route vehicles">
|
||||
<template #append>
|
||||
<MoreBtn />
|
||||
</template>
|
||||
</VCardItem>
|
||||
|
||||
<VDataTableServer
|
||||
v-model:items-per-page="itemsPerPage"
|
||||
:items-per-page-options="[
|
||||
{ value: 5, title: '5' },
|
||||
{ value: 10, title: '10' },
|
||||
{ value: 20, title: '20' },
|
||||
{ value: -1, title: '$vuetify.dataFooter.itemsPerPageAll' },
|
||||
]"
|
||||
:items-length="totalVehicles"
|
||||
:items="vehicles"
|
||||
item-value="location"
|
||||
:headers="headers"
|
||||
show-select
|
||||
class="text-no-wrap"
|
||||
@update:options="updateOptions"
|
||||
>
|
||||
<template #item.location="{ item }">
|
||||
<div class="py-2">
|
||||
<VAvatar
|
||||
variant="tonal"
|
||||
class="me-4"
|
||||
color="secondary"
|
||||
>
|
||||
<VIcon
|
||||
icon="ri-bus-line"
|
||||
size="28"
|
||||
/>
|
||||
</VAvatar>
|
||||
<RouterLink
|
||||
:to="{ name: 'apps-logistics-fleet' }"
|
||||
class="text-base text-high-emphasis"
|
||||
>
|
||||
VOL-{{ item.location }}
|
||||
</RouterLink>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template #item.startRoute="{ item }">
|
||||
{{ item.startCity }}, {{ item.startCountry }}
|
||||
</template>
|
||||
|
||||
<template #item.endRoute="{ item }">
|
||||
{{ item.endCity }}, {{ item.endCountry }}
|
||||
</template>
|
||||
|
||||
<template #item.warnings="{ item }">
|
||||
<VChip
|
||||
:color="resolveChipColor(item.warnings)"
|
||||
size="small"
|
||||
>
|
||||
{{ item.warnings }}
|
||||
</VChip>
|
||||
</template>
|
||||
|
||||
<template #item.progress="{ item }">
|
||||
<div
|
||||
class="d-flex align-center gap-x-4"
|
||||
style="min-inline-size: 240px;"
|
||||
>
|
||||
<div class="w-100">
|
||||
<VProgressLinear
|
||||
:model-value="item.progress"
|
||||
rounded
|
||||
color="primary"
|
||||
:height="8"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
{{ item.progress }}%
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- Pagination -->
|
||||
<template #bottom>
|
||||
<VDivider />
|
||||
|
||||
<div class="d-flex justify-end flex-wrap gap-x-6 px-2 py-1">
|
||||
<div class="d-flex align-center gap-x-2 text-medium-emphasis text-base">
|
||||
Rows Per Page:
|
||||
<VSelect
|
||||
v-model="itemsPerPage"
|
||||
class="per-page-select"
|
||||
variant="plain"
|
||||
:items="[10, 20, 25, 50, 100]"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<p class="d-flex align-center text-base text-high-emphasis me-2 mb-0">
|
||||
{{ paginationMeta({ page, itemsPerPage }, totalVehicles) }}
|
||||
</p>
|
||||
|
||||
<div class="d-flex gap-x-2 align-center me-2">
|
||||
<VBtn
|
||||
class="flip-in-rtl"
|
||||
icon="ri-arrow-left-s-line"
|
||||
variant="text"
|
||||
density="comfortable"
|
||||
color="high-emphasis"
|
||||
:disabled="page <= 1"
|
||||
@click="page <= 1 ? page = 1 : page--"
|
||||
/>
|
||||
|
||||
<VBtn
|
||||
class="flip-in-rtl"
|
||||
icon="ri-arrow-right-s-line"
|
||||
density="comfortable"
|
||||
variant="text"
|
||||
color="high-emphasis"
|
||||
:disabled="page >= Math.ceil(totalVehicles / itemsPerPage)"
|
||||
@click="page >= Math.ceil(totalVehicles / itemsPerPage) ? page = Math.ceil(totalVehicles / itemsPerPage) : page++ "
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</VDataTableServer>
|
||||
</VCard>
|
||||
</template>
|
@@ -0,0 +1,256 @@
|
||||
<script setup>
|
||||
const chartColors = {
|
||||
line: {
|
||||
series1: '#FFB400',
|
||||
series2: '#9055FD',
|
||||
},
|
||||
}
|
||||
|
||||
const headingColor = 'rgba(var(--v-theme-on-background), var(--v-high-emphasis-opacity))'
|
||||
const labelColor = 'rgba(var(--v-theme-on-background), var(--v-disabled-opacity))'
|
||||
const borderColor = 'rgba(var(--v-border-color), var(--v-border-opacity))'
|
||||
|
||||
const series = [
|
||||
{
|
||||
name: 'Shipment',
|
||||
type: 'column',
|
||||
data: [
|
||||
38,
|
||||
45,
|
||||
33,
|
||||
38,
|
||||
32,
|
||||
50,
|
||||
48,
|
||||
40,
|
||||
42,
|
||||
37,
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'Delivery',
|
||||
type: 'line',
|
||||
data: [
|
||||
23,
|
||||
28,
|
||||
23,
|
||||
32,
|
||||
28,
|
||||
44,
|
||||
32,
|
||||
38,
|
||||
26,
|
||||
34,
|
||||
],
|
||||
},
|
||||
]
|
||||
|
||||
const shipmentConfig = {
|
||||
chart: {
|
||||
type: 'line',
|
||||
stacked: false,
|
||||
parentHeightOffset: 0,
|
||||
toolbar: { show: false },
|
||||
zoom: { enabled: false },
|
||||
},
|
||||
markers: {
|
||||
size: 5,
|
||||
colors: '#fff',
|
||||
strokeColors: chartColors.line.series2,
|
||||
hover: { size: 6 },
|
||||
borderRadius: 4,
|
||||
},
|
||||
stroke: {
|
||||
curve: 'smooth',
|
||||
width: [
|
||||
0,
|
||||
3,
|
||||
],
|
||||
lineCap: 'round',
|
||||
},
|
||||
legend: {
|
||||
show: true,
|
||||
position: 'bottom',
|
||||
markers: {
|
||||
width: 8,
|
||||
height: 8,
|
||||
offsetX: -3,
|
||||
},
|
||||
height: 40,
|
||||
offsetY: 10,
|
||||
itemMargin: {
|
||||
horizontal: 10,
|
||||
vertical: 0,
|
||||
},
|
||||
fontSize: '15px',
|
||||
fontFamily: 'Inter',
|
||||
fontWeight: 400,
|
||||
labels: {
|
||||
colors: headingColor,
|
||||
useSeriesColors: !1,
|
||||
},
|
||||
},
|
||||
grid: {
|
||||
strokeDashArray: 8,
|
||||
borderColor,
|
||||
xaxis: { lines: { show: false } },
|
||||
},
|
||||
colors: [
|
||||
chartColors.line.series1,
|
||||
chartColors.line.series2,
|
||||
],
|
||||
fill: {
|
||||
opacity: [
|
||||
1,
|
||||
1,
|
||||
],
|
||||
},
|
||||
plotOptions: {
|
||||
bar: {
|
||||
columnWidth: '30%',
|
||||
borderRadius: 4,
|
||||
borderRadiusApplication: 'around',
|
||||
},
|
||||
},
|
||||
dataLabels: { enabled: false },
|
||||
xaxis: {
|
||||
tickAmount: 10,
|
||||
categories: [
|
||||
'1 Jan',
|
||||
'2 Jan',
|
||||
'3 Jan',
|
||||
'4 Jan',
|
||||
'5 Jan',
|
||||
'6 Jan',
|
||||
'7 Jan',
|
||||
'8 Jan',
|
||||
'9 Jan',
|
||||
'10 Jan',
|
||||
],
|
||||
labels: {
|
||||
style: {
|
||||
colors: labelColor,
|
||||
fontSize: '13px',
|
||||
fontFamily: 'Inter',
|
||||
fontWeight: 400,
|
||||
},
|
||||
},
|
||||
axisBorder: {
|
||||
show: false,
|
||||
offsetY: 8,
|
||||
},
|
||||
axisTicks: { show: false },
|
||||
},
|
||||
yaxis: {
|
||||
tickAmount: 4,
|
||||
min: 10,
|
||||
max: 50,
|
||||
labels: {
|
||||
style: {
|
||||
colors: labelColor,
|
||||
fontSize: '13px',
|
||||
fontFamily: 'Inter',
|
||||
fontWeight: 400,
|
||||
},
|
||||
formatter(val) {
|
||||
return `${ val }%`
|
||||
},
|
||||
},
|
||||
},
|
||||
responsive: [
|
||||
{
|
||||
breakpoint: 1400,
|
||||
options: {
|
||||
chart: { height: 310 },
|
||||
xaxis: { labels: { style: { fontSize: '10px' } } },
|
||||
legend: {
|
||||
itemMargin: {
|
||||
vertical: 0,
|
||||
horizontal: 10,
|
||||
},
|
||||
fontSize: '13px',
|
||||
offsetY: 12,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
breakpoint: 1025,
|
||||
options: {
|
||||
chart: { height: 415 },
|
||||
plotOptions: { bar: { columnWidth: '50%' } },
|
||||
},
|
||||
},
|
||||
{
|
||||
breakpoint: 982,
|
||||
options: { plotOptions: { bar: { columnWidth: '30%' } } },
|
||||
},
|
||||
{
|
||||
breakpoint: 480,
|
||||
options: {
|
||||
chart: { height: 250 },
|
||||
legend: { offsetY: 7 },
|
||||
},
|
||||
},
|
||||
],
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VCard>
|
||||
<VCardItem
|
||||
title="Shipment statistics"
|
||||
subtitle="Total number of deliveries 23.8k"
|
||||
>
|
||||
<template #append>
|
||||
<VBtnGroup
|
||||
density="compact"
|
||||
variant="outlined"
|
||||
divided
|
||||
>
|
||||
<VBtn color="primary">
|
||||
January
|
||||
</VBtn>
|
||||
|
||||
<VBtn
|
||||
icon="ri-arrow-down-s-line"
|
||||
color="primary"
|
||||
/>
|
||||
</VBtnGroup>
|
||||
</template>
|
||||
</VCardItem>
|
||||
|
||||
<VCardText>
|
||||
<VueApexCharts
|
||||
id="shipment-statistics"
|
||||
height="320"
|
||||
:options="shipmentConfig"
|
||||
:series="series"
|
||||
/>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
@use "@core-scss/template/libs/apex-chart.scss";
|
||||
|
||||
.v-btn-group--divided .v-btn:not(:last-child) {
|
||||
border-inline-end-color: rgba(var(--v-theme-primary), 0.5);
|
||||
}
|
||||
|
||||
#shipment-statistics {
|
||||
.apexcharts-legend-text {
|
||||
font-size: 15px !important;
|
||||
line-height: 22px;
|
||||
}
|
||||
|
||||
.apexcharts-legend{
|
||||
.apexcharts-legend-series {
|
||||
border: 1px solid rgba(var(--v-theme-on-surface), 0.12);
|
||||
border-radius: 0.375rem;
|
||||
block-size: 83%;
|
||||
padding-block: 4px;
|
||||
padding-inline: 16px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
154
resources/js/views/apps/logistics/LogisticsVehicleOverview.vue
Normal file
154
resources/js/views/apps/logistics/LogisticsVehicleOverview.vue
Normal file
@@ -0,0 +1,154 @@
|
||||
<script setup>
|
||||
const vehicleData = [
|
||||
{
|
||||
icon: 'ri-car-line',
|
||||
title: 'On the way',
|
||||
time: '2hr 10min',
|
||||
percentage: 39.7,
|
||||
color: {
|
||||
bg: 'rgba(var(--v-theme-on-surface), var(--v-hover-opacity))',
|
||||
text: 'rgba(var(--v-theme-on-surface), var(--v-high-emphasis-opacity))',
|
||||
},
|
||||
},
|
||||
{
|
||||
icon: 'ri-download-cloud-2-line',
|
||||
title: 'Unloading',
|
||||
time: '3hr 15min',
|
||||
percentage: 28.3,
|
||||
color: {
|
||||
bg: 'rgb(var(--v-theme-primary))',
|
||||
text: 'rgb(var(--v-theme-on-primary))',
|
||||
},
|
||||
},
|
||||
{
|
||||
icon: 'ri-upload-line',
|
||||
title: 'Loading',
|
||||
time: '1hr 24min',
|
||||
percentage: 17.4,
|
||||
color: {
|
||||
bg: 'rgb(var(--v-theme-info))',
|
||||
text: 'rgb(var(--v-theme-on-primary))',
|
||||
},
|
||||
},
|
||||
{
|
||||
icon: 'ri-timer-line',
|
||||
title: 'Waiting',
|
||||
time: '5hr 19min',
|
||||
percentage: 14.6,
|
||||
color: {
|
||||
bg: 'rgb(var(--v-tooltip-background))',
|
||||
text: 'rgba(var(--v-theme-surface))',
|
||||
},
|
||||
},
|
||||
]
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VCard>
|
||||
<VCardItem title="Vehicles Overview">
|
||||
<template #append>
|
||||
<MoreBtn />
|
||||
</template>
|
||||
</VCardItem>
|
||||
<VCardText>
|
||||
<div class="d-flex mb-6">
|
||||
<div
|
||||
v-for="(item, index) in vehicleData"
|
||||
:key="item.title"
|
||||
:style="`inline-size: ${item.percentage}%;`"
|
||||
>
|
||||
<div class="vehicle-progress-label position-relative mb-4 text-body-1 d-none d-sm-block">
|
||||
{{ item.title }}
|
||||
</div>
|
||||
<VProgressLinear
|
||||
:color="item.color.bg"
|
||||
model-value="100"
|
||||
height="46"
|
||||
:class="index === 0 ? 'rounded-s' : index === vehicleData.length - 1 ? 'rounded-e' : ''"
|
||||
>
|
||||
<p
|
||||
class="text-sm font-weight-medium mb-0"
|
||||
:style="`color: ${item.color.text}`"
|
||||
>
|
||||
{{ item.percentage }}%
|
||||
</p>
|
||||
</VProgressLinear>
|
||||
</div>
|
||||
</div>
|
||||
<VTable class="text-no-wrap">
|
||||
<tbody>
|
||||
<tr
|
||||
v-for="(vehicle, index) in vehicleData"
|
||||
:key="index"
|
||||
>
|
||||
<td
|
||||
width="70%"
|
||||
class="ps-0"
|
||||
>
|
||||
<div class="d-flex align-center text-high-emphasis">
|
||||
<VIcon
|
||||
:icon="vehicle.icon"
|
||||
size="24"
|
||||
class="me-2"
|
||||
/>
|
||||
<h6 class="text-h6 font-weight-regular">
|
||||
{{ vehicle.title }}
|
||||
</h6>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<h6 class="text-h6">
|
||||
{{ vehicle.time }}
|
||||
</h6>
|
||||
</td>
|
||||
<td>
|
||||
<span class="text-body-1">{{ vehicle.percentage }}%</span>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</VTable>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.vehicle-progress-label {
|
||||
padding-block-end: 1rem;
|
||||
|
||||
&::after {
|
||||
position: absolute;
|
||||
display: inline-block;
|
||||
background-color: rgba(var(--v-theme-on-surface), var(--v-border-opacity));
|
||||
block-size: 10px;
|
||||
content: "";
|
||||
inline-size: 2px;
|
||||
inset-block-end: 0;
|
||||
inset-inline-start: 0;
|
||||
|
||||
[dir="rtl"] & {
|
||||
inset-inline: unset 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<style lang="scss">
|
||||
.v-progress-linear__content {
|
||||
justify-content: start;
|
||||
padding-inline-start: 1rem;
|
||||
|
||||
}
|
||||
|
||||
@media (max-width: 1080px) {
|
||||
.v-progress-linear__content {
|
||||
padding-inline-start: 0.75rem !important;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 576px) {
|
||||
.v-progress-linear__content {
|
||||
padding-inline-start: 0.3rem !important;
|
||||
}
|
||||
}
|
||||
</style>
|
Reference in New Issue
Block a user