Initial commit

This commit is contained in:
2025-08-04 16:33:07 +03:30
commit f798e8e35c
9595 changed files with 1208683 additions and 0 deletions

View File

@@ -0,0 +1,85 @@
<script setup>
import { useTheme } from 'vuetify'
const vuetifyTheme = useTheme()
const currentTheme = vuetifyTheme.current.value.colors
const series = [{
data: [
400,
200,
650,
500,
],
}]
const chartOptions = {
chart: {
type: 'area',
toolbar: { show: false },
sparkline: { enabled: true },
},
markers: {
colors: 'transparent',
strokeColors: 'transparent',
},
grid: { show: false },
colors: [currentTheme.success],
fill: {
type: 'gradient',
gradient: {
shadeIntensity: 0.8,
opacityFrom: 0.6,
opacityTo: 0.1,
},
},
dataLabels: { enabled: false },
stroke: {
width: 2,
curve: 'smooth',
},
xaxis: {
show: true,
lines: { show: false },
labels: { show: false },
stroke: { width: 0 },
axisBorder: { show: false },
},
yaxis: {
stroke: { width: 0 },
show: false,
},
responsive: [
{
breakpoint: 1387,
options: { chart: { height: 80 } },
},
{
breakpoint: 1200,
options: { chart: { height: 120 } },
},
],
}
</script>
<template>
<VCard>
<VCardText>
<h5 class="text-h5 mb-3">
Average Daily Sales
</h5>
<p class="mb-0">
Total Sales This Month
</p>
<h4 class="text-h4">
$28,450
</h4>
</VCardText>
<VueApexCharts
:options="chartOptions"
:series="series"
:height="80"
/>
</VCard>
</template>

View File

@@ -0,0 +1,220 @@
<script setup>
import { useTheme } from 'vuetify'
import { hexToRgb } from '@layouts/utils'
const vuetifyTheme = useTheme()
const series = [{
data: [
40,
65,
50,
45,
90,
55,
70,
],
}]
const chartOptions = computed(() => {
const currentTheme = vuetifyTheme.current.value.colors
const variableTheme = vuetifyTheme.current.value.variables
return {
chart: {
parentHeightOffset: 0,
type: 'bar',
toolbar: { show: false },
},
plotOptions: {
bar: {
barHeight: '60%',
columnWidth: '38%',
startingShape: 'rounded',
endingShape: 'rounded',
borderRadius: 4,
distributed: true,
},
},
grid: {
show: false,
padding: {
top: -30,
bottom: 0,
left: -10,
right: -10,
},
},
colors: [
`rgba(${ hexToRgb(currentTheme.primary) },${ variableTheme['dragged-opacity'] })`,
`rgba(${ hexToRgb(currentTheme.primary) },${ variableTheme['dragged-opacity'] })`,
`rgba(${ hexToRgb(currentTheme.primary) },${ variableTheme['dragged-opacity'] })`,
`rgba(${ hexToRgb(currentTheme.primary) },${ variableTheme['dragged-opacity'] })`,
`rgba(${ hexToRgb(currentTheme.primary) }, 1)`,
`rgba(${ hexToRgb(currentTheme.primary) },${ variableTheme['dragged-opacity'] })`,
`rgba(${ hexToRgb(currentTheme.primary) },${ variableTheme['dragged-opacity'] })`,
],
dataLabels: { enabled: false },
legend: { show: false },
xaxis: {
categories: [
'Mo',
'Tu',
'We',
'Th',
'Fr',
'Sa',
'Su',
],
axisBorder: { show: false },
axisTicks: { show: false },
labels: {
style: {
colors: `rgba(${ hexToRgb(currentTheme['on-surface']) },${ variableTheme['disabled-opacity'] })`,
fontSize: '13px',
fontFamily: 'Public Sans',
},
},
},
yaxis: { labels: { show: false } },
tooltip: { enabled: false },
responsive: [{
breakpoint: 1025,
options: { chart: { height: 199 } },
}],
}
})
const earningsReports = [
{
color: 'primary',
icon: 'tabler-currency-dollar',
title: 'Earnings',
amount: '$545.69',
progress: '55',
},
{
color: 'info',
icon: 'tabler-chart-pie-2',
title: 'Profit',
amount: '$256.34',
progress: '25',
},
{
color: 'error',
icon: 'tabler-brand-paypal',
title: 'Expense',
amount: '$74.19',
progress: '65',
},
]
const moreList = [
{
title: 'View More',
value: 'View More',
},
{
title: 'Delete',
value: 'Delete',
},
]
</script>
<template>
<VCard>
<VCardItem class="pb-sm-0">
<VCardTitle>Earning Reports</VCardTitle>
<VCardSubtitle>Weekly Earnings Overview</VCardSubtitle>
<template #append>
<div class="mt-n4 me-n2">
<MoreBtn
size="small"
:menu-list="moreList"
/>
</div>
</template>
</VCardItem>
<VCardText>
<VRow>
<VCol
cols="12"
sm="5"
lg="6"
class="d-flex flex-column align-self-center"
>
<div class="d-flex align-center gap-2 mb-3 flex-wrap">
<h2 class="text-h2">
$468
</h2>
<VChip
label
size="small"
color="success"
>
+4.2%
</VChip>
</div>
<span class="text-sm text-medium-emphasis">
You informed of this week compared to last week
</span>
</VCol>
<VCol
cols="12"
sm="7"
lg="6"
>
<VueApexCharts
:options="chartOptions"
:series="series"
height="161"
/>
</VCol>
</VRow>
<div class="border rounded mt-5 pa-5">
<VRow>
<VCol
v-for="report in earningsReports"
:key="report.title"
cols="12"
sm="4"
>
<div class="d-flex align-center">
<VAvatar
rounded
size="26"
:color="report.color"
variant="tonal"
class="me-2"
>
<VIcon
size="18"
:icon="report.icon"
/>
</VAvatar>
<h6 class="text-base font-weight-regular">
{{ report.title }}
</h6>
</div>
<h6 class="text-h4 my-2">
{{ report.amount }}
</h6>
<VProgressLinear
:model-value="report.progress"
:color="report.color"
height="4"
rounded
rounded-bar
/>
</VCol>
</VRow>
</div>
</VCardText>
</VCard>
</template>

View File

@@ -0,0 +1,131 @@
<script setup>
const monthlyCampaignState = [
{
avatarColor: 'success',
avatarIcon: 'tabler-mail',
title: 'Emails',
count: '12,346',
stats: '0.3%',
statsColor: 'success',
},
{
avatarColor: 'info',
avatarIcon: 'tabler-link',
title: 'Opened',
count: '8,734',
stats: '2.1%',
statsColor: 'success',
},
{
avatarColor: 'warning',
avatarIcon: 'tabler-mouse',
title: 'Clicked',
count: '967',
stats: '1.4%',
statsColor: 'error',
},
{
avatarColor: 'primary',
avatarIcon: 'tabler-users',
title: 'Subscribe',
count: '345',
stats: '8.5%',
statsColor: 'success',
},
{
avatarColor: 'secondary',
avatarIcon: 'tabler-alert-triangle',
title: 'Complaints',
count: '10',
stats: '1.5%',
statsColor: 'error',
},
{
avatarColor: 'error',
avatarIcon: 'tabler-ban',
title: 'Unsubscribe',
count: '86',
stats: '0.8%',
statsColor: 'success',
},
]
const moreList = [
{
title: 'Refresh',
value: 'refresh',
},
{
title: 'Download',
value: 'Download',
},
{
title: 'View All',
value: 'View All',
},
]
</script>
<template>
<VCard>
<VCardItem>
<VCardTitle>Monthly Campaign State</VCardTitle>
<VCardSubtitle>
8.52k Social Visitors
</VCardSubtitle>
<template #append>
<div class="mt-n4 me-n2">
<MoreBtn
size="small"
:menu-list="moreList"
/>
</div>
</template>
</VCardItem>
<VCardText>
<VList class="card-list">
<VListItem
v-for="state in monthlyCampaignState"
:key="state.title"
>
<template #prepend>
<VAvatar
:color="state.avatarColor"
variant="tonal"
size="34"
rounded
class="me-1"
>
<VIcon
:icon="state.avatarIcon"
size="22"
/>
</VAvatar>
</template>
<VListItemTitle class="font-weight-medium me-4">
{{ state.title }}
</VListItemTitle>
<template #append>
<div class="d-flex gap-x-4">
<div class="text-body-1">
{{ state.count }}
</div>
<div :class="`text-${state.statsColor}`">
{{ state.stats }}
</div>
</div>
</template>
</VListItem>
</VList>
</VCardText>
</VCard>
</template>
<style lang="scss" scoped>
.card-list {
--v-card-list-gap: 1.5rem;
}
</style>

View File

@@ -0,0 +1,186 @@
<script setup>
const projectTableHeaders = [
{
title: 'PROJECT',
key: 'project',
},
{
title: 'LEADER',
key: 'leader',
},
{
title: 'Team',
key: 'team',
sortable: false,
},
{
title: 'PROGRESS',
key: 'progress',
},
{
title: 'Action',
key: 'Action',
sortable: false,
},
]
const search = ref('')
const itemsPerPage = ref(5)
const page = ref(1)
const sortBy = ref()
const orderBy = ref()
const { data: projectsData } = await useApi(createUrl('/dashboard/analytics/projects', {
query: {
q: search,
itemsPerPage,
page,
sortBy,
orderBy,
},
}))
const updateOptions = options => {
sortBy.value = options.sortBy[0]?.key
orderBy.value = options.sortBy[0]?.order
}
const projects = computed(() => projectsData.value?.projects)
const totalProjects = computed(() => projectsData.value?.totalProjects)
const moreList = [
{
title: 'Download',
value: 'Download',
},
{
title: 'Delete',
value: 'Delete',
},
{
title: 'View',
value: 'View',
},
]
</script>
<template>
<VCard v-if="projects">
<VCardItem class="project-header d-flex flex-wrap justify-space-between gap-4">
<VCardTitle>Project List</VCardTitle>
<template #append>
<div style="inline-size: 250px;">
<AppTextField
v-model="search"
placeholder="Search Project"
/>
</div>
</template>
</VCardItem>
<VDivider />
<!-- SECTION Table -->
<VDataTableServer
v-model:items-per-page="itemsPerPage"
v-model:page="page"
:items="projects"
:items-length="totalProjects"
item-value="name"
:headers="projectTableHeaders"
class="text-no-wrap"
show-select
@update:options="updateOptions"
>
<!-- projects -->
<template #item.project="{ item }">
<div
class="d-flex align-center gap-x-3"
style="padding-block: 7px;"
>
<VAvatar
:size="34"
:image="item.logo"
/>
<div>
<h6 class="text-h6 text-no-wrap">
{{ item.name }}
</h6>
<div class="text-body-2">
{{ item.project }}
</div>
</div>
</div>
</template>
<template #item.leader="{ item }">
<div class="text-base text-high-emphasis">
{{ item.leader }}
</div>
</template>
<!-- Team -->
<template #item.team="{ item }">
<div class="d-flex">
<div class="v-avatar-group">
<VAvatar
v-for="(data, index) in item.team"
:key="index"
size="26"
>
<VImg :src="data" />
</VAvatar>
<VAvatar
v-if="item.extraMembers"
:color="$vuetify.theme.current.dark ? '#373b50' : '#eeedf0'"
:size="26"
>
<div class="text-caption text-high-emphasis">
+{{ item.extraMembers }}
</div>
</VAvatar>
</div>
</div>
</template>
<!-- Progress -->
<template #item.progress="{ item }">
<div class="d-flex align-center gap-3">
<div class="flex-grow-1">
<VProgressLinear
:height="6"
:model-value="item.progress"
color="primary"
rounded
/>
</div>
<div class="text-body-1 text-high-emphasis">
{{ item.progress }}%
</div>
</div>
</template>
<!-- Action -->
<template #item.Action>
<MoreBtn :menu-list="moreList" />
</template>
<!-- TODO Refactor this after vuetify provides proper solution for removing default footer -->
<template #bottom>
<TablePagination
v-model:page="page"
:items-per-page="itemsPerPage"
:total-items="totalProjects"
/>
</template>
</VDataTableServer>
<!-- !SECTION -->
</VCard>
</template>
<style lang="scss">
.project-header .v-card-item__append {
padding-inline-start: 0;
}
</style>

View File

@@ -0,0 +1,123 @@
<script setup>
import auFlag from '@images/icons/countries/au.png'
import brFlag from '@images/icons/countries/br.png'
import cnFlag from '@images/icons/countries/cn.png'
import frFlag from '@images/icons/countries/fr.png'
import inFlag from '@images/icons/countries/in.png'
import usFlag from '@images/icons/countries/us.png'
const salesByCountries = [
{
avatarImg: usFlag,
stats: '$8,567k',
subtitle: 'United states',
profitLoss: 25.8,
},
{
avatarImg: brFlag,
stats: '$2,415k',
subtitle: 'Brazil',
profitLoss: -6.2,
},
{
avatarImg: inFlag,
stats: '$865k',
subtitle: 'India',
profitLoss: 12.4,
},
{
avatarImg: auFlag,
stats: '$745k',
subtitle: 'Australia',
profitLoss: -11.9,
},
{
avatarImg: frFlag,
stats: '$45',
subtitle: 'France',
profitLoss: 16.2,
},
{
avatarImg: cnFlag,
stats: '$12k',
subtitle: 'China',
profitLoss: 14.8,
},
]
const moreList = [
{
title: 'Refresh',
value: 'refresh',
},
{
title: 'Download',
value: 'Download',
},
{
title: 'View All',
value: 'View All',
},
]
</script>
<template>
<VCard
title="Sales by Countries"
subtitle="Monthly Sales Overview"
>
<template #append>
<div class="mt-n4 me-n2">
<MoreBtn
size="small"
:menu-list="moreList"
/>
</div>
</template>
<VCardText>
<VList class="card-list">
<VListItem
v-for="country in salesByCountries"
:key="country.stats"
>
<template #prepend>
<VAvatar
size="34"
color="secondary"
variant="tonal"
class="me-1"
:image="country.avatarImg"
/>
</template>
<VListItemTitle class="font-weight-medium">
{{ country.stats }}
</VListItemTitle>
<VListItemSubtitle>
{{ country.subtitle }}
</VListItemSubtitle>
<template #append>
<div :class="`d-flex align-center ${country.profitLoss > 0 ? 'text-success' : 'text-error'}`">
<VIcon
:icon="country.profitLoss > 0 ? 'tabler-chevron-up' : 'tabler-chevron-down'"
size="20"
class="me-1"
/>
<div class="font-weight-medium">
{{ Math.abs(country.profitLoss) }}%
</div>
</div>
</template>
</VListItem>
</VList>
</VCardText>
</VCard>
</template>
<style lang="scss" scoped>
.card-list {
--v-card-list-gap: 1rem;
}
</style>

View File

@@ -0,0 +1,110 @@
<template>
<VCard>
<VCardText>
<div class="d-flex align-center justify-space-between">
<div class="text-body-1">
Sales Overview
</div>
<div class="text-success font-weight-medium">
+18.2%
</div>
</div>
<h4 class="text-h4">
$42.5k
</h4>
</VCardText>
<VCardText>
<VRow no-gutters>
<VCol cols="5">
<div class="py-2">
<div class="d-flex align-center mb-3">
<VAvatar
color="info"
variant="tonal"
:size="24"
rounded
class="me-2"
>
<VIcon
size="18"
icon="tabler-shopping-cart"
/>
</VAvatar>
<span>Order</span>
</div>
<h5 class="text-h5">
62.2%
</h5>
<div class="text-body-2 text-disabled">
6,440
</div>
</div>
</VCol>
<VCol cols="2">
<div class="d-flex flex-column align-center justify-center h-100">
<VDivider
vertical
class="mx-auto"
/>
<VAvatar
size="24"
color="rgba(var(--v-theme-on-surface), var(--v-hover-opacity))"
class="my-2"
>
<div class="text-overline text-disabled">
VS
</div>
</VAvatar>
<VDivider
vertical
class="mx-auto"
/>
</div>
</VCol>
<VCol
cols="5"
class="text-end"
>
<div class="py-2">
<div class="d-flex align-center justify-end mb-3">
<span class="me-2">Visits</span>
<VAvatar
color="primary"
variant="tonal"
:size="24"
rounded
>
<VIcon
size="18"
icon="tabler-link"
/>
</VAvatar>
</div>
<h5 class="text-h5">
25.5%
</h5>
<div class="text-body-2 text-disabled">
12,749
</div>
</div>
</VCol>
</VRow>
<div class="mt-6">
<VProgressLinear
model-value="72"
color="#00CFE8"
height="10"
bg-color="primary"
:rounded-bar="false"
rounded
/>
</div>
</VCardText>
</VCard>
</template>

View File

@@ -0,0 +1,133 @@
<script setup>
const sourceVisits = [
{
avatarIcon: 'tabler-shadow',
title: 'Direct Source',
subtitle: 'Direct link click',
stats: '1.2k',
profitLoss: 4.2,
},
{
avatarIcon: 'tabler-globe',
title: 'Social Network',
subtitle: 'Social Channels',
stats: '31.5k',
profitLoss: 8.2,
},
{
avatarIcon: 'tabler-mail',
title: 'Email Newsletter',
subtitle: 'Mail Campaigns',
stats: '893',
profitLoss: 2.4,
},
{
avatarIcon: 'tabler-external-link',
title: 'Referrals',
subtitle: 'Impact Radius Visits',
stats: '342',
profitLoss: -0.4,
},
{
avatarIcon: 'tabler-ad',
title: 'ADVT',
subtitle: 'Google ADVT',
stats: '2.15k',
profitLoss: 9.1,
},
{
avatarIcon: 'tabler-star',
title: 'Other',
subtitle: 'Many Sources',
stats: '12.5k',
profitLoss: 6.2,
},
]
const moreList = [
{
title: 'Refresh',
value: 'refresh',
},
{
title: 'Download',
value: 'Download',
},
{
title: 'View All',
value: 'View All',
},
]
</script>
<template>
<VCard>
<VCardItem>
<VCardTitle>Source Visits</VCardTitle>
<VCardSubtitle>
38.4k Visitors
</VCardSubtitle>
<template #append>
<div class="mt-n4 me-n2">
<MoreBtn
size="small"
:menu-list="moreList"
/>
</div>
</template>
</VCardItem>
<VCardText>
<VList class="card-list">
<VListItem
v-for="visit in sourceVisits"
:key="visit.title"
>
<template #prepend>
<VAvatar
size="38"
color="secondary"
variant="tonal"
class="me-1"
rounded
>
<VIcon
:icon="visit.avatarIcon"
size="22"
/>
</VAvatar>
</template>
<VListItemTitle class="font-weight-medium me-4">
{{ visit.title }}
</VListItemTitle>
<VListItemSubtitle class="me-4">
{{ visit.subtitle }}
</VListItemSubtitle>
<template #append>
<div class="d-flex align-center gap-x-4">
<div class="text-body-1">
{{ visit.stats }}
</div>
<VChip
label
size="small"
:color="visit.profitLoss > 0 ? 'success' : 'error'"
>
{{ visit.profitLoss > 0 ? '+' : '' }}
{{ visit.profitLoss }}%
</VChip>
</div>
</template>
</VListItem>
</VList>
</VCardText>
</VCard>
</template>
<style lang="scss" scoped>
.card-list {
--v-card-list-gap: 1.5rem;
}
</style>

View File

@@ -0,0 +1,191 @@
<script setup>
import { useTheme } from 'vuetify'
import { hexToRgb } from '@layouts/utils'
const vuetifyTheme = useTheme()
const series = [85]
const chartOptions = computed(() => {
const currentTheme = vuetifyTheme.current.value.colors
const variableTheme = vuetifyTheme.current.value.variables
return {
labels: ['Completed Task'],
chart: { type: 'radialBar' },
plotOptions: {
radialBar: {
offsetY: 10,
startAngle: -140,
endAngle: 130,
hollow: { size: '65%' },
track: {
background: currentTheme.surface,
strokeWidth: '100%',
},
dataLabels: {
name: {
offsetY: -20,
color: `rgba(${ hexToRgb(currentTheme['on-surface']) },${ variableTheme['disabled-opacity'] })`,
fontSize: '13px',
fontWeight: '400',
fontFamily: 'Public Sans',
},
value: {
offsetY: 10,
color: `rgba(${ hexToRgb(currentTheme['on-background']) },${ variableTheme['high-emphasis-opacity'] })`,
fontSize: '38px',
fontWeight: '500',
fontFamily: 'Public Sans',
},
},
},
},
colors: [currentTheme.primary],
fill: {
type: 'gradient',
gradient: {
shade: 'dark',
shadeIntensity: 0.5,
gradientToColors: [currentTheme.primary],
inverseColors: true,
opacityFrom: 1,
opacityTo: 0.6,
stops: [
30,
70,
100,
],
},
},
stroke: { dashArray: 10 },
grid: {
padding: {
top: -20,
bottom: 5,
},
},
states: {
hover: { filter: { type: 'none' } },
active: { filter: { type: 'none' } },
},
responsive: [{
breakpoint: 960,
options: { chart: { height: 280 } },
}],
}
})
const supportTicket = [
{
avatarColor: 'primary',
avatarIcon: 'tabler-ticket',
title: 'New Tickets',
subtitle: '142',
},
{
avatarColor: 'info',
avatarIcon: 'tabler-check',
title: 'Open Tickets',
subtitle: '28',
},
{
avatarColor: 'warning',
avatarIcon: 'tabler-clock',
title: 'Response Time',
subtitle: '1 Day',
},
]
const moreList = [
{
title: 'View More',
value: 'View More',
},
{
title: 'Delete',
value: 'Delete',
},
]
</script>
<template>
<VCard>
<VCardItem>
<VCardTitle>Support Tracker</VCardTitle>
<VCardSubtitle>Last 7 Days</VCardSubtitle>
<template #append>
<div class="mt-n4 me-n2">
<MoreBtn
size="small"
:menu-list="moreList"
/>
</div>
</template>
</VCardItem>
<VCardText>
<VRow>
<VCol
cols="12"
lg="4"
md="4"
>
<div class="mb-lg-6 mb-4 mt-2">
<h2 class="text-h2">
164
</h2>
<p class="text-base mb-0">
Total Tickets
</p>
</div>
<VList class="card-list">
<VListItem
v-for="ticket in supportTicket"
:key="ticket.title"
>
<VListItemTitle class="font-weight-medium">
{{ ticket.title }}
</VListItemTitle>
<VListItemSubtitle>
{{ ticket.subtitle }}
</VListItemSubtitle>
<template #prepend>
<VAvatar
rounded
size="34"
:color="ticket.avatarColor"
variant="tonal"
class="me-1"
>
<VIcon
size="22"
:icon="ticket.avatarIcon"
/>
</VAvatar>
</template>
</VListItem>
</VList>
</VCol>
<VCol
cols="12"
lg="8"
md="8"
>
<VueApexCharts
:options="chartOptions"
:series="series"
height="360"
/>
</VCol>
</VRow>
</VCardText>
</VCard>
</template>
<style lang="scss" scoped>
.card-list {
--v-card-list-gap: 16px;
}
</style>

View File

@@ -0,0 +1,296 @@
<script setup>
import { useTheme } from 'vuetify'
const vuetifyTheme = useTheme()
const series = [
{
name: 'Earning',
data: [
15,
10,
20,
8,
12,
18,
12,
5,
],
},
{
name: 'Expense',
data: [
-7,
-10,
-7,
-12,
-6,
-9,
-5,
-8,
],
},
]
const chartOptions = computed(() => {
const currentTheme = vuetifyTheme.current.value.colors
return {
chart: {
parentHeightOffset: 0,
stacked: true,
type: 'bar',
toolbar: { show: false },
},
tooltip: { enabled: false },
legend: { show: false },
stroke: {
curve: 'smooth',
width: 6,
lineCap: 'round',
colors: [currentTheme.surface],
},
plotOptions: {
bar: {
horizontal: false,
columnWidth: '45%',
borderRadius: 8,
borderRadiusApplication: 'around',
borderRadiusWhenStacked: 'all',
},
},
colors: [
'rgba(var(--v-theme-primary),1)',
'rgba(var(--v-theme-secondary),1)',
],
dataLabels: { enabled: false },
grid: {
show: false,
padding: {
top: -40,
bottom: -20,
left: -10,
right: -2,
},
},
xaxis: {
labels: { show: false },
axisTicks: { show: false },
axisBorder: { show: false },
},
yaxis: { labels: { show: false } },
responsive: [
{
breakpoint: 1600,
options: {
plotOptions: {
bar: {
columnWidth: '50%',
borderRadius: 8,
},
},
},
},
{
breakpoint: 1468,
options: {
plotOptions: {
bar: {
columnWidth: '60%',
borderRadius: 8,
},
},
},
},
{
breakpoint: 1279,
options: {
plotOptions: {
bar: {
columnWidth: '35%',
borderRadius: 8,
},
},
},
},
{
breakpoint: 1197,
options: {
chart: { height: 228 },
plotOptions: {
bar: {
borderRadius: 8,
columnWidth: '40%',
},
},
},
},
{
breakpoint: 912,
options: {
chart: { height: 232 },
plotOptions: {
bar: {
borderRadius: 8,
columnWidth: '55%',
},
},
},
},
{
breakpoint: 725,
options: {
plotOptions: {
bar: {
columnWidth: '70%',
borderRadius: 8,
},
},
},
},
{
breakpoint: 600,
options: {
plotOptions: {
bar: {
borderRadius: 8,
columnWidth: '40%',
},
},
},
},
{
breakpoint: 475,
options: {
plotOptions: {
bar: {
borderRadius: 8,
columnWidth: '50%',
},
},
},
},
{
breakpoint: 381,
options: {
plotOptions: {
bar: {
columnWidth: '60%',
borderRadius: 8,
},
},
},
},
],
states: {
hover: { filter: { type: 'none' } },
active: { filter: { type: 'none' } },
},
}
})
const totalEarnings = [
{
avatar: 'tabler-brand-paypal',
avatarColor: 'primary',
title: 'Total Revenue',
subtitle: 'Client Payment',
earning: '+$126',
},
{
avatar: 'tabler-currency-dollar',
avatarColor: 'secondary',
title: 'Total Sales',
subtitle: 'Total Sales',
earning: '+$98',
},
]
const moreList = [
{
title: 'View More',
value: 'View More',
},
{
title: 'Delete',
value: 'Delete',
},
]
</script>
<template>
<VCard>
<VCardItem class="pb-0">
<VCardTitle>Total Earning</VCardTitle>
<div class="d-flex align-center mt-2">
<h2 class="text-h2 me-2">
87%
</h2>
<div class="text-success">
<VIcon
size="20"
icon="tabler-chevron-up"
/>
<span class="text-base">25.8%</span>
</div>
</div>
<template #append>
<div class="mt-n10 me-n2">
<MoreBtn
size="small"
:menu-list="moreList"
/>
</div>
</template>
</VCardItem>
<VCardText>
<VueApexCharts
:options="chartOptions"
:series="series"
height="191"
class="my-2"
/>
<VList class="card-list">
<VListItem
v-for="earning in totalEarnings"
:key="earning.title"
>
<VListItemTitle class="font-weight-medium">
{{ earning.title }}
</VListItemTitle>
<VListItemSubtitle>
{{ earning.subtitle }}
</VListItemSubtitle>
<template #prepend>
<VAvatar
size="38"
:color="earning.avatarColor"
variant="tonal"
rounded
class="me-1"
>
<VIcon
:icon="earning.avatar"
size="22"
/>
</VAvatar>
</template>
<template #append>
<span class="text-success font-weight-medium">{{ earning.earning }}</span>
</template>
</VListItem>
</VList>
</VCardText>
</VCard>
</template>
<style lang="scss" scoped>
.card-list {
--v-card-list-gap: 16px;
}
</style>

View File

@@ -0,0 +1,188 @@
<script setup>
import { VIcon } from 'vuetify/components/VIcon'
import sliderBar1 from '@images/illustrations/sidebar-pic-1.png'
import sliderBar2 from '@images/illustrations/sidebar-pic-2.png'
import sliderBar3 from '@images/illustrations/sidebar-pic-3.png'
const websiteAnalytics = [
{
name: 'Traffic',
slideImg: sliderBar1,
data: [
{
number: '1.5k',
text: 'Sessions',
},
{
number: '3.1k',
text: 'Page Views',
},
{
number: '1.2k',
text: 'Leads',
},
{
number: '12%',
text: 'Conversions',
},
],
},
{
name: 'Spending',
slideImg: sliderBar2,
data: [
{
number: '12h',
text: 'Spend',
},
{
number: '182',
text: 'Order Size',
},
{
number: '127',
text: 'Order',
},
{
number: '23k',
text: 'Items',
},
],
},
{
name: 'Revenue Sources',
slideImg: sliderBar3,
data: [
{
number: '268',
text: 'Direct',
},
{
number: '890',
text: 'Organic',
},
{
number: '622',
text: 'Referral',
},
{
number: '1.2k',
text: 'Campaign',
},
],
},
]
</script>
<template>
<VCard
color="primary"
height="260"
>
<VCarousel
cycle
:continuous="false"
:show-arrows="false"
hide-delimiter-background
:delimiter-icon="() => h(VIcon, { icon: 'fa-circle', size: '8' })"
height="260"
class="carousel-delimiter-top-end web-analytics-carousel"
>
<VCarouselItem
v-for="item in websiteAnalytics"
:key="item.name"
>
<VCardText class="position-relative">
<VRow>
<VCol cols="12">
<h5 class="text-h5 text-white">
Website Analytics
</h5>
<p class="text-sm mb-0">
Total 28.5% Conversion Rate
</p>
</VCol>
<VCol
cols="12"
sm="6"
order="2"
order-sm="1"
>
<VRow>
<VCol
cols="12"
class="pb-0 pt-1"
>
<h6 class="text-h6 text-white mb-1 mt-5">
{{ item.name }}
</h6>
</VCol>
<VCol
v-for="d in item.data"
:key="d.number"
cols="6"
class="text-no-wrap pb-2"
>
<VChip
label
variant="flat"
size="default"
color="rgb(var(--v-theme-primary-darken-1))"
class="font-weight-medium text-white rounded me-2 px-2"
style="block-size: 30px;"
>
<span class="text-base">{{ d.number }}</span>
</VChip>
<span class="d-inline-block">{{ d.text }}</span>
</VCol>
</VRow>
</VCol>
<VCol
cols="12"
sm="6"
order="1"
order-sm="2"
class="text-center"
>
<img
:src="item.slideImg"
class="card-website-analytics-img"
style="filter: drop-shadow(0 4px 60px rgba(0, 0, 0, 50%));"
>
</VCol>
</VRow>
</VCardText>
</VCarouselItem>
</VCarousel>
</VCard>
</template>
<style lang="scss">
.card-website-analytics-img {
block-size: 150px;
}
@media screen and (min-width: 600px) {
.card-website-analytics-img {
position: absolute;
margin: auto;
inset-block-end: 1rem;
inset-inline-end: 2.5rem;
}
}
.web-analytics-carousel {
.v-carousel__controls {
.v-carousel__controls__item {
&.v-btn--active {
.v-icon {
opacity: 1 !important;
}
}
}
}
}
</style>