Initial commit
This commit is contained in:
@@ -0,0 +1,375 @@
|
||||
<script setup>
|
||||
import avatar1 from '@images/avatars/avatar-1.png'
|
||||
|
||||
const accountData = {
|
||||
avatarImg: avatar1,
|
||||
firstName: 'john',
|
||||
lastName: 'Doe',
|
||||
email: 'johnDoe@example.com',
|
||||
org: 'Pixinvent',
|
||||
phone: '+1 (917) 543-9876',
|
||||
address: '123 Main St, New York, NY 10001',
|
||||
state: 'New York',
|
||||
zip: '10001',
|
||||
country: 'USA',
|
||||
language: 'English',
|
||||
timezone: '(GMT-11:00) International Date Line West',
|
||||
currency: 'USD',
|
||||
}
|
||||
|
||||
const refInputEl = ref()
|
||||
const isConfirmDialogOpen = ref(false)
|
||||
const accountDataLocal = ref(structuredClone(accountData))
|
||||
const isAccountDeactivated = ref(false)
|
||||
const validateAccountDeactivation = [v => !!v || 'Please confirm account deactivation']
|
||||
|
||||
const resetForm = () => {
|
||||
accountDataLocal.value = structuredClone(accountData)
|
||||
}
|
||||
|
||||
const changeAvatar = file => {
|
||||
const fileReader = new FileReader()
|
||||
const { files } = file.target
|
||||
if (files && files.length) {
|
||||
fileReader.readAsDataURL(files[0])
|
||||
fileReader.onload = () => {
|
||||
if (typeof fileReader.result === 'string')
|
||||
accountDataLocal.value.avatarImg = fileReader.result
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// reset avatar image
|
||||
const resetAvatar = () => {
|
||||
accountDataLocal.value.avatarImg = accountData.avatarImg
|
||||
}
|
||||
|
||||
const timezones = [
|
||||
'(GMT-11:00) International Date Line West',
|
||||
'(GMT-11:00) Midway Island',
|
||||
'(GMT-10:00) Hawaii',
|
||||
'(GMT-09:00) Alaska',
|
||||
'(GMT-08:00) Pacific Time (US & Canada)',
|
||||
'(GMT-08:00) Tijuana',
|
||||
'(GMT-07:00) Arizona',
|
||||
'(GMT-07:00) Chihuahua',
|
||||
'(GMT-07:00) La Paz',
|
||||
'(GMT-07:00) Mazatlan',
|
||||
'(GMT-07:00) Mountain Time (US & Canada)',
|
||||
'(GMT-06:00) Central America',
|
||||
'(GMT-06:00) Central Time (US & Canada)',
|
||||
'(GMT-06:00) Guadalajara',
|
||||
'(GMT-06:00) Mexico City',
|
||||
'(GMT-06:00) Monterrey',
|
||||
'(GMT-06:00) Saskatchewan',
|
||||
'(GMT-05:00) Bogota',
|
||||
'(GMT-05:00) Eastern Time (US & Canada)',
|
||||
'(GMT-05:00) Indiana (East)',
|
||||
'(GMT-05:00) Lima',
|
||||
'(GMT-05:00) Quito',
|
||||
'(GMT-04:00) Atlantic Time (Canada)',
|
||||
'(GMT-04:00) Caracas',
|
||||
'(GMT-04:00) La Paz',
|
||||
'(GMT-04:00) Santiago',
|
||||
'(GMT-03:30) Newfoundland',
|
||||
'(GMT-03:00) Brasilia',
|
||||
'(GMT-03:00) Buenos Aires',
|
||||
'(GMT-03:00) Georgetown',
|
||||
'(GMT-03:00) Greenland',
|
||||
'(GMT-02:00) Mid-Atlantic',
|
||||
'(GMT-01:00) Azores',
|
||||
'(GMT-01:00) Cape Verde Is.',
|
||||
'(GMT+00:00) Casablanca',
|
||||
'(GMT+00:00) Dublin',
|
||||
'(GMT+00:00) Edinburgh',
|
||||
'(GMT+00:00) Lisbon',
|
||||
'(GMT+00:00) London',
|
||||
]
|
||||
|
||||
const currencies = [
|
||||
'USD',
|
||||
'EUR',
|
||||
'GBP',
|
||||
'AUD',
|
||||
'BRL',
|
||||
'CAD',
|
||||
'CNY',
|
||||
'CZK',
|
||||
'DKK',
|
||||
'HKD',
|
||||
'HUF',
|
||||
'INR',
|
||||
]
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VRow>
|
||||
<VCol cols="12">
|
||||
<VCard>
|
||||
<VCardText class="d-flex">
|
||||
<!-- 👉 Avatar -->
|
||||
<VAvatar
|
||||
rounded
|
||||
size="100"
|
||||
class="me-6"
|
||||
:image="accountDataLocal.avatarImg"
|
||||
/>
|
||||
|
||||
<!-- 👉 Upload Photo -->
|
||||
<form class="d-flex flex-column justify-center gap-4">
|
||||
<div class="d-flex flex-wrap gap-4">
|
||||
<VBtn
|
||||
color="primary"
|
||||
size="small"
|
||||
@click="refInputEl?.click()"
|
||||
>
|
||||
<VIcon
|
||||
icon="tabler-cloud-upload"
|
||||
class="d-sm-none"
|
||||
/>
|
||||
<span class="d-none d-sm-block">Upload new photo</span>
|
||||
</VBtn>
|
||||
|
||||
<input
|
||||
ref="refInputEl"
|
||||
type="file"
|
||||
name="file"
|
||||
accept=".jpeg,.png,.jpg,GIF"
|
||||
hidden
|
||||
@input="changeAvatar"
|
||||
>
|
||||
|
||||
<VBtn
|
||||
type="reset"
|
||||
size="small"
|
||||
color="secondary"
|
||||
variant="tonal"
|
||||
@click="resetAvatar"
|
||||
>
|
||||
<span class="d-none d-sm-block">Reset</span>
|
||||
<VIcon
|
||||
icon="tabler-refresh"
|
||||
class="d-sm-none"
|
||||
/>
|
||||
</VBtn>
|
||||
</div>
|
||||
|
||||
<p class="text-body-1 mb-0">
|
||||
Allowed JPG, GIF or PNG. Max size of 800K
|
||||
</p>
|
||||
</form>
|
||||
</VCardText>
|
||||
|
||||
<VCardText class="pt-2">
|
||||
<!-- 👉 Form -->
|
||||
<VForm class="mt-3">
|
||||
<VRow>
|
||||
<!-- 👉 First Name -->
|
||||
<VCol
|
||||
md="6"
|
||||
cols="12"
|
||||
>
|
||||
<AppTextField
|
||||
v-model="accountDataLocal.firstName"
|
||||
placeholder="John"
|
||||
label="First Name"
|
||||
/>
|
||||
</VCol>
|
||||
|
||||
<!-- 👉 Last Name -->
|
||||
<VCol
|
||||
md="6"
|
||||
cols="12"
|
||||
>
|
||||
<AppTextField
|
||||
v-model="accountDataLocal.lastName"
|
||||
placeholder="Doe"
|
||||
label="Last Name"
|
||||
/>
|
||||
</VCol>
|
||||
|
||||
<!-- 👉 Email -->
|
||||
<VCol
|
||||
cols="12"
|
||||
md="6"
|
||||
>
|
||||
<AppTextField
|
||||
v-model="accountDataLocal.email"
|
||||
label="E-mail"
|
||||
placeholder="johndoe@gmail.com"
|
||||
type="email"
|
||||
/>
|
||||
</VCol>
|
||||
|
||||
<!-- 👉 Organization -->
|
||||
<VCol
|
||||
cols="12"
|
||||
md="6"
|
||||
>
|
||||
<AppTextField
|
||||
v-model="accountDataLocal.org"
|
||||
label="Organization"
|
||||
placeholder="Pixinvent"
|
||||
/>
|
||||
</VCol>
|
||||
|
||||
<!-- 👉 Phone -->
|
||||
<VCol
|
||||
cols="12"
|
||||
md="6"
|
||||
>
|
||||
<AppTextField
|
||||
v-model="accountDataLocal.phone"
|
||||
label="Phone Number"
|
||||
placeholder="+1 (917) 543-9876"
|
||||
/>
|
||||
</VCol>
|
||||
|
||||
<!-- 👉 Address -->
|
||||
<VCol
|
||||
cols="12"
|
||||
md="6"
|
||||
>
|
||||
<AppTextField
|
||||
v-model="accountDataLocal.address"
|
||||
label="Address"
|
||||
placeholder="123 Main St, New York, NY 10001"
|
||||
/>
|
||||
</VCol>
|
||||
|
||||
<!-- 👉 State -->
|
||||
<VCol
|
||||
cols="12"
|
||||
md="6"
|
||||
>
|
||||
<AppTextField
|
||||
v-model="accountDataLocal.state"
|
||||
label="State"
|
||||
placeholder="New York"
|
||||
/>
|
||||
</VCol>
|
||||
|
||||
<!-- 👉 Zip Code -->
|
||||
<VCol
|
||||
cols="12"
|
||||
md="6"
|
||||
>
|
||||
<AppTextField
|
||||
v-model="accountDataLocal.zip"
|
||||
label="Zip Code"
|
||||
placeholder="10001"
|
||||
/>
|
||||
</VCol>
|
||||
|
||||
<!-- 👉 Country -->
|
||||
<VCol
|
||||
cols="12"
|
||||
md="6"
|
||||
>
|
||||
<AppSelect
|
||||
v-model="accountDataLocal.country"
|
||||
label="Country"
|
||||
:items="['USA', 'Canada', 'UK', 'India', 'Australia']"
|
||||
placeholder="Select Country"
|
||||
/>
|
||||
</VCol>
|
||||
|
||||
<!-- 👉 Language -->
|
||||
<VCol
|
||||
cols="12"
|
||||
md="6"
|
||||
>
|
||||
<AppSelect
|
||||
v-model="accountDataLocal.language"
|
||||
label="Language"
|
||||
placeholder="Select Language"
|
||||
:items="['English', 'Spanish', 'Arabic', 'Hindi', 'Urdu']"
|
||||
/>
|
||||
</VCol>
|
||||
|
||||
<!-- 👉 Timezone -->
|
||||
<VCol
|
||||
cols="12"
|
||||
md="6"
|
||||
>
|
||||
<AppSelect
|
||||
v-model="accountDataLocal.timezone"
|
||||
label="Timezone"
|
||||
placeholder="Select Timezone"
|
||||
:items="timezones"
|
||||
:menu-props="{ maxHeight: 200 }"
|
||||
/>
|
||||
</VCol>
|
||||
|
||||
<!-- 👉 Currency -->
|
||||
<VCol
|
||||
cols="12"
|
||||
md="6"
|
||||
>
|
||||
<AppSelect
|
||||
v-model="accountDataLocal.currency"
|
||||
label="Currency"
|
||||
placeholder="Select Currency"
|
||||
:items="currencies"
|
||||
:menu-props="{ maxHeight: 200 }"
|
||||
/>
|
||||
</VCol>
|
||||
|
||||
<!-- 👉 Form Actions -->
|
||||
<VCol
|
||||
cols="12"
|
||||
class="d-flex flex-wrap gap-4"
|
||||
>
|
||||
<VBtn>Save changes</VBtn>
|
||||
|
||||
<VBtn
|
||||
color="secondary"
|
||||
variant="tonal"
|
||||
type="reset"
|
||||
@click.prevent="resetForm"
|
||||
>
|
||||
Cancel
|
||||
</VBtn>
|
||||
</VCol>
|
||||
</VRow>
|
||||
</VForm>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
</VCol>
|
||||
|
||||
<VCol cols="12">
|
||||
<!-- 👉 Delete Account -->
|
||||
<VCard title="Delete Account">
|
||||
<VCardText>
|
||||
<!-- 👉 Checkbox and Button -->
|
||||
<div>
|
||||
<VCheckbox
|
||||
v-model="isAccountDeactivated"
|
||||
:rules="validateAccountDeactivation"
|
||||
label="I confirm my account deactivation"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<VBtn
|
||||
:disabled="!isAccountDeactivated"
|
||||
color="error"
|
||||
class="mt-6"
|
||||
@click="isConfirmDialogOpen = true"
|
||||
>
|
||||
Deactivate Account
|
||||
</VBtn>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
</VCol>
|
||||
</VRow>
|
||||
|
||||
<!-- Confirm Dialog -->
|
||||
<ConfirmDialog
|
||||
v-model:is-dialog-visible="isConfirmDialogOpen"
|
||||
confirmation-question="Are you sure you want to deactivate your account?"
|
||||
confirm-title="Deactivated!"
|
||||
confirm-msg="Your account has been deactivated successfully."
|
||||
cancel-title="Cancelled"
|
||||
cancel-msg="Account Deactivation Cancelled!"
|
||||
/>
|
||||
</template>
|
||||
@@ -0,0 +1,513 @@
|
||||
<script setup>
|
||||
import BillingHistoryTable from './BillingHistoryTable.vue'
|
||||
import mastercard from '@images/icons/payments/mastercard.png'
|
||||
import visa from '@images/icons/payments/visa.png'
|
||||
|
||||
const selectedPaymentMethod = ref('credit-debit-atm-card')
|
||||
const isPricingPlanDialogVisible = ref(false)
|
||||
const isConfirmDialogVisible = ref(false)
|
||||
const isCardEditDialogVisible = ref(false)
|
||||
const isCardDetailSaveBilling = ref(false)
|
||||
|
||||
const creditCards = [
|
||||
{
|
||||
name: 'Tom McBride',
|
||||
number: '5531234567899856',
|
||||
expiry: '12/24',
|
||||
isPrimary: true,
|
||||
type: 'visa',
|
||||
cvv: '456',
|
||||
image: mastercard,
|
||||
},
|
||||
{
|
||||
name: 'Mildred Wagner',
|
||||
number: '4851234567895896',
|
||||
expiry: '10/27',
|
||||
isPrimary: false,
|
||||
type: 'mastercard',
|
||||
cvv: '123',
|
||||
image: visa,
|
||||
},
|
||||
]
|
||||
|
||||
const countryList = [
|
||||
'United States',
|
||||
'Canada',
|
||||
'United Kingdom',
|
||||
'Australia',
|
||||
'New Zealand',
|
||||
'India',
|
||||
'Russia',
|
||||
'China',
|
||||
'Japan',
|
||||
]
|
||||
|
||||
const currentCardDetails = ref()
|
||||
|
||||
const openEditCardDialog = cardDetails => {
|
||||
currentCardDetails.value = cardDetails
|
||||
isCardEditDialogVisible.value = true
|
||||
}
|
||||
|
||||
const cardNumber = ref(135632156548789)
|
||||
const cardName = ref('john Doe')
|
||||
const cardExpiryDate = ref('05/24')
|
||||
const cardCvv = ref(420)
|
||||
|
||||
const resetPaymentForm = () => {
|
||||
cardNumber.value = 135632156548789
|
||||
cardName.value = 'john Doe'
|
||||
cardExpiryDate.value = '05/24'
|
||||
cardCvv.value = 420
|
||||
selectedPaymentMethod.value = 'credit-debit-atm-card'
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VRow>
|
||||
<!-- 👉 Current Plan -->
|
||||
<VCol cols="12">
|
||||
<VCard title="Current Plan">
|
||||
<VCardText>
|
||||
<VRow>
|
||||
<VCol
|
||||
cols="12"
|
||||
md="6"
|
||||
>
|
||||
<div>
|
||||
<div class="mb-6">
|
||||
<h3 class="text-body-1 text-high-emphasis font-weight-medium mb-1">
|
||||
Your Current Plan is Basic
|
||||
</h3>
|
||||
<p class="text-body-1">
|
||||
A simple start for everyone
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="mb-6">
|
||||
<h3 class="text-body-1 text-high-emphasis font-weight-medium mb-1">
|
||||
Active until Dec 09, 2021
|
||||
</h3>
|
||||
<p class="text-body-1">
|
||||
We will send you a notification upon Subscription expiration
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h3 class="text-body-1 text-high-emphasis font-weight-medium mb-1">
|
||||
<span class="me-2">$199 Per Month</span>
|
||||
<VChip
|
||||
color="primary"
|
||||
size="small"
|
||||
label
|
||||
>
|
||||
Popular
|
||||
</VChip>
|
||||
</h3>
|
||||
<p class="text-base mb-0">
|
||||
Standard plan for small to medium businesses
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</VCol>
|
||||
|
||||
<VCol
|
||||
cols="12"
|
||||
md="6"
|
||||
>
|
||||
<VAlert
|
||||
icon="tabler-alert-triangle"
|
||||
type="warning"
|
||||
variant="tonal"
|
||||
>
|
||||
<VAlertTitle class="mb-1">
|
||||
We need your attention!
|
||||
</VAlertTitle>
|
||||
|
||||
<span>Your plan requires update</span>
|
||||
</VAlert>
|
||||
|
||||
<!-- progress -->
|
||||
<h6 class="d-flex font-weight-medium text-body-1 text-high-emphasis mt-6 mb-1">
|
||||
<span>Days</span>
|
||||
<VSpacer />
|
||||
<span>12 of 30 Days</span>
|
||||
</h6>
|
||||
|
||||
<VProgressLinear
|
||||
color="primary"
|
||||
rounded
|
||||
model-value="15"
|
||||
/>
|
||||
|
||||
<p class="text-body-2 mt-1 mb-0">
|
||||
18 days remaining until your plan requires update
|
||||
</p>
|
||||
</VCol>
|
||||
|
||||
<VCol cols="12">
|
||||
<div class="d-flex flex-wrap gap-4">
|
||||
<VBtn @click="isPricingPlanDialogVisible = true">
|
||||
upgrade plan
|
||||
</VBtn>
|
||||
|
||||
<VBtn
|
||||
color="error"
|
||||
variant="tonal"
|
||||
@click="isConfirmDialogVisible = true"
|
||||
>
|
||||
Cancel Subscription
|
||||
</VBtn>
|
||||
</div>
|
||||
</VCol>
|
||||
</VRow>
|
||||
|
||||
<!-- 👉 Confirm Dialog -->
|
||||
<ConfirmDialog
|
||||
v-model:is-dialog-visible="isConfirmDialogVisible"
|
||||
confirmation-question="Are you sure to cancel your subscription?"
|
||||
cancel-msg="Unsubscription Cancelled!!"
|
||||
cancel-title="Cancelled"
|
||||
confirm-msg="Your subscription cancelled successfully."
|
||||
confirm-title="Unsubscribed!"
|
||||
/>
|
||||
|
||||
<!-- 👉 plan and pricing dialog -->
|
||||
<PricingPlanDialog v-model:is-dialog-visible="isPricingPlanDialogVisible" />
|
||||
</VCardText>
|
||||
</VCard>
|
||||
</VCol>
|
||||
|
||||
<!-- 👉 Payment Methods -->
|
||||
<VCol cols="12">
|
||||
<VCard title="Payment Methods">
|
||||
<VCardText>
|
||||
<VForm @submit.prevent="() => {}">
|
||||
<VRow>
|
||||
<VCol
|
||||
cols="12"
|
||||
md="6"
|
||||
>
|
||||
<VRow>
|
||||
<!-- 👉 card type switch -->
|
||||
<VCol cols="12">
|
||||
<VRadioGroup
|
||||
v-model="selectedPaymentMethod"
|
||||
inline
|
||||
>
|
||||
<VRadio
|
||||
value="credit-debit-atm-card"
|
||||
label="Credit/Debit/ATM Card"
|
||||
color="primary"
|
||||
class="me-6"
|
||||
/>
|
||||
<VRadio
|
||||
value="paypal-account"
|
||||
label="Paypal account"
|
||||
color="primary"
|
||||
/>
|
||||
</VRadioGroup>
|
||||
</VCol>
|
||||
|
||||
<VCol cols="12">
|
||||
<VRow>
|
||||
<!-- 👉 Card Number -->
|
||||
<VCol cols="12">
|
||||
<AppTextField
|
||||
v-model="cardNumber"
|
||||
label="Card Number"
|
||||
placeholder="1234 1234 1234 1234"
|
||||
type="number"
|
||||
/>
|
||||
</VCol>
|
||||
|
||||
<!-- 👉 Name -->
|
||||
<VCol
|
||||
cols="12"
|
||||
md="6"
|
||||
>
|
||||
<AppTextField
|
||||
v-model="cardName"
|
||||
label="Name"
|
||||
placeholder="John Doe"
|
||||
/>
|
||||
</VCol>
|
||||
|
||||
<!-- 👉 Expiry date -->
|
||||
<VCol
|
||||
cols="6"
|
||||
md="3"
|
||||
>
|
||||
<AppTextField
|
||||
v-model="cardExpiryDate"
|
||||
label="Expiry Date"
|
||||
placeholder="MM/YY"
|
||||
/>
|
||||
</VCol>
|
||||
|
||||
<!-- 👉 Cvv code -->
|
||||
<VCol
|
||||
cols="6"
|
||||
md="3"
|
||||
>
|
||||
<AppTextField
|
||||
v-model="cardCvv"
|
||||
type="number"
|
||||
label="CVV Code"
|
||||
placeholder="123"
|
||||
/>
|
||||
</VCol>
|
||||
|
||||
<!-- 👉 Future Billing switch -->
|
||||
<VCol cols="12">
|
||||
<VSwitch
|
||||
v-model="isCardDetailSaveBilling"
|
||||
density="compact"
|
||||
label="Save card for future billing?"
|
||||
/>
|
||||
</VCol>
|
||||
</VRow>
|
||||
</VCol>
|
||||
<VCol
|
||||
cols="12"
|
||||
class="d-flex flex-wrap gap-4"
|
||||
>
|
||||
<VBtn type="submit">
|
||||
Save changes
|
||||
</VBtn>
|
||||
<VBtn
|
||||
color="secondary"
|
||||
variant="tonal"
|
||||
@click="resetPaymentForm"
|
||||
>
|
||||
Cancel
|
||||
</VBtn>
|
||||
</VCol>
|
||||
</VRow>
|
||||
</VCol>
|
||||
|
||||
<!-- 👉 Saved Cards -->
|
||||
<VCol
|
||||
cols="12"
|
||||
md="6"
|
||||
>
|
||||
<h6 class="text-body-1 text-high-emphasis font-weight-medium mb-6">
|
||||
My Cards
|
||||
</h6>
|
||||
|
||||
<div class="d-flex flex-column gap-y-6">
|
||||
<VCard
|
||||
v-for="card in creditCards"
|
||||
:key="card.name"
|
||||
flat
|
||||
color="rgba(var(--v-theme-on-surface),var(--v-hover-opacity))"
|
||||
>
|
||||
<VCardText class="d-flex flex-sm-row flex-column">
|
||||
<div class="text-no-wrap">
|
||||
<img
|
||||
:src="card.image"
|
||||
height="25"
|
||||
>
|
||||
<h4 class="my-2 text-body-1 text-high-emphasis d-flex align-center">
|
||||
<div class="me-4 font-weight-medium">
|
||||
{{ card.name }}
|
||||
</div>
|
||||
<VChip
|
||||
v-if="card.isPrimary"
|
||||
label
|
||||
color="primary"
|
||||
size="small"
|
||||
>
|
||||
Primary
|
||||
</VChip>
|
||||
</h4>
|
||||
<div class="text-body-1">
|
||||
**** **** **** {{ card.number.substring(card.number.length - 4) }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<VSpacer />
|
||||
|
||||
<div class="d-flex flex-column text-sm-end">
|
||||
<div class="d-flex flex-wrap gap-4 order-sm-0 order-1">
|
||||
<VBtn
|
||||
variant="tonal"
|
||||
size="small"
|
||||
@click="openEditCardDialog(card)"
|
||||
>
|
||||
Edit
|
||||
</VBtn>
|
||||
<VBtn
|
||||
color="error"
|
||||
size="small"
|
||||
variant="tonal"
|
||||
>
|
||||
Delete
|
||||
</VBtn>
|
||||
</div>
|
||||
<span class="text-body-2 my-4 order-sm-1 order-0">Card expires at {{ card.expiry }}</span>
|
||||
</div>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
</div>
|
||||
|
||||
<!-- 👉 Add Edit Card Dialog -->
|
||||
<CardAddEditDialog
|
||||
v-model:is-dialog-visible="isCardEditDialogVisible"
|
||||
:card-details="currentCardDetails"
|
||||
/>
|
||||
</VCol>
|
||||
</VRow>
|
||||
</VForm>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
</VCol>
|
||||
|
||||
<!-- 👉 Billing Address -->
|
||||
<VCol cols="12">
|
||||
<VCard title="Billing Address">
|
||||
<VCardText>
|
||||
<VForm @submit.prevent="() => {}">
|
||||
<VRow>
|
||||
<!-- 👉 Company name -->
|
||||
<VCol
|
||||
cols="12"
|
||||
md="6"
|
||||
>
|
||||
<AppTextField
|
||||
label="Company Name"
|
||||
placeholder="Pixinvent"
|
||||
/>
|
||||
</VCol>
|
||||
|
||||
<!-- 👉 Billing Email -->
|
||||
<VCol
|
||||
cols="12"
|
||||
md="6"
|
||||
>
|
||||
<AppTextField
|
||||
label="Billing Email"
|
||||
placeholder="pixinvent@email.com"
|
||||
/>
|
||||
</VCol>
|
||||
|
||||
<!-- 👉 Tax ID -->
|
||||
<VCol
|
||||
cols="12"
|
||||
md="6"
|
||||
>
|
||||
<AppTextField
|
||||
label="Tax ID"
|
||||
placeholder="123 123 1233"
|
||||
/>
|
||||
</VCol>
|
||||
|
||||
<!-- 👉 Vat Number -->
|
||||
<VCol
|
||||
cols="12"
|
||||
md="6"
|
||||
>
|
||||
<AppTextField
|
||||
label="VAT Number"
|
||||
placeholder="121212"
|
||||
/>
|
||||
</VCol>
|
||||
|
||||
<!-- 👉 Mobile -->
|
||||
<VCol
|
||||
cols="12"
|
||||
md="6"
|
||||
>
|
||||
<AppTextField
|
||||
dirty
|
||||
label="Phone Number"
|
||||
type="number"
|
||||
prefix="US (+1)"
|
||||
placeholder="+1 123 456 7890"
|
||||
/>
|
||||
</VCol>
|
||||
|
||||
<!-- 👉 Country -->
|
||||
<VCol
|
||||
cols="12"
|
||||
md="6"
|
||||
>
|
||||
<AppSelect
|
||||
label="Country"
|
||||
:items="countryList"
|
||||
placeholder="Select Country"
|
||||
/>
|
||||
</VCol>
|
||||
|
||||
<!-- 👉 Billing Address -->
|
||||
<VCol cols="12">
|
||||
<AppTextField
|
||||
label="Billing Address"
|
||||
placeholder="1234 Main St"
|
||||
/>
|
||||
</VCol>
|
||||
|
||||
<!-- 👉 State -->
|
||||
<VCol
|
||||
cols="12"
|
||||
md="6"
|
||||
>
|
||||
<AppTextField
|
||||
label="State"
|
||||
placeholder="New York"
|
||||
/>
|
||||
</VCol>
|
||||
|
||||
<!-- 👉 Zip Code -->
|
||||
<VCol
|
||||
cols="12"
|
||||
md="6"
|
||||
>
|
||||
<AppTextField
|
||||
label="Zip Code"
|
||||
type="number"
|
||||
placeholder="100006"
|
||||
/>
|
||||
</VCol>
|
||||
|
||||
<!-- 👉 Actions Button -->
|
||||
<VCol
|
||||
cols="12"
|
||||
class="d-flex flex-wrap gap-4"
|
||||
>
|
||||
<VBtn type="submit">
|
||||
Save changes
|
||||
</VBtn>
|
||||
<VBtn
|
||||
type="reset"
|
||||
color="secondary"
|
||||
variant="tonal"
|
||||
>
|
||||
Discard
|
||||
</VBtn>
|
||||
</VCol>
|
||||
</VRow>
|
||||
</VForm>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
</VCol>
|
||||
|
||||
<!-- 👉 Billing History -->
|
||||
<VCol cols="12">
|
||||
<BillingHistoryTable />
|
||||
</VCol>
|
||||
</VRow>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
.pricing-dialog {
|
||||
.pricing-title {
|
||||
font-size: 1.5rem !important;
|
||||
}
|
||||
|
||||
.v-card {
|
||||
border: 1px solid rgba(var(--v-border-color), var(--v-border-opacity));
|
||||
box-shadow: none;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,204 @@
|
||||
<script setup>
|
||||
import asana from '@images/icons/brands/asana.png'
|
||||
import behance from '@images/icons/brands/behance.png'
|
||||
import dribbble from '@images/icons/brands/dribbble.png'
|
||||
import facebook from '@images/icons/brands/facebook.png'
|
||||
import github from '@images/icons/brands/github.png'
|
||||
import google from '@images/icons/brands/google.png'
|
||||
import linkedin from '@images/icons/brands/linkedin.png'
|
||||
import mailchimp from '@images/icons/brands/mailchimp.png'
|
||||
import slack from '@images/icons/brands/slack.png'
|
||||
import twitter from '@images/icons/brands/twitter.png'
|
||||
|
||||
const connectedAccounts = ref([
|
||||
{
|
||||
logo: google,
|
||||
name: 'Google',
|
||||
subtitle: 'Calendar and contacts',
|
||||
connected: true,
|
||||
},
|
||||
{
|
||||
logo: slack,
|
||||
name: 'Slack',
|
||||
subtitle: 'Communication',
|
||||
connected: false,
|
||||
},
|
||||
{
|
||||
logo: github,
|
||||
name: 'GitHub',
|
||||
subtitle: 'Manage your Git repositories',
|
||||
connected: true,
|
||||
},
|
||||
{
|
||||
logo: mailchimp,
|
||||
name: 'MailChimp',
|
||||
color: 'yellow',
|
||||
subtitle: 'Email marketing service',
|
||||
connected: true,
|
||||
},
|
||||
{
|
||||
logo: asana,
|
||||
name: 'Asana',
|
||||
subtitle: 'Task management',
|
||||
connected: false,
|
||||
},
|
||||
])
|
||||
|
||||
const socialAccounts = ref([
|
||||
{
|
||||
logo: facebook,
|
||||
name: 'Facebook',
|
||||
connected: false,
|
||||
},
|
||||
{
|
||||
logo: twitter,
|
||||
name: 'Twitter',
|
||||
links: {
|
||||
username: '@Pixinvent',
|
||||
link: 'https://twitter.com/Pixinvents',
|
||||
},
|
||||
connected: true,
|
||||
},
|
||||
{
|
||||
logo: linkedin,
|
||||
name: 'LinkedIn',
|
||||
links: {
|
||||
username: '@Pixinvent',
|
||||
link: 'https://in.linkedin.com/in/pixinvent-creative-studio-561a4713b',
|
||||
},
|
||||
connected: true,
|
||||
},
|
||||
{
|
||||
logo: dribbble,
|
||||
name: 'Dribbble',
|
||||
connected: false,
|
||||
},
|
||||
{
|
||||
logo: behance,
|
||||
name: 'Behance',
|
||||
connected: false,
|
||||
},
|
||||
])
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VCard>
|
||||
<VRow>
|
||||
<VCol
|
||||
cols="12"
|
||||
md="6"
|
||||
class="pe-md-0 pb-0 pb-md-3"
|
||||
>
|
||||
<!-- 👉 Connected Accounts -->
|
||||
<VCard
|
||||
title="Connected Accounts"
|
||||
subtitle="Display content from your connected accounts on your site"
|
||||
flat
|
||||
>
|
||||
<VCardText>
|
||||
<VList class="card-list">
|
||||
<VListItem
|
||||
v-for="item in connectedAccounts"
|
||||
:key="item.logo"
|
||||
>
|
||||
<template #prepend>
|
||||
<VAvatar>
|
||||
<img
|
||||
:src="item.logo"
|
||||
height="32"
|
||||
>
|
||||
</VAvatar>
|
||||
</template>
|
||||
<VListItemTitle>
|
||||
<h6 class="text-h6">
|
||||
{{ item.name }}
|
||||
</h6>
|
||||
</VListItemTitle>
|
||||
<VListItemSubtitle class="text-xs">
|
||||
{{ item.subtitle }}
|
||||
</VListItemSubtitle>
|
||||
<template #append>
|
||||
<VListItemAction>
|
||||
<VSwitch
|
||||
v-model="item.connected"
|
||||
density="compact"
|
||||
class="me-1"
|
||||
/>
|
||||
</VListItemAction>
|
||||
</template>
|
||||
</VListItem>
|
||||
</VList>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
</VCol>
|
||||
<VCol
|
||||
cols="12"
|
||||
md="6"
|
||||
class="ps-md-0 pt-0 pt-md-3"
|
||||
>
|
||||
<!-- 👉 Social Accounts -->
|
||||
<VCard
|
||||
title="Social Accounts"
|
||||
subtitle="Display content from social accounts on your site"
|
||||
flat
|
||||
>
|
||||
<VCardText>
|
||||
<VList class="card-list">
|
||||
<VListItem
|
||||
v-for="item in socialAccounts"
|
||||
:key="item.logo"
|
||||
>
|
||||
<template #prepend>
|
||||
<VAvatar rounded>
|
||||
<img
|
||||
:src="item.logo"
|
||||
height="32"
|
||||
>
|
||||
</VAvatar>
|
||||
</template>
|
||||
<VListItemTitle>
|
||||
<h6 class="text-h6">
|
||||
{{ item.name }}
|
||||
</h6>
|
||||
</VListItemTitle>
|
||||
<VListItemSubtitle v-if="item.links?.link">
|
||||
<a
|
||||
:href="item.links.link"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>{{ item.links?.username }}</a>
|
||||
</VListItemSubtitle>
|
||||
<VListItemSubtitle
|
||||
v-else
|
||||
class="text-xs"
|
||||
>
|
||||
Not Connected
|
||||
</VListItemSubtitle>
|
||||
<template #append>
|
||||
<VListItemAction>
|
||||
<IconBtn
|
||||
variant="tonal"
|
||||
:color="item.connected ? 'error' : 'secondary'"
|
||||
class="rounded"
|
||||
>
|
||||
<VIcon
|
||||
size="22"
|
||||
:icon="item.connected ? 'tabler-trash' : 'tabler-link' "
|
||||
/>
|
||||
</IconBtn>
|
||||
</VListItemAction>
|
||||
</template>
|
||||
</VListItem>
|
||||
</VList>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
</VCol>
|
||||
</VRow>
|
||||
</VCard>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
.card-list {
|
||||
--v-card-list-gap: 16px;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,118 @@
|
||||
<script setup>
|
||||
const recentDevices = ref([
|
||||
{
|
||||
type: 'New for you',
|
||||
email: true,
|
||||
browser: true,
|
||||
app: true,
|
||||
},
|
||||
{
|
||||
type: 'Account activity',
|
||||
email: true,
|
||||
browser: true,
|
||||
app: true,
|
||||
},
|
||||
{
|
||||
type: 'A new browser used to sign in',
|
||||
email: true,
|
||||
browser: true,
|
||||
app: false,
|
||||
},
|
||||
{
|
||||
type: 'A new device is linked',
|
||||
email: true,
|
||||
browser: false,
|
||||
app: false,
|
||||
},
|
||||
])
|
||||
|
||||
const selectedNotification = ref('Only when I\'m online')
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VCard>
|
||||
<VCardItem>
|
||||
<VCardTitle>Recent Devices</VCardTitle>
|
||||
<p class="text-body-1 mb-0">
|
||||
We need permission from your browser to show notifications. <span class="text-primary cursor-pointer">Request Permission</span>
|
||||
</p>
|
||||
</VCardItem>
|
||||
|
||||
<VCardText class="px-0">
|
||||
<VDivider />
|
||||
<VTable class="text-no-wrap rounded">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">
|
||||
Type
|
||||
</th>
|
||||
<th scope="col">
|
||||
EMAIL
|
||||
</th>
|
||||
<th scope="col">
|
||||
BROWSER
|
||||
</th>
|
||||
<th scope="col">
|
||||
App
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr
|
||||
v-for="device in recentDevices"
|
||||
:key="device.type"
|
||||
>
|
||||
<td class="text-body-1 text-high-emphasis">
|
||||
{{ device.type }}
|
||||
</td>
|
||||
<td>
|
||||
<VCheckbox v-model="device.email" />
|
||||
</td>
|
||||
<td>
|
||||
<VCheckbox v-model="device.browser" />
|
||||
</td>
|
||||
<td>
|
||||
<VCheckbox v-model="device.app" />
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</VTable>
|
||||
<VDivider />
|
||||
</VCardText>
|
||||
|
||||
<VCardText>
|
||||
<VForm @submit.prevent="() => {}">
|
||||
<h6 class="text-body-1 font-weight-medium mb-6">
|
||||
When should we send you notifications?
|
||||
</h6>
|
||||
|
||||
<VRow>
|
||||
<VCol
|
||||
cols="12"
|
||||
sm="6"
|
||||
>
|
||||
<AppSelect
|
||||
v-model="selectedNotification"
|
||||
mandatory
|
||||
placeholder="Select an option"
|
||||
:items="['Only when I\'m online', 'Anytime']"
|
||||
/>
|
||||
</VCol>
|
||||
</VRow>
|
||||
|
||||
<div class="d-flex flex-wrap gap-4 mt-6">
|
||||
<VBtn type="submit">
|
||||
Save Changes
|
||||
</VBtn>
|
||||
<VBtn
|
||||
color="secondary"
|
||||
variant="tonal"
|
||||
type="reset"
|
||||
>
|
||||
Discard
|
||||
</VBtn>
|
||||
</div>
|
||||
</VForm>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
</template>
|
||||
@@ -0,0 +1,414 @@
|
||||
<script setup>
|
||||
import laptopGirl from '@images/illustrations/laptop-girl.png'
|
||||
|
||||
const isCurrentPasswordVisible = ref(false)
|
||||
const isNewPasswordVisible = ref(false)
|
||||
const isConfirmPasswordVisible = ref(false)
|
||||
const currentPassword = ref('')
|
||||
const newPassword = ref('')
|
||||
const confirmPassword = ref('')
|
||||
|
||||
const passwordRequirements = [
|
||||
'Minimum 8 characters long - the more, the better',
|
||||
'At least one lowercase character',
|
||||
'At least one number, symbol, or whitespace character',
|
||||
]
|
||||
|
||||
const serverKeys = [
|
||||
{
|
||||
name: 'Server Key 1',
|
||||
key: '23eaf7f0-f4f7-495e-8b86-fad3261282ac',
|
||||
createdOn: '28 Apr 2021, 18:20 GTM+4:10',
|
||||
permission: 'Full Access',
|
||||
},
|
||||
{
|
||||
name: 'Server Key 2',
|
||||
key: 'bb98e571-a2e2-4de8-90a9-2e231b5e99',
|
||||
createdOn: '12 Feb 2021, 10:30 GTM+2:30',
|
||||
permission: 'Read Only',
|
||||
},
|
||||
{
|
||||
name: 'Server Key 3',
|
||||
key: '2e915e59-3105-47f2-8838-6e46bf83b711',
|
||||
createdOn: '28 Dec 2020, 12:21 GTM+4:10',
|
||||
permission: 'Full Access',
|
||||
},
|
||||
]
|
||||
|
||||
const recentDevicesHeaders = [
|
||||
{
|
||||
title: 'BROWSER',
|
||||
key: 'browser',
|
||||
},
|
||||
{
|
||||
title: 'DEVICE',
|
||||
key: 'device',
|
||||
},
|
||||
{
|
||||
title: 'LOCATION',
|
||||
key: 'location',
|
||||
},
|
||||
{
|
||||
title: 'RECENT ACTIVITY',
|
||||
key: 'recentActivity',
|
||||
},
|
||||
]
|
||||
|
||||
const recentDevices = [
|
||||
{
|
||||
browser: 'Chrome on Windows',
|
||||
device: 'HP Spectre 360',
|
||||
location: 'New York, NY',
|
||||
recentActivity: '28 Apr 2022, 18:20',
|
||||
deviceIcon: {
|
||||
icon: 'tabler-brand-windows',
|
||||
color: 'primary',
|
||||
},
|
||||
},
|
||||
{
|
||||
browser: 'Chrome on iPhone',
|
||||
device: 'iPhone 12x',
|
||||
location: 'Los Angeles, CA',
|
||||
recentActivity: '20 Apr 2022, 10:20',
|
||||
deviceIcon: {
|
||||
icon: 'tabler-device-mobile',
|
||||
color: 'error',
|
||||
},
|
||||
},
|
||||
{
|
||||
browser: 'Chrome on Android',
|
||||
device: 'Oneplus 9 Pro',
|
||||
location: 'San Francisco, CA',
|
||||
recentActivity: '16 Apr 2022, 04:20',
|
||||
deviceIcon: {
|
||||
icon: 'tabler-brand-android',
|
||||
color: 'success',
|
||||
},
|
||||
},
|
||||
{
|
||||
browser: 'Chrome on macOS',
|
||||
device: 'Apple iMac',
|
||||
location: 'New York, NY',
|
||||
recentActivity: '28 Apr 2022, 18:20',
|
||||
deviceIcon: {
|
||||
icon: 'tabler-brand-apple',
|
||||
color: 'secondary',
|
||||
},
|
||||
},
|
||||
{
|
||||
browser: 'Chrome on Windows',
|
||||
device: 'HP Spectre 360',
|
||||
location: 'Los Angeles, CA',
|
||||
recentActivity: '20 Apr 2022, 10:20',
|
||||
deviceIcon: {
|
||||
icon: 'tabler-brand-windows',
|
||||
color: 'primary',
|
||||
},
|
||||
},
|
||||
{
|
||||
browser: 'Chrome on Android',
|
||||
device: 'Oneplus 9 Pro',
|
||||
location: 'San Francisco, CA',
|
||||
recentActivity: '16 Apr 2022, 04:20',
|
||||
deviceIcon: {
|
||||
icon: 'tabler-brand-android',
|
||||
color: 'success',
|
||||
},
|
||||
},
|
||||
]
|
||||
|
||||
const isOneTimePasswordDialogVisible = ref(false)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VRow>
|
||||
<!-- SECTION: Change Password -->
|
||||
<VCol cols="12">
|
||||
<VCard title="Change Password">
|
||||
<VForm>
|
||||
<VCardText class="pt-0">
|
||||
<!-- 👉 Current Password -->
|
||||
<VRow>
|
||||
<VCol
|
||||
cols="12"
|
||||
md="6"
|
||||
>
|
||||
<!-- 👉 current password -->
|
||||
<AppTextField
|
||||
v-model="currentPassword"
|
||||
:type="isCurrentPasswordVisible ? 'text' : 'password'"
|
||||
:append-inner-icon="isCurrentPasswordVisible ? 'tabler-eye-off' : 'tabler-eye'"
|
||||
label="Current Password"
|
||||
autocomplete="on"
|
||||
placeholder="············"
|
||||
@click:append-inner="isCurrentPasswordVisible = !isCurrentPasswordVisible"
|
||||
/>
|
||||
</VCol>
|
||||
</VRow>
|
||||
|
||||
<!-- 👉 New Password -->
|
||||
<VRow>
|
||||
<VCol
|
||||
cols="12"
|
||||
md="6"
|
||||
>
|
||||
<!-- 👉 new password -->
|
||||
<AppTextField
|
||||
v-model="newPassword"
|
||||
:type="isNewPasswordVisible ? 'text' : 'password'"
|
||||
:append-inner-icon="isNewPasswordVisible ? 'tabler-eye-off' : 'tabler-eye'"
|
||||
label="New Password"
|
||||
autocomplete="on"
|
||||
placeholder="············"
|
||||
@click:append-inner="isNewPasswordVisible = !isNewPasswordVisible"
|
||||
/>
|
||||
</VCol>
|
||||
|
||||
<VCol
|
||||
cols="12"
|
||||
md="6"
|
||||
>
|
||||
<!-- 👉 confirm password -->
|
||||
<AppTextField
|
||||
v-model="confirmPassword"
|
||||
:type="isConfirmPasswordVisible ? 'text' : 'password'"
|
||||
:append-inner-icon="isConfirmPasswordVisible ? 'tabler-eye-off' : 'tabler-eye'"
|
||||
label="Confirm New Password"
|
||||
autocomplete="on"
|
||||
placeholder="············"
|
||||
@click:append-inner="isConfirmPasswordVisible = !isConfirmPasswordVisible"
|
||||
/>
|
||||
</VCol>
|
||||
</VRow>
|
||||
</VCardText>
|
||||
|
||||
<!-- 👉 Password Requirements -->
|
||||
<VCardText>
|
||||
<h6 class="text-h6 text-medium-emphasis mb-4">
|
||||
Password Requirements:
|
||||
</h6>
|
||||
|
||||
<VList class="card-list">
|
||||
<VListItem
|
||||
v-for="item in passwordRequirements"
|
||||
:key="item"
|
||||
:title="item"
|
||||
class="text-medium-emphasis"
|
||||
>
|
||||
<template #prepend>
|
||||
<VIcon
|
||||
size="10"
|
||||
icon="tabler-circle-filled"
|
||||
/>
|
||||
</template>
|
||||
</VListItem>
|
||||
</VList>
|
||||
</VCardText>
|
||||
|
||||
<!-- 👉 Action Buttons -->
|
||||
<VCardText class="d-flex flex-wrap gap-4">
|
||||
<VBtn>Save changes</VBtn>
|
||||
|
||||
<VBtn
|
||||
type="reset"
|
||||
color="secondary"
|
||||
variant="tonal"
|
||||
>
|
||||
Reset
|
||||
</VBtn>
|
||||
</VCardText>
|
||||
</VForm>
|
||||
</VCard>
|
||||
</VCol>
|
||||
<!-- !SECTION -->
|
||||
|
||||
<!-- SECTION Two-steps verification -->
|
||||
<VCol cols="12">
|
||||
<VCard title="Two-steps verification">
|
||||
<VCardText>
|
||||
<h5 class="text-h5 text-medium-emphasis mb-4">
|
||||
Two factor authentication is not enabled yet.
|
||||
</h5>
|
||||
<p class="mb-6">
|
||||
Two-factor authentication adds an additional layer of security to your account by
|
||||
requiring more than just a password to log in.
|
||||
<a
|
||||
href="javascript:void(0)"
|
||||
class="text-decoration-none"
|
||||
>Learn more.</a>
|
||||
</p>
|
||||
|
||||
<VBtn @click="isOneTimePasswordDialogVisible = true">
|
||||
Enable two-factor authentication
|
||||
</VBtn>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
</VCol>
|
||||
<!-- !SECTION -->
|
||||
|
||||
<VCol cols="12">
|
||||
<!-- SECTION: Create an API key -->
|
||||
<VCard title="Create an API key">
|
||||
<VRow no-gutters>
|
||||
<!-- 👉 Choose API Key -->
|
||||
<VCol
|
||||
cols="12"
|
||||
md="5"
|
||||
order-md="0"
|
||||
order="1"
|
||||
>
|
||||
<VCardText class="pt-1">
|
||||
<VForm @submit.prevent="() => { }">
|
||||
<VRow>
|
||||
<!-- 👉 Choose API Key -->
|
||||
<VCol cols="12">
|
||||
<AppSelect
|
||||
label="Choose the API key type you want to create"
|
||||
placeholder="Select API key type"
|
||||
:items="['Full Control', 'Modify', 'Read & Execute', 'List Folder Contents', 'Read Only', 'Read & Write']"
|
||||
/>
|
||||
</VCol>
|
||||
|
||||
<!-- 👉 Name the API Key -->
|
||||
<VCol cols="12">
|
||||
<AppTextField
|
||||
label="Name the API key"
|
||||
placeholder="Name the API key"
|
||||
/>
|
||||
</VCol>
|
||||
|
||||
<!-- 👉 Create Key Button -->
|
||||
<VCol cols="12">
|
||||
<VBtn
|
||||
type="submit"
|
||||
block
|
||||
>
|
||||
Create Key
|
||||
</VBtn>
|
||||
</VCol>
|
||||
</VRow>
|
||||
</VForm>
|
||||
</VCardText>
|
||||
</VCol>
|
||||
|
||||
<!-- 👉 Lady image -->
|
||||
<VCol
|
||||
cols="12"
|
||||
md="7"
|
||||
order="0"
|
||||
order-md="1"
|
||||
class="d-flex flex-column justify-center align-center"
|
||||
>
|
||||
<VImg
|
||||
:src="laptopGirl"
|
||||
:width="$vuetify.display.smAndDown ? '150' : '200'"
|
||||
:style="$vuetify.display.smAndDown ? 'margin-block-end: 24px' : 'position: absolute; bottom: 0;'"
|
||||
/>
|
||||
</VCol>
|
||||
</VRow>
|
||||
</VCard>
|
||||
<!-- !SECTION -->
|
||||
</VCol>
|
||||
|
||||
<VCol cols="12">
|
||||
<!-- SECTION: API Keys List -->
|
||||
<VCard>
|
||||
<VCardItem class="pb-4">
|
||||
<VCardTitle>API Key List & Access</VCardTitle>
|
||||
</VCardItem>
|
||||
<VCardText>
|
||||
An API key is a simple encrypted string that identifies an application without any principal. They are useful
|
||||
for accessing public data anonymously, and are used to associate API requests with your project for quota and
|
||||
billing.
|
||||
</VCardText>
|
||||
|
||||
<!-- 👉 Server Status -->
|
||||
<VCardText class="d-flex flex-column gap-y-6">
|
||||
<VCard
|
||||
v-for="serverKey in serverKeys"
|
||||
:key="serverKey.key"
|
||||
flat
|
||||
class="pa-4"
|
||||
color="rgba(var(--v-theme-on-surface),var(--v-hover-opacity))"
|
||||
>
|
||||
<div class="d-flex flex-column gap-y-2">
|
||||
<div class="d-flex align-center flex-wrap">
|
||||
<h5 class="text-h5 me-3">
|
||||
{{ serverKey.name }}
|
||||
</h5>
|
||||
<VChip
|
||||
label
|
||||
color="primary"
|
||||
size="small"
|
||||
>
|
||||
{{ serverKey.permission }}
|
||||
</VChip>
|
||||
</div>
|
||||
<div class="d-flex align-center text-base font-weight-medium">
|
||||
<h6 class="text-h6 text-medium-emphasis me-3">
|
||||
{{ serverKey.key }}
|
||||
</h6>
|
||||
<div class="cursor-pointer">
|
||||
<VIcon
|
||||
icon="tabler-copy"
|
||||
size="20"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-disabled">
|
||||
Created on {{ serverKey.createdOn }}
|
||||
</div>
|
||||
</div>
|
||||
</VCard>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
<!-- !SECTION -->
|
||||
</VCol>
|
||||
|
||||
<!-- SECTION Recent Devices -->
|
||||
<VCol cols="12">
|
||||
<!-- 👉 Table -->
|
||||
<VCard title="Recent Devices">
|
||||
<VDivider />
|
||||
|
||||
<VDataTable
|
||||
:headers="recentDevicesHeaders"
|
||||
:items="recentDevices"
|
||||
hide-default-footer
|
||||
class="text-no-wrap"
|
||||
>
|
||||
<template #item.browser="{ item }">
|
||||
<div class="d-flex">
|
||||
<VIcon
|
||||
start
|
||||
size="22"
|
||||
:icon="item.deviceIcon.icon"
|
||||
:color="item.deviceIcon.color"
|
||||
/>
|
||||
<div class="text-high-emphasis text-body-1 font-weight-medium">
|
||||
{{ item.browser }}
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<!-- TODO Refactor this after vuetify provides proper solution for removing default footer -->
|
||||
<template #bottom />
|
||||
</VDataTable>
|
||||
</VCard>
|
||||
</VCol>
|
||||
<!-- !SECTION -->
|
||||
</VRow>
|
||||
|
||||
<!-- SECTION Enable One time password -->
|
||||
<TwoFactorAuthDialog v-model:is-dialog-visible="isOneTimePasswordDialogVisible" />
|
||||
<!-- !SECTION -->
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.card-list {
|
||||
--v-card-list-gap: 16px;
|
||||
}
|
||||
|
||||
.server-close-btn {
|
||||
inset-inline-end: 0.5rem;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,329 @@
|
||||
<script setup>
|
||||
const searchQuery = ref('')
|
||||
const selectedStatus = ref()
|
||||
const selectedRows = ref([])
|
||||
|
||||
// Data table options
|
||||
const itemsPerPage = ref(10)
|
||||
const page = ref(1)
|
||||
const sortBy = ref()
|
||||
const orderBy = ref()
|
||||
|
||||
const updateOptions = options => {
|
||||
sortBy.value = options.sortBy[0]?.key
|
||||
orderBy.value = options.sortBy[0]?.order
|
||||
}
|
||||
|
||||
// 👉 headers
|
||||
const headers = [
|
||||
{
|
||||
title: '#',
|
||||
key: 'id',
|
||||
},
|
||||
{
|
||||
title: 'Status',
|
||||
key: 'status',
|
||||
sortable: false,
|
||||
},
|
||||
{
|
||||
title: 'Client',
|
||||
key: 'client',
|
||||
},
|
||||
{
|
||||
title: 'Total',
|
||||
key: 'total',
|
||||
},
|
||||
{
|
||||
title: 'Issued Date',
|
||||
key: 'date',
|
||||
},
|
||||
{
|
||||
title: 'Balance',
|
||||
key: 'balance',
|
||||
},
|
||||
{
|
||||
title: 'Actions',
|
||||
key: 'actions',
|
||||
sortable: false,
|
||||
},
|
||||
]
|
||||
|
||||
const {
|
||||
data: invoiceData,
|
||||
execute: fetchInvoices,
|
||||
} = await useApi(createUrl('/apps/invoice', {
|
||||
query: {
|
||||
q: searchQuery,
|
||||
status: selectedStatus,
|
||||
itemsPerPage,
|
||||
page,
|
||||
sortBy,
|
||||
orderBy,
|
||||
},
|
||||
}))
|
||||
|
||||
const invoices = computed(() => invoiceData.value?.invoices)
|
||||
const totalInvoices = computed(() => invoiceData.value?.totalInvoices)
|
||||
|
||||
// 👉 Invoice balance variant resolver
|
||||
const resolveInvoiceBalanceVariant = (balance, total) => {
|
||||
if (balance === total)
|
||||
return {
|
||||
status: 'Unpaid',
|
||||
chip: { color: 'error' },
|
||||
}
|
||||
if (balance === 0)
|
||||
return {
|
||||
status: 'Paid',
|
||||
chip: { color: 'success' },
|
||||
}
|
||||
|
||||
return {
|
||||
status: balance,
|
||||
chip: { variant: 'text' },
|
||||
}
|
||||
}
|
||||
|
||||
const resolveInvoiceStatusVariantAndIcon = status => {
|
||||
if (status === 'Partial Payment')
|
||||
return {
|
||||
variant: 'warning',
|
||||
icon: 'tabler-chart-pie',
|
||||
}
|
||||
if (status === 'Paid')
|
||||
return {
|
||||
variant: 'success',
|
||||
icon: 'tabler-check',
|
||||
}
|
||||
if (status === 'Downloaded')
|
||||
return {
|
||||
variant: 'info',
|
||||
icon: 'tabler-arrow-down',
|
||||
}
|
||||
if (status === 'Draft')
|
||||
return {
|
||||
variant: 'primary',
|
||||
icon: 'tabler-folder',
|
||||
}
|
||||
if (status === 'Sent')
|
||||
return {
|
||||
variant: 'secondary',
|
||||
icon: 'tabler-mail',
|
||||
}
|
||||
if (status === 'Past Due')
|
||||
return {
|
||||
variant: 'error',
|
||||
icon: 'tabler-alert-circle',
|
||||
}
|
||||
|
||||
return {
|
||||
variant: 'secondary',
|
||||
icon: 'tabler-x',
|
||||
}
|
||||
}
|
||||
|
||||
const deleteInvoice = async id => {
|
||||
await $api(`/apps/invoice/${ id }`, { method: 'DELETE' })
|
||||
fetchInvoices()
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VCard
|
||||
v-if="invoices"
|
||||
id="invoice-list"
|
||||
title="Billing History"
|
||||
>
|
||||
<VCardText class="d-flex align-center flex-wrap gap-4">
|
||||
<!-- 👉 Create invoice -->
|
||||
|
||||
<div class="d-flex gap-2">
|
||||
<VLabel>Show</VLabel>
|
||||
<AppSelect
|
||||
v-model="itemsPerPage"
|
||||
:items="[5, 10, 20, 25, 50]"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<VBtn
|
||||
prepend-icon="tabler-plus"
|
||||
:to="{ name: 'apps-invoice-add' }"
|
||||
>
|
||||
Create invoice
|
||||
</VBtn>
|
||||
|
||||
<VSpacer />
|
||||
|
||||
<div class="d-flex align-end flex-wrap gap-4">
|
||||
<!-- 👉 Search -->
|
||||
<div class="invoice-list-search">
|
||||
<AppTextField
|
||||
v-model="searchQuery"
|
||||
placeholder="Search Invoice"
|
||||
/>
|
||||
</div>
|
||||
<div class="invoice-list-status">
|
||||
<AppSelect
|
||||
v-model="selectedStatus"
|
||||
placeholder="Invoice Status"
|
||||
clearable
|
||||
clear-icon="tabler-x"
|
||||
:items="['Downloaded', 'Draft', 'Sent', 'Paid', 'Partial Payment', 'Past Due']"
|
||||
style="inline-size: 12rem;"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</VCardText>
|
||||
|
||||
<VDivider />
|
||||
|
||||
<!-- SECTION DataTable -->
|
||||
<VDataTableServer
|
||||
v-model="selectedRows"
|
||||
v-model:items-per-page="itemsPerPage"
|
||||
v-model:page="page"
|
||||
show-select
|
||||
:items-length="totalInvoices"
|
||||
:headers="headers"
|
||||
:items="invoices"
|
||||
class="text-no-wrap"
|
||||
@update:options="updateOptions"
|
||||
>
|
||||
<!-- id -->
|
||||
<template #item.id="{ item }">
|
||||
<div class="text-body-1">
|
||||
<RouterLink :to="{ name: 'apps-invoice-preview-id', params: { id: item.id } }">
|
||||
#{{ item.id }}
|
||||
</RouterLink>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- status -->
|
||||
<template #item.status="{ item }">
|
||||
<VTooltip>
|
||||
<template #activator="{ props }">
|
||||
<VAvatar
|
||||
:size="28"
|
||||
v-bind="props"
|
||||
:color="resolveInvoiceStatusVariantAndIcon(item.invoiceStatus).variant"
|
||||
variant="tonal"
|
||||
>
|
||||
<VIcon
|
||||
size="16"
|
||||
:icon="resolveInvoiceStatusVariantAndIcon(item.invoiceStatus).icon"
|
||||
/>
|
||||
</VAvatar>
|
||||
</template>
|
||||
<p class="mb-0">
|
||||
{{ item.invoiceStatus }}
|
||||
</p>
|
||||
<p class="mb-0">
|
||||
Balance: {{ item.balance }}
|
||||
</p>
|
||||
<p class="mb-0">
|
||||
Due date: {{ item.dueDate }}
|
||||
</p>
|
||||
</VTooltip>
|
||||
</template>
|
||||
|
||||
<!-- client -->
|
||||
<template #item.client="{ item }">
|
||||
<div class="d-flex align-center">
|
||||
<VAvatar
|
||||
size="34"
|
||||
:color="!item.avatar.length ? resolveInvoiceStatusVariantAndIcon(item.invoiceStatus).variant : undefined"
|
||||
:variant="!item.avatar.length ? 'tonal' : undefined"
|
||||
class="me-3"
|
||||
>
|
||||
<VImg
|
||||
v-if="item.avatar.length"
|
||||
:src="item.avatar"
|
||||
/>
|
||||
<span v-else>{{ avatarText(item.client.name) }}</span>
|
||||
</VAvatar>
|
||||
<div class="d-flex flex-column">
|
||||
<RouterLink
|
||||
class="font-weight-medium text-body-1 text-high-emphasis mb-0 text-link"
|
||||
:to="{ name: 'pages-user-profile-tab', params: { tab: 'profile' } }"
|
||||
>
|
||||
{{ item.client.name }}
|
||||
</RouterLink>
|
||||
<span class="text-body-2">{{ item.client.companyEmail }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- Total -->
|
||||
<template #item.total="{ item }">
|
||||
${{ item.total }}
|
||||
</template>
|
||||
|
||||
<!-- Issued Date -->
|
||||
<template #item.date="{ item }">
|
||||
{{ item.issuedDate }}
|
||||
</template>
|
||||
|
||||
<!-- Balance -->
|
||||
<template #item.balance="{ item }">
|
||||
<VChip
|
||||
v-if="typeof ((resolveInvoiceBalanceVariant(item.balance, item.total)).status) === 'string'"
|
||||
:color="resolveInvoiceBalanceVariant(item.balance, item.total).chip.color"
|
||||
size="small"
|
||||
label
|
||||
>
|
||||
{{ (resolveInvoiceBalanceVariant(item.balance, item.total)).status }}
|
||||
</VChip>
|
||||
<div
|
||||
v-else
|
||||
class="text-body-1 text-high-emphasis"
|
||||
>
|
||||
{{ Number((resolveInvoiceBalanceVariant(item.balance, item.total)).status) > 0 ? `$${(resolveInvoiceBalanceVariant(item.balance, item.total)).status}` : `-$${Math.abs(Number((resolveInvoiceBalanceVariant(item.balance, item.total)).status))}` }}
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- Actions -->
|
||||
<template #item.actions="{ item }">
|
||||
<IconBtn @click="deleteInvoice(item.id)">
|
||||
<VIcon
|
||||
icon="tabler-trash"
|
||||
size="20"
|
||||
/>
|
||||
</IconBtn>
|
||||
|
||||
<IconBtn :to="{ name: 'apps-invoice-preview-id', params: { id: item.id } }">
|
||||
<VIcon
|
||||
icon="tabler-eye"
|
||||
size="20"
|
||||
/>
|
||||
</IconBtn>
|
||||
<IconBtn>
|
||||
<VIcon
|
||||
icon="tabler-dots-vertical"
|
||||
size="20"
|
||||
/>
|
||||
</IconBtn>
|
||||
</template>
|
||||
|
||||
<template #bottom>
|
||||
<TablePagination
|
||||
v-model:page="page"
|
||||
:items-per-page="itemsPerPage"
|
||||
:total-items="totalInvoices"
|
||||
/>
|
||||
</template>
|
||||
</VDataTableServer>
|
||||
<!-- !SECTION -->
|
||||
</VCard>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
#invoice-list {
|
||||
.invoice-list-actions {
|
||||
inline-size: 8rem;
|
||||
}
|
||||
|
||||
.invoice-list-search {
|
||||
inline-size: 12rem;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
46
resources/js/views/pages/authentication/AuthProvider.vue
Normal file
46
resources/js/views/pages/authentication/AuthProvider.vue
Normal file
@@ -0,0 +1,46 @@
|
||||
<script setup>
|
||||
import { useTheme } from 'vuetify'
|
||||
|
||||
const { global } = useTheme()
|
||||
|
||||
const authProviders = [
|
||||
{
|
||||
icon: 'tabler-brand-facebook-filled',
|
||||
color: '#4267b2',
|
||||
colorInDark: '#497CE2',
|
||||
},
|
||||
{
|
||||
icon: 'tabler-brand-twitter-filled',
|
||||
color: '#1da1f2',
|
||||
colorInDark: '#1da1f2',
|
||||
},
|
||||
{
|
||||
icon: 'tabler-brand-github-filled',
|
||||
color: '#272727',
|
||||
colorInDark: '#fff',
|
||||
},
|
||||
{
|
||||
icon: 'tabler-brand-google-filled',
|
||||
color: '#dd4b39',
|
||||
colorInDark: '#db4437',
|
||||
},
|
||||
]
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="d-flex justify-center flex-wrap gap-1">
|
||||
<VBtn
|
||||
v-for="link in authProviders"
|
||||
:key="link.icon"
|
||||
icon
|
||||
variant="text"
|
||||
size="small"
|
||||
:color="global.name.value === 'dark' ? link.colorInDark : link.color"
|
||||
>
|
||||
<VIcon
|
||||
size="20"
|
||||
:icon="link.icon"
|
||||
/>
|
||||
</VBtn>
|
||||
</div>
|
||||
</template>
|
||||
@@ -0,0 +1,131 @@
|
||||
<script setup>
|
||||
import bootstrapLogo from '@images/icons/brands/bootstrap-logo.png'
|
||||
import figmaLogo from '@images/icons/brands/figma-logo.png'
|
||||
import laravelLogo from '@images/icons/brands/laravel-logo.png'
|
||||
import reactLogo from '@images/icons/brands/react-logo.png'
|
||||
import sketchLogo from '@images/icons/brands/sketch-logo.png'
|
||||
import vuejsLogo from '@images/icons/brands/vuejs-logo.png'
|
||||
|
||||
const activeProjects = [
|
||||
{
|
||||
avatarImg: laravelLogo,
|
||||
title: 'Laravel',
|
||||
subtitle: 'Ecommerce',
|
||||
stats: '65',
|
||||
progressColor: 'error',
|
||||
},
|
||||
{
|
||||
avatarImg: figmaLogo,
|
||||
title: 'Figma',
|
||||
subtitle: 'App UI Kit',
|
||||
stats: '86',
|
||||
progressColor: 'primary',
|
||||
},
|
||||
{
|
||||
avatarImg: vuejsLogo,
|
||||
title: 'VueJs',
|
||||
subtitle: 'Calendar App',
|
||||
stats: '90',
|
||||
progressColor: 'success',
|
||||
},
|
||||
{
|
||||
avatarImg: reactLogo,
|
||||
title: 'React',
|
||||
subtitle: 'Dashboard',
|
||||
stats: '37',
|
||||
progressColor: 'info',
|
||||
},
|
||||
{
|
||||
avatarImg: bootstrapLogo,
|
||||
title: 'Bootstrap',
|
||||
subtitle: 'Website',
|
||||
stats: '22',
|
||||
progressColor: 'primary',
|
||||
},
|
||||
{
|
||||
avatarImg: sketchLogo,
|
||||
title: 'Sketch',
|
||||
subtitle: 'Website Design',
|
||||
stats: '29',
|
||||
progressColor: 'warning',
|
||||
},
|
||||
]
|
||||
|
||||
const moreList = [
|
||||
{
|
||||
title: 'Refresh',
|
||||
value: 'refresh',
|
||||
},
|
||||
{
|
||||
title: 'Download',
|
||||
value: 'Download',
|
||||
},
|
||||
{
|
||||
title: 'View All',
|
||||
value: 'View All',
|
||||
},
|
||||
]
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VCard>
|
||||
<VCardItem>
|
||||
<VCardTitle>Active Projects</VCardTitle>
|
||||
<VCardSubtitle>
|
||||
Average 72% completed
|
||||
</VCardSubtitle>
|
||||
<template #append>
|
||||
<div class="mt-n4 me-n2">
|
||||
<MoreBtn :menu-list="moreList" />
|
||||
</div>
|
||||
</template>
|
||||
</VCardItem>
|
||||
|
||||
<VCardText>
|
||||
<VList class="card-list">
|
||||
<VListItem
|
||||
v-for="project in activeProjects"
|
||||
:key="project.title"
|
||||
>
|
||||
<template #prepend>
|
||||
<VAvatar
|
||||
size="34"
|
||||
rounded
|
||||
class="me-1"
|
||||
>
|
||||
<img :src="project.avatarImg">
|
||||
</VAvatar>
|
||||
</template>
|
||||
|
||||
<VListItemTitle class="font-weight-medium">
|
||||
{{ project.title }}
|
||||
</VListItemTitle>
|
||||
<VListItemSubtitle class="me-4">
|
||||
{{ project.subtitle }}
|
||||
</VListItemSubtitle>
|
||||
|
||||
<template #append>
|
||||
<div class="d-flex align-center gap-x-4">
|
||||
<div style="inline-size: 4.875rem;">
|
||||
<VProgressLinear
|
||||
:model-value="project.stats"
|
||||
:color="project.progressColor"
|
||||
height="8"
|
||||
rounded-bar
|
||||
rounded
|
||||
/>
|
||||
</div>
|
||||
<span class="text-disabled">{{ project.stats }}%</span>
|
||||
</div>
|
||||
</template>
|
||||
</VListItem>
|
||||
</VList>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.card-list {
|
||||
--v-card-list-gap: 16px;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,182 @@
|
||||
<script setup>
|
||||
import avatar1 from '@images/avatars/avatar-1.png'
|
||||
import avatar2 from '@images/avatars/avatar-2.png'
|
||||
import avatar3 from '@images/avatars/avatar-3.png'
|
||||
import pdf from '@images/icons/project-icons/pdf.png'
|
||||
|
||||
const moreList = [
|
||||
{
|
||||
title: 'Refresh',
|
||||
value: 'refresh',
|
||||
},
|
||||
{
|
||||
title: 'Download',
|
||||
value: 'Download',
|
||||
},
|
||||
{
|
||||
title: 'View All',
|
||||
value: 'View All',
|
||||
},
|
||||
]
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VCard>
|
||||
<VCardItem>
|
||||
<template #prepend>
|
||||
<VIcon
|
||||
icon="tabler-list-details"
|
||||
size="24"
|
||||
color="high-emphasis"
|
||||
class="me-1"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<VCardTitle>Activity Timeline</VCardTitle>
|
||||
|
||||
<template #append>
|
||||
<div class="me-n2">
|
||||
<MoreBtn :menu-list="moreList" />
|
||||
</div>
|
||||
</template>
|
||||
</VCardItem>
|
||||
|
||||
<VCardText>
|
||||
<VTimeline
|
||||
side="end"
|
||||
align="start"
|
||||
line-inset="8"
|
||||
truncate-line="start"
|
||||
density="compact"
|
||||
>
|
||||
<!-- SECTION Timeline Item: Flight -->
|
||||
<VTimelineItem
|
||||
dot-color="primary"
|
||||
size="x-small"
|
||||
>
|
||||
<!-- 👉 Header -->
|
||||
<div class="d-flex justify-space-between align-center gap-2 flex-wrap mb-2">
|
||||
<span class="app-timeline-title">
|
||||
12 Invoices have been paid
|
||||
</span>
|
||||
<span class="app-timeline-meta">12 min ago</span>
|
||||
</div>
|
||||
|
||||
<!-- 👉 Content -->
|
||||
<div class="app-timeline-text mt-1">
|
||||
Invoices have been paid to the company
|
||||
</div>
|
||||
|
||||
<div class="d-inline-flex align-center timeline-chip mt-2">
|
||||
<img
|
||||
:src="pdf"
|
||||
height="20"
|
||||
class="me-2"
|
||||
alt="img"
|
||||
>
|
||||
<span class="app-timeline-text font-weight-medium">
|
||||
invoice.pdf
|
||||
</span>
|
||||
</div>
|
||||
</VTimelineItem>
|
||||
<!-- !SECTION -->
|
||||
|
||||
<!-- SECTION Timeline Item: Interview Schedule -->
|
||||
<VTimelineItem
|
||||
size="x-small"
|
||||
dot-color="success"
|
||||
>
|
||||
<!-- 👉 Header -->
|
||||
<div class="d-flex justify-space-between align-center flex-wrap mb-2">
|
||||
<div class="app-timeline-title">
|
||||
Client Meeting
|
||||
</div>
|
||||
<span class="app-timeline-meta">45 min ago</span>
|
||||
</div>
|
||||
|
||||
<div class="app-timeline-text mt-1">
|
||||
Project meeting with john @10:15am
|
||||
</div>
|
||||
|
||||
<!-- 👉 Person -->
|
||||
<div class="d-flex justify-space-between align-center flex-wrap">
|
||||
<!-- 👉 Avatar & Personal Info -->
|
||||
<div class="d-flex align-center mt-2">
|
||||
<VAvatar
|
||||
size="32"
|
||||
class="me-2"
|
||||
:image="avatar1"
|
||||
/>
|
||||
<div class="d-flex flex-column">
|
||||
<p class="text-sm font-weight-medium text-medium-emphasis mb-0">
|
||||
Lester McCarthy (Client)
|
||||
</p>
|
||||
<span class="text-sm">CEO of Pixinvent</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</VTimelineItem>
|
||||
<!-- !SECTION -->
|
||||
|
||||
<!-- SECTION Design Review -->
|
||||
<VTimelineItem
|
||||
size="x-small"
|
||||
dot-color="info"
|
||||
>
|
||||
<!-- 👉 Header -->
|
||||
<div class="d-flex justify-space-between align-center flex-wrap mb-2">
|
||||
<span class="app-timeline-title">
|
||||
Create a new project for client
|
||||
</span>
|
||||
<span class="app-timeline-meta">2 Day Ago</span>
|
||||
</div>
|
||||
|
||||
<!-- 👉 Content -->
|
||||
<p class="app-timeline-text mt-1 mb-2">
|
||||
6 team members in a project
|
||||
</p>
|
||||
|
||||
<div class="v-avatar-group demo-avatar-group">
|
||||
<VAvatar :size="40">
|
||||
<VImg :src="avatar1" />
|
||||
<VTooltip
|
||||
activator="parent"
|
||||
location="top"
|
||||
>
|
||||
John Doe
|
||||
</VTooltip>
|
||||
</VAvatar>
|
||||
|
||||
<VAvatar :size="40">
|
||||
<VImg :src="avatar2" />
|
||||
<VTooltip
|
||||
activator="parent"
|
||||
location="top"
|
||||
>
|
||||
Jennie Obrien
|
||||
</VTooltip>
|
||||
</VAvatar>
|
||||
|
||||
<VAvatar :size="40">
|
||||
<VImg :src="avatar3" />
|
||||
<VTooltip
|
||||
activator="parent"
|
||||
location="top"
|
||||
>
|
||||
Peter Harper
|
||||
</VTooltip>
|
||||
</VAvatar>
|
||||
|
||||
<VAvatar
|
||||
:size="40"
|
||||
:color="$vuetify.theme.current.dark ? '#373b50' : '#eeedf0'"
|
||||
>
|
||||
+3
|
||||
</VAvatar>
|
||||
</div>
|
||||
</VTimelineItem>
|
||||
<!-- !SECTION -->
|
||||
</VTimeline>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
</template>
|
||||
@@ -0,0 +1,87 @@
|
||||
<script setup>
|
||||
const assignmentData = [
|
||||
{
|
||||
title: 'User Experience Design',
|
||||
tasks: 120,
|
||||
progress: 72,
|
||||
color: 'primary',
|
||||
},
|
||||
{
|
||||
title: 'Basic fundamentals',
|
||||
tasks: 32,
|
||||
progress: 48,
|
||||
color: 'success',
|
||||
},
|
||||
{
|
||||
title: 'React Native components',
|
||||
tasks: 182,
|
||||
progress: 15,
|
||||
color: 'error',
|
||||
},
|
||||
{
|
||||
title: 'Basic of music theory',
|
||||
tasks: 56,
|
||||
progress: 24,
|
||||
color: 'info',
|
||||
},
|
||||
]
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VCard>
|
||||
<VCardItem title="Assignment progress">
|
||||
<template #append>
|
||||
<MoreBtn />
|
||||
</template>
|
||||
</VCardItem>
|
||||
<VCardText>
|
||||
<VList class="card-list">
|
||||
<VListItem
|
||||
v-for="assignment in assignmentData"
|
||||
:key="assignment.title"
|
||||
>
|
||||
<template #prepend>
|
||||
<VProgressCircular
|
||||
v-model="assignment.progress"
|
||||
:size="54"
|
||||
class="me-4"
|
||||
:color="assignment.color"
|
||||
>
|
||||
<span class="text-body-1 text-high-emphasis font-weight-medium">
|
||||
{{ assignment.progress }}%
|
||||
</span>
|
||||
</VProgressCircular>
|
||||
</template>
|
||||
<VListItemTitle class="font-weight-medium mb-2 me-2">
|
||||
{{ assignment.title }}
|
||||
</VListItemTitle>
|
||||
|
||||
<VListItemSubtitle class="me-2">
|
||||
{{ assignment.tasks }} Tasks
|
||||
</VListItemSubtitle>
|
||||
<template #append>
|
||||
<VBtn
|
||||
icon
|
||||
variant="tonal"
|
||||
color="secondary"
|
||||
rounded
|
||||
size="30"
|
||||
>
|
||||
<VIcon
|
||||
icon="tabler-chevron-right"
|
||||
class="flip-in-rtl"
|
||||
size="20"
|
||||
/>
|
||||
</VBtn>
|
||||
</template>
|
||||
</VListItem>
|
||||
</VList>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.card-list {
|
||||
--v-card-list-gap: 2rem;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,115 @@
|
||||
<script setup>
|
||||
import brave from '@images/logos/brave.png'
|
||||
import chrome from '@images/logos/chrome.png'
|
||||
import firefox from '@images/logos/firefox.png'
|
||||
import internetExplorer from '@images/logos/internet-explorer.png'
|
||||
import operaMini from '@images/logos/opera-mini.png'
|
||||
import safari from '@images/logos/safari.png'
|
||||
|
||||
const browserStates = [
|
||||
{
|
||||
avatarImg: chrome,
|
||||
title: 'Google Chrome',
|
||||
stats: '90.4',
|
||||
progress: 'secondary',
|
||||
},
|
||||
{
|
||||
avatarImg: safari,
|
||||
title: 'Apple Safari',
|
||||
stats: '70.6',
|
||||
progress: 'success',
|
||||
},
|
||||
{
|
||||
avatarImg: firefox,
|
||||
title: 'Mozilla Firefox',
|
||||
stats: '35.5',
|
||||
progress: 'primary',
|
||||
},
|
||||
{
|
||||
avatarImg: operaMini,
|
||||
title: 'Opera Mini',
|
||||
stats: '80.0',
|
||||
progress: 'error',
|
||||
},
|
||||
{
|
||||
avatarImg: internetExplorer,
|
||||
title: 'Internet Explorer',
|
||||
stats: '62.2',
|
||||
progress: 'info',
|
||||
},
|
||||
{
|
||||
avatarImg: brave,
|
||||
title: 'Brave',
|
||||
stats: '46.3',
|
||||
progress: 'warning',
|
||||
},
|
||||
]
|
||||
|
||||
const moreList = [
|
||||
{
|
||||
title: 'Refresh',
|
||||
value: 'refresh',
|
||||
},
|
||||
{
|
||||
title: 'Download',
|
||||
value: 'Download',
|
||||
},
|
||||
{
|
||||
title: 'View All',
|
||||
value: 'View All',
|
||||
},
|
||||
]
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VCard
|
||||
title="Browser States"
|
||||
subtitle="Counter April 2022"
|
||||
>
|
||||
<template #append>
|
||||
<div class="mt-n4 me-n2">
|
||||
<MoreBtn :menu-list="moreList" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<VCardText>
|
||||
<VList class="card-list">
|
||||
<VListItem
|
||||
v-for="state in browserStates"
|
||||
:key="state.title"
|
||||
>
|
||||
<template #prepend>
|
||||
<img
|
||||
:src="state.avatarImg"
|
||||
height="28"
|
||||
width="28"
|
||||
class="me-4"
|
||||
>
|
||||
</template>
|
||||
|
||||
<VListItemTitle class="font-weight-medium me-4">
|
||||
{{ state.title }}
|
||||
</VListItemTitle>
|
||||
|
||||
<template #append>
|
||||
<div class="text-body-1 me-4">
|
||||
{{ state.stats }}%
|
||||
</div>
|
||||
<VProgressCircular
|
||||
:model-value="state.stats"
|
||||
:color="state.progress"
|
||||
width="3"
|
||||
size="28"
|
||||
/>
|
||||
</template>
|
||||
</VListItem>
|
||||
</VList>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.card-list {
|
||||
--v-card-list-gap: 2rem;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,42 @@
|
||||
<script setup>
|
||||
import congoImg from '@images/illustrations/congo-illustration.png'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VCard>
|
||||
<VRow no-gutters>
|
||||
<VCol cols="8">
|
||||
<VCardText>
|
||||
<h5 class="text-h5 text-no-wrap">
|
||||
Congratulations John! 🎉
|
||||
</h5>
|
||||
<p class="mb-3">
|
||||
Best seller of the month
|
||||
</p>
|
||||
<h4 class="text-h4 text-primary mb-1">
|
||||
$48.9k
|
||||
</h4>
|
||||
<VBtn>View Sales</VBtn>
|
||||
</VCardText>
|
||||
</VCol>
|
||||
|
||||
<VCol cols="4">
|
||||
<VCardText class="pb-0 px-0 position-relative h-100">
|
||||
<VImg
|
||||
:src="congoImg"
|
||||
height="147"
|
||||
class="congo-john-img w-100"
|
||||
/>
|
||||
</VCardText>
|
||||
</VCol>
|
||||
</VRow>
|
||||
</VCard>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.congo-john-img {
|
||||
position: absolute;
|
||||
inset-block-end: 0;
|
||||
inset-inline-end: 1.25rem;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,113 @@
|
||||
<script setup>
|
||||
const deliveryData = [
|
||||
{
|
||||
title: 'Packages in transit',
|
||||
value: '10k',
|
||||
change: 25.8,
|
||||
icon: 'tabler-box',
|
||||
color: 'primary',
|
||||
},
|
||||
{
|
||||
title: 'Packages out for delivery',
|
||||
value: '5k',
|
||||
change: 4.3,
|
||||
icon: 'tabler-truck',
|
||||
color: 'info',
|
||||
},
|
||||
{
|
||||
title: 'Packages delivered',
|
||||
value: '15k',
|
||||
change: -12.5,
|
||||
icon: 'tabler-circle-check',
|
||||
color: 'success',
|
||||
},
|
||||
{
|
||||
title: 'Delivery success rate',
|
||||
value: '95%',
|
||||
change: 35.6,
|
||||
icon: 'tabler-percentage',
|
||||
color: 'warning',
|
||||
},
|
||||
{
|
||||
title: 'Average delivery time',
|
||||
value: '2.5 Days',
|
||||
change: -2.15,
|
||||
icon: 'tabler-clock',
|
||||
color: 'secondary',
|
||||
},
|
||||
{
|
||||
title: 'Customer satisfaction',
|
||||
value: '4.5/5',
|
||||
change: 5.7,
|
||||
icon: 'tabler-users',
|
||||
color: 'error',
|
||||
},
|
||||
]
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VCard>
|
||||
<VCardItem title="Delivery performance">
|
||||
<VCardSubtitle>
|
||||
12% increase in this month
|
||||
</VCardSubtitle>
|
||||
<template #append>
|
||||
<MoreBtn />
|
||||
</template>
|
||||
</VCardItem>
|
||||
|
||||
<VCardText>
|
||||
<VList class="card-list">
|
||||
<VListItem
|
||||
v-for="(data, index) in deliveryData"
|
||||
:key="index"
|
||||
>
|
||||
<div class="d-flex gap-x-4 align-center">
|
||||
<VAvatar
|
||||
:color="data.color"
|
||||
variant="tonal"
|
||||
rounded
|
||||
size="38"
|
||||
class="me-1"
|
||||
>
|
||||
<VIcon
|
||||
:icon="data.icon"
|
||||
size="26"
|
||||
/>
|
||||
</VAvatar>
|
||||
|
||||
<div>
|
||||
<VListItemTitle class="text-body-1 text-high-emphasis">
|
||||
{{ data.title }}
|
||||
</VListItemTitle>
|
||||
<VListItemSubtitle>
|
||||
<div
|
||||
:class="data.change > 0 ? 'text-success' : 'text-error'"
|
||||
class="d-flex align-center"
|
||||
>
|
||||
<VIcon
|
||||
:icon="data.change > 0 ? 'tabler-chevron-up' : 'tabler-chevron-down'"
|
||||
class="me-1"
|
||||
size="20"
|
||||
/>
|
||||
<span>{{ data.change }}%</span>
|
||||
</div>
|
||||
</VListItemSubtitle>
|
||||
</div>
|
||||
</div>
|
||||
<template #append>
|
||||
<span class="text-body-1 font-weight-medium">
|
||||
{{ data.value }}
|
||||
</span>
|
||||
</template>
|
||||
</VListItem>
|
||||
</VList>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.card-list {
|
||||
--v-card-list-gap: 1.5rem;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,194 @@
|
||||
<script setup>
|
||||
import { useTheme } from 'vuetify'
|
||||
import { hexToRgb } from '@layouts/utils'
|
||||
|
||||
const vuetifyTheme = useTheme()
|
||||
|
||||
const series = [{
|
||||
data: [
|
||||
40,
|
||||
95,
|
||||
60,
|
||||
45,
|
||||
90,
|
||||
50,
|
||||
75,
|
||||
],
|
||||
}]
|
||||
|
||||
const chartOptions = computed(() => {
|
||||
const currentTheme = vuetifyTheme.current.value.colors
|
||||
const variableTheme = vuetifyTheme.current.value.variables
|
||||
const labelColor = `rgba(${ hexToRgb(currentTheme['on-background']) },${ variableTheme['disabled-opacity'] })`
|
||||
const labelPrimaryColor = `rgba(${ hexToRgb(currentTheme.primary) },0.1)`
|
||||
|
||||
return {
|
||||
chart: {
|
||||
type: 'bar',
|
||||
toolbar: { show: false },
|
||||
},
|
||||
tooltip: { enabled: false },
|
||||
plotOptions: {
|
||||
bar: {
|
||||
barHeight: '60%',
|
||||
columnWidth: '60%',
|
||||
startingShape: 'rounded',
|
||||
endingShape: 'rounded',
|
||||
borderRadius: 4,
|
||||
distributed: true,
|
||||
},
|
||||
},
|
||||
grid: {
|
||||
show: false,
|
||||
padding: {
|
||||
top: -20,
|
||||
bottom: 0,
|
||||
left: -10,
|
||||
right: -10,
|
||||
},
|
||||
},
|
||||
colors: [
|
||||
labelPrimaryColor,
|
||||
labelPrimaryColor,
|
||||
labelPrimaryColor,
|
||||
labelPrimaryColor,
|
||||
`rgba(${ hexToRgb(currentTheme.primary) }, 1)`,
|
||||
labelPrimaryColor,
|
||||
labelPrimaryColor,
|
||||
],
|
||||
dataLabels: { enabled: false },
|
||||
legend: { show: false },
|
||||
xaxis: {
|
||||
categories: [
|
||||
'Mo',
|
||||
'Tu',
|
||||
'We',
|
||||
'Th',
|
||||
'Fr',
|
||||
'Sa',
|
||||
'Su',
|
||||
],
|
||||
axisBorder: { show: false },
|
||||
axisTicks: { show: false },
|
||||
labels: {
|
||||
style: {
|
||||
colors: labelColor,
|
||||
fontSize: '13px',
|
||||
},
|
||||
},
|
||||
},
|
||||
yaxis: { labels: { show: false } },
|
||||
}
|
||||
})
|
||||
|
||||
const earningReports = [
|
||||
{
|
||||
avatarIcon: 'tabler-chart-pie-2',
|
||||
avatarColor: 'primary',
|
||||
title: 'Net Profit',
|
||||
subtitle: '12.4k Sales',
|
||||
earnings: '$1,619',
|
||||
percentage: '18.6%',
|
||||
},
|
||||
{
|
||||
avatarIcon: 'tabler-currency-dollar',
|
||||
avatarColor: 'success',
|
||||
title: 'Total Income',
|
||||
subtitle: 'Sales, Affiliation',
|
||||
earnings: '$3,571',
|
||||
percentage: '39.6%',
|
||||
},
|
||||
{
|
||||
avatarIcon: 'tabler-credit-card',
|
||||
avatarColor: 'secondary',
|
||||
title: 'Total Expenses',
|
||||
subtitle: 'ADVT, Marketing',
|
||||
earnings: '$430',
|
||||
percentage: '52.8%',
|
||||
},
|
||||
]
|
||||
|
||||
const moreList = [
|
||||
{
|
||||
title: 'Refresh',
|
||||
value: 'refresh',
|
||||
},
|
||||
{
|
||||
title: 'Download',
|
||||
value: 'Download',
|
||||
},
|
||||
{
|
||||
title: 'View All',
|
||||
value: 'View All',
|
||||
},
|
||||
]
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VCard
|
||||
title="Earning Reports"
|
||||
subtitle="Weekly Earnings Overview"
|
||||
>
|
||||
<template #append>
|
||||
<div class="mt-n4 me-n2">
|
||||
<MoreBtn :menu-list="moreList" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<VCardText class="pb-0">
|
||||
<VList class="card-list mb-3">
|
||||
<VListItem
|
||||
v-for="report in earningReports"
|
||||
:key="report.title"
|
||||
>
|
||||
<template #prepend>
|
||||
<VAvatar
|
||||
rounded
|
||||
size="34"
|
||||
variant="tonal"
|
||||
:color="report.avatarColor"
|
||||
class="me-1"
|
||||
>
|
||||
<VIcon
|
||||
:icon="report.avatarIcon"
|
||||
size="22"
|
||||
/>
|
||||
</VAvatar>
|
||||
</template>
|
||||
|
||||
<VListItemTitle class="font-weight-medium me-4">
|
||||
{{ report.title }}
|
||||
</VListItemTitle>
|
||||
<VListItemSubtitle class="me-4">
|
||||
{{ report.subtitle }}
|
||||
</VListItemSubtitle>
|
||||
|
||||
<template #append>
|
||||
<div class="d-flex align-center text-body-2">
|
||||
<span class="me-4">{{ report.earnings }}</span>
|
||||
<VIcon
|
||||
color="success"
|
||||
icon="tabler-chevron-up"
|
||||
size="20"
|
||||
class="me-1"
|
||||
/>
|
||||
<span class="text-disabled">{{ report.percentage }}</span>
|
||||
</div>
|
||||
</template>
|
||||
</VListItem>
|
||||
</VList>
|
||||
|
||||
<VueApexCharts
|
||||
:options="chartOptions"
|
||||
:series="series"
|
||||
:height="180"
|
||||
/>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.card-list {
|
||||
--v-card-list-gap: 1rem;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,148 @@
|
||||
<script setup>
|
||||
import aeIcon from '@images/icons/payments/ae-icon.png'
|
||||
import mastercardIcon from '@images/icons/payments/mastercard-icon.png'
|
||||
import visaIcon from '@images/icons/payments/visa-icon.png'
|
||||
|
||||
const lastTransitions = [
|
||||
{
|
||||
cardImg: visaIcon,
|
||||
lastDigit: '*4230',
|
||||
cardType: 'Credit',
|
||||
sentDate: '17 Mar 2022',
|
||||
status: 'Verified',
|
||||
trend: '+$1,678',
|
||||
},
|
||||
{
|
||||
cardImg: mastercardIcon,
|
||||
lastDigit: '*5578',
|
||||
cardType: 'Credit',
|
||||
sentDate: '12 Feb 2022',
|
||||
status: 'Rejected',
|
||||
trend: '-$839',
|
||||
},
|
||||
{
|
||||
cardImg: aeIcon,
|
||||
lastDigit: '*4567',
|
||||
cardType: 'Credit',
|
||||
sentDate: '28 Feb 2022',
|
||||
status: 'Verified',
|
||||
trend: '+$435',
|
||||
},
|
||||
{
|
||||
cardImg: visaIcon,
|
||||
lastDigit: '*5699',
|
||||
cardType: 'Credit',
|
||||
sentDate: '8 Jan 2022',
|
||||
status: 'Pending',
|
||||
trend: '+$2,345',
|
||||
},
|
||||
{
|
||||
cardImg: visaIcon,
|
||||
lastDigit: '*5699',
|
||||
cardType: 'Credit',
|
||||
sentDate: '8 Jan 2022',
|
||||
status: 'Rejected',
|
||||
trend: '-$234',
|
||||
},
|
||||
]
|
||||
|
||||
const resolveStatus = {
|
||||
Verified: 'success',
|
||||
Rejected: 'error',
|
||||
Pending: 'secondary',
|
||||
}
|
||||
|
||||
const moreList = [
|
||||
{
|
||||
title: 'Refresh',
|
||||
value: 'refresh',
|
||||
},
|
||||
{
|
||||
title: 'Download',
|
||||
value: 'Download',
|
||||
},
|
||||
{
|
||||
title: 'View All',
|
||||
value: 'View All',
|
||||
},
|
||||
]
|
||||
|
||||
const getPaddingStyle = index => index ? 'padding-block-end: 1.5rem;' : 'padding-block: 1.5rem;'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VCard title="Last Transaction">
|
||||
<template #append>
|
||||
<div class="me-n2">
|
||||
<MoreBtn :menu-list="moreList" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<VDivider />
|
||||
<VTable class="text-no-wrap transaction-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>CARD</th>
|
||||
<th>DATE</th>
|
||||
<th>STATUS</th>
|
||||
<th>TREND</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
<tr
|
||||
v-for="(transition, index) in lastTransitions"
|
||||
:key="index"
|
||||
>
|
||||
<td :style="getPaddingStyle(index)">
|
||||
<div class="d-flex align-center">
|
||||
<div class="me-4">
|
||||
<VImg
|
||||
:src="transition.cardImg"
|
||||
width="50"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<p class="font-weight-medium text-base mb-0 text-high-emphasis">
|
||||
{{ transition.lastDigit }}
|
||||
</p>
|
||||
<p class="text-sm mb-0">
|
||||
{{ transition.cardType }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td :style="getPaddingStyle(index)">
|
||||
<p class="text-high-emphasis text-base mb-0">
|
||||
Sent
|
||||
</p>
|
||||
<span class="text-sm">{{ transition.sentDate }}</span>
|
||||
</td>
|
||||
<td :style="getPaddingStyle(index)">
|
||||
<VChip
|
||||
label
|
||||
:color="resolveStatus[transition.status]"
|
||||
size="small"
|
||||
>
|
||||
{{ transition.status }}
|
||||
</VChip>
|
||||
</td>
|
||||
<td :style="getPaddingStyle(index)">
|
||||
<div class="text-high-emphasis text-base">
|
||||
{{ transition.trend }}
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</VTable>
|
||||
</VCard>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
.transaction-table {
|
||||
&.v-table .v-table__wrapper > table > tbody > tr:not(:last-child) > td,
|
||||
&.v-table .v-table__wrapper > table > tbody > tr:not(:last-child) > th {
|
||||
border-block-end: none !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,128 @@
|
||||
<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 :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>
|
||||
356
resources/js/views/pages/cards/card-advance/CardAdvanceOrder.vue
Normal file
356
resources/js/views/pages/cards/card-advance/CardAdvanceOrder.vue
Normal file
@@ -0,0 +1,356 @@
|
||||
<script setup>
|
||||
const currentTab = ref('New')
|
||||
|
||||
const tabsData = [
|
||||
'New',
|
||||
'Preparing',
|
||||
'Shipping',
|
||||
]
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VCard class="country-order-card">
|
||||
<VCardItem
|
||||
title="Orders by countries"
|
||||
subtitle="62 deliveries in progress"
|
||||
class="pb-4"
|
||||
>
|
||||
<template #append>
|
||||
<MoreBtn />
|
||||
</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="tabler-circle-check"
|
||||
dot-color="rgba(var(--v-theme-surface))"
|
||||
icon-color="success"
|
||||
fill-dot
|
||||
size="20"
|
||||
:elevation="0"
|
||||
>
|
||||
<div class="text-body-2 text-uppercase text-success">
|
||||
Sender
|
||||
</div>
|
||||
<div class="app-timeline-title">
|
||||
Myrtle Ullrich
|
||||
</div>
|
||||
<div class="app-timeline-text">
|
||||
101 Boulder, California(CA), 95959
|
||||
</div>
|
||||
</VTimelineItem>
|
||||
<VTimelineItem
|
||||
icon="tabler-map-pin"
|
||||
dot-color="rgba(var(--v-theme-surface))"
|
||||
icon-color="primary"
|
||||
fill-dot
|
||||
size="20"
|
||||
:elevation="0"
|
||||
>
|
||||
<div class="text-body-2 text-primary text-uppercase">
|
||||
Receiver
|
||||
</div>
|
||||
<div class="app-timeline-title">
|
||||
Barry Schowalter
|
||||
</div>
|
||||
<div class="app-timeline-text">
|
||||
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="tabler-circle-check"
|
||||
dot-color="rgba(var(--v-theme-surface))"
|
||||
icon-color="success"
|
||||
fill-dot
|
||||
size="20"
|
||||
:elevation="0"
|
||||
>
|
||||
<div class="text-body-2 text-uppercase text-success">
|
||||
Sender
|
||||
</div>
|
||||
<div class="app-timeline-title">
|
||||
Veronica Herman
|
||||
</div>
|
||||
<div class="app-timeline-text">
|
||||
162 Windsor, California(CA), 95492
|
||||
</div>
|
||||
</VTimelineItem>
|
||||
|
||||
<VTimelineItem
|
||||
icon="tabler-map-pin"
|
||||
dot-color="rgba(var(--v-theme-surface))"
|
||||
icon-color="primary"
|
||||
fill-dot
|
||||
size="20"
|
||||
:elevation="0"
|
||||
>
|
||||
<div class="text-body-2 text-primary text-uppercase">
|
||||
Receiver
|
||||
</div>
|
||||
<div class="app-timeline-title">
|
||||
Helen Jacobs
|
||||
</div>
|
||||
<div class="app-timeline-text">
|
||||
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="tabler-circle-check"
|
||||
dot-color="rgba(var(--v-theme-surface))"
|
||||
icon-color="success"
|
||||
fill-dot
|
||||
size="20"
|
||||
:elevation="0"
|
||||
>
|
||||
<div class="text-body-2 text-uppercase text-success">
|
||||
Sender
|
||||
</div>
|
||||
<div class="app-timeline-title">
|
||||
Myrtle Ullrich
|
||||
</div>
|
||||
<div class="app-timeline-text">
|
||||
101 Boulder, California(CA), 95959
|
||||
</div>
|
||||
</VTimelineItem>
|
||||
<VTimelineItem
|
||||
icon="tabler-map-pin"
|
||||
dot-color="rgba(var(--v-theme-surface))"
|
||||
icon-color="primary"
|
||||
fill-dot
|
||||
size="20"
|
||||
:elevation="0"
|
||||
>
|
||||
<div class="text-body-2 text-primary text-uppercase">
|
||||
Receiver
|
||||
</div>
|
||||
<div class="app-timeline-title">
|
||||
Barry Schowalter
|
||||
</div>
|
||||
<div class="app-timeline-text">
|
||||
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="tabler-circle-check"
|
||||
dot-color="rgba(var(--v-theme-surface))"
|
||||
icon-color="success"
|
||||
fill-dot
|
||||
size="20"
|
||||
:elevation="0"
|
||||
>
|
||||
<div class="text-body-2 text-uppercase text-success">
|
||||
Sender
|
||||
</div>
|
||||
<div class="app-timeline-title">
|
||||
Veronica Herman
|
||||
</div>
|
||||
<div class="app-timeline-text">
|
||||
162 Windsor, California(CA), 95492
|
||||
</div>
|
||||
</VTimelineItem>
|
||||
|
||||
<VTimelineItem
|
||||
icon="tabler-map-pin"
|
||||
dot-color="rgba(var(--v-theme-surface))"
|
||||
icon-color="primary"
|
||||
fill-dot
|
||||
size="20"
|
||||
:elevation="0"
|
||||
>
|
||||
<div class="text-body-2 text-primary text-uppercase">
|
||||
Receiver
|
||||
</div>
|
||||
<div class="app-timeline-title">
|
||||
Helen Jacobs
|
||||
</div>
|
||||
<div class="app-timeline-text">
|
||||
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="tabler-circle-check"
|
||||
dot-color="rgba(var(--v-theme-surface))"
|
||||
icon-color="success"
|
||||
fill-dot
|
||||
size="20"
|
||||
:elevation="0"
|
||||
>
|
||||
<div class="text-body-2 text-uppercase text-success">
|
||||
Sender
|
||||
</div>
|
||||
<div class="app-timeline-title">
|
||||
Myrtle Ullrich
|
||||
</div>
|
||||
<div class="app-timeline-text">
|
||||
101 Boulder, California(CA), 95959
|
||||
</div>
|
||||
</VTimelineItem>
|
||||
<VTimelineItem
|
||||
icon="tabler-map-pin"
|
||||
dot-color="rgba(var(--v-theme-surface))"
|
||||
icon-color="primary"
|
||||
fill-dot
|
||||
size="20"
|
||||
:elevation="0"
|
||||
>
|
||||
<div class="text-body-2 text-primary text-uppercase">
|
||||
Receiver
|
||||
</div>
|
||||
<div class="app-timeline-title">
|
||||
Barry Schowalter
|
||||
</div>
|
||||
<div class="app-timeline-text">
|
||||
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="tabler-circle-check"
|
||||
dot-color="rgba(var(--v-theme-surface))"
|
||||
icon-color="success"
|
||||
fill-dot
|
||||
size="20"
|
||||
:elevation="0"
|
||||
>
|
||||
<div class="text-body-2 text-uppercase text-success">
|
||||
Sender
|
||||
</div>
|
||||
<div class="app-timeline-title">
|
||||
Veronica Herman
|
||||
</div>
|
||||
<div class="app-timeline-text">
|
||||
162 Windsor, California(CA), 95492
|
||||
</div>
|
||||
</VTimelineItem>
|
||||
|
||||
<VTimelineItem
|
||||
icon="tabler-map-pin"
|
||||
dot-color="rgba(var(--v-theme-surface))"
|
||||
icon-color="primary"
|
||||
fill-dot
|
||||
size="20"
|
||||
:elevation="0"
|
||||
>
|
||||
<div class="text-body-2 text-primary text-uppercase">
|
||||
Receiver
|
||||
</div>
|
||||
<div class="app-timeline-title">
|
||||
Helen Jacobs
|
||||
</div>
|
||||
<div class="app-timeline-text">
|
||||
487 Sunset, California(CA), 94043
|
||||
</div>
|
||||
</VTimelineItem>
|
||||
</VTimeline>
|
||||
</div>
|
||||
</VWindowItem>
|
||||
</VWindow>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
.country-order-card {
|
||||
.v-timeline .v-timeline-divider__dot .v-timeline-divider__inner-dot {
|
||||
box-shadow: none !important;
|
||||
}
|
||||
|
||||
.v-timeline-item {
|
||||
.v-timeline-divider {
|
||||
.v-timeline-divider__dot {
|
||||
background: none !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,65 @@
|
||||
<script setup>
|
||||
import avatar1 from '@images/avatars/avatar-1.png'
|
||||
import avatar2 from '@images/avatars/avatar-2.png'
|
||||
import avatar3 from '@images/avatars/avatar-3.png'
|
||||
import avatar4 from '@images/avatars/avatar-4.png'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VCard>
|
||||
<VCardItem title="Popular Instructors">
|
||||
<template #append>
|
||||
<MoreBtn />
|
||||
</template>
|
||||
</VCardItem>
|
||||
<VDivider />
|
||||
<div class="d-flex justify-space-between py-4 px-6">
|
||||
<div class="text-body-1 text-uppercase">
|
||||
instructors
|
||||
</div>
|
||||
<div class="text-body-1 text-uppercase">
|
||||
Courses
|
||||
</div>
|
||||
</div>
|
||||
<VDivider />
|
||||
<VCardText>
|
||||
<VList class="card-list">
|
||||
<VListItem
|
||||
v-for="instructor in [
|
||||
{ name: 'Jordan Stevenson', profession: 'Business Intelligence', totalCourses: 33, avatar: avatar1 },
|
||||
{ name: 'Bentlee Emblin', profession: 'Digital Marketing', totalCourses: 52, avatar: avatar2 },
|
||||
{ name: 'Benedetto Rossiter', profession: 'UI/UX Design', totalCourses: 12, avatar: avatar3 },
|
||||
{ name: 'Beverlie Krabbe', profession: 'Vue', totalCourses: 8, avatar: avatar4 },
|
||||
]"
|
||||
:key="instructor.name"
|
||||
>
|
||||
<template #prepend>
|
||||
<VAvatar
|
||||
size="34"
|
||||
class="me-1"
|
||||
:image="instructor.avatar"
|
||||
/>
|
||||
</template>
|
||||
<VListItemTitle class="font-weight-medium me-4">
|
||||
{{ instructor.name }}
|
||||
</VListItemTitle>
|
||||
<VListItemSubtitle class="me-4">
|
||||
{{ instructor.profession }}
|
||||
</VListItemSubtitle>
|
||||
|
||||
<template #append>
|
||||
<h6 class="text-h6">
|
||||
{{ instructor.totalCourses }}
|
||||
</h6>
|
||||
</template>
|
||||
</VListItem>
|
||||
</VList>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
.card-list {
|
||||
--v-card-list-gap: 1rem;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,112 @@
|
||||
<script setup>
|
||||
import amazonEchoDot from '@images/eCommerce/amazon-echo-dot.png'
|
||||
import appleWatch from '@images/eCommerce/apple-watch.png'
|
||||
import headphone from '@images/eCommerce/headphone.png'
|
||||
import iphone from '@images/eCommerce/iphone.png'
|
||||
import nike from '@images/eCommerce/nike.png'
|
||||
import sonyDualsense from '@images/eCommerce/sony-dualsense.png'
|
||||
|
||||
const popularProducts = [
|
||||
{
|
||||
avatarImg: iphone,
|
||||
title: 'Apple iPhone 13',
|
||||
subtitle: 'Item: #FXZ-4567',
|
||||
stats: '$999.29',
|
||||
},
|
||||
{
|
||||
avatarImg: nike,
|
||||
title: 'Nike Air Jordan',
|
||||
subtitle: 'Item: #FXZ-3456',
|
||||
stats: '$72.40',
|
||||
},
|
||||
{
|
||||
avatarImg: headphone,
|
||||
title: 'Beats Studio 2',
|
||||
subtitle: 'Item: #FXZ-9485',
|
||||
stats: '$99',
|
||||
},
|
||||
{
|
||||
avatarImg: appleWatch,
|
||||
title: 'Apple Watch Series 7',
|
||||
subtitle: 'Item: #FXZ-2345',
|
||||
stats: '$249.99',
|
||||
},
|
||||
{
|
||||
avatarImg: amazonEchoDot,
|
||||
title: 'Amazon Echo Dot',
|
||||
subtitle: 'Item: #FXZ-8959',
|
||||
stats: '$79.40',
|
||||
},
|
||||
{
|
||||
avatarImg: sonyDualsense,
|
||||
title: 'Play Station Console',
|
||||
subtitle: 'Item: #FXZ-7892',
|
||||
stats: '$129.48',
|
||||
},
|
||||
]
|
||||
|
||||
const moreList = [
|
||||
{
|
||||
title: 'Refresh',
|
||||
value: 'refresh',
|
||||
},
|
||||
{
|
||||
title: 'Download',
|
||||
value: 'Download',
|
||||
},
|
||||
{
|
||||
title: 'View All',
|
||||
value: 'View All',
|
||||
},
|
||||
]
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VCard
|
||||
title="Popular Products"
|
||||
subtitle="Total 10.4k Visitors"
|
||||
>
|
||||
<template #append>
|
||||
<div class="mt-n4 me-n2">
|
||||
<MoreBtn :menu-list="moreList" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<VCardText>
|
||||
<VList class="card-list">
|
||||
<VListItem
|
||||
v-for="product in popularProducts"
|
||||
:key="product.title"
|
||||
>
|
||||
<template #prepend>
|
||||
<VAvatar
|
||||
size="46"
|
||||
rounded
|
||||
class="me-1"
|
||||
:image="product.avatarImg"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<VListItemTitle class="font-weight-medium me-4">
|
||||
{{ product.title }}
|
||||
</VListItemTitle>
|
||||
<VListItemSubtitle class="me-4">
|
||||
{{ product.subtitle }}
|
||||
</VListItemSubtitle>
|
||||
|
||||
<template #append>
|
||||
<div class="d-flex align-center">
|
||||
<span class="text-body-1">{{ product.stats }}</span>
|
||||
</div>
|
||||
</template>
|
||||
</VListItem>
|
||||
</VList>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.card-list {
|
||||
--v-card-list-gap: 24px;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,120 @@
|
||||
<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 :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>
|
||||
@@ -0,0 +1,130 @@
|
||||
<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-discount',
|
||||
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 :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: 16px;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,91 @@
|
||||
<script setup>
|
||||
const coursesData = [
|
||||
{
|
||||
title: 'Videography Basic Design Course',
|
||||
views: '1.2k',
|
||||
icon: 'tabler-brand-zoom',
|
||||
color: 'primary',
|
||||
},
|
||||
{
|
||||
title: 'Basic Front-end Development Course',
|
||||
views: '834',
|
||||
icon: 'tabler-code',
|
||||
color: 'info',
|
||||
},
|
||||
{
|
||||
title: 'Basic Fundamentals of Photography',
|
||||
views: '3.7k',
|
||||
icon: 'tabler-camera',
|
||||
color: 'success',
|
||||
},
|
||||
{
|
||||
title: 'Advance Dribble Base Visual Design',
|
||||
views: '2.5k',
|
||||
icon: 'tabler-brand-dribbble',
|
||||
color: 'warning',
|
||||
},
|
||||
{
|
||||
title: 'Your First Singing Lesson',
|
||||
views: '948',
|
||||
icon: 'tabler-microphone-2',
|
||||
color: 'error',
|
||||
},
|
||||
]
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VCard>
|
||||
<VCardItem title="Top Courses">
|
||||
<template #append>
|
||||
<MoreBtn />
|
||||
</template>
|
||||
</VCardItem>
|
||||
|
||||
<VCardText>
|
||||
<VList class="card-list">
|
||||
<VListItem
|
||||
v-for="(course, index) in coursesData"
|
||||
:key="index"
|
||||
>
|
||||
<template #prepend>
|
||||
<VAvatar
|
||||
rounded
|
||||
variant="tonal"
|
||||
:color="course.color"
|
||||
class="me-1"
|
||||
>
|
||||
<VIcon
|
||||
:icon="course.icon"
|
||||
size="24"
|
||||
/>
|
||||
</VAvatar>
|
||||
</template>
|
||||
|
||||
<VListItemTitle class="me-4">
|
||||
<div class="d-flex flex-column">
|
||||
<h6 class="text-h6 text-truncate">
|
||||
{{ course.title }}
|
||||
</h6>
|
||||
<div>
|
||||
<VChip
|
||||
variant="tonal"
|
||||
color="secondary"
|
||||
label
|
||||
size="small"
|
||||
>
|
||||
{{ course.views }} Views
|
||||
</VChip>
|
||||
</div>
|
||||
</div>
|
||||
</VListItemTitle>
|
||||
</VListItem>
|
||||
</VList>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.card-list {
|
||||
--v-card-list-gap: 24px;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,131 @@
|
||||
<script setup>
|
||||
const transitions = [
|
||||
{
|
||||
avatarIcon: 'tabler-wallet',
|
||||
avatarColor: 'primary',
|
||||
title: 'Wallet',
|
||||
subtitle: 'Starbucks',
|
||||
stats: '-$75',
|
||||
profit: false,
|
||||
},
|
||||
{
|
||||
avatarIcon: 'tabler-building-bank',
|
||||
avatarColor: 'success',
|
||||
title: 'Bank Transfer',
|
||||
subtitle: 'Add Money',
|
||||
stats: '+$480',
|
||||
profit: true,
|
||||
},
|
||||
{
|
||||
avatarIcon: 'tabler-brand-paypal',
|
||||
avatarColor: 'error',
|
||||
title: 'PayPal',
|
||||
subtitle: 'Client Payment',
|
||||
stats: '+$268',
|
||||
profit: true,
|
||||
},
|
||||
{
|
||||
avatarIcon: 'tabler-credit-card',
|
||||
avatarColor: 'secondary',
|
||||
title: 'Master Card',
|
||||
subtitle: 'Ordered iPhone 13',
|
||||
stats: '-$699',
|
||||
profit: false,
|
||||
},
|
||||
{
|
||||
avatarIcon: 'tabler-currency-dollar',
|
||||
avatarColor: 'info',
|
||||
title: 'Bank Transactions',
|
||||
subtitle: 'Refund',
|
||||
stats: '+$98',
|
||||
profit: true,
|
||||
},
|
||||
{
|
||||
avatarIcon: 'tabler-brand-paypal',
|
||||
avatarColor: 'error',
|
||||
title: 'PayPal',
|
||||
subtitle: 'Client Payment',
|
||||
stats: '+$126',
|
||||
profit: true,
|
||||
},
|
||||
{
|
||||
avatarIcon: 'tabler-building-bank',
|
||||
avatarColor: 'success',
|
||||
title: 'Bank Transfer',
|
||||
subtitle: 'Pay Office Rent',
|
||||
stats: '-$1290',
|
||||
profit: false,
|
||||
},
|
||||
]
|
||||
|
||||
const moreList = [
|
||||
{
|
||||
title: 'Refresh',
|
||||
value: 'refresh',
|
||||
},
|
||||
{
|
||||
title: 'Download',
|
||||
value: 'Download',
|
||||
},
|
||||
{
|
||||
title: 'View All',
|
||||
value: 'View All',
|
||||
},
|
||||
]
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VCard
|
||||
title="Transactions"
|
||||
subtitle="Total 58 Transactions done in this Month"
|
||||
>
|
||||
<template #append>
|
||||
<div class="mt-n4 me-n2">
|
||||
<MoreBtn :menu-list="moreList" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<VCardText>
|
||||
<VList class="card-list">
|
||||
<VListItem
|
||||
v-for="transition in transitions"
|
||||
:key="transition.title"
|
||||
>
|
||||
<template #prepend>
|
||||
<VAvatar
|
||||
size="34"
|
||||
:color="transition.avatarColor"
|
||||
variant="tonal"
|
||||
class="me-1"
|
||||
rounded
|
||||
>
|
||||
<VIcon
|
||||
:icon="transition.avatarIcon"
|
||||
size="22"
|
||||
/>
|
||||
</VAvatar>
|
||||
</template>
|
||||
|
||||
<VListItemTitle class="font-weight-medium">
|
||||
{{ transition.title }}
|
||||
</VListItemTitle>
|
||||
<VListItemSubtitle>
|
||||
{{ transition.subtitle }}
|
||||
</VListItemSubtitle>
|
||||
|
||||
<template #append>
|
||||
<div class="d-flex align-center">
|
||||
<span :class="`${transition.profit ? 'text-success' : 'text-error'} font-weight-medium me-2`">{{ transition.stats }}</span>
|
||||
</div>
|
||||
</template>
|
||||
</VListItem>
|
||||
</VList>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.card-list {
|
||||
--v-card-list-gap: 16px;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,54 @@
|
||||
<script setup>
|
||||
import girlWithLaptop from '@images/illustrations/laptop-girl.png'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VCard>
|
||||
<VCardText>
|
||||
<div class="d-flex justify-center align-start pb-0 px-3 pt-3 mb-4 bg-light-primary rounded">
|
||||
<VImg
|
||||
:src="girlWithLaptop"
|
||||
width="145"
|
||||
height="152"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<h5 class="text-h5 mb-2">
|
||||
Upcoming Webinar
|
||||
</h5>
|
||||
<div class="text-body-2">
|
||||
Next Generation Frontend Architecture Using Layout Engine And Vue.
|
||||
</div>
|
||||
<div class="d-flex justify-space-between gap-4 flex-wrap my-4">
|
||||
<div
|
||||
v-for="{ icon, title, value } in [{ icon: 'tabler-calendar', title: '17 Nov 23', value: 'Date' }, { icon: 'tabler-clock', title: '32 Minutes', value: 'Duration' }]"
|
||||
:key="title"
|
||||
class="d-flex gap-x-3 align-center"
|
||||
>
|
||||
<VAvatar
|
||||
color="primary"
|
||||
variant="tonal"
|
||||
rounded
|
||||
>
|
||||
<VIcon
|
||||
:icon="icon"
|
||||
size="28"
|
||||
/>
|
||||
</VAvatar>
|
||||
<div>
|
||||
<h6 class="text-h6">
|
||||
{{ title }}
|
||||
</h6>
|
||||
<div class="text-sm">
|
||||
{{ value }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<VBtn block>
|
||||
Join the event
|
||||
</VBtn>
|
||||
</div>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
</template>
|
||||
@@ -0,0 +1,95 @@
|
||||
<script setup>
|
||||
const assignmentData = [
|
||||
{
|
||||
title: 'Incorrect Address',
|
||||
subtitle: 'all exceptions',
|
||||
color: 'success',
|
||||
progress: 83,
|
||||
badgeValue: '+10%',
|
||||
},
|
||||
{
|
||||
title: 'Good',
|
||||
subtitle: '24 vehicles',
|
||||
color: 'info',
|
||||
progress: 17,
|
||||
badgeValue: '8.1',
|
||||
},
|
||||
{
|
||||
title: 'Average',
|
||||
subtitle: '14 vehicles',
|
||||
color: 'primary',
|
||||
progress: 8,
|
||||
badgeValue: '-2.5%',
|
||||
},
|
||||
{
|
||||
title: 'Bad',
|
||||
subtitle: '8 vehicles',
|
||||
color: 'warning',
|
||||
progress: 6,
|
||||
badgeValue: '-3.4%',
|
||||
},
|
||||
{
|
||||
title: 'Not Working',
|
||||
subtitle: '4 vehicles',
|
||||
color: 'error',
|
||||
progress: 2,
|
||||
badgeValue: '+12.6%',
|
||||
},
|
||||
]
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VCard>
|
||||
<VCardItem title="Vehicle Condition">
|
||||
<template #append>
|
||||
<MoreBtn />
|
||||
</template>
|
||||
</VCardItem>
|
||||
<VCardText>
|
||||
<VList class="card-list">
|
||||
<VListItem
|
||||
v-for="assignment in assignmentData"
|
||||
:key="assignment.title"
|
||||
>
|
||||
<template #prepend>
|
||||
<VProgressCircular
|
||||
v-model="assignment.progress"
|
||||
:size="52"
|
||||
class="me-4"
|
||||
:color="assignment.color"
|
||||
>
|
||||
<span class="text-body-1 text-high-emphasis font-weight-medium">
|
||||
{{ assignment.progress }}%
|
||||
</span>
|
||||
</VProgressCircular>
|
||||
</template>
|
||||
<VListItemTitle
|
||||
class="font-weight-medium mb-2 me-2"
|
||||
:class="`text-${assignment.color}`"
|
||||
>
|
||||
{{ assignment.title }}
|
||||
</VListItemTitle>
|
||||
|
||||
<VListItemSubtitle class="me-2">
|
||||
{{ assignment.subtitle }}
|
||||
</VListItemSubtitle>
|
||||
<template #append>
|
||||
<VChip
|
||||
label
|
||||
color="secondary"
|
||||
size="small"
|
||||
>
|
||||
{{ assignment.badgeValue }}
|
||||
</VChip>
|
||||
</template>
|
||||
</VListItem>
|
||||
</VList>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.card-list {
|
||||
--v-card-list-gap: 1.75rem;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,185 @@
|
||||
<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">
|
||||
<VCarousel
|
||||
cycle
|
||||
:continuous="false"
|
||||
:show-arrows="false"
|
||||
hide-delimiter-background
|
||||
:delimiter-icon="() => h(VIcon, { icon: 'fa-circle', size: '8' })"
|
||||
height="auto"
|
||||
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: 2rem;
|
||||
inset-inline-end: 2rem;
|
||||
}
|
||||
}
|
||||
|
||||
.web-analytics-carousel {
|
||||
.v-carousel__controls {
|
||||
.v-carousel__controls__item {
|
||||
&.v-btn--active {
|
||||
.v-icon {
|
||||
opacity: 1 !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
482
resources/js/views/pages/cards/card-basic/CardBasic.vue
Normal file
482
resources/js/views/pages/cards/card-basic/CardBasic.vue
Normal file
@@ -0,0 +1,482 @@
|
||||
<script setup>
|
||||
import avatar1 from '@images/avatars/avatar-1.png'
|
||||
import avatar2 from '@images/avatars/avatar-2.png'
|
||||
import avatar3 from '@images/avatars/avatar-3.png'
|
||||
import avatar4 from '@images/avatars/avatar-4.png'
|
||||
import eCommerce2 from '@images/eCommerce/2.png'
|
||||
import pages1 from '@images/pages/1.png'
|
||||
import pages2 from '@images/pages/2.png'
|
||||
import pages3 from '@images/pages/3.png'
|
||||
import pages5 from '@images/pages/5.jpg'
|
||||
import pages6 from '@images/pages/6.jpg'
|
||||
|
||||
const avatars = [
|
||||
avatar1,
|
||||
avatar2,
|
||||
avatar3,
|
||||
avatar4,
|
||||
]
|
||||
|
||||
const isCardDetailsVisible = ref(false)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VRow>
|
||||
<!-- 👉 Influencing The Influencer -->
|
||||
<VCol
|
||||
cols="12"
|
||||
sm="6"
|
||||
md="4"
|
||||
>
|
||||
<VCard>
|
||||
<VImg
|
||||
:src="pages1"
|
||||
cover
|
||||
/>
|
||||
|
||||
<VCardItem>
|
||||
<VCardTitle>Influencing The Influencer</VCardTitle>
|
||||
</VCardItem>
|
||||
|
||||
<VCardText>
|
||||
Cancun is back, better than ever! Over a hundred Mexico resorts have reopened and the state tourism minister predicts Cancun will draw as many visitors in 2006 as it did two years ago.
|
||||
</VCardText>
|
||||
</VCard>
|
||||
</VCol>
|
||||
|
||||
<!-- 👉 Robert Meyer -->
|
||||
<VCol
|
||||
cols="12"
|
||||
sm="6"
|
||||
md="4"
|
||||
>
|
||||
<VCard>
|
||||
<VImg :src="pages2" />
|
||||
|
||||
<VCardText class="position-relative">
|
||||
<!-- User Avatar -->
|
||||
<VAvatar
|
||||
size="75"
|
||||
class="avatar-center"
|
||||
:image="avatar1"
|
||||
/>
|
||||
|
||||
<!-- Title, Subtitle & Action Button -->
|
||||
<div class="d-flex justify-space-between flex-wrap pt-8">
|
||||
<div class="me-2 mb-2">
|
||||
<VCardTitle class="pa-0">
|
||||
Robert Meyer
|
||||
</VCardTitle>
|
||||
<VCardSubtitle class="text-caption pa-0">
|
||||
London, UK
|
||||
</VCardSubtitle>
|
||||
</div>
|
||||
<VBtn>send request</VBtn>
|
||||
</div>
|
||||
|
||||
<!-- Mutual Friends -->
|
||||
<div class="d-flex justify-space-between align-center mt-8">
|
||||
<span class="font-weight-medium">18 mutual friends</span>
|
||||
|
||||
<div class="v-avatar-group">
|
||||
<VAvatar
|
||||
v-for="avatar in avatars"
|
||||
:key="avatar"
|
||||
:image="avatar"
|
||||
size="38"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
</VCol>
|
||||
|
||||
<!-- 👉 Popular Uses Of The Internet -->
|
||||
<VCol
|
||||
cols="12"
|
||||
md="4"
|
||||
sm="6"
|
||||
>
|
||||
<VCard>
|
||||
<VImg :src="pages3" />
|
||||
|
||||
<VCardItem>
|
||||
<VCardTitle>Popular Uses Of The Internet</VCardTitle>
|
||||
</VCardItem>
|
||||
|
||||
<VCardText>
|
||||
Although cards can support multiple actions, UI controls, and an overflow menu.
|
||||
</VCardText>
|
||||
|
||||
<VCardActions>
|
||||
<VBtn @click="isCardDetailsVisible = !isCardDetailsVisible">
|
||||
Details
|
||||
</VBtn>
|
||||
|
||||
<VSpacer />
|
||||
|
||||
<VBtn
|
||||
icon
|
||||
size="small"
|
||||
@click="isCardDetailsVisible = !isCardDetailsVisible"
|
||||
>
|
||||
<VIcon :icon="isCardDetailsVisible ? 'tabler-chevron-up' : 'tabler-chevron-down'" />
|
||||
</VBtn>
|
||||
</VCardActions>
|
||||
|
||||
<VExpandTransition>
|
||||
<div v-show="isCardDetailsVisible">
|
||||
<VDivider />
|
||||
<VCardText>
|
||||
I'm a thing. But, like most politicians, he promised more than he could deliver. You won't have time for sleeping, soldier, not with all the bed making you'll be doing. Then we'll go with that data file! Hey, you add a one and two zeros to that or we walk! You're going to do his laundry? I've got to find a way to escape.
|
||||
</VCardText>
|
||||
</div>
|
||||
</VExpandTransition>
|
||||
</VCard>
|
||||
</VCol>
|
||||
|
||||
<!-- 👉 Apple iPhone 11 Pro -->
|
||||
<VCol
|
||||
sm="6"
|
||||
cols="12"
|
||||
>
|
||||
<VCard>
|
||||
<div class="d-flex justify-space-between flex-wrap flex-md-nowrap flex-column flex-md-row">
|
||||
<div class="ma-auto pa-5">
|
||||
<VImg
|
||||
width="137"
|
||||
height="176"
|
||||
:src="eCommerce2"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<VDivider :vertical="$vuetify.display.mdAndUp" />
|
||||
|
||||
<div>
|
||||
<VCardItem>
|
||||
<VCardTitle>Apple iPhone 11 Pro</VCardTitle>
|
||||
</VCardItem>
|
||||
|
||||
<VCardText>
|
||||
Apple iPhone 11 Pro smartphone. Announced Sep 2019. Features 5.8″ display Apple A13 Bionic
|
||||
</VCardText>
|
||||
|
||||
<VCardText class="text-subtitle-1">
|
||||
<span>Price :</span> <span class="font-weight-medium">$899</span>
|
||||
</VCardText>
|
||||
|
||||
<VCardActions class="justify-space-between">
|
||||
<VBtn>
|
||||
<VIcon icon="tabler-shopping-cart-plus" />
|
||||
<span class="ms-2">Add to cart</span>
|
||||
</VBtn>
|
||||
|
||||
<IconBtn
|
||||
color="secondary"
|
||||
icon="tabler-share"
|
||||
/>
|
||||
</VCardActions>
|
||||
</div>
|
||||
</div>
|
||||
</VCard>
|
||||
</VCol>
|
||||
|
||||
<!-- 👉 Stump town Roasters. -->
|
||||
<VCol
|
||||
sm="6"
|
||||
cols="12"
|
||||
>
|
||||
<VCard>
|
||||
<div class="d-flex flex-column-reverse flex-md-row">
|
||||
<div>
|
||||
<VCardItem>
|
||||
<VCardTitle>Stumptown Roasters</VCardTitle>
|
||||
</VCardItem>
|
||||
|
||||
<VCardText class="d-flex align-center flex-wrap text-body-1">
|
||||
<VRating
|
||||
:model-value="5"
|
||||
readonly
|
||||
class="me-3"
|
||||
density="compact"
|
||||
/>
|
||||
<span>5 Star | 98 reviews</span>
|
||||
</VCardText>
|
||||
|
||||
<VCardText>
|
||||
Before there was a United States of America, there were coffee houses, because how are you supposed to build.
|
||||
</VCardText>
|
||||
|
||||
<VCardActions>
|
||||
<VBtn>Location</VBtn>
|
||||
<VBtn>Reviews</VBtn>
|
||||
</VCardActions>
|
||||
</div>
|
||||
|
||||
<div class="ma-auto pa-5">
|
||||
<VImg
|
||||
:width="176"
|
||||
:src="pages5"
|
||||
class="rounded"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</VCard>
|
||||
</VCol>
|
||||
|
||||
<!-- 👉 Apple Watch card -->
|
||||
<VCol
|
||||
lg="4"
|
||||
sm="6"
|
||||
cols="12"
|
||||
>
|
||||
<VCard>
|
||||
<VImg :src="pages6" />
|
||||
|
||||
<VCardItem>
|
||||
<VCardTitle>Apple Watch</VCardTitle>
|
||||
</VCardItem>
|
||||
|
||||
<VCardText>
|
||||
<p class="font-weight-medium text-base">
|
||||
$249.40
|
||||
</p>
|
||||
|
||||
<p class="mb-0">
|
||||
3.1GHz 6-core 10th-generation Intel Core i5 processor, Turbo Boost up to 4.5GHz
|
||||
</p>
|
||||
</VCardText>
|
||||
|
||||
<VBtn
|
||||
block
|
||||
class="rounded-t-0"
|
||||
>
|
||||
Add to cart
|
||||
</VBtn>
|
||||
</VCard>
|
||||
</VCol>
|
||||
|
||||
<!-- 👉 Lifetime Membership -->
|
||||
<VCol
|
||||
md="6"
|
||||
lg="8"
|
||||
cols="12"
|
||||
>
|
||||
<VCard>
|
||||
<VRow no-gutters>
|
||||
<VCol
|
||||
cols="12"
|
||||
sm="8"
|
||||
md="12"
|
||||
lg="7"
|
||||
order="2"
|
||||
order-lg="1"
|
||||
>
|
||||
<VCardItem>
|
||||
<VCardTitle>Lifetime Membership</VCardTitle>
|
||||
</VCardItem>
|
||||
|
||||
<VCardText>
|
||||
Here, I focus on a range of items and features that we use in life without giving them a second thought such as Coca Cola, body muscles and holding ones own breath. Though, most of these notes are not fundamentally necessary, they are such that you can use them for a good laugh, at a drinks party or for picking up women or men.
|
||||
</VCardText>
|
||||
|
||||
<VCardText>
|
||||
<VDivider />
|
||||
</VCardText>
|
||||
|
||||
<VCardText class="d-flex justify-center">
|
||||
<div class="me-auto pe-4">
|
||||
<p class="d-flex align-center mb-6">
|
||||
<VIcon
|
||||
color="primary"
|
||||
icon="tabler-lock-open"
|
||||
size="22"
|
||||
/>
|
||||
<span class="ms-3">Full Access</span>
|
||||
</p>
|
||||
|
||||
<p class="d-flex align-center mb-0">
|
||||
<VIcon
|
||||
color="primary"
|
||||
icon="tabler-user"
|
||||
size="22"
|
||||
/>
|
||||
<span class="ms-3">15 Members</span>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<VDivider
|
||||
v-if="$vuetify.display.smAndUp"
|
||||
vertical
|
||||
inset
|
||||
/>
|
||||
|
||||
<div class="ms-auto ps-4">
|
||||
<p class="d-flex align-center mb-6">
|
||||
<VIcon
|
||||
color="primary"
|
||||
icon="tabler-star"
|
||||
size="22"
|
||||
/>
|
||||
<span class="ms-3">Access all Features</span>
|
||||
</p>
|
||||
|
||||
<p class="d-flex align-center mb-0">
|
||||
<VIcon
|
||||
color="primary"
|
||||
icon="tabler-trending-up"
|
||||
size="22"
|
||||
/>
|
||||
<span class="ms-3">Lifetime Free Update</span>
|
||||
</p>
|
||||
</div>
|
||||
</VCardText>
|
||||
</VCol>
|
||||
|
||||
<VCol
|
||||
cols="12"
|
||||
sm="4"
|
||||
md="12"
|
||||
lg="5"
|
||||
order="1"
|
||||
order-lg="2"
|
||||
class="member-pricing-bg text-center"
|
||||
>
|
||||
<div class="membership-pricing d-flex flex-column align-center py-14 h-100 justify-center">
|
||||
<p class="mb-5">
|
||||
<sub class="text-h5">$</sub>
|
||||
<sup class="text-h2 font-weight-medium">899</sup>
|
||||
<sub class="text-h5">USD</sub>
|
||||
</p>
|
||||
|
||||
<p class="text-sm">
|
||||
5 Tips For Offshore <br> Software Development
|
||||
</p>
|
||||
|
||||
<VBtn class="mt-8">
|
||||
Contact Now
|
||||
</VBtn>
|
||||
</div>
|
||||
</VCol>
|
||||
</VRow>
|
||||
</VCard>
|
||||
</VCol>
|
||||
|
||||
<!-- 👉 Influencing The Influencer -->
|
||||
<VCol
|
||||
cols="12"
|
||||
lg="4"
|
||||
md="6"
|
||||
>
|
||||
<VCard title="Influencing The Influencer">
|
||||
<VCardText>
|
||||
Computers have become ubiquitous in almost every facet of our lives. At work, desk jockeys spend hours in front of their desktops, while delivery people scan bar codes with handhelds and workers in the field stay in touch.
|
||||
</VCardText>
|
||||
|
||||
<VCardText>
|
||||
If you're in the market for new desktops, notebooks, or PDAs, there are a myriad of choices.
|
||||
</VCardText>
|
||||
|
||||
<VCardActions>
|
||||
<VBtn>Read More</VBtn>
|
||||
</VCardActions>
|
||||
</VCard>
|
||||
</VCol>
|
||||
|
||||
<!-- 👉 The Best Answers -->
|
||||
<VCol
|
||||
cols="12"
|
||||
lg="4"
|
||||
md="6"
|
||||
>
|
||||
<VCard title="The Best Answers">
|
||||
<VCardText class="d-flex align-center flex-wrap">
|
||||
<VRating
|
||||
:model-value="5"
|
||||
readonly
|
||||
density="compact"
|
||||
class="me-3"
|
||||
/>
|
||||
<span class="text-subtitle-2">5 Star | 98 reviews</span>
|
||||
</VCardText>
|
||||
|
||||
<VCardText>
|
||||
If you are looking for a new way to promote your business that won't cost you more money, maybe printing is one of the options you won't resist.
|
||||
</VCardText>
|
||||
|
||||
<VCardText>
|
||||
become fast, easy and simple. If you want your promotional material to be an eye-catching
|
||||
</VCardText>
|
||||
|
||||
<VCardActions>
|
||||
<VBtn>Location</VBtn>
|
||||
<VBtn>Reviews</VBtn>
|
||||
</VCardActions>
|
||||
</VCard>
|
||||
</VCol>
|
||||
|
||||
<!-- 👉 Support -->
|
||||
<VCol
|
||||
cols="12"
|
||||
md="6"
|
||||
lg="4"
|
||||
>
|
||||
<VCard class="text-center">
|
||||
<VCardText class="d-flex flex-column justify-center align-center">
|
||||
<VAvatar
|
||||
color="primary"
|
||||
variant="tonal"
|
||||
size="50"
|
||||
class="mb-4"
|
||||
>
|
||||
<VIcon
|
||||
size="2rem"
|
||||
icon="tabler-help"
|
||||
/>
|
||||
</VAvatar>
|
||||
|
||||
<h6 class="text-h6">
|
||||
Support
|
||||
</h6>
|
||||
</VCardText>
|
||||
|
||||
<VCardText>
|
||||
<p>
|
||||
According to us blisters are a very common thing and we come across them very often in our daily lives. It is a very common occurrence like cold or fever depending upon your lifestyle.
|
||||
</p>
|
||||
</VCardText>
|
||||
|
||||
<VCardText class="justify-center">
|
||||
<VBtn variant="elevated">
|
||||
Contact Now
|
||||
</VBtn>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
</VCol>
|
||||
</VRow>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.avatar-center {
|
||||
position: absolute;
|
||||
border: 3px solid rgb(var(--v-theme-surface));
|
||||
inset-block-start: -2rem;
|
||||
inset-inline-start: 1rem;
|
||||
}
|
||||
|
||||
// membership pricing
|
||||
.member-pricing-bg {
|
||||
position: relative;
|
||||
background-color: rgba(var(--v-theme-on-surface), var(--v-hover-opacity));
|
||||
}
|
||||
|
||||
.membership-pricing {
|
||||
sup {
|
||||
inset-block-start: 9px;
|
||||
}
|
||||
}
|
||||
|
||||
.v-btn {
|
||||
transform: none;
|
||||
}
|
||||
</style>
|
||||
92
resources/js/views/pages/cards/card-basic/CardNavigation.vue
Normal file
92
resources/js/views/pages/cards/card-basic/CardNavigation.vue
Normal file
@@ -0,0 +1,92 @@
|
||||
<script setup>
|
||||
const navigationTab = ref('Item One')
|
||||
const navigationTab2 = ref('Item One')
|
||||
|
||||
const tabItems = [
|
||||
'Item One',
|
||||
'Item Two',
|
||||
'Item Three',
|
||||
]
|
||||
|
||||
const tabContent = 'Although cards can support multiple actions, UI controls, and an overflow menu, use restraint and remember that cards...'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VRow>
|
||||
<VCol
|
||||
md="6"
|
||||
cols="12"
|
||||
>
|
||||
<VCard>
|
||||
<VTabs v-model="navigationTab">
|
||||
<VTab
|
||||
v-for="item in tabItems"
|
||||
:key="item"
|
||||
>
|
||||
{{ item }}
|
||||
</VTab>
|
||||
</VTabs>
|
||||
|
||||
<!-- tabs content -->
|
||||
<VWindow v-model="navigationTab">
|
||||
<VWindowItem
|
||||
v-for="item in tabItems"
|
||||
:key="item"
|
||||
:value="item"
|
||||
>
|
||||
<VCardItem>
|
||||
<VCardTitle>Navigation Card</VCardTitle>
|
||||
</VCardItem>
|
||||
|
||||
<VCardText>
|
||||
{{ tabContent }}
|
||||
</VCardText>
|
||||
|
||||
<VCardText>
|
||||
<VBtn>Learn More</VBtn>
|
||||
</VCardText>
|
||||
</VWindowItem>
|
||||
</VWindow>
|
||||
</VCard>
|
||||
</VCol>
|
||||
|
||||
<VCol
|
||||
md="6"
|
||||
cols="12"
|
||||
>
|
||||
<VCard>
|
||||
<VTabs
|
||||
v-model="navigationTab2"
|
||||
align-tabs="center"
|
||||
>
|
||||
<VTab
|
||||
v-for="item in tabItems"
|
||||
:key="item"
|
||||
>
|
||||
{{ item }}
|
||||
</VTab>
|
||||
</VTabs>
|
||||
|
||||
<!-- tabs content -->
|
||||
<VWindow v-model="navigationTab2">
|
||||
<VWindowItem
|
||||
v-for="item in tabItems"
|
||||
:key="item"
|
||||
:value="item"
|
||||
class="text-center"
|
||||
>
|
||||
<VCardItem>
|
||||
<VCardTitle>Navigation Card</VCardTitle>
|
||||
</VCardItem>
|
||||
|
||||
<VCardText>{{ tabContent }}</VCardText>
|
||||
|
||||
<VCardText>
|
||||
<VBtn>Learn More</VBtn>
|
||||
</VCardText>
|
||||
</VWindowItem>
|
||||
</VWindow>
|
||||
</VCard>
|
||||
</VCol>
|
||||
</VRow>
|
||||
</template>
|
||||
97
resources/js/views/pages/cards/card-basic/CardSolid.vue
Normal file
97
resources/js/views/pages/cards/card-basic/CardSolid.vue
Normal file
@@ -0,0 +1,97 @@
|
||||
<script setup>
|
||||
import avatar1 from '@images/avatars/avatar-1.png'
|
||||
import avatar4 from '@images/avatars/avatar-4.png'
|
||||
import avatar8 from '@images/avatars/avatar-8.png'
|
||||
|
||||
const solidCardData = [
|
||||
{
|
||||
cardBg: '#16B1FF',
|
||||
title: 'Twitter Card',
|
||||
icon: 'tabler-brand-twitter',
|
||||
text: '"Turns out semicolon-less style is easier and safer in TS because most gotcha edge cases are type invalid as well."',
|
||||
avatarImg: avatar4,
|
||||
avatarName: 'Mary Vaughn',
|
||||
likes: '1.2k',
|
||||
share: '80',
|
||||
},
|
||||
{
|
||||
cardBg: '#3B5998',
|
||||
title: 'Facebook Card',
|
||||
icon: 'tabler-brand-facebook',
|
||||
text: 'You\'ve read about the importance of being courageous, rebellious and imaginative. These are all vital ingredients in an.',
|
||||
avatarImg: avatar1,
|
||||
avatarName: 'Eugene Clarke',
|
||||
likes: '3.2k',
|
||||
share: '49',
|
||||
},
|
||||
{
|
||||
cardBg: '#007BB6',
|
||||
title: 'LinkedIn Card',
|
||||
icon: 'tabler-brand-linkedin',
|
||||
text: 'With the Internet spreading like wildfire and reaching every part of our daily life, more and more traffic is directed.',
|
||||
avatarImg: avatar8,
|
||||
avatarName: 'Anne Burke1',
|
||||
likes: '1.2k',
|
||||
share: '80',
|
||||
},
|
||||
]
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VRow>
|
||||
<VCol
|
||||
v-for="data in solidCardData"
|
||||
:key="data.icon"
|
||||
cols="12"
|
||||
md="6"
|
||||
lg="4"
|
||||
>
|
||||
<VCard :color="data.cardBg">
|
||||
<VCardItem>
|
||||
<template #prepend>
|
||||
<VIcon
|
||||
size="1.9rem"
|
||||
color="white"
|
||||
:icon="data.icon"
|
||||
/>
|
||||
</template>
|
||||
<VCardTitle class="text-white">
|
||||
{{ data.title }}
|
||||
</VCardTitle>
|
||||
</VCardItem>
|
||||
|
||||
<VCardText>
|
||||
<p class="clamp-text text-white mb-0">
|
||||
{{ data.text }}
|
||||
</p>
|
||||
</VCardText>
|
||||
|
||||
<VCardText class="d-flex justify-space-between align-center flex-wrap">
|
||||
<div class="text-no-wrap">
|
||||
<VAvatar
|
||||
size="34"
|
||||
:image="data.avatarImg"
|
||||
/>
|
||||
<span class="text-white ms-2">{{ data.avatarName }}</span>
|
||||
</div>
|
||||
|
||||
<div class="d-flex align-center">
|
||||
<IconBtn
|
||||
icon="tabler-heart"
|
||||
color="white"
|
||||
class="me-1"
|
||||
/>
|
||||
<span class="text-subtitle-2 text-white me-4">{{ data.likes }}</span>
|
||||
|
||||
<IconBtn
|
||||
icon="tabler-share"
|
||||
color="white"
|
||||
class="me-1"
|
||||
/>
|
||||
<span class="text-subtitle-2 text-white mt-1">{{ data.share }}</span>
|
||||
</div>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
</VCol>
|
||||
</VRow>
|
||||
</template>
|
||||
@@ -0,0 +1,77 @@
|
||||
<template>
|
||||
<VCard>
|
||||
<VCardItem class="pb-2">
|
||||
<VCardTitle>Statistics</VCardTitle>
|
||||
|
||||
<template #append>
|
||||
<div class="me-n3">
|
||||
<IconBtn>
|
||||
<VIcon icon="tabler-dots-vertical" />
|
||||
</IconBtn>
|
||||
</div>
|
||||
</template>
|
||||
</VCardItem>
|
||||
|
||||
<VCardText>
|
||||
<div class="d-flex justify-space-between align-center mb-2">
|
||||
<h6 class="text-h6">
|
||||
Subscribers Gained
|
||||
</h6>
|
||||
<VChip
|
||||
label
|
||||
color="success"
|
||||
size="small"
|
||||
>
|
||||
+92k
|
||||
</VChip>
|
||||
</div>
|
||||
|
||||
<div class="d-flex justify-space-between align-center mb-1">
|
||||
<div class="text-base">
|
||||
1.2k new subscriber
|
||||
</div>
|
||||
|
||||
<div class="text-disabled text-sm">
|
||||
85%
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<VProgressLinear
|
||||
model-value="85"
|
||||
color="primary"
|
||||
height="8"
|
||||
rounded
|
||||
/>
|
||||
|
||||
<div class="d-flex justify-space-between align-center mb-2 mt-6">
|
||||
<h6 class="text-h6">
|
||||
Orders Received
|
||||
</h6>
|
||||
<VChip
|
||||
label
|
||||
size="small"
|
||||
color="success"
|
||||
>
|
||||
+38k
|
||||
</VChip>
|
||||
</div>
|
||||
|
||||
<div class="d-flex justify-space-between mb-1">
|
||||
<div class="text-base">
|
||||
2.4k new orders
|
||||
</div>
|
||||
|
||||
<div class="text-disabled text-sm">
|
||||
65%
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<VProgressLinear
|
||||
model-value="65"
|
||||
color="info"
|
||||
height="8"
|
||||
rounded
|
||||
/>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
</template>
|
||||
@@ -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="122"
|
||||
/>
|
||||
</VCard>
|
||||
</template>
|
||||
@@ -0,0 +1,175 @@
|
||||
<script setup>
|
||||
import { useTheme } from 'vuetify'
|
||||
import { hexToRgb } from '@layouts/utils'
|
||||
|
||||
const vuetifyTheme = useTheme()
|
||||
|
||||
const series = [{
|
||||
data: [
|
||||
30,
|
||||
40,
|
||||
50,
|
||||
60,
|
||||
70,
|
||||
80,
|
||||
90,
|
||||
],
|
||||
}]
|
||||
|
||||
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: '100%',
|
||||
columnWidth: '25%',
|
||||
startingShape: 'rounded',
|
||||
endingShape: 'rounded',
|
||||
borderRadius: 4,
|
||||
},
|
||||
},
|
||||
colors: [`rgba(${ hexToRgb(currentTheme.warning) }, 1)`],
|
||||
grid: {
|
||||
show: false,
|
||||
padding: {
|
||||
top: -30,
|
||||
left: -18,
|
||||
bottom: -13,
|
||||
right: -10,
|
||||
},
|
||||
},
|
||||
dataLabels: { enabled: false },
|
||||
tooltip: { enabled: false },
|
||||
legend: { show: false },
|
||||
xaxis: {
|
||||
categories: [
|
||||
'01',
|
||||
'02',
|
||||
'03',
|
||||
'04',
|
||||
'05',
|
||||
'06',
|
||||
'07',
|
||||
],
|
||||
axisBorder: { show: false },
|
||||
axisTicks: { show: false },
|
||||
labels: {
|
||||
style: {
|
||||
colors: `rgba(${ hexToRgb(currentTheme['on-surface']) },${ variableTheme['disabled-opacity'] })`,
|
||||
fontSize: '13px',
|
||||
fontFamily: 'Public sans',
|
||||
},
|
||||
show: true,
|
||||
},
|
||||
},
|
||||
yaxis: { labels: { show: false } },
|
||||
responsive: [
|
||||
{
|
||||
breakpoint: 1441,
|
||||
options: { plotOptions: { bar: { borderRadius: 4 } } },
|
||||
},
|
||||
{
|
||||
breakpoint: 1200,
|
||||
options: {
|
||||
plotOptions: {
|
||||
bar: {
|
||||
columnWidth: '25%',
|
||||
borderRadius: 6,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
breakpoint: 992,
|
||||
options: {
|
||||
plotOptions: {
|
||||
bar: {
|
||||
borderRadius: 6,
|
||||
columnWidth: '25%',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
breakpoint: 836,
|
||||
options: { plotOptions: { bar: { columnWidth: '30%' } } },
|
||||
},
|
||||
{
|
||||
breakpoint: 738,
|
||||
options: {
|
||||
plotOptions: {
|
||||
bar: {
|
||||
columnWidth: '35%',
|
||||
borderRadius: 6,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
breakpoint: 576,
|
||||
options: {
|
||||
plotOptions: {
|
||||
bar: {
|
||||
columnWidth: '25%',
|
||||
borderRadius: 8,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
breakpoint: 500,
|
||||
options: {
|
||||
plotOptions: {
|
||||
bar: {
|
||||
columnWidth: '24%',
|
||||
borderRadius: 6,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
breakpoint: 450,
|
||||
options: { plotOptions: { bar: { borderRadius: 6 } } },
|
||||
},
|
||||
],
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VCard>
|
||||
<VCardText>
|
||||
<div class="d-flex justify-space-between">
|
||||
<div>
|
||||
<h4 class="text-h4">
|
||||
2.84k
|
||||
</h4>
|
||||
<div class="text-subtitle-2">
|
||||
Avg Daily Traffic
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<VChip
|
||||
label
|
||||
color="success"
|
||||
size="small"
|
||||
>
|
||||
<span class="font-weight-medium">+15%</span>
|
||||
</VChip>
|
||||
</div>
|
||||
|
||||
<VueApexCharts
|
||||
:options="chartOptions"
|
||||
:series="series"
|
||||
:height="145"
|
||||
/>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
</template>
|
||||
@@ -0,0 +1,115 @@
|
||||
<script setup>
|
||||
import { useTheme } from 'vuetify'
|
||||
import { hexToRgb } from '@layouts/utils'
|
||||
|
||||
const vuetifyTheme = useTheme()
|
||||
const series = [78]
|
||||
|
||||
const chartOptions = computed(() => {
|
||||
const currentTheme = vuetifyTheme.current.value.colors
|
||||
const variableTheme = vuetifyTheme.current.value.variables
|
||||
|
||||
return {
|
||||
chart: {
|
||||
sparkline: { enabled: true },
|
||||
parentHeightOffset: 0,
|
||||
type: 'radialBar',
|
||||
},
|
||||
colors: ['rgba(var(--v-theme-warning),1)'],
|
||||
plotOptions: {
|
||||
radialBar: {
|
||||
offsetY: 0,
|
||||
startAngle: -90,
|
||||
endAngle: 90,
|
||||
hollow: { size: '65%' },
|
||||
track: {
|
||||
strokeWidth: '45%',
|
||||
background: `rgba(${ hexToRgb(String(variableTheme['border-color'])) },${ variableTheme['border-opacity'] })`,
|
||||
},
|
||||
dataLabels: {
|
||||
name: { show: false },
|
||||
value: {
|
||||
fontSize: '24px',
|
||||
color: `rgba(${ hexToRgb(currentTheme['on-background']) },${ variableTheme['high-emphasis-opacity'] })`,
|
||||
fontWeight: 600,
|
||||
offsetY: -5,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
grid: {
|
||||
show: false,
|
||||
padding: { bottom: 5 },
|
||||
},
|
||||
stroke: { lineCap: 'round' },
|
||||
labels: ['Progress'],
|
||||
responsive: [
|
||||
{
|
||||
breakpoint: 1442,
|
||||
options: {
|
||||
chart: { height: 140 },
|
||||
plotOptions: {
|
||||
radialBar: {
|
||||
dataLabels: { value: { fontSize: '24px' } },
|
||||
hollow: { size: '60%' },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
breakpoint: 1370,
|
||||
options: { chart: { height: 120 } },
|
||||
},
|
||||
{
|
||||
breakpoint: 1280,
|
||||
options: {
|
||||
chart: { height: 200 },
|
||||
plotOptions: {
|
||||
radialBar: {
|
||||
dataLabels: { value: { fontSize: '18px' } },
|
||||
hollow: { size: '70%' },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
breakpoint: 960,
|
||||
options: {
|
||||
chart: { height: 250 },
|
||||
plotOptions: {
|
||||
radialBar: {
|
||||
hollow: { size: '70%' },
|
||||
dataLabels: { value: { fontSize: '24px' } },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VCard>
|
||||
<VCardItem class="pb-3">
|
||||
<VCardTitle>
|
||||
82.5K
|
||||
</VCardTitle>
|
||||
<VCardSubtitle>
|
||||
Expenses
|
||||
</VCardSubtitle>
|
||||
</VCardItem>
|
||||
<VCardText>
|
||||
<VueApexCharts
|
||||
:options="chartOptions"
|
||||
:series="series"
|
||||
type="radialBar"
|
||||
:height="135"
|
||||
/>
|
||||
|
||||
<div class="text-sm text-center clamp-text text-disabled mt-3">
|
||||
$21k Expenses more than last month
|
||||
</div>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
</template>
|
||||
@@ -0,0 +1,141 @@
|
||||
<script setup>
|
||||
import { useTheme } from 'vuetify'
|
||||
import { hexToRgb } from '@layouts/utils'
|
||||
|
||||
const vuetifyTheme = useTheme()
|
||||
|
||||
const series = [
|
||||
45,
|
||||
58,
|
||||
30,
|
||||
50,
|
||||
]
|
||||
|
||||
const chartOptions = computed(() => {
|
||||
const currentTheme = vuetifyTheme.current.value.colors
|
||||
const variableTheme = vuetifyTheme.current.value.variables
|
||||
const labelSuccessColor = `rgba(${ hexToRgb(currentTheme.success) },0.2)`
|
||||
const headingColor = `rgba(${ hexToRgb(currentTheme['on-background']) },${ variableTheme['high-emphasis-opacity'] })`
|
||||
|
||||
const chartColors = {
|
||||
donut: {
|
||||
series1: currentTheme.success,
|
||||
series2: '#28c76fb3',
|
||||
series3: '#28c76f80',
|
||||
series4: labelSuccessColor,
|
||||
},
|
||||
}
|
||||
|
||||
return {
|
||||
chart: {
|
||||
parentHeightOffset: 0,
|
||||
type: 'donut',
|
||||
},
|
||||
labels: [
|
||||
'Electronic',
|
||||
'Sports',
|
||||
'Decor',
|
||||
'Fashion',
|
||||
],
|
||||
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: false },
|
||||
tooltip: { theme: false },
|
||||
grid: {
|
||||
padding: {
|
||||
top: 15,
|
||||
right: -20,
|
||||
left: -20,
|
||||
},
|
||||
},
|
||||
states: { hover: { filter: { type: 'none' } } },
|
||||
plotOptions: {
|
||||
pie: {
|
||||
donut: {
|
||||
size: '70%',
|
||||
labels: {
|
||||
show: true,
|
||||
value: {
|
||||
fontSize: '1.375rem',
|
||||
fontFamily: 'Public Sans',
|
||||
color: headingColor,
|
||||
fontWeight: 600,
|
||||
offsetY: -15,
|
||||
formatter(val) {
|
||||
return `${ Number.parseInt(val) }%`
|
||||
},
|
||||
},
|
||||
name: {
|
||||
offsetY: 20,
|
||||
fontFamily: 'Public Sans',
|
||||
},
|
||||
total: {
|
||||
show: true,
|
||||
showAlways: true,
|
||||
color: currentTheme.success,
|
||||
fontSize: '.8125rem',
|
||||
label: 'Total',
|
||||
fontFamily: 'Public Sans',
|
||||
formatter() {
|
||||
return '184'
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VCard class="overflow-visible">
|
||||
<VCardText class="d-flex justify-space-between">
|
||||
<div class="d-flex flex-column">
|
||||
<div class="mb-auto">
|
||||
<h5 class="text-h5 text-no-wrap">
|
||||
Generated Leads
|
||||
</h5>
|
||||
<div class="text-body-1">
|
||||
Monthly Report
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h3 class="text-h3">
|
||||
4,350
|
||||
</h3>
|
||||
<div class="d-flex gap-x-1 align-center">
|
||||
<VIcon
|
||||
icon="tabler-chevron-up"
|
||||
size="20"
|
||||
color="success"
|
||||
/>
|
||||
<div class="text-base text-success">
|
||||
15.8%
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<VueApexCharts
|
||||
:options="chartOptions"
|
||||
:series="series"
|
||||
:height="147"
|
||||
:width="130"
|
||||
/>
|
||||
</div>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
</template>
|
||||
@@ -0,0 +1,79 @@
|
||||
<script setup>
|
||||
import { useTheme } from 'vuetify'
|
||||
|
||||
const vuetifyTheme = useTheme()
|
||||
|
||||
const series = [{
|
||||
data: [
|
||||
200,
|
||||
200,
|
||||
500,
|
||||
500,
|
||||
300,
|
||||
300,
|
||||
100,
|
||||
100,
|
||||
450,
|
||||
450,
|
||||
650,
|
||||
650,
|
||||
],
|
||||
}]
|
||||
|
||||
const chartOptions = computed(() => {
|
||||
const currentTheme = vuetifyTheme.current.value.colors
|
||||
|
||||
return {
|
||||
chart: {
|
||||
height: 90,
|
||||
parentHeightOffset: 0,
|
||||
toolbar: { show: false },
|
||||
sparkline: { enabled: true },
|
||||
},
|
||||
tooltip: { enabled: false },
|
||||
markers: { strokeColor: 'transparent' },
|
||||
colors: [currentTheme.error],
|
||||
stroke: { width: 3 },
|
||||
grid: { padding: { bottom: -10 } },
|
||||
responsive: [
|
||||
{
|
||||
breakpoint: 1200,
|
||||
options: { chart: { height: 110 } },
|
||||
},
|
||||
{
|
||||
breakpoint: 768,
|
||||
options: { chart: { height: 90 } },
|
||||
},
|
||||
],
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VCard>
|
||||
<VCardItem class="pb-3">
|
||||
<VCardTitle>
|
||||
Impression
|
||||
</VCardTitle>
|
||||
<VCardSubtitle>
|
||||
Expenses
|
||||
</VCardSubtitle>
|
||||
</VCardItem>
|
||||
<VCardText>
|
||||
<VueApexCharts
|
||||
:options="chartOptions"
|
||||
:series="series"
|
||||
:height="68"
|
||||
/>
|
||||
|
||||
<div class="d-flex align-center justify-space-between gap-x-2 mt-3">
|
||||
<h4 class="text-h4 text-center">
|
||||
26.1k
|
||||
</h4>
|
||||
<span class="text-sm text-error">
|
||||
-24.5%
|
||||
</span>
|
||||
</div>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
</template>
|
||||
@@ -0,0 +1,186 @@
|
||||
<script setup>
|
||||
const series = [{
|
||||
name: '2020',
|
||||
data: [
|
||||
60,
|
||||
50,
|
||||
20,
|
||||
45,
|
||||
50,
|
||||
30,
|
||||
70,
|
||||
],
|
||||
}]
|
||||
|
||||
const chartOptions = computed(() => {
|
||||
return {
|
||||
chart: {
|
||||
height: 90,
|
||||
parentHeightOffset: 0,
|
||||
type: 'bar',
|
||||
toolbar: { show: false },
|
||||
},
|
||||
tooltip: { enabled: false },
|
||||
plotOptions: {
|
||||
bar: {
|
||||
barHeight: '100%',
|
||||
columnWidth: '30%',
|
||||
startingShape: 'rounded',
|
||||
endingShape: 'rounded',
|
||||
borderRadius: 4,
|
||||
colors: {
|
||||
backgroundBarColors: [
|
||||
'rgba(var(--v-track-bg))',
|
||||
'rgba(var(--v-track-bg))',
|
||||
'rgba(var(--v-track-bg))',
|
||||
'rgba(var(--v-track-bg))',
|
||||
'rgba(var(--v-track-bg))',
|
||||
'rgba(var(--v-track-bg))',
|
||||
'rgba(var(--v-track-bg))',
|
||||
'rgba(var(--v-track-bg))',
|
||||
'rgba(var(--v-track-bg))',
|
||||
'rgba(var(--v-track-bg))',
|
||||
'rgba(var(--v-track-bg))',
|
||||
'rgba(var(--v-track-bg))',
|
||||
'rgba(var(--v-track-bg))',
|
||||
'rgba(var(--v-track-bg))',
|
||||
],
|
||||
backgroundBarRadius: 4,
|
||||
},
|
||||
},
|
||||
},
|
||||
colors: ['rgba(var(--v-theme-primary),1)'],
|
||||
grid: {
|
||||
show: false,
|
||||
padding: {
|
||||
top: -30,
|
||||
left: -16,
|
||||
bottom: 0,
|
||||
right: -6,
|
||||
},
|
||||
},
|
||||
dataLabels: { enabled: false },
|
||||
legend: { show: false },
|
||||
xaxis: {
|
||||
categories: [
|
||||
'M',
|
||||
'T',
|
||||
'W',
|
||||
'T',
|
||||
'F',
|
||||
'S',
|
||||
'S',
|
||||
],
|
||||
axisBorder: { show: false },
|
||||
axisTicks: { show: false },
|
||||
labels: { show: false },
|
||||
},
|
||||
yaxis: { labels: { show: false } },
|
||||
responsive: [
|
||||
{
|
||||
breakpoint: 1441,
|
||||
options: {
|
||||
plotOptions: {
|
||||
bar: {
|
||||
columnWidth: '30%',
|
||||
borderRadius: 4,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
breakpoint: 1368,
|
||||
options: { plotOptions: { bar: { columnWidth: '48%' } } },
|
||||
},
|
||||
{
|
||||
breakpoint: 1264,
|
||||
options: {
|
||||
plotOptions: {
|
||||
bar: {
|
||||
borderRadius: 6,
|
||||
columnWidth: '30%',
|
||||
colors: { backgroundBarRadius: 6 },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
breakpoint: 960,
|
||||
options: {
|
||||
plotOptions: {
|
||||
bar: {
|
||||
columnWidth: '15%',
|
||||
borderRadius: 4,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
breakpoint: 883,
|
||||
options: { plotOptions: { bar: { columnWidth: '20%' } } },
|
||||
},
|
||||
{
|
||||
breakpoint: 768,
|
||||
options: { plotOptions: { bar: { columnWidth: '25%' } } },
|
||||
},
|
||||
{
|
||||
breakpoint: 600,
|
||||
options: {
|
||||
plotOptions: {
|
||||
bar: {
|
||||
columnWidth: '15%',
|
||||
borderRadius: 4,
|
||||
},
|
||||
colors: { backgroundBarRadius: 9 },
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
breakpoint: 479,
|
||||
options: {
|
||||
plotOptions: {
|
||||
bar: { borderRadius: 4 },
|
||||
colors: { backgroundBarRadius: 9 },
|
||||
},
|
||||
grid: {
|
||||
padding: {
|
||||
right: -15,
|
||||
left: -15,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
breakpoint: 400,
|
||||
options: { plotOptions: { bar: { borderRadius: 3 } } },
|
||||
},
|
||||
],
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VCard>
|
||||
<VCardItem class="pb-3">
|
||||
<VCardTitle>Orders</VCardTitle>
|
||||
<VCardSubtitle>Last Week</VCardSubtitle>
|
||||
</VCardItem>
|
||||
|
||||
<VCardText>
|
||||
<VueApexCharts
|
||||
:options="chartOptions"
|
||||
:series="series"
|
||||
:height="70"
|
||||
/>
|
||||
|
||||
<div class="d-flex align-center justify-space-between gap-x-2 mt-3">
|
||||
<h4 class="text-h4 text-center">
|
||||
124k
|
||||
</h4>
|
||||
<div class="text-sm text-success">
|
||||
+12.6%
|
||||
</div>
|
||||
</div>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
</template>
|
||||
@@ -0,0 +1,200 @@
|
||||
<script setup>
|
||||
import { useTheme } from 'vuetify'
|
||||
import { hexToRgb } from '@layouts/utils'
|
||||
|
||||
const vuetifyTheme = useTheme()
|
||||
|
||||
const series = [{
|
||||
data: [
|
||||
25,
|
||||
40,
|
||||
55,
|
||||
70,
|
||||
85,
|
||||
70,
|
||||
55,
|
||||
],
|
||||
}]
|
||||
|
||||
const chartOptions = computed(() => {
|
||||
const currentTheme = vuetifyTheme.current.value.colors
|
||||
const variableTheme = vuetifyTheme.current.value.variables
|
||||
const labelSuccessColor = `rgba(${ hexToRgb(currentTheme.success) },0.2)`
|
||||
const labelColor = `rgba(${ hexToRgb(currentTheme['on-surface']) },${ variableTheme['disabled-opacity'] })`
|
||||
|
||||
return {
|
||||
chart: {
|
||||
height: 162,
|
||||
type: 'bar',
|
||||
parentHeightOffset: 0,
|
||||
toolbar: { show: false },
|
||||
},
|
||||
plotOptions: {
|
||||
bar: {
|
||||
barHeight: '80%',
|
||||
columnWidth: '30%',
|
||||
startingShape: 'rounded',
|
||||
endingShape: 'rounded',
|
||||
borderRadius: 6,
|
||||
distributed: true,
|
||||
},
|
||||
},
|
||||
tooltip: { enabled: false },
|
||||
grid: {
|
||||
show: false,
|
||||
padding: {
|
||||
top: -20,
|
||||
bottom: -12,
|
||||
left: -10,
|
||||
right: 0,
|
||||
},
|
||||
},
|
||||
colors: [
|
||||
labelSuccessColor,
|
||||
labelSuccessColor,
|
||||
labelSuccessColor,
|
||||
labelSuccessColor,
|
||||
currentTheme.success,
|
||||
labelSuccessColor,
|
||||
labelSuccessColor,
|
||||
],
|
||||
dataLabels: { enabled: false },
|
||||
legend: { show: false },
|
||||
xaxis: {
|
||||
categories: [
|
||||
'M',
|
||||
'T',
|
||||
'W',
|
||||
'T',
|
||||
'F',
|
||||
'S',
|
||||
'S',
|
||||
],
|
||||
axisBorder: { show: false },
|
||||
axisTicks: { show: false },
|
||||
labels: {
|
||||
style: {
|
||||
colors: labelColor,
|
||||
fontSize: '13px',
|
||||
fontFamily: 'Public sans',
|
||||
},
|
||||
},
|
||||
},
|
||||
yaxis: { labels: { show: false } },
|
||||
states: { hover: { filter: { type: 'none' } } },
|
||||
responsive: [
|
||||
{
|
||||
breakpoint: 1640,
|
||||
options: {
|
||||
plotOptions: {
|
||||
bar: {
|
||||
columnWidth: '40%',
|
||||
borderRadius: 6,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
breakpoint: 1471,
|
||||
options: { plotOptions: { bar: { columnWidth: '50%' } } },
|
||||
},
|
||||
{
|
||||
breakpoint: 1350,
|
||||
options: { plotOptions: { bar: { columnWidth: '57%' } } },
|
||||
},
|
||||
{
|
||||
breakpoint: 1032,
|
||||
options: {
|
||||
plotOptions: {
|
||||
bar: {
|
||||
columnWidth: '50%',
|
||||
borderRadius: 4,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
breakpoint: 992,
|
||||
options: {
|
||||
plotOptions: {
|
||||
bar: {
|
||||
columnWidth: '40%',
|
||||
borderRadius: 4,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
breakpoint: 855,
|
||||
options: {
|
||||
plotOptions: {
|
||||
bar: {
|
||||
columnWidth: '50%',
|
||||
borderRadius: 6,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
breakpoint: 440,
|
||||
options: {
|
||||
plotOptions: {
|
||||
bar: {
|
||||
columnWidth: '30%',
|
||||
borderRadius: 4,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
breakpoint: 381,
|
||||
options: {
|
||||
plotOptions: {
|
||||
bar: {
|
||||
columnWidth: '45%',
|
||||
borderRadius: 4,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VCard>
|
||||
<VCardText class="d-flex justify-space-between">
|
||||
<div class="d-flex flex-column">
|
||||
<div class="mb-auto">
|
||||
<h5 class="text-h5 text-no-wrap mb-2">
|
||||
Revenue Growth
|
||||
</h5>
|
||||
<div class="text-body-1">
|
||||
Weekly Report
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h5 class="text-h3 mb-2">
|
||||
$4,673
|
||||
</h5>
|
||||
<VChip
|
||||
label
|
||||
color="success"
|
||||
size="small"
|
||||
>
|
||||
+15.2%
|
||||
</VChip>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<VueApexCharts
|
||||
:options="chartOptions"
|
||||
:series="series"
|
||||
:height="162"
|
||||
/>
|
||||
</div>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
</template>
|
||||
@@ -0,0 +1,91 @@
|
||||
<script setup>
|
||||
import { useTheme } from 'vuetify'
|
||||
|
||||
const vuetifyTheme = useTheme()
|
||||
const currentTheme = vuetifyTheme.current.value.colors
|
||||
|
||||
const series = [{
|
||||
name: 'Subscribers',
|
||||
data: [
|
||||
200,
|
||||
55,
|
||||
400,
|
||||
250,
|
||||
],
|
||||
}]
|
||||
|
||||
const chartOptions = {
|
||||
chart: {
|
||||
type: 'area',
|
||||
parentHeightOffset: 0,
|
||||
toolbar: { show: false },
|
||||
sparkline: { enabled: true },
|
||||
},
|
||||
markers: {
|
||||
colors: 'transparent',
|
||||
strokeColors: 'transparent',
|
||||
},
|
||||
grid: { show: false },
|
||||
colors: [currentTheme.success],
|
||||
fill: {
|
||||
type: 'gradient',
|
||||
gradient: {
|
||||
shadeIntensity: 0.9,
|
||||
opacityFrom: 0.5,
|
||||
opacityTo: 0.07,
|
||||
stops: [
|
||||
0,
|
||||
80,
|
||||
100,
|
||||
],
|
||||
},
|
||||
},
|
||||
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,
|
||||
},
|
||||
tooltip: { enabled: false },
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VCard>
|
||||
<VCardItem class="pb-3">
|
||||
<VCardTitle>
|
||||
Sales
|
||||
</VCardTitle>
|
||||
<VCardSubtitle>
|
||||
Last Year
|
||||
</VCardSubtitle>
|
||||
</VCardItem>
|
||||
|
||||
<VueApexCharts
|
||||
:options="chartOptions"
|
||||
:series="series"
|
||||
:height="76"
|
||||
/>
|
||||
|
||||
<VCardText class="pt-1">
|
||||
<div class="d-flex align-center justify-space-between gap-x-2">
|
||||
<h4 class="text-h4 text-center">
|
||||
175k
|
||||
</h4>
|
||||
<span class="text-sm text-error">
|
||||
-16.2%
|
||||
</span>
|
||||
</div>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
</template>
|
||||
@@ -0,0 +1,108 @@
|
||||
<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="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>
|
||||
</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="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>
|
||||
</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>
|
||||
@@ -0,0 +1,238 @@
|
||||
<script setup>
|
||||
import { useTheme } from 'vuetify'
|
||||
|
||||
const vuetifyTheme = useTheme()
|
||||
|
||||
const series = [
|
||||
{
|
||||
name: 'PRODUCT A',
|
||||
data: [
|
||||
4,
|
||||
3,
|
||||
6,
|
||||
4,
|
||||
3,
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'PRODUCT B',
|
||||
data: [
|
||||
-3,
|
||||
-4,
|
||||
-3,
|
||||
-2,
|
||||
-3,
|
||||
],
|
||||
},
|
||||
]
|
||||
|
||||
const chartOptions = computed(() => {
|
||||
const currentTheme = vuetifyTheme.current.value.colors
|
||||
|
||||
return {
|
||||
chart: {
|
||||
type: 'bar',
|
||||
height: 90,
|
||||
parentHeightOffset: 0,
|
||||
stacked: true,
|
||||
toolbar: { show: false },
|
||||
},
|
||||
series: [
|
||||
{
|
||||
name: 'PRODUCT A',
|
||||
data: [
|
||||
4,
|
||||
3,
|
||||
6,
|
||||
4,
|
||||
3,
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'PRODUCT B',
|
||||
data: [
|
||||
-3,
|
||||
-4,
|
||||
-3,
|
||||
-2,
|
||||
-3,
|
||||
],
|
||||
},
|
||||
],
|
||||
plotOptions: {
|
||||
bar: {
|
||||
horizontal: false,
|
||||
columnWidth: '40%',
|
||||
borderRadius: 5,
|
||||
borderRadiusApplication: 'around',
|
||||
borderRadiusWhenStacked: 'all',
|
||||
},
|
||||
},
|
||||
dataLabels: { enabled: false },
|
||||
tooltip: { enabled: false },
|
||||
stroke: {
|
||||
curve: 'smooth',
|
||||
width: 4,
|
||||
lineCap: 'round',
|
||||
colors: [currentTheme.surface],
|
||||
},
|
||||
legend: { show: false },
|
||||
colors: [
|
||||
'rgba(var(--v-theme-primary),1)',
|
||||
'rgba(var(--v-theme-success),1)',
|
||||
],
|
||||
grid: {
|
||||
show: false,
|
||||
padding: {
|
||||
top: -50,
|
||||
right: -10,
|
||||
left: -8,
|
||||
bottom: -30,
|
||||
},
|
||||
},
|
||||
xaxis: {
|
||||
categories: [
|
||||
'Mon',
|
||||
'Tue',
|
||||
'Wed',
|
||||
'Thu',
|
||||
'Fri',
|
||||
],
|
||||
labels: { show: false },
|
||||
axisBorder: { show: false },
|
||||
axisTicks: { show: false },
|
||||
},
|
||||
yaxis: { show: false },
|
||||
responsive: [
|
||||
{
|
||||
breakpoint: 1441,
|
||||
options: {
|
||||
plotOptions: {
|
||||
bar: {
|
||||
columnWidth: '50%',
|
||||
borderRadius: 4,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
breakpoint: 1300,
|
||||
options: {
|
||||
plotOptions: {
|
||||
bar: {
|
||||
columnWidth: '60%',
|
||||
borderRadius: 4,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
breakpoint: 1280,
|
||||
options: {
|
||||
plotOptions: {
|
||||
bar: {
|
||||
borderRadius: 6,
|
||||
columnWidth: '30%',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
breakpoint: 1025,
|
||||
options: {
|
||||
plotOptions: {
|
||||
bar: {
|
||||
borderRadius: 6,
|
||||
columnWidth: '30%',
|
||||
},
|
||||
},
|
||||
chart: { height: 110 },
|
||||
},
|
||||
},
|
||||
{
|
||||
breakpoint: 960,
|
||||
options: {
|
||||
plotOptions: {
|
||||
bar: {
|
||||
borderRadius: 6,
|
||||
columnWidth: '25%',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
breakpoint: 782,
|
||||
options: {
|
||||
plotOptions: {
|
||||
bar: {
|
||||
columnWidth: '30%',
|
||||
borderRadius: 6,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
breakpoint: 600,
|
||||
options: {
|
||||
plotOptions: {
|
||||
bar: {
|
||||
borderRadius: 6,
|
||||
columnWidth: '20%',
|
||||
},
|
||||
},
|
||||
chart: { height: 160 },
|
||||
},
|
||||
},
|
||||
{
|
||||
breakpoint: 426,
|
||||
options: {
|
||||
plotOptions: {
|
||||
bar: {
|
||||
borderRadius: 6,
|
||||
columnWidth: '30%',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
breakpoint: 385,
|
||||
options: { plotOptions: { bar: { borderRadius: 6 } } },
|
||||
},
|
||||
],
|
||||
states: {
|
||||
hover: { filter: { type: 'none' } },
|
||||
active: { filter: { type: 'none' } },
|
||||
},
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VCard>
|
||||
<VCardItem class="pb-3">
|
||||
<VCardTitle>
|
||||
Sessions
|
||||
</VCardTitle>
|
||||
<VCardSubtitle>
|
||||
This Month
|
||||
</VCardSubtitle>
|
||||
</VCardItem>
|
||||
|
||||
<VCardText>
|
||||
<VueApexCharts
|
||||
:options="chartOptions"
|
||||
:series="series"
|
||||
:height="68"
|
||||
/>
|
||||
|
||||
<div class="d-flex align-center justify-space-between gap-x-2 mt-3">
|
||||
<h4 class="text-h4">
|
||||
45.1k
|
||||
</h4>
|
||||
<div class="text-sm text-success">
|
||||
+12.6%
|
||||
</div>
|
||||
</div>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
</template>
|
||||
@@ -0,0 +1,89 @@
|
||||
<script setup>
|
||||
import { useTheme } from 'vuetify'
|
||||
|
||||
const vuetifyTheme = useTheme()
|
||||
const currentTheme = vuetifyTheme.current.value.colors
|
||||
|
||||
const series = [{
|
||||
name: 'Subscribers',
|
||||
data: [
|
||||
200,
|
||||
55,
|
||||
400,
|
||||
250,
|
||||
],
|
||||
}]
|
||||
|
||||
const chartOptions = {
|
||||
chart: {
|
||||
type: 'area',
|
||||
parentHeightOffset: 0,
|
||||
toolbar: { show: false },
|
||||
sparkline: { enabled: true },
|
||||
},
|
||||
markers: {
|
||||
colors: 'transparent',
|
||||
strokeColors: 'transparent',
|
||||
},
|
||||
grid: { show: false },
|
||||
colors: [currentTheme.success],
|
||||
fill: {
|
||||
type: 'gradient',
|
||||
gradient: {
|
||||
shadeIntensity: 0.9,
|
||||
opacityFrom: 0.5,
|
||||
opacityTo: 0.07,
|
||||
stops: [
|
||||
0,
|
||||
80,
|
||||
100,
|
||||
],
|
||||
},
|
||||
},
|
||||
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,
|
||||
},
|
||||
tooltip: { enabled: false },
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VCard>
|
||||
<VCardText class="pb-2">
|
||||
<h6 class="text-h6">
|
||||
Sales
|
||||
</h6>
|
||||
<span class="text-body-2">Last Year</span>
|
||||
</VCardText>
|
||||
|
||||
<VueApexCharts
|
||||
:options="chartOptions"
|
||||
:series="series"
|
||||
:height="90"
|
||||
/>
|
||||
|
||||
<VCardText class="pt-0">
|
||||
<div class="d-flex align-center justify-space-between mt-3">
|
||||
<h6 class="text-h6 text-center font-weight-medium">
|
||||
175k
|
||||
</h6>
|
||||
<span class="text-sm text-error">
|
||||
-16.2%
|
||||
</span>
|
||||
</div>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
</template>
|
||||
@@ -0,0 +1,106 @@
|
||||
<script setup>
|
||||
import { useTheme } from 'vuetify'
|
||||
import { hexToRgb } from '@core/utils/colorConverter'
|
||||
|
||||
const vuetifyTheme = useTheme()
|
||||
|
||||
const series = [{
|
||||
data: [
|
||||
0,
|
||||
25,
|
||||
10,
|
||||
40,
|
||||
25,
|
||||
55,
|
||||
],
|
||||
}]
|
||||
|
||||
const chartOptions = computed(() => {
|
||||
const currentTheme = vuetifyTheme.current.value.colors
|
||||
const variableTheme = vuetifyTheme.current.value.variables
|
||||
|
||||
return {
|
||||
chart: {
|
||||
height: 90,
|
||||
type: 'line',
|
||||
parentHeightOffset: 0,
|
||||
toolbar: { show: false },
|
||||
},
|
||||
grid: {
|
||||
borderColor: `rgba(${ hexToRgb(String(variableTheme['border-color'])) },${ variableTheme['border-opacity'] })`,
|
||||
strokeDashArray: 6,
|
||||
xaxis: { lines: { show: true } },
|
||||
yaxis: { lines: { show: false } },
|
||||
padding: {
|
||||
top: -18,
|
||||
left: -4,
|
||||
right: 7,
|
||||
bottom: -10,
|
||||
},
|
||||
},
|
||||
colors: [currentTheme.info],
|
||||
stroke: { width: 2 },
|
||||
tooltip: {
|
||||
enabled: false,
|
||||
shared: false,
|
||||
intersect: true,
|
||||
x: { show: false },
|
||||
},
|
||||
xaxis: {
|
||||
labels: { show: false },
|
||||
axisTicks: { show: false },
|
||||
axisBorder: { show: false },
|
||||
},
|
||||
yaxis: { labels: { show: false } },
|
||||
markers: {
|
||||
size: 3.5,
|
||||
fillColor: currentTheme.info,
|
||||
strokeColors: 'transparent',
|
||||
strokeWidth: 3.2,
|
||||
discrete: [{
|
||||
seriesIndex: 0,
|
||||
dataPointIndex: 5,
|
||||
fillColor: currentTheme.surface,
|
||||
strokeColor: currentTheme.info,
|
||||
size: 5,
|
||||
shape: 'circle',
|
||||
}],
|
||||
hover: { size: 5.5 },
|
||||
},
|
||||
responsive: [{
|
||||
breakpoint: 960,
|
||||
options: { chart: { height: 110 } },
|
||||
}],
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VCard>
|
||||
<VCardItem class="pb-3">
|
||||
<VCardTitle>
|
||||
Profit
|
||||
</VCardTitle>
|
||||
<VCardSubtitle>
|
||||
Last Month
|
||||
</VCardSubtitle>
|
||||
</VCardItem>
|
||||
<VCardText>
|
||||
<VueApexCharts
|
||||
type="line"
|
||||
:options="chartOptions"
|
||||
:series="series"
|
||||
:height="68"
|
||||
/>
|
||||
|
||||
<div class="d-flex align-center justify-space-between gap-x-2 mt-3">
|
||||
<h4 class="text-h4 text-center font-weight-medium">
|
||||
624k
|
||||
</h4>
|
||||
<span class="text-sm text-success">
|
||||
+8.24%
|
||||
</span>
|
||||
</div>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
</template>
|
||||
@@ -0,0 +1,67 @@
|
||||
<script setup>
|
||||
const statistics = [
|
||||
{
|
||||
title: 'Sales',
|
||||
stats: '230k',
|
||||
icon: 'tabler-chart-pie-2',
|
||||
color: 'primary',
|
||||
},
|
||||
{
|
||||
title: 'Customers',
|
||||
stats: '8.549k',
|
||||
icon: 'tabler-users',
|
||||
color: 'info',
|
||||
},
|
||||
{
|
||||
title: 'Products',
|
||||
stats: '1.423k',
|
||||
icon: 'tabler-shopping-cart',
|
||||
color: 'error',
|
||||
},
|
||||
{
|
||||
title: 'Revenue',
|
||||
stats: '$9745',
|
||||
icon: 'tabler-currency-dollar',
|
||||
color: 'success',
|
||||
},
|
||||
]
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VCard title="Statistics">
|
||||
<template #append>
|
||||
<span class="text-disabled text-subtitle-2">Updated 1 month ago</span>
|
||||
</template>
|
||||
|
||||
<VCardText>
|
||||
<VRow>
|
||||
<VCol
|
||||
v-for="item in statistics"
|
||||
:key="item.title"
|
||||
cols="6"
|
||||
md="3"
|
||||
>
|
||||
<div class="d-flex gap-x-4 align-center">
|
||||
<VAvatar
|
||||
:color="item.color"
|
||||
variant="tonal"
|
||||
size="40"
|
||||
rounded
|
||||
>
|
||||
<VIcon :icon="item.icon" />
|
||||
</VAvatar>
|
||||
|
||||
<div class="d-flex flex-column">
|
||||
<h5 class="text-h5">
|
||||
{{ item.stats }}
|
||||
</h5>
|
||||
<div class="text-body-2">
|
||||
{{ item.title }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</VCol>
|
||||
</VRow>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
</template>
|
||||
@@ -0,0 +1,116 @@
|
||||
<script setup>
|
||||
const logisticData = ref([
|
||||
{
|
||||
icon: 'tabler-truck',
|
||||
color: 'primary',
|
||||
title: 'On route vehicles',
|
||||
value: 42,
|
||||
change: 18.2,
|
||||
isHover: false,
|
||||
},
|
||||
{
|
||||
icon: 'tabler-alert-triangle',
|
||||
color: 'warning',
|
||||
title: 'Vehicles with errors',
|
||||
value: 8,
|
||||
change: -8.7,
|
||||
isHover: false,
|
||||
},
|
||||
{
|
||||
icon: 'tabler-git-fork',
|
||||
color: 'error',
|
||||
title: 'Deviated from route',
|
||||
value: 27,
|
||||
change: 4.3,
|
||||
isHover: false,
|
||||
},
|
||||
{
|
||||
icon: 'tabler-clock',
|
||||
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.38)`"
|
||||
@mouseenter="data.isHover = true"
|
||||
@mouseleave="data.isHover = false"
|
||||
>
|
||||
<VCardText>
|
||||
<div class="d-flex align-center gap-x-4 mb-1">
|
||||
<VAvatar
|
||||
variant="tonal"
|
||||
:color="data.color"
|
||||
rounded
|
||||
>
|
||||
<VIcon
|
||||
:icon="data.icon"
|
||||
size="28"
|
||||
/>
|
||||
</VAvatar>
|
||||
<h4 class="text-h4">
|
||||
{{ data.value }}
|
||||
</h4>
|
||||
</div>
|
||||
<div class="text-body-1 mb-1">
|
||||
{{ data.title }}
|
||||
</div>
|
||||
<div class="d-flex gap-x-2 align-center">
|
||||
<h6 class="text-h6">
|
||||
{{ (data.change > 0) ? '+' : '' }} {{ data.change }}%
|
||||
</h6>
|
||||
<div class="text-disabled">
|
||||
than last week
|
||||
</div>
|
||||
</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(8);
|
||||
|
||||
transition: all 0.1s ease-out;
|
||||
}
|
||||
}
|
||||
|
||||
.skin--bordered {
|
||||
.logistics-card-statistics {
|
||||
border-block-end-width: 2px;
|
||||
|
||||
&:hover {
|
||||
border-block-end-width: 3px;
|
||||
margin-block-end: -2px;
|
||||
transition: all 0.1s ease-out;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,188 @@
|
||||
<script setup>
|
||||
const vehicleData = [
|
||||
{
|
||||
icon: 'tabler-car',
|
||||
title: 'On the way',
|
||||
time: '2hr 10min',
|
||||
percentage: 39.7,
|
||||
},
|
||||
{
|
||||
icon: 'tabler-circle-arrow-down',
|
||||
title: 'Unloading',
|
||||
time: '3hr 15min',
|
||||
percentage: 28.3,
|
||||
},
|
||||
{
|
||||
icon: 'tabler-circle-arrow-up',
|
||||
title: 'Loading',
|
||||
time: '1hr 24min',
|
||||
percentage: 17.4,
|
||||
},
|
||||
{
|
||||
icon: 'tabler-clock',
|
||||
title: 'Waiting',
|
||||
time: '5hr 19min',
|
||||
percentage: 14.6,
|
||||
},
|
||||
]
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VCard>
|
||||
<VCardItem title="Vehicles Overview">
|
||||
<template #append>
|
||||
<MoreBtn />
|
||||
</template>
|
||||
</VCardItem>
|
||||
<VCardText>
|
||||
<div class="d-flex mb-6">
|
||||
<div style="inline-size: 39.7%;">
|
||||
<div class="vehicle-progress-label position-relative mb-6 text-body-1 d-none d-sm-block">
|
||||
On the way
|
||||
</div>
|
||||
<VProgressLinear
|
||||
color="rgba(var(--v-theme-on-surface), var(--v-hover-opacity))"
|
||||
model-value="100"
|
||||
height="46"
|
||||
class="rounded-e-0 rounded-lg"
|
||||
>
|
||||
<div class="text-start text-sm font-weight-medium">
|
||||
39.7%
|
||||
</div>
|
||||
</VProgressLinear>
|
||||
</div>
|
||||
<div style="inline-size: 28.3%;">
|
||||
<div class="vehicle-progress-label position-relative mb-6 text-body-1 d-none d-sm-block">
|
||||
Unloading
|
||||
</div>
|
||||
<VProgressLinear
|
||||
color="rgb(var(--v-theme-primary))"
|
||||
model-value="100"
|
||||
class="rounded-0"
|
||||
height="46"
|
||||
>
|
||||
<div class="text-white text-sm font-weight-medium text-start">
|
||||
28.3%
|
||||
</div>
|
||||
</VProgressLinear>
|
||||
</div>
|
||||
<div style="inline-size: 17.4%;">
|
||||
<div class="vehicle-progress-label position-relative mb-6 text-body-1 d-none d-sm-block">
|
||||
Loading
|
||||
</div>
|
||||
<VProgressLinear
|
||||
color="rgb(var(--v-theme-info))"
|
||||
model-value="100"
|
||||
height="46"
|
||||
class="rounded-0"
|
||||
>
|
||||
<div class="text-white text-sm font-weight-medium text-start">
|
||||
17.4%
|
||||
</div>
|
||||
</VProgressLinear>
|
||||
</div>
|
||||
<div style="inline-size: 14.6%;">
|
||||
<div class="vehicle-progress-label position-relative mb-6 text-body-1 d-none d-sm-block">
|
||||
Waiting
|
||||
</div>
|
||||
<VProgressLinear
|
||||
color="rgb(var(--v-tooltip-background))"
|
||||
model-value="100"
|
||||
height="46"
|
||||
class="rounded-s-0 rounded-lg"
|
||||
>
|
||||
<div class="text-sm text-surface font-weight-medium text-start">
|
||||
14.6%
|
||||
</div>
|
||||
</VProgressLinear>
|
||||
</div>
|
||||
</div>
|
||||
<VTable class="text-no-wrap">
|
||||
<tbody>
|
||||
<tr
|
||||
v-for="(vehicle, index) in vehicleData"
|
||||
:key="index"
|
||||
>
|
||||
<td
|
||||
width="70%"
|
||||
style="padding-inline-start: 0 !important;"
|
||||
>
|
||||
<div class="d-flex align-center gap-x-2">
|
||||
<VIcon
|
||||
:icon="vehicle.icon"
|
||||
size="24"
|
||||
class="text-high-emphasis"
|
||||
/>
|
||||
<div class="text-body-1 text-high-emphasis">
|
||||
{{ vehicle.title }}
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<h6 class="text-h6">
|
||||
{{ vehicle.time }}
|
||||
</h6>
|
||||
</td>
|
||||
<td>
|
||||
<div class="text-body-1">
|
||||
{{ vehicle.percentage }}%
|
||||
</div>
|
||||
</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;
|
||||
}
|
||||
|
||||
#shipment-statistics .apexcharts-legend-series {
|
||||
padding-inline: 16px;
|
||||
}
|
||||
|
||||
@media (max-width: 1080px) {
|
||||
#shipment-statistics .apexcharts-legend-series {
|
||||
padding-inline: 12px;
|
||||
}
|
||||
|
||||
.v-progress-linear__content {
|
||||
padding-inline-start: 0.75rem !important;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 576px) {
|
||||
#shipment-statistics .apexcharts-legend-series {
|
||||
padding-inline: 8px;
|
||||
}
|
||||
|
||||
.v-progress-linear__content {
|
||||
padding-inline-start: 0.125rem !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,206 @@
|
||||
<script setup>
|
||||
const colors = {
|
||||
series1: '#7367F0',
|
||||
series2: '#8F85F3',
|
||||
series3: '#ABA4F6',
|
||||
}
|
||||
|
||||
const bodyColor = 'rgba(var(--v-theme-on-background), var(--v-medium-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: 'Delivery rate',
|
||||
type: 'column',
|
||||
data: [
|
||||
5,
|
||||
4.5,
|
||||
4,
|
||||
3,
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'Delivery time',
|
||||
type: 'column',
|
||||
data: [
|
||||
4,
|
||||
3.5,
|
||||
3,
|
||||
2.5,
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'Delivery exceptions',
|
||||
type: 'column',
|
||||
data: [
|
||||
3.5,
|
||||
3,
|
||||
2.5,
|
||||
2,
|
||||
],
|
||||
},
|
||||
]
|
||||
|
||||
const chartOptions = {
|
||||
chart: {
|
||||
type: 'bar',
|
||||
parentHeightOffset: 0,
|
||||
stacked: false,
|
||||
toolbar: { show: false },
|
||||
zoom: { enabled: false },
|
||||
},
|
||||
plotOptions: {
|
||||
bar: {
|
||||
horizontal: false,
|
||||
columnWidth: '50%',
|
||||
borderRadiusApplication: 'end',
|
||||
borderRadius: 4,
|
||||
},
|
||||
},
|
||||
dataLabels: { enabled: false },
|
||||
xaxis: {
|
||||
tickAmount: 10,
|
||||
categories: [
|
||||
'Carrier A',
|
||||
'Carrier B',
|
||||
'Carrier C',
|
||||
'Carrier D',
|
||||
],
|
||||
labels: {
|
||||
style: {
|
||||
colors: labelColor,
|
||||
fontSize: '13px',
|
||||
fontFamily: 'Public Sans',
|
||||
fontWeight: 400,
|
||||
},
|
||||
},
|
||||
axisBorder: { show: false },
|
||||
axisTicks: { show: false },
|
||||
},
|
||||
yaxis: {
|
||||
tickAmount: 4,
|
||||
max: 5,
|
||||
labels: {
|
||||
style: {
|
||||
colors: labelColor,
|
||||
fontSize: '13px',
|
||||
fontFamily: 'Public Sans',
|
||||
fontWeight: 400,
|
||||
},
|
||||
formatter(o) {
|
||||
return o
|
||||
},
|
||||
},
|
||||
},
|
||||
legend: {
|
||||
position: 'bottom',
|
||||
markers: {
|
||||
width: 8,
|
||||
height: 8,
|
||||
offsetX: -3,
|
||||
radius: 12,
|
||||
},
|
||||
height: 33,
|
||||
offsetY: 10,
|
||||
itemMargin: {
|
||||
horizontal: 10,
|
||||
vertical: 0,
|
||||
},
|
||||
fontSize: '13px',
|
||||
fontFamily: 'Public Sans',
|
||||
fontWeight: 400,
|
||||
labels: {
|
||||
colors: bodyColor,
|
||||
useSeriesColors: false,
|
||||
},
|
||||
},
|
||||
grid: {
|
||||
borderColor,
|
||||
strokeDashArray: 6,
|
||||
},
|
||||
colors: [
|
||||
colors.series1,
|
||||
colors.series2,
|
||||
colors.series3,
|
||||
],
|
||||
fill: { opacity: 1 },
|
||||
responsive: [
|
||||
{
|
||||
breakpoint: 1400,
|
||||
options: {
|
||||
chart: { height: 275 },
|
||||
legend: {
|
||||
fontSize: '13px',
|
||||
offsetY: 10,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
breakpoint: 576,
|
||||
options: {
|
||||
chart: { height: 300 },
|
||||
legend: {
|
||||
itemMargin: {
|
||||
vertical: 5,
|
||||
horizontal: 10,
|
||||
},
|
||||
offsetY: 7,
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
const moreList = [
|
||||
{
|
||||
title: 'View More',
|
||||
value: 'View More',
|
||||
},
|
||||
{
|
||||
title: 'Delete',
|
||||
value: 'Delete',
|
||||
},
|
||||
]
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VCard>
|
||||
<VCardItem class="pb-0">
|
||||
<VCardTitle>Carrier Performance</VCardTitle>
|
||||
|
||||
<template #append>
|
||||
<MoreBtn :menu-list="moreList" />
|
||||
</template>
|
||||
</VCardItem>
|
||||
|
||||
<VCardText>
|
||||
<VueApexCharts
|
||||
:options="chartOptions"
|
||||
:series="series"
|
||||
height="300"
|
||||
class="carrier-chart my-2"
|
||||
/>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
@use "@core-scss/template/libs/apex-chart.scss";
|
||||
|
||||
.carrier-chart {
|
||||
.apexcharts-legend {
|
||||
.apexcharts-legend-series {
|
||||
border: 1px solid rgba(var(--v-border-color), var(--v-border-opacity));
|
||||
border-radius: 6px;
|
||||
margin-block-end: 0.3125rem !important;
|
||||
margin-inline: 0 1rem !important;
|
||||
padding-inline: 0.75rem;
|
||||
|
||||
&:last-child {
|
||||
margin-inline: 0 !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,146 @@
|
||||
<script setup>
|
||||
const chartColors = {
|
||||
donut: {
|
||||
series1: '#28C76F',
|
||||
series2: '#53D28C',
|
||||
series3: '#7EDDA9',
|
||||
series4: '#A9E9C5',
|
||||
},
|
||||
}
|
||||
|
||||
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: labelColor,
|
||||
useSeriesColors: false,
|
||||
},
|
||||
},
|
||||
tooltip: { theme: false },
|
||||
grid: { padding: { top: 15 } },
|
||||
plotOptions: {
|
||||
pie: {
|
||||
donut: {
|
||||
size: '75%',
|
||||
labels: {
|
||||
show: true,
|
||||
value: {
|
||||
fontSize: '38px',
|
||||
color: headingColor,
|
||||
fontWeight: 500,
|
||||
offsetY: -15,
|
||||
formatter(val) {
|
||||
return `${ Number.parseInt(val) }%`
|
||||
},
|
||||
},
|
||||
name: { offsetY: 30 },
|
||||
total: {
|
||||
show: true,
|
||||
fontSize: '0.9375rem',
|
||||
label: 'AVG. Exceptions',
|
||||
color: labelColor,
|
||||
formatter() {
|
||||
return '30%'
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
responsive: [{
|
||||
breakpoint: 420,
|
||||
options: {
|
||||
chart: { height: 400 },
|
||||
plotOptions: {
|
||||
pie: {
|
||||
donut: {
|
||||
size: '75%',
|
||||
labels: {
|
||||
show: true,
|
||||
value: {
|
||||
fontSize: '24px',
|
||||
color: headingColor,
|
||||
fontWeight: 500,
|
||||
offsetY: -15,
|
||||
formatter(val) {
|
||||
return `${ Number.parseInt(val) }%`
|
||||
},
|
||||
},
|
||||
name: { offsetY: 30 },
|
||||
total: {
|
||||
show: true,
|
||||
fontSize: '0.9375rem',
|
||||
label: 'AVG. Exceptions',
|
||||
color: labelColor,
|
||||
formatter() {
|
||||
return '30%'
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}],
|
||||
}
|
||||
</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,217 @@
|
||||
<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 :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">
|
||||
<h4 class="text-h2">
|
||||
$468
|
||||
</h4>
|
||||
<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>
|
||||
@@ -0,0 +1,627 @@
|
||||
<script setup>
|
||||
import { useTheme } from 'vuetify'
|
||||
import { hexToRgb } from '@layouts/utils'
|
||||
|
||||
const vuetifyTheme = useTheme()
|
||||
const currentTab = ref(0)
|
||||
const refVueApexChart = ref()
|
||||
|
||||
const chartConfigs = computed(() => {
|
||||
const currentTheme = vuetifyTheme.current.value.colors
|
||||
const variableTheme = vuetifyTheme.current.value.variables
|
||||
const labelPrimaryColor = `rgba(${ hexToRgb(currentTheme.primary) },${ variableTheme['dragged-opacity'] })`
|
||||
const legendColor = `rgba(${ hexToRgb(currentTheme['on-background']) },${ variableTheme['high-emphasis-opacity'] })`
|
||||
const borderColor = `rgba(${ hexToRgb(String(variableTheme['border-color'])) },${ variableTheme['border-opacity'] })`
|
||||
const labelColor = `rgba(${ hexToRgb(currentTheme['on-surface']) },${ variableTheme['disabled-opacity'] })`
|
||||
|
||||
return [
|
||||
{
|
||||
title: 'Orders',
|
||||
icon: 'tabler-shopping-cart',
|
||||
chartOptions: {
|
||||
chart: {
|
||||
parentHeightOffset: 0,
|
||||
type: 'bar',
|
||||
toolbar: { show: false },
|
||||
},
|
||||
plotOptions: {
|
||||
bar: {
|
||||
columnWidth: '32%',
|
||||
borderRadiusApplication: 'end',
|
||||
borderRadius: 4,
|
||||
distributed: true,
|
||||
dataLabels: { position: 'top' },
|
||||
},
|
||||
},
|
||||
grid: {
|
||||
show: false,
|
||||
padding: {
|
||||
top: 0,
|
||||
bottom: 0,
|
||||
left: -10,
|
||||
right: -10,
|
||||
},
|
||||
},
|
||||
colors: [
|
||||
labelPrimaryColor,
|
||||
labelPrimaryColor,
|
||||
`rgba(${ hexToRgb(currentTheme.primary) }, 1)`,
|
||||
labelPrimaryColor,
|
||||
labelPrimaryColor,
|
||||
labelPrimaryColor,
|
||||
labelPrimaryColor,
|
||||
labelPrimaryColor,
|
||||
labelPrimaryColor,
|
||||
],
|
||||
dataLabels: {
|
||||
enabled: true,
|
||||
formatter(val) {
|
||||
return `${ val }k`
|
||||
},
|
||||
offsetY: -25,
|
||||
style: {
|
||||
fontSize: '15px',
|
||||
colors: [legendColor],
|
||||
fontWeight: '600',
|
||||
fontFamily: 'Public Sans',
|
||||
},
|
||||
},
|
||||
legend: { show: false },
|
||||
tooltip: { enabled: false },
|
||||
xaxis: {
|
||||
categories: [
|
||||
'Jan',
|
||||
'Feb',
|
||||
'Mar',
|
||||
'Apr',
|
||||
'May',
|
||||
'Jun',
|
||||
'Jul',
|
||||
'Aug',
|
||||
'Sep',
|
||||
],
|
||||
axisBorder: {
|
||||
show: true,
|
||||
color: borderColor,
|
||||
},
|
||||
axisTicks: { show: false },
|
||||
labels: {
|
||||
style: {
|
||||
colors: labelColor,
|
||||
fontSize: '13px',
|
||||
fontFamily: 'Public Sans',
|
||||
},
|
||||
},
|
||||
},
|
||||
yaxis: {
|
||||
labels: {
|
||||
offsetX: -15,
|
||||
formatter(val) {
|
||||
return `${ val / 1 }k`
|
||||
},
|
||||
style: {
|
||||
fontSize: '13px',
|
||||
colors: labelColor,
|
||||
fontFamily: 'Public Sans',
|
||||
},
|
||||
min: 0,
|
||||
max: 60000,
|
||||
tickAmount: 6,
|
||||
},
|
||||
},
|
||||
responsive: [
|
||||
{
|
||||
breakpoint: 1441,
|
||||
options: { plotOptions: { bar: { columnWidth: '41%' } } },
|
||||
},
|
||||
{
|
||||
breakpoint: 590,
|
||||
options: {
|
||||
plotOptions: { bar: { columnWidth: '40%' } },
|
||||
yaxis: { labels: { show: false } },
|
||||
dataLabels: {
|
||||
style: {
|
||||
fontSize: '12px',
|
||||
fontWeight: '400',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
series: [{
|
||||
data: [
|
||||
28,
|
||||
10,
|
||||
45,
|
||||
38,
|
||||
15,
|
||||
30,
|
||||
35,
|
||||
30,
|
||||
8,
|
||||
],
|
||||
}],
|
||||
},
|
||||
{
|
||||
title: 'Sales',
|
||||
icon: 'tabler-chart-bar',
|
||||
chartOptions: {
|
||||
chart: {
|
||||
parentHeightOffset: 0,
|
||||
type: 'bar',
|
||||
toolbar: { show: false },
|
||||
},
|
||||
plotOptions: {
|
||||
bar: {
|
||||
columnWidth: '32%',
|
||||
borderRadiusApplication: 'end',
|
||||
borderRadius: 4,
|
||||
distributed: true,
|
||||
dataLabels: { position: 'top' },
|
||||
},
|
||||
},
|
||||
grid: {
|
||||
show: false,
|
||||
padding: {
|
||||
top: 0,
|
||||
bottom: 0,
|
||||
left: -10,
|
||||
right: -10,
|
||||
},
|
||||
},
|
||||
colors: [
|
||||
labelPrimaryColor,
|
||||
labelPrimaryColor,
|
||||
labelPrimaryColor,
|
||||
labelPrimaryColor,
|
||||
labelPrimaryColor,
|
||||
labelPrimaryColor,
|
||||
`rgba(${ hexToRgb(currentTheme.primary) }, 1)`,
|
||||
labelPrimaryColor,
|
||||
labelPrimaryColor,
|
||||
],
|
||||
dataLabels: {
|
||||
enabled: true,
|
||||
formatter(val) {
|
||||
return `${ val }k`
|
||||
},
|
||||
offsetY: -25,
|
||||
style: {
|
||||
fontSize: '15px',
|
||||
colors: [legendColor],
|
||||
fontWeight: '600',
|
||||
fontFamily: 'Public Sans',
|
||||
},
|
||||
},
|
||||
legend: { show: false },
|
||||
tooltip: { enabled: false },
|
||||
xaxis: {
|
||||
categories: [
|
||||
'Jan',
|
||||
'Feb',
|
||||
'Mar',
|
||||
'Apr',
|
||||
'May',
|
||||
'Jun',
|
||||
'Jul',
|
||||
'Aug',
|
||||
'Sep',
|
||||
],
|
||||
axisBorder: {
|
||||
show: true,
|
||||
color: borderColor,
|
||||
},
|
||||
axisTicks: { show: false },
|
||||
labels: {
|
||||
style: {
|
||||
colors: labelColor,
|
||||
fontSize: '13px',
|
||||
fontFamily: 'Public Sans',
|
||||
},
|
||||
},
|
||||
},
|
||||
yaxis: {
|
||||
labels: {
|
||||
offsetX: -15,
|
||||
formatter(val) {
|
||||
return `${ val / 1 }k`
|
||||
},
|
||||
style: {
|
||||
fontSize: '13px',
|
||||
colors: labelColor,
|
||||
fontFamily: 'Public Sans',
|
||||
},
|
||||
min: 0,
|
||||
max: 60000,
|
||||
tickAmount: 6,
|
||||
},
|
||||
},
|
||||
responsive: [
|
||||
{
|
||||
breakpoint: 1441,
|
||||
options: { plotOptions: { bar: { columnWidth: '41%' } } },
|
||||
},
|
||||
{
|
||||
breakpoint: 590,
|
||||
options: {
|
||||
plotOptions: { bar: { columnWidth: '61%' } },
|
||||
grid: { padding: { right: 0 } },
|
||||
dataLabels: {
|
||||
style: {
|
||||
fontSize: '12px',
|
||||
fontWeight: '400',
|
||||
},
|
||||
},
|
||||
yaxis: { labels: { show: false } },
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
series: [{
|
||||
data: [
|
||||
35,
|
||||
25,
|
||||
15,
|
||||
40,
|
||||
42,
|
||||
25,
|
||||
48,
|
||||
8,
|
||||
30,
|
||||
],
|
||||
}],
|
||||
},
|
||||
{
|
||||
title: 'Profit',
|
||||
icon: 'tabler-currency-dollar',
|
||||
chartOptions: {
|
||||
chart: {
|
||||
parentHeightOffset: 0,
|
||||
type: 'bar',
|
||||
toolbar: { show: false },
|
||||
},
|
||||
plotOptions: {
|
||||
bar: {
|
||||
columnWidth: '32%',
|
||||
borderRadiusApplication: 'end',
|
||||
borderRadius: 4,
|
||||
distributed: true,
|
||||
dataLabels: { position: 'top' },
|
||||
},
|
||||
},
|
||||
grid: {
|
||||
show: false,
|
||||
padding: {
|
||||
top: 0,
|
||||
bottom: 0,
|
||||
left: -10,
|
||||
right: -10,
|
||||
},
|
||||
},
|
||||
colors: [
|
||||
labelPrimaryColor,
|
||||
labelPrimaryColor,
|
||||
labelPrimaryColor,
|
||||
labelPrimaryColor,
|
||||
`rgba(${ hexToRgb(currentTheme.primary) }, 1)`,
|
||||
labelPrimaryColor,
|
||||
labelPrimaryColor,
|
||||
labelPrimaryColor,
|
||||
labelPrimaryColor,
|
||||
],
|
||||
dataLabels: {
|
||||
enabled: true,
|
||||
formatter(val) {
|
||||
return `${ val }k`
|
||||
},
|
||||
offsetY: -25,
|
||||
style: {
|
||||
fontSize: '15px',
|
||||
colors: [legendColor],
|
||||
fontWeight: '600',
|
||||
fontFamily: 'Public Sans',
|
||||
},
|
||||
},
|
||||
legend: { show: false },
|
||||
tooltip: { enabled: false },
|
||||
xaxis: {
|
||||
categories: [
|
||||
'Jan',
|
||||
'Feb',
|
||||
'Mar',
|
||||
'Apr',
|
||||
'May',
|
||||
'Jun',
|
||||
'Jul',
|
||||
'Aug',
|
||||
'Sep',
|
||||
],
|
||||
axisBorder: {
|
||||
show: true,
|
||||
color: borderColor,
|
||||
},
|
||||
axisTicks: { show: false },
|
||||
labels: {
|
||||
style: {
|
||||
colors: labelColor,
|
||||
fontSize: '13px',
|
||||
fontFamily: 'Public Sans',
|
||||
},
|
||||
},
|
||||
},
|
||||
yaxis: {
|
||||
labels: {
|
||||
offsetX: -15,
|
||||
formatter(val) {
|
||||
return `${ val / 1 }k`
|
||||
},
|
||||
style: {
|
||||
fontSize: '13px',
|
||||
colors: labelColor,
|
||||
fontFamily: 'Public Sans',
|
||||
},
|
||||
min: 0,
|
||||
max: 60000,
|
||||
tickAmount: 6,
|
||||
},
|
||||
},
|
||||
responsive: [
|
||||
{
|
||||
breakpoint: 1441,
|
||||
options: { plotOptions: { bar: { columnWidth: '41%' } } },
|
||||
},
|
||||
{
|
||||
breakpoint: 590,
|
||||
options: {
|
||||
plotOptions: { bar: { columnWidth: '61%' } },
|
||||
grid: { padding: { right: 0 } },
|
||||
dataLabels: {
|
||||
style: {
|
||||
fontSize: '12px',
|
||||
fontWeight: '400',
|
||||
},
|
||||
},
|
||||
yaxis: { labels: { show: false } },
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
series: [{
|
||||
data: [
|
||||
10,
|
||||
22,
|
||||
27,
|
||||
33,
|
||||
42,
|
||||
32,
|
||||
27,
|
||||
22,
|
||||
8,
|
||||
],
|
||||
}],
|
||||
},
|
||||
{
|
||||
title: 'Income',
|
||||
icon: 'tabler-chart-pie-2',
|
||||
chartOptions: {
|
||||
chart: {
|
||||
parentHeightOffset: 0,
|
||||
type: 'bar',
|
||||
toolbar: { show: false },
|
||||
},
|
||||
plotOptions: {
|
||||
bar: {
|
||||
columnWidth: '32%',
|
||||
borderRadius: 6,
|
||||
distributed: true,
|
||||
borderRadiusApplication: 'end',
|
||||
dataLabels: { position: 'top' },
|
||||
},
|
||||
},
|
||||
grid: {
|
||||
show: false,
|
||||
padding: {
|
||||
top: 0,
|
||||
bottom: 0,
|
||||
left: -10,
|
||||
right: -10,
|
||||
},
|
||||
},
|
||||
colors: [
|
||||
labelPrimaryColor,
|
||||
labelPrimaryColor,
|
||||
labelPrimaryColor,
|
||||
labelPrimaryColor,
|
||||
labelPrimaryColor,
|
||||
labelPrimaryColor,
|
||||
labelPrimaryColor,
|
||||
labelPrimaryColor,
|
||||
`rgba(${ hexToRgb(currentTheme.primary) }, 1)`,
|
||||
],
|
||||
dataLabels: {
|
||||
enabled: true,
|
||||
formatter(val) {
|
||||
return `${ val }k`
|
||||
},
|
||||
offsetY: -25,
|
||||
style: {
|
||||
fontSize: '15px',
|
||||
colors: [legendColor],
|
||||
fontWeight: '600',
|
||||
fontFamily: 'Public Sans',
|
||||
},
|
||||
},
|
||||
legend: { show: false },
|
||||
tooltip: { enabled: false },
|
||||
xaxis: {
|
||||
categories: [
|
||||
'Jan',
|
||||
'Feb',
|
||||
'Mar',
|
||||
'Apr',
|
||||
'May',
|
||||
'Jun',
|
||||
'Jul',
|
||||
'Aug',
|
||||
'Sep',
|
||||
],
|
||||
axisBorder: {
|
||||
show: true,
|
||||
color: borderColor,
|
||||
},
|
||||
axisTicks: { show: false },
|
||||
labels: {
|
||||
style: {
|
||||
colors: labelColor,
|
||||
fontSize: '13px',
|
||||
fontFamily: 'Public Sans',
|
||||
},
|
||||
},
|
||||
},
|
||||
yaxis: {
|
||||
labels: {
|
||||
offsetX: -15,
|
||||
formatter(val) {
|
||||
return `${ val / 1 }k`
|
||||
},
|
||||
style: {
|
||||
fontSize: '13px',
|
||||
colors: labelColor,
|
||||
fontFamily: 'Public Sans',
|
||||
},
|
||||
min: 0,
|
||||
max: 60000,
|
||||
tickAmount: 6,
|
||||
},
|
||||
},
|
||||
responsive: [
|
||||
{
|
||||
breakpoint: 1441,
|
||||
options: { plotOptions: { bar: { columnWidth: '41%' } } },
|
||||
},
|
||||
{
|
||||
breakpoint: 590,
|
||||
options: {
|
||||
plotOptions: { bar: { columnWidth: '50%' } },
|
||||
dataLabels: {
|
||||
style: {
|
||||
fontSize: '12px',
|
||||
fontWeight: '400',
|
||||
},
|
||||
},
|
||||
grid: { padding: { right: 0 } },
|
||||
yaxis: { labels: { show: false } },
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
series: [{
|
||||
data: [
|
||||
5,
|
||||
9,
|
||||
12,
|
||||
18,
|
||||
20,
|
||||
25,
|
||||
30,
|
||||
36,
|
||||
48,
|
||||
],
|
||||
}],
|
||||
},
|
||||
]
|
||||
})
|
||||
|
||||
const moreList = [
|
||||
{
|
||||
title: 'View More',
|
||||
value: 'View More',
|
||||
},
|
||||
{
|
||||
title: 'Delete',
|
||||
value: 'Delete',
|
||||
},
|
||||
]
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VCard
|
||||
title="Earning Reports"
|
||||
subtitle="Yearly Earnings Overview"
|
||||
>
|
||||
<template #append>
|
||||
<div class="mt-n4 me-n2">
|
||||
<MoreBtn :menu-list="moreList" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<VCardText>
|
||||
<VSlideGroup
|
||||
v-model="currentTab"
|
||||
show-arrows
|
||||
mandatory
|
||||
class="mb-10"
|
||||
>
|
||||
<VSlideGroupItem
|
||||
v-for="(report, index) in chartConfigs"
|
||||
:key="report.title"
|
||||
v-slot="{ isSelected, toggle }"
|
||||
:value="index"
|
||||
>
|
||||
<div
|
||||
style="block-size: 100px; inline-size: 110px;"
|
||||
:style="isSelected ? 'border-color:rgb(var(--v-theme-primary)) !important' : ''"
|
||||
:class="isSelected ? 'border' : 'border border-dashed'"
|
||||
class="d-flex flex-column justify-center align-center cursor-pointer rounded py-4 px-5 me-4"
|
||||
@click="toggle"
|
||||
>
|
||||
<VAvatar
|
||||
rounded
|
||||
size="38"
|
||||
:color="isSelected ? 'primary' : ''"
|
||||
variant="tonal"
|
||||
class="mb-2"
|
||||
>
|
||||
<VIcon
|
||||
size="22"
|
||||
:icon="report.icon"
|
||||
/>
|
||||
</VAvatar>
|
||||
<h6 class="text-base font-weight-medium mb-0">
|
||||
{{ report.title }}
|
||||
</h6>
|
||||
</div>
|
||||
</VSlideGroupItem>
|
||||
|
||||
<!-- 👉 slider more -->
|
||||
<VSlideGroupItem>
|
||||
<div
|
||||
style="block-size: 100px; inline-size: 110px;"
|
||||
class="d-flex flex-column justify-center align-center rounded border border-dashed py-4 px-5"
|
||||
>
|
||||
<VAvatar
|
||||
rounded
|
||||
size="38"
|
||||
variant="tonal"
|
||||
>
|
||||
<VIcon
|
||||
size="22"
|
||||
icon="tabler-plus"
|
||||
/>
|
||||
</VAvatar>
|
||||
</div>
|
||||
</VSlideGroupItem>
|
||||
</VSlideGroup>
|
||||
|
||||
<VueApexCharts
|
||||
ref="refVueApexChart"
|
||||
:key="currentTab"
|
||||
:options="chartConfigs[Number(currentTab)].chartOptions"
|
||||
:series="chartConfigs[Number(currentTab)].series"
|
||||
height="230"
|
||||
class="mt-3"
|
||||
/>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
</template>
|
||||
@@ -0,0 +1,164 @@
|
||||
<script setup>
|
||||
import { useTheme } from 'vuetify'
|
||||
import { prefixWithPlus } from '@core/utils/formatters'
|
||||
|
||||
const vuetifyTheme = useTheme()
|
||||
|
||||
const series = [{
|
||||
data: [
|
||||
2000,
|
||||
2000,
|
||||
4000,
|
||||
4000,
|
||||
3050,
|
||||
3050,
|
||||
2000,
|
||||
2000,
|
||||
3050,
|
||||
3050,
|
||||
4700,
|
||||
4700,
|
||||
2750,
|
||||
2750,
|
||||
5700,
|
||||
5700,
|
||||
],
|
||||
}]
|
||||
|
||||
const chartOptions = computed(() => {
|
||||
const currentTheme = vuetifyTheme.current.value.colors
|
||||
|
||||
return {
|
||||
chart: {
|
||||
type: 'area',
|
||||
toolbar: false,
|
||||
},
|
||||
markers: { strokeColor: 'transparent' },
|
||||
dataLabels: { enabled: false },
|
||||
grid: {
|
||||
show: false,
|
||||
padding: {
|
||||
left: -10,
|
||||
right: -5,
|
||||
top: -40,
|
||||
},
|
||||
},
|
||||
stroke: {
|
||||
width: 3,
|
||||
curve: 'straight',
|
||||
},
|
||||
colors: [currentTheme.primary],
|
||||
fill: {
|
||||
type: 'gradient',
|
||||
gradient: {
|
||||
opacityFrom: 0.6,
|
||||
opacityTo: 0.15,
|
||||
stops: [
|
||||
0,
|
||||
95,
|
||||
100,
|
||||
],
|
||||
},
|
||||
},
|
||||
xaxis: {
|
||||
labels: { show: false },
|
||||
axisBorder: { show: false },
|
||||
axisTicks: { show: false },
|
||||
lines: { show: false },
|
||||
},
|
||||
yaxis: {
|
||||
labels: { show: false },
|
||||
min: 1000,
|
||||
max: 6000,
|
||||
tickAmount: 5,
|
||||
},
|
||||
tooltip: { enabled: false },
|
||||
}
|
||||
})
|
||||
|
||||
const projectStatus = [
|
||||
{
|
||||
title: 'Donates',
|
||||
amount: '$756.26',
|
||||
lossProfit: -139.34,
|
||||
},
|
||||
{
|
||||
title: 'Podcasts',
|
||||
amount: '$2,207.03',
|
||||
lossProfit: +576.24,
|
||||
},
|
||||
]
|
||||
|
||||
const moreList = [
|
||||
{
|
||||
title: 'View More',
|
||||
value: 'View More',
|
||||
},
|
||||
{
|
||||
title: 'Delete',
|
||||
value: 'Delete',
|
||||
},
|
||||
]
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VCard title="Project Status">
|
||||
<template #append>
|
||||
<div class="mt-n4 me-n2">
|
||||
<MoreBtn :menu-list="moreList" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<VCardText>
|
||||
<VList class="card-list mb-6">
|
||||
<VListItem>
|
||||
<VListItemTitle class="font-weight-medium">
|
||||
$4,3742
|
||||
</VListItemTitle>
|
||||
<template #prepend>
|
||||
<VAvatar
|
||||
color="primary"
|
||||
variant="tonal"
|
||||
rounded
|
||||
icon="tabler-currency-dollar"
|
||||
/>
|
||||
</template>
|
||||
<VListItemSubtitle>
|
||||
Your Earnings
|
||||
</VListItemSubtitle>
|
||||
|
||||
<template #append>
|
||||
<span class="text-success font-weight-medium">+10.2%</span>
|
||||
</template>
|
||||
</VListItem>
|
||||
</VList>
|
||||
|
||||
<VueApexCharts
|
||||
:options="chartOptions"
|
||||
:series="series"
|
||||
height="208"
|
||||
/>
|
||||
|
||||
<VList class="card-list">
|
||||
<VListItem
|
||||
v-for="status in projectStatus"
|
||||
:key="status.title"
|
||||
>
|
||||
<VListItemTitle class="font-weight-medium">
|
||||
{{ status.title }}
|
||||
</VListItemTitle>
|
||||
<template #append>
|
||||
<span class="me-3 text-medium-emphasis">{{ status.amount }}</span>
|
||||
<span :class="status.lossProfit > 0 ? 'text-success' : 'text-error'">{{ prefixWithPlus(status.lossProfit) }}</span>
|
||||
</template>
|
||||
</VListItem>
|
||||
</VList>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.card-list {
|
||||
--v-card-list-gap: 16px;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,385 @@
|
||||
<script setup>
|
||||
import { useTheme } from 'vuetify'
|
||||
import { hexToRgb } from '@layouts/utils'
|
||||
|
||||
const vuetifyTheme = useTheme()
|
||||
|
||||
const series = {
|
||||
bar: [
|
||||
{
|
||||
name: 'Earning',
|
||||
data: [
|
||||
270,
|
||||
210,
|
||||
180,
|
||||
200,
|
||||
250,
|
||||
280,
|
||||
250,
|
||||
270,
|
||||
150,
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'Expense',
|
||||
data: [
|
||||
-140,
|
||||
-160,
|
||||
-180,
|
||||
-150,
|
||||
-100,
|
||||
-60,
|
||||
-80,
|
||||
-100,
|
||||
-180,
|
||||
],
|
||||
},
|
||||
],
|
||||
line: [
|
||||
{
|
||||
name: 'Last Month',
|
||||
data: [
|
||||
20,
|
||||
10,
|
||||
30,
|
||||
16,
|
||||
24,
|
||||
5,
|
||||
40,
|
||||
23,
|
||||
28,
|
||||
5,
|
||||
30,
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'This Month',
|
||||
data: [
|
||||
50,
|
||||
40,
|
||||
60,
|
||||
46,
|
||||
54,
|
||||
35,
|
||||
70,
|
||||
53,
|
||||
58,
|
||||
35,
|
||||
60,
|
||||
],
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
const chartOptions = computed(() => {
|
||||
const currentTheme = vuetifyTheme.current.value.colors
|
||||
const variableTheme = vuetifyTheme.current.value.variables
|
||||
const labelColor = `rgba(${ hexToRgb(currentTheme['on-surface']) },${ variableTheme['disabled-opacity'] })`
|
||||
const legendColor = `rgba(${ hexToRgb(currentTheme['on-background']) },${ variableTheme['high-emphasis-opacity'] })`
|
||||
const borderColor = `rgba(${ hexToRgb(String(variableTheme['border-color'])) },${ variableTheme['border-opacity'] })`
|
||||
|
||||
return {
|
||||
bar: {
|
||||
chart: {
|
||||
parentHeightOffset: 0,
|
||||
stacked: true,
|
||||
type: 'bar',
|
||||
toolbar: { show: false },
|
||||
},
|
||||
tooltip: { enabled: false },
|
||||
plotOptions: {
|
||||
bar: {
|
||||
horizontal: false,
|
||||
columnWidth: '40%',
|
||||
borderRadius: 8,
|
||||
borderRadiusApplication: 'around',
|
||||
borderRadiusWhenStacked: 'all',
|
||||
},
|
||||
},
|
||||
colors: [
|
||||
'rgba(var(--v-theme-primary),1)',
|
||||
'rgba(var(--v-theme-warning),1)',
|
||||
],
|
||||
dataLabels: { enabled: false },
|
||||
stroke: {
|
||||
curve: 'smooth',
|
||||
width: 6,
|
||||
lineCap: 'round',
|
||||
colors: [currentTheme.surface],
|
||||
},
|
||||
legend: {
|
||||
show: true,
|
||||
horizontalAlign: 'right',
|
||||
position: 'top',
|
||||
fontFamily: 'Public Sans',
|
||||
fontSize: '13px',
|
||||
markers: {
|
||||
height: 12,
|
||||
width: 12,
|
||||
radius: 12,
|
||||
offsetX: -3,
|
||||
offsetY: 2,
|
||||
},
|
||||
labels: { colors: legendColor },
|
||||
itemMargin: { horizontal: 5 },
|
||||
},
|
||||
grid: {
|
||||
show: false,
|
||||
padding: {
|
||||
bottom: -8,
|
||||
top: 20,
|
||||
},
|
||||
},
|
||||
xaxis: {
|
||||
categories: [
|
||||
'Jan',
|
||||
'Feb',
|
||||
'Mar',
|
||||
'Apr',
|
||||
'May',
|
||||
'Jun',
|
||||
'Jul',
|
||||
'Aug',
|
||||
'Sep',
|
||||
],
|
||||
labels: {
|
||||
style: {
|
||||
fontSize: '13px',
|
||||
colors: labelColor,
|
||||
fontFamily: 'Public Sans',
|
||||
},
|
||||
},
|
||||
axisTicks: { show: false },
|
||||
axisBorder: { show: false },
|
||||
},
|
||||
yaxis: {
|
||||
labels: {
|
||||
offsetX: -16,
|
||||
style: {
|
||||
fontSize: '13px',
|
||||
colors: labelColor,
|
||||
fontFamily: 'Public Sans',
|
||||
},
|
||||
},
|
||||
min: -200,
|
||||
max: 300,
|
||||
tickAmount: 5,
|
||||
},
|
||||
responsive: [
|
||||
{
|
||||
breakpoint: 1700,
|
||||
options: { plotOptions: { bar: { columnWidth: '43%' } } },
|
||||
},
|
||||
{
|
||||
breakpoint: 1526,
|
||||
options: { plotOptions: { bar: { columnWidth: '52%' } } },
|
||||
},
|
||||
{
|
||||
breakpoint: 1359,
|
||||
options: { plotOptions: { bar: { columnWidth: '60%' } } },
|
||||
},
|
||||
{
|
||||
breakpoint: 1025,
|
||||
options: {
|
||||
plotOptions: { bar: { columnWidth: '70%' } },
|
||||
chart: { height: 390 },
|
||||
},
|
||||
},
|
||||
{
|
||||
breakpoint: 991,
|
||||
options: {
|
||||
plotOptions: {
|
||||
bar: {
|
||||
columnWidth: '60%',
|
||||
borderRadius: 6,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
breakpoint: 850,
|
||||
options: {
|
||||
plotOptions: {
|
||||
bar: {
|
||||
columnWidth: '48%',
|
||||
borderRadius: 6,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
breakpoint: 776,
|
||||
options: {
|
||||
plotOptions: {
|
||||
bar: {
|
||||
columnWidth: '68%',
|
||||
borderRadius: 6,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
breakpoint: 449,
|
||||
options: {
|
||||
plotOptions: {
|
||||
bar: {
|
||||
columnWidth: '70%',
|
||||
borderRadius: 6,
|
||||
},
|
||||
},
|
||||
chart: { height: 360 },
|
||||
xaxis: { labels: { offsetY: -5 } },
|
||||
},
|
||||
},
|
||||
{
|
||||
breakpoint: 394,
|
||||
options: {
|
||||
plotOptions: {
|
||||
bar: {
|
||||
columnWidth: '88%',
|
||||
borderRadius: 6,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
states: {
|
||||
hover: { filter: { type: 'none' } },
|
||||
active: { filter: { type: 'none' } },
|
||||
},
|
||||
},
|
||||
line: {
|
||||
chart: {
|
||||
toolbar: { show: false },
|
||||
zoom: { enabled: false },
|
||||
type: 'line',
|
||||
},
|
||||
stroke: {
|
||||
curve: 'smooth',
|
||||
dashArray: [
|
||||
5,
|
||||
0,
|
||||
],
|
||||
width: [
|
||||
1,
|
||||
2,
|
||||
],
|
||||
},
|
||||
legend: { show: false },
|
||||
colors: [
|
||||
borderColor,
|
||||
currentTheme.primary,
|
||||
],
|
||||
grid: {
|
||||
show: false,
|
||||
borderColor,
|
||||
padding: {
|
||||
top: -30,
|
||||
bottom: -15,
|
||||
left: 25,
|
||||
},
|
||||
},
|
||||
markers: { size: 0 },
|
||||
xaxis: {
|
||||
labels: { show: false },
|
||||
axisTicks: { show: false },
|
||||
axisBorder: { show: false },
|
||||
},
|
||||
yaxis: { show: false },
|
||||
tooltip: { enabled: false },
|
||||
},
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VCard class="revenue-report">
|
||||
<VRow no-gutters>
|
||||
<VCol
|
||||
cols="12"
|
||||
sm="8"
|
||||
lg="8"
|
||||
:class="$vuetify.display.smAndUp ? 'border-e' : 'border-b'"
|
||||
>
|
||||
<VCardText>
|
||||
<h6 class="text-h5 mb-sm-n8">
|
||||
Revenue Report
|
||||
</h6>
|
||||
|
||||
<VueApexCharts
|
||||
:options="chartOptions.bar"
|
||||
:series="series.bar"
|
||||
height="365"
|
||||
/>
|
||||
</VCardText>
|
||||
</VCol>
|
||||
|
||||
<VCol
|
||||
cols="12"
|
||||
sm="4"
|
||||
>
|
||||
<VCardText class="d-flex flex-column justify-center align-center text-center h-100">
|
||||
<VBtn
|
||||
variant="tonal"
|
||||
size="small"
|
||||
class="d-flex mx-auto"
|
||||
>
|
||||
<span>2022</span>
|
||||
<template #append>
|
||||
<VIcon
|
||||
size="16"
|
||||
icon="tabler-chevron-down"
|
||||
/>
|
||||
</template>
|
||||
<VMenu activator="parent">
|
||||
<VList>
|
||||
<VListItem
|
||||
v-for="(item, index) in ['2021', '2020', '2019']"
|
||||
:key="index"
|
||||
:value="index"
|
||||
>
|
||||
<VListItemTitle>{{ item }}</VListItemTitle>
|
||||
</VListItem>
|
||||
</VList>
|
||||
</VMenu>
|
||||
</VBtn>
|
||||
|
||||
<div class="d-flex flex-column my-8">
|
||||
<h5 class="font-weight-medium text-h3">
|
||||
$25,825
|
||||
</h5>
|
||||
<p class="mb-0">
|
||||
<span class="text-high-emphasis font-weight-medium me-1">Budget:</span>
|
||||
<span>56,800</span>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<VueApexCharts
|
||||
:options="chartOptions.line"
|
||||
:series="series.line"
|
||||
height="100"
|
||||
/>
|
||||
|
||||
<VBtn class="mt-8">
|
||||
Increase Budget
|
||||
</VBtn>
|
||||
</VCardText>
|
||||
</VCol>
|
||||
</VRow>
|
||||
</VCard>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
.revenue-report {
|
||||
.apexcharts-legend {
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
@media (max-width: 599px) {
|
||||
.apexcharts-legend.apx-legend-position-top.apexcharts-align-right {
|
||||
justify-content: flex-start;
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
161
resources/js/views/pages/cards/card-widgets/CardWidgetsSales.vue
Normal file
161
resources/js/views/pages/cards/card-widgets/CardWidgetsSales.vue
Normal file
@@ -0,0 +1,161 @@
|
||||
<script setup>
|
||||
import { useTheme } from 'vuetify'
|
||||
import { hexToRgb } from '@layouts/utils'
|
||||
|
||||
const vuetifyTheme = useTheme()
|
||||
|
||||
const series = [
|
||||
{
|
||||
name: 'Sales',
|
||||
data: [
|
||||
32,
|
||||
27,
|
||||
27,
|
||||
30,
|
||||
25,
|
||||
25,
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'Visits',
|
||||
data: [
|
||||
25,
|
||||
35,
|
||||
20,
|
||||
20,
|
||||
20,
|
||||
20,
|
||||
],
|
||||
},
|
||||
]
|
||||
|
||||
const chartOptions = computed(() => {
|
||||
const currentTheme = vuetifyTheme.current.value.colors
|
||||
const variableTheme = vuetifyTheme.current.value.variables
|
||||
const borderColor = `rgba(${ hexToRgb(String(variableTheme['border-color'])) },${ variableTheme['border-opacity'] })`
|
||||
const labelColor = `rgba(${ hexToRgb(currentTheme['on-surface']) },${ variableTheme['disabled-opacity'] })`
|
||||
const legendColor = `rgba(${ hexToRgb(currentTheme['on-background']) },${ variableTheme['medium-emphasis-opacity'] })`
|
||||
|
||||
return {
|
||||
chart: {
|
||||
type: 'radar',
|
||||
toolbar: { show: false },
|
||||
},
|
||||
plotOptions: {
|
||||
radar: {
|
||||
polygons: {
|
||||
strokeColors: borderColor,
|
||||
connectorColors: borderColor,
|
||||
},
|
||||
},
|
||||
},
|
||||
stroke: {
|
||||
show: false,
|
||||
width: 0,
|
||||
},
|
||||
legend: {
|
||||
show: true,
|
||||
fontSize: '13px',
|
||||
position: 'bottom',
|
||||
labels: {
|
||||
colors: legendColor,
|
||||
useSeriesColors: false,
|
||||
},
|
||||
markers: {
|
||||
height: 12,
|
||||
width: 12,
|
||||
offsetX: -8,
|
||||
},
|
||||
itemMargin: { horizontal: 10 },
|
||||
onItemHover: { highlightDataSeries: false },
|
||||
},
|
||||
colors: [
|
||||
currentTheme.primary,
|
||||
currentTheme.info,
|
||||
],
|
||||
fill: {
|
||||
opacity: [
|
||||
1,
|
||||
0.85,
|
||||
],
|
||||
},
|
||||
markers: { size: 0 },
|
||||
grid: {
|
||||
show: false,
|
||||
padding: {
|
||||
top: 0,
|
||||
bottom: -5,
|
||||
},
|
||||
},
|
||||
xaxis: {
|
||||
categories: [
|
||||
'Jan',
|
||||
'Feb',
|
||||
'Mar',
|
||||
'Apr',
|
||||
'May',
|
||||
'Jun',
|
||||
],
|
||||
labels: {
|
||||
show: true,
|
||||
style: {
|
||||
colors: [
|
||||
labelColor,
|
||||
labelColor,
|
||||
labelColor,
|
||||
labelColor,
|
||||
labelColor,
|
||||
labelColor,
|
||||
],
|
||||
fontSize: '13px',
|
||||
fontFamily: 'Public Sans',
|
||||
},
|
||||
},
|
||||
},
|
||||
yaxis: {
|
||||
show: false,
|
||||
min: 0,
|
||||
max: 40,
|
||||
tickAmount: 4,
|
||||
},
|
||||
responsive: [{
|
||||
breakpoint: 769,
|
||||
options: { chart: { height: 372 } },
|
||||
}],
|
||||
}
|
||||
})
|
||||
|
||||
const moreList = [
|
||||
{
|
||||
title: 'View More',
|
||||
value: 'View More',
|
||||
},
|
||||
{
|
||||
title: 'Delete',
|
||||
value: 'Delete',
|
||||
},
|
||||
]
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VCard>
|
||||
<VCardItem class="pb-4">
|
||||
<VCardTitle>Sales</VCardTitle>
|
||||
<VCardSubtitle>Last 6 Months</VCardSubtitle>
|
||||
|
||||
<template #append>
|
||||
<div class="mt-n4 me-n2">
|
||||
<MoreBtn :menu-list="moreList" />
|
||||
</div>
|
||||
</template>
|
||||
</VCardItem>
|
||||
|
||||
<VCardText>
|
||||
<VueApexCharts
|
||||
:options="chartOptions"
|
||||
:series="series"
|
||||
height="290"
|
||||
/>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
</template>
|
||||
@@ -0,0 +1,188 @@
|
||||
<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 :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>
|
||||
@@ -0,0 +1,213 @@
|
||||
<script setup>
|
||||
const borderColor = 'rgba(var(--v-border-color), var(--v-border-opacity))'
|
||||
|
||||
const topicsChartConfig = {
|
||||
chart: {
|
||||
height: 270,
|
||||
type: 'bar',
|
||||
toolbar: { show: false },
|
||||
},
|
||||
plotOptions: {
|
||||
bar: {
|
||||
horizontal: true,
|
||||
barHeight: '70%',
|
||||
distributed: true,
|
||||
borderRadius: 7,
|
||||
borderRadiusApplication: 'end',
|
||||
},
|
||||
},
|
||||
colors: [
|
||||
'rgba(var(--v-theme-primary),1)',
|
||||
'rgba(var(--v-theme-info),1)',
|
||||
'rgba(var(--v-theme-success),1)',
|
||||
'rgba(var(--v-theme-secondary),1)',
|
||||
'rgba(var(--v-theme-error),1)',
|
||||
'rgba(var(--v-theme-warning),1)',
|
||||
],
|
||||
grid: {
|
||||
borderColor,
|
||||
strokeDashArray: 10,
|
||||
xaxis: { lines: { show: true } },
|
||||
yaxis: { lines: { show: false } },
|
||||
padding: {
|
||||
top: -35,
|
||||
bottom: -12,
|
||||
},
|
||||
},
|
||||
dataLabels: {
|
||||
enabled: true,
|
||||
style: {
|
||||
colors: ['#fff'],
|
||||
fontWeight: 200,
|
||||
fontSize: '13px',
|
||||
},
|
||||
offsetX: 0,
|
||||
dropShadow: { enabled: false },
|
||||
formatter(val, opt) {
|
||||
return topicsChartConfig.labels[opt.dataPointIndex]
|
||||
},
|
||||
},
|
||||
labels: [
|
||||
'UI Design',
|
||||
'UX Design',
|
||||
'Music',
|
||||
'Animation',
|
||||
'Vue',
|
||||
'SEO',
|
||||
],
|
||||
xaxis: {
|
||||
categories: [
|
||||
'6',
|
||||
'5',
|
||||
'4',
|
||||
'3',
|
||||
'2',
|
||||
'1',
|
||||
],
|
||||
axisBorder: { show: false },
|
||||
axisTicks: { show: false },
|
||||
labels: {
|
||||
style: {
|
||||
colors: 'rgba(var(--v-theme-on-background), var(--v-disabled-opacity))',
|
||||
fontSize: '13px',
|
||||
},
|
||||
formatter(val) {
|
||||
return `${ val }%`
|
||||
},
|
||||
},
|
||||
},
|
||||
yaxis: {
|
||||
max: 35,
|
||||
labels: {
|
||||
style: {
|
||||
colors: 'rgba(var(--v-theme-on-background), var(--v-disabled-opacity))',
|
||||
fontSize: '13px',
|
||||
},
|
||||
},
|
||||
},
|
||||
tooltip: {
|
||||
enabled: true,
|
||||
style: { fontSize: '12px' },
|
||||
onDatasetHover: { highlightDataSeries: false },
|
||||
},
|
||||
legend: { show: false },
|
||||
}
|
||||
|
||||
const topicsChartSeries = [{
|
||||
data: [
|
||||
35,
|
||||
20,
|
||||
14,
|
||||
12,
|
||||
10,
|
||||
9,
|
||||
],
|
||||
}]
|
||||
|
||||
const topicsData = [
|
||||
{
|
||||
title: 'UI Design',
|
||||
value: 35,
|
||||
color: 'primary',
|
||||
},
|
||||
{
|
||||
title: 'UX Design',
|
||||
value: 20,
|
||||
color: 'info',
|
||||
},
|
||||
{
|
||||
title: 'Music',
|
||||
value: 14,
|
||||
color: 'success',
|
||||
},
|
||||
{
|
||||
title: 'Animation',
|
||||
value: 12,
|
||||
color: 'secondary',
|
||||
},
|
||||
{
|
||||
title: 'Vue',
|
||||
value: 10,
|
||||
color: 'error',
|
||||
},
|
||||
{
|
||||
title: 'SEO',
|
||||
value: 9,
|
||||
color: 'warning',
|
||||
},
|
||||
]
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<!-- 👉 Topic You are Interested in -->
|
||||
<VCard>
|
||||
<VCardItem title="Topic you are interested in">
|
||||
<template #append>
|
||||
<MoreBtn />
|
||||
</template>
|
||||
</VCardItem>
|
||||
|
||||
<VCardText>
|
||||
<VRow>
|
||||
<VCol
|
||||
cols="12"
|
||||
md="6"
|
||||
xl="8"
|
||||
lg="7"
|
||||
>
|
||||
<div>
|
||||
<VueApexCharts
|
||||
type="bar"
|
||||
height="260"
|
||||
:options="topicsChartConfig"
|
||||
:series="topicsChartSeries"
|
||||
/>
|
||||
</div>
|
||||
</VCol>
|
||||
|
||||
<VCol
|
||||
cols="12"
|
||||
md="6"
|
||||
lg="5"
|
||||
xl="4"
|
||||
>
|
||||
<div class="topic-progress d-flex flex-wrap gap-x-6 gap-y-10 ms-auto">
|
||||
<div
|
||||
v-for="topic in topicsData"
|
||||
:key="topic.title"
|
||||
class="d-flex gap-x-2"
|
||||
>
|
||||
<VBadge
|
||||
dot
|
||||
inline
|
||||
class="mt-1 custom-badge"
|
||||
:color="topic.color"
|
||||
/>
|
||||
<div>
|
||||
<div
|
||||
class="text-body-1"
|
||||
style="min-inline-size: 90px;"
|
||||
>
|
||||
{{ topic.title }}
|
||||
</div>
|
||||
<h5 class="text-h5">
|
||||
{{ topic.value }}%
|
||||
</h5>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</VCol>
|
||||
</VRow>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
@use "@core-scss/template/libs/apex-chart.scss";
|
||||
|
||||
@media screen and (min-width: 960px) {
|
||||
.topic-progress {
|
||||
inline-size: 17rem;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,268 @@
|
||||
<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: 1468,
|
||||
options: { plotOptions: { bar: { columnWidth: '70%' } } },
|
||||
},
|
||||
{
|
||||
breakpoint: 1279,
|
||||
options: { plotOptions: { bar: { columnWidth: '40%' } } },
|
||||
},
|
||||
{
|
||||
breakpoint: 1197,
|
||||
options: {
|
||||
chart: { height: 228 },
|
||||
plotOptions: {
|
||||
bar: {
|
||||
borderRadius: 6,
|
||||
columnWidth: '40%',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
breakpoint: 912,
|
||||
options: {
|
||||
chart: { height: 232 },
|
||||
plotOptions: {
|
||||
bar: {
|
||||
borderRadius: 6,
|
||||
columnWidth: '60%',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
breakpoint: 670,
|
||||
options: {
|
||||
plotOptions: {
|
||||
bar: {
|
||||
columnWidth: '70%',
|
||||
borderRadius: 6,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
breakpoint: 600,
|
||||
options: {
|
||||
plotOptions: {
|
||||
bar: {
|
||||
borderRadius: 8,
|
||||
columnWidth: '40%',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
breakpoint: 475,
|
||||
options: {
|
||||
plotOptions: {
|
||||
bar: {
|
||||
borderRadius: 6,
|
||||
columnWidth: '50%',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
breakpoint: 381,
|
||||
options: {
|
||||
plotOptions: {
|
||||
bar: {
|
||||
columnWidth: '60%',
|
||||
borderRadius: 6,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
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 :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>
|
||||
@@ -0,0 +1,53 @@
|
||||
<script setup>
|
||||
const props = defineProps({
|
||||
articles: {
|
||||
type: Array,
|
||||
required: true,
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VRow v-if="props.articles.length">
|
||||
<VCol
|
||||
v-for="article in props.articles"
|
||||
:key="article.title"
|
||||
cols="12"
|
||||
md="4"
|
||||
>
|
||||
<VCard
|
||||
flat
|
||||
border
|
||||
>
|
||||
<VCardText class="align-center text-center d-flex flex-column gap-3">
|
||||
<img
|
||||
:src="article.img"
|
||||
alt="svg"
|
||||
height="58"
|
||||
width="58"
|
||||
>
|
||||
|
||||
<h5 class="text-h5">
|
||||
{{ article.title }}
|
||||
</h5>
|
||||
<p class="text-body-1 mb-0">
|
||||
{{ article.subtitle }}
|
||||
</p>
|
||||
|
||||
<VBtn
|
||||
size="small"
|
||||
variant="tonal"
|
||||
:to="{
|
||||
name: 'front-pages-help-center-article-title',
|
||||
params: {
|
||||
title: 'how-to-add-product-in-cart',
|
||||
},
|
||||
}"
|
||||
>
|
||||
Read More
|
||||
</VBtn>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
</VCol>
|
||||
</VRow>
|
||||
</template>
|
||||
@@ -0,0 +1,16 @@
|
||||
<template>
|
||||
<VCardText class="text-center py-4">
|
||||
<h4 class="text-h4 text-center">
|
||||
Still need help?
|
||||
</h4>
|
||||
<p class="my-4 text-body-1">
|
||||
Our specialists are always happy to help.
|
||||
<br>
|
||||
Contact us during standard business hours or email us 24/7, and we'll get back to you.
|
||||
</p>
|
||||
<div class="d-flex justify-center gap-4 flex-wrap">
|
||||
<VBtn>Visit our community</VBtn>
|
||||
<VBtn>Contact us</VBtn>
|
||||
</div>
|
||||
</VCardText>
|
||||
</template>
|
||||
@@ -0,0 +1,94 @@
|
||||
<script setup>
|
||||
const props = defineProps({
|
||||
categories: {
|
||||
type: Array,
|
||||
required: true,
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VRow>
|
||||
<VCol
|
||||
v-for="article in props.categories"
|
||||
:key="article.title"
|
||||
cols="12"
|
||||
sm="6"
|
||||
lg="4"
|
||||
>
|
||||
<VCard :title="article.title">
|
||||
<template #prepend>
|
||||
<VAvatar
|
||||
rounded
|
||||
color="primary"
|
||||
variant="tonal"
|
||||
size="32"
|
||||
class="me-1"
|
||||
>
|
||||
<VIcon
|
||||
:icon="article.icon"
|
||||
size="20"
|
||||
/>
|
||||
</VAvatar>
|
||||
</template>
|
||||
|
||||
<VCardText>
|
||||
<VList class="card-list">
|
||||
<VListItem
|
||||
v-for="(item, index) in article.articles"
|
||||
:key="index"
|
||||
class="text-disabled"
|
||||
>
|
||||
<RouterLink
|
||||
:to="{
|
||||
name: 'front-pages-help-center-article-title',
|
||||
params: {
|
||||
title: 'how-to-add-product-in-cart',
|
||||
},
|
||||
}"
|
||||
class="text-high-emphasis"
|
||||
>
|
||||
<div>{{ item.title }}</div>
|
||||
</RouterLink>
|
||||
<template #append>
|
||||
<VIcon
|
||||
icon="tabler-chevron-right"
|
||||
class="flip-in-rtl"
|
||||
size="20"
|
||||
/>
|
||||
</template>
|
||||
</VListItem>
|
||||
</VList>
|
||||
|
||||
<div class="mt-6">
|
||||
<RouterLink
|
||||
:to="{
|
||||
name: 'front-pages-help-center-article-title',
|
||||
params: {
|
||||
title: 'how-to-add-product-in-cart',
|
||||
},
|
||||
}"
|
||||
class="text-base d-flex align-center font-weight-medium d-inline-block"
|
||||
>
|
||||
<span class="d-inline-block">
|
||||
See All Articles
|
||||
</span>
|
||||
|
||||
<VIcon
|
||||
icon="tabler-arrow-right"
|
||||
size="18"
|
||||
class="ms-3 flip-in-rtl"
|
||||
/>
|
||||
</RouterLink>
|
||||
</div>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
</VCol>
|
||||
</VRow>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
.card-list {
|
||||
--v-card-list-gap: 0.5rem;
|
||||
}
|
||||
</style>
|
||||
49
resources/js/views/pages/typography/TypographyHeadlines.vue
Normal file
49
resources/js/views/pages/typography/TypographyHeadlines.vue
Normal file
@@ -0,0 +1,49 @@
|
||||
<template>
|
||||
<VCard title="Headlines">
|
||||
<VCardText>
|
||||
<VRow>
|
||||
<VCol cols="12">
|
||||
<h1 class="text-h1">
|
||||
Heading 1
|
||||
</h1>
|
||||
<span>font-size: 2.875rem / line-height: 4.25rem / font-weight: 500</span>
|
||||
</VCol>
|
||||
|
||||
<VCol cols="12">
|
||||
<h2 class="text-h2">
|
||||
Heading 2
|
||||
</h2>
|
||||
<span>font-size: 2.375rem / line-height: 3.5rem / font-weight: 500</span>
|
||||
</VCol>
|
||||
|
||||
<VCol cols="12">
|
||||
<h3 class="text-h3">
|
||||
Heading 3
|
||||
</h3>
|
||||
<span>font-size: 1.75rem / line-height: 2.625rem / font-weight: 500</span>
|
||||
</VCol>
|
||||
|
||||
<VCol cols="12">
|
||||
<h4 class="text-h4">
|
||||
Heading 4
|
||||
</h4>
|
||||
<span>font-size: 1.5rem / line-height: 2.375rem / font-weight: 500</span>
|
||||
</VCol>
|
||||
|
||||
<VCol cols="12">
|
||||
<h5 class="text-h5">
|
||||
Heading 5
|
||||
</h5>
|
||||
<span>font-size: 1.125rem / line-height: 1.75rem / font-weight: 500</span>
|
||||
</VCol>
|
||||
|
||||
<VCol cols="12">
|
||||
<h6 class="text-h6">
|
||||
Heading 6
|
||||
</h6>
|
||||
<span>font-size: 0.9375rem / line-height: 1.375rem / font-weight: 500</span>
|
||||
</VCol>
|
||||
</VRow>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
</template>
|
||||
139
resources/js/views/pages/typography/TypographyTexts.vue
Normal file
139
resources/js/views/pages/typography/TypographyTexts.vue
Normal file
@@ -0,0 +1,139 @@
|
||||
<template>
|
||||
<VCard title="Texts">
|
||||
<VCardText>
|
||||
<VRow no-gutters>
|
||||
<VCol
|
||||
cols="12"
|
||||
md="2"
|
||||
>
|
||||
<p class="text-subtitle-1">
|
||||
text-subtitle-1
|
||||
</p>
|
||||
</VCol>
|
||||
<VCol
|
||||
cols="12"
|
||||
md="10"
|
||||
class="mb-6"
|
||||
>
|
||||
<p class="text-subtitle-1 mb-1">
|
||||
Cupcake ipsum dolor sit amet fruitcake donut chocolate.
|
||||
</p>
|
||||
<span>font-size: 0.9375rem / line-height: 1.375rem / font-weight: 400</span>
|
||||
</VCol>
|
||||
|
||||
<VCol
|
||||
cols="12"
|
||||
md="2"
|
||||
>
|
||||
<p class="text-subtitle-2">
|
||||
text-subtitle-2
|
||||
</p>
|
||||
</VCol>
|
||||
<VCol
|
||||
cols="12"
|
||||
md="10"
|
||||
class="mb-6"
|
||||
>
|
||||
<p class="text-subtitle-2 mb-1">
|
||||
Cupcake ipsum dolor sit amet fruitcake donut chocolate.
|
||||
</p>
|
||||
<span>font-size: 0.8125rem / line-height: 1.25rem / font-weight: 400</span>
|
||||
</VCol>
|
||||
|
||||
<VCol
|
||||
cols="12"
|
||||
md="2"
|
||||
>
|
||||
<p class="text-body-1">
|
||||
text-body-1
|
||||
</p>
|
||||
</VCol>
|
||||
<VCol
|
||||
cols="12"
|
||||
md="10"
|
||||
class="mb-6"
|
||||
>
|
||||
<p class="text-body-1 mb-1">
|
||||
Cupcake ipsum dolor sit amet fruitcake donut chocolate.
|
||||
</p>
|
||||
<span>font-size: 0.9375rem / line-height: 1.375rem / font-weight: 400</span>
|
||||
</VCol>
|
||||
|
||||
<VCol
|
||||
cols="12"
|
||||
md="2"
|
||||
>
|
||||
<p class="text-body-2">
|
||||
text-body-2
|
||||
</p>
|
||||
</VCol>
|
||||
<VCol
|
||||
cols="12"
|
||||
md="10"
|
||||
class="mb-6"
|
||||
>
|
||||
<p class="text-body-2 mb-1">
|
||||
Cupcake ipsum dolor sit amet fruitcake donut chocolate.
|
||||
</p>
|
||||
<span>font-size: 0.8125rem / line-height: 1.25rem / font-weight: 400</span>
|
||||
</VCol>
|
||||
|
||||
<VCol
|
||||
cols="12"
|
||||
md="2"
|
||||
>
|
||||
<p class="text-caption">
|
||||
text-caption
|
||||
</p>
|
||||
</VCol>
|
||||
<VCol
|
||||
cols="12"
|
||||
md="10"
|
||||
class="mb-6"
|
||||
>
|
||||
<p class="text-caption mb-1">
|
||||
Cupcake ipsum dolor sit amet fruitcake donut chocolate.
|
||||
</p>
|
||||
<span>font-size: 0.8125rem / line-height: 1.125rem / font-weight: 400</span>
|
||||
</VCol>
|
||||
|
||||
<VCol
|
||||
cols="12"
|
||||
md="2"
|
||||
>
|
||||
<p class="text-overline">
|
||||
text-overline
|
||||
</p>
|
||||
</VCol>
|
||||
<VCol
|
||||
cols="12"
|
||||
md="10"
|
||||
class="mb-6"
|
||||
>
|
||||
<p class="text-overline mb-1">
|
||||
Cupcake ipsum dolor sit amet fruitcake donut chocolate.
|
||||
</p>
|
||||
<span>font-size: 0.75rem / line-height: 0.875rem / font-weight: 400</span>
|
||||
</VCol>
|
||||
|
||||
<VCol
|
||||
cols="12"
|
||||
md="2"
|
||||
>
|
||||
<p class="text-button">
|
||||
text-button
|
||||
</p>
|
||||
</VCol>
|
||||
<VCol
|
||||
cols="12"
|
||||
md="10"
|
||||
>
|
||||
<p class="text-button mb-1">
|
||||
Cupcake ipsum dolor sit amet fruitcake donut chocolate.
|
||||
</p>
|
||||
<span>font-size: 0.9375rem / line-height: 1.125rem / font-weight: 500</span>
|
||||
</VCol>
|
||||
</VRow>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
</template>
|
||||
88
resources/js/views/pages/user-profile/UserProfileHeader.vue
Normal file
88
resources/js/views/pages/user-profile/UserProfileHeader.vue
Normal file
@@ -0,0 +1,88 @@
|
||||
<script setup>
|
||||
const profileHeaderData = ref()
|
||||
const { data, error } = await useApi('/pages/profile/header')
|
||||
if (error.value) {
|
||||
console.log(error.value)
|
||||
} else {
|
||||
if (data.value)
|
||||
profileHeaderData.value = data.value
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VCard v-if="profileHeaderData">
|
||||
<VImg
|
||||
:src="profileHeaderData.coverImg"
|
||||
min-height="125"
|
||||
max-height="250"
|
||||
cover
|
||||
/>
|
||||
|
||||
<VCardText class="d-flex align-bottom flex-sm-row flex-column justify-center gap-x-6">
|
||||
<div class="d-flex h-0">
|
||||
<VAvatar
|
||||
rounded
|
||||
size="130"
|
||||
:image="profileHeaderData.profileImg"
|
||||
class="user-profile-avatar mx-auto"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="user-profile-info w-100 mt-16 pt-6 pt-sm-0 mt-sm-0">
|
||||
<h4 class="text-h4 text-center text-sm-start font-weight-medium mb-2">
|
||||
{{ profileHeaderData?.fullName }}
|
||||
</h4>
|
||||
|
||||
<div class="d-flex align-center justify-center justify-sm-space-between flex-wrap gap-5">
|
||||
<div class="d-flex flex-wrap justify-center justify-sm-start flex-grow-1 gap-6">
|
||||
<span class="d-flex gap-x-2 align-center">
|
||||
<VIcon
|
||||
size="24"
|
||||
icon="tabler-palette"
|
||||
/>
|
||||
<div class="text-body-1 font-weight-medium">
|
||||
{{ profileHeaderData?.designation }}
|
||||
</div>
|
||||
</span>
|
||||
|
||||
<span class="d-flex gap-x-2 align-center">
|
||||
<VIcon
|
||||
size="24"
|
||||
icon="tabler-map-pin"
|
||||
/>
|
||||
<div class="text-body-1 font-weight-medium">
|
||||
{{ profileHeaderData?.location }}
|
||||
</div>
|
||||
</span>
|
||||
|
||||
<span class="d-flex gap-x-2 align-center">
|
||||
<VIcon
|
||||
size="24"
|
||||
icon="tabler-calendar"
|
||||
/>
|
||||
<div class="text-body-1 font-weight-medium">
|
||||
{{ profileHeaderData?.joiningDate }}
|
||||
</div>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<VBtn prepend-icon="tabler-user-check">
|
||||
Connected
|
||||
</VBtn>
|
||||
</div>
|
||||
</div>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
.user-profile-avatar {
|
||||
border: 5px solid rgb(var(--v-theme-surface));
|
||||
background-color: rgb(var(--v-theme-surface)) !important;
|
||||
inset-block-start: -3rem;
|
||||
|
||||
.v-img__img {
|
||||
border-radius: 0.125rem;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
127
resources/js/views/pages/user-profile/connections/index.vue
Normal file
127
resources/js/views/pages/user-profile/connections/index.vue
Normal file
@@ -0,0 +1,127 @@
|
||||
<script setup>
|
||||
const router = useRoute('pages-user-profile-tab')
|
||||
const connectionData = ref([])
|
||||
|
||||
const fetchProjectData = async () => {
|
||||
if (router.params.tab === 'connections') {
|
||||
const data = await $api('/pages/profile', { query: { tab: router.params.tab } }).catch(err => console.log(err))
|
||||
|
||||
connectionData.value = data
|
||||
}
|
||||
}
|
||||
|
||||
watch(router, fetchProjectData, { immediate: true })
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VRow>
|
||||
<VCol
|
||||
v-for="data in connectionData"
|
||||
:key="data.name"
|
||||
sm="6"
|
||||
lg="4"
|
||||
cols="12"
|
||||
>
|
||||
<VCard>
|
||||
<div class="vertical-more">
|
||||
<MoreBtn
|
||||
:menu-list="[
|
||||
{ title: 'Share connection', value: 'Share connection' },
|
||||
{ title: 'Block connection', value: 'Block connection' },
|
||||
{ type: 'divider', class: 'my-2' },
|
||||
{ title: 'Delete', value: 'Delete', class: 'text-error' },
|
||||
]"
|
||||
item-props
|
||||
/>
|
||||
</div>
|
||||
|
||||
<VCardItem>
|
||||
<VCardTitle class="d-flex flex-column align-center justify-center gap-y-6">
|
||||
<VAvatar
|
||||
size="100"
|
||||
:image="data.avatar"
|
||||
class="mt-5"
|
||||
/>
|
||||
|
||||
<div class="text-center">
|
||||
<h5 class="text-h5">
|
||||
{{ data.name }}
|
||||
</h5>
|
||||
<h6 class="text-body-1">
|
||||
{{ data.designation }}
|
||||
</h6>
|
||||
</div>
|
||||
|
||||
<div class="d-flex align-center flex-wrap gap-4">
|
||||
<VChip
|
||||
v-for="chip in data.chips"
|
||||
:key="chip.title"
|
||||
label
|
||||
:color="chip.color"
|
||||
size="small"
|
||||
>
|
||||
{{ chip.title }}
|
||||
</VChip>
|
||||
</div>
|
||||
</VCardTitle>
|
||||
</VCardItem>
|
||||
|
||||
<VCardText>
|
||||
<div class="d-flex justify-space-around mb-2">
|
||||
<div class="text-center">
|
||||
<h5 class="text-h5">
|
||||
{{ data.projects }}
|
||||
</h5>
|
||||
<div class="text-body-1">
|
||||
Projects
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-center">
|
||||
<h5 class="text-h5">
|
||||
{{ data.tasks }}
|
||||
</h5>
|
||||
<div class="text-body-1">
|
||||
Tasks
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-center">
|
||||
<h5 class="text-h5">
|
||||
{{ data.connections }}
|
||||
</h5>
|
||||
<div class="text-body-1">
|
||||
Connections
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="d-flex justify-center gap-4 mt-6">
|
||||
<VBtn
|
||||
:prepend-icon="data.isConnected ? 'tabler-user-check' : 'tabler-user-plus'"
|
||||
:variant="data.isConnected ? 'elevated' : 'tonal'"
|
||||
>
|
||||
{{ data.isConnected ? 'connected' : 'connect' }}
|
||||
</VBtn>
|
||||
|
||||
<IconBtn
|
||||
variant="tonal"
|
||||
class="rounded"
|
||||
>
|
||||
<VIcon
|
||||
icon="tabler-mail"
|
||||
color="secondary"
|
||||
/>
|
||||
</IconBtn>
|
||||
</div>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
</VCol>
|
||||
</VRow>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
.vertical-more {
|
||||
position: absolute;
|
||||
inset-block-start: 1rem;
|
||||
inset-inline-end: 0.5rem;
|
||||
}
|
||||
</style>
|
||||
111
resources/js/views/pages/user-profile/profile/About.vue
Normal file
111
resources/js/views/pages/user-profile/profile/About.vue
Normal file
@@ -0,0 +1,111 @@
|
||||
<script setup>
|
||||
const props = defineProps({
|
||||
data: {
|
||||
type: null,
|
||||
required: true,
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VCard class="mb-6">
|
||||
<VCardText>
|
||||
<p class="text-sm text-disabled">
|
||||
ABOUT
|
||||
</p>
|
||||
|
||||
<VList class="card-list text-medium-emphasis">
|
||||
<VListItem
|
||||
v-for="item in props.data.about"
|
||||
:key="item.property"
|
||||
>
|
||||
<VListItemTitle>
|
||||
<span class="d-flex align-center">
|
||||
<VIcon
|
||||
:icon="item.icon"
|
||||
size="24"
|
||||
class="me-2"
|
||||
/>
|
||||
<div class="text-body-1 font-weight-medium me-2">{{ item.property }}:</div>
|
||||
<div>{{ item.value }}</div>
|
||||
</span>
|
||||
</VListItemTitle>
|
||||
</VListItem>
|
||||
</VList>
|
||||
|
||||
<p class="text-sm text-disabled mt-6">
|
||||
CONTACTS
|
||||
</p>
|
||||
|
||||
<VList class="card-list text-medium-emphasis">
|
||||
<VListItem
|
||||
v-for="item in props.data.contacts"
|
||||
:key="item.property"
|
||||
>
|
||||
<VListItemTitle>
|
||||
<span class="d-flex align-center">
|
||||
<VIcon
|
||||
:icon="item.icon"
|
||||
size="24"
|
||||
class="me-2"
|
||||
/>
|
||||
<div class="text-body-1 font-weight-medium me-2">{{ item.property }}:</div>
|
||||
<div>{{ item.value }}</div>
|
||||
</span>
|
||||
</VListItemTitle>
|
||||
</VListItem>
|
||||
</VList>
|
||||
|
||||
<p class="text-sm text-disabled mt-6">
|
||||
TEAMS
|
||||
</p>
|
||||
|
||||
<VList class="card-list text-medium-emphasis">
|
||||
<VListItem
|
||||
v-for="item in props.data.teams"
|
||||
:key="item.property"
|
||||
>
|
||||
<VListItemTitle>
|
||||
<span class="d-flex align-center">
|
||||
<div class="text-body-1 font-weight-medium me-2">{{ item.property }}</div>
|
||||
<div>{{ item.value }}</div>
|
||||
</span>
|
||||
</VListItemTitle>
|
||||
</VListItem>
|
||||
</VList>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
|
||||
<VCard>
|
||||
<VCardText>
|
||||
<p class="text-sm text-disabled">
|
||||
OVERVIEW
|
||||
</p>
|
||||
|
||||
<VList class="card-list text-medium-emphasis">
|
||||
<VListItem
|
||||
v-for="item in props.data.overview"
|
||||
:key="item.property"
|
||||
>
|
||||
<VListItemTitle>
|
||||
<span class="d-flex align-center">
|
||||
<VIcon
|
||||
:icon="item.icon"
|
||||
size="24"
|
||||
class="me-2"
|
||||
/>
|
||||
<div class="text-body-1 font-weight-medium me-2">{{ item.property }}:</div>
|
||||
<div>{{ item.value }}</div>
|
||||
</span>
|
||||
</VListItemTitle>
|
||||
</VListItem>
|
||||
</VList>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.card-list {
|
||||
--v-card-list-gap: 16px;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,160 @@
|
||||
<script setup>
|
||||
import avatar1 from '@images/avatars/avatar-1.png'
|
||||
import avatar2 from '@images/avatars/avatar-2.png'
|
||||
import avatar3 from '@images/avatars/avatar-3.png'
|
||||
import pdf from '@images/icons/project-icons/pdf.png'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VCard>
|
||||
<VCardItem>
|
||||
<template #prepend>
|
||||
<VIcon
|
||||
icon="tabler-chart-bar"
|
||||
size="24"
|
||||
class="me-2"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<VCardTitle>Activity Timeline</VCardTitle>
|
||||
</VCardItem>
|
||||
|
||||
<VCardText>
|
||||
<VTimeline
|
||||
side="end"
|
||||
align="start"
|
||||
line-inset="8"
|
||||
truncate-line="start"
|
||||
density="compact"
|
||||
>
|
||||
<!-- SECTION Timeline Item: Flight -->
|
||||
<VTimelineItem
|
||||
dot-color="primary"
|
||||
size="x-small"
|
||||
>
|
||||
<!-- 👉 Header -->
|
||||
<div class="d-flex justify-space-between align-center gap-2 flex-wrap mb-2">
|
||||
<span class="app-timeline-title">
|
||||
12 Invoices have been paid
|
||||
</span>
|
||||
<span class="app-timeline-meta">12 min ago</span>
|
||||
</div>
|
||||
|
||||
<!-- 👉 Content -->
|
||||
<div class="app-timeline-text mt-1">
|
||||
Invoices have been paid to the company
|
||||
</div>
|
||||
|
||||
<div class="d-inline-flex align-center timeline-chip mt-2">
|
||||
<img
|
||||
:src="pdf"
|
||||
height="20"
|
||||
class="me-2"
|
||||
alt="img"
|
||||
>
|
||||
<span class="app-timeline-text font-weight-medium">
|
||||
invoice.pdf
|
||||
</span>
|
||||
</div>
|
||||
</VTimelineItem>
|
||||
<!-- !SECTION -->
|
||||
|
||||
<!-- SECTION Timeline Item: Interview Schedule -->
|
||||
<VTimelineItem
|
||||
size="x-small"
|
||||
dot-color="success"
|
||||
>
|
||||
<!-- 👉 Header -->
|
||||
<div class="d-flex justify-space-between align-center flex-wrap mb-2">
|
||||
<div class="app-timeline-title">
|
||||
Client Meeting
|
||||
</div>
|
||||
<span class="app-timeline-meta">45 min ago</span>
|
||||
</div>
|
||||
|
||||
<div class="app-timeline-text mt-1">
|
||||
Project meeting with john @10:15am
|
||||
</div>
|
||||
|
||||
<!-- 👉 Person -->
|
||||
<div class="d-flex justify-space-between align-center flex-wrap">
|
||||
<!-- 👉 Avatar & Personal Info -->
|
||||
<div class="d-flex align-center mt-2">
|
||||
<VAvatar
|
||||
size="32"
|
||||
class="me-2"
|
||||
:image="avatar1"
|
||||
/>
|
||||
<div class="d-flex flex-column">
|
||||
<p class="text-sm font-weight-medium text-medium-emphasis mb-0">
|
||||
Lester McCarthy (Client)
|
||||
</p>
|
||||
<span class="text-sm">CEO of Pixinvent</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</VTimelineItem>
|
||||
<!-- !SECTION -->
|
||||
|
||||
<!-- SECTION Design Review -->
|
||||
<VTimelineItem
|
||||
size="x-small"
|
||||
dot-color="info"
|
||||
>
|
||||
<!-- 👉 Header -->
|
||||
<div class="d-flex justify-space-between align-center flex-wrap mb-2">
|
||||
<span class="app-timeline-title">
|
||||
Create a new project for client
|
||||
</span>
|
||||
<span class="app-timeline-meta">2 Day Ago</span>
|
||||
</div>
|
||||
|
||||
<!-- 👉 Content -->
|
||||
<p class="app-timeline-text mt-1 mb-2">
|
||||
6 team members in a project
|
||||
</p>
|
||||
|
||||
<div class="v-avatar-group demo-avatar-group">
|
||||
<VAvatar :size="40">
|
||||
<VImg :src="avatar1" />
|
||||
<VTooltip
|
||||
activator="parent"
|
||||
location="top"
|
||||
>
|
||||
John Doe
|
||||
</VTooltip>
|
||||
</VAvatar>
|
||||
|
||||
<VAvatar :size="40">
|
||||
<VImg :src="avatar2" />
|
||||
<VTooltip
|
||||
activator="parent"
|
||||
location="top"
|
||||
>
|
||||
Jennie Obrien
|
||||
</VTooltip>
|
||||
</VAvatar>
|
||||
|
||||
<VAvatar :size="40">
|
||||
<VImg :src="avatar3" />
|
||||
<VTooltip
|
||||
activator="parent"
|
||||
location="top"
|
||||
>
|
||||
Peter Harper
|
||||
</VTooltip>
|
||||
</VAvatar>
|
||||
|
||||
<VAvatar
|
||||
:size="40"
|
||||
:color="$vuetify.theme.current.dark ? '#373b50' : '#eeedf0'"
|
||||
>
|
||||
+3
|
||||
</VAvatar>
|
||||
</div>
|
||||
</VTimelineItem>
|
||||
<!-- !SECTION -->
|
||||
</VTimeline>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
</template>
|
||||
84
resources/js/views/pages/user-profile/profile/Connection.vue
Normal file
84
resources/js/views/pages/user-profile/profile/Connection.vue
Normal file
@@ -0,0 +1,84 @@
|
||||
<script setup>
|
||||
const props = defineProps({
|
||||
connectionsData: {
|
||||
type: Array,
|
||||
required: true,
|
||||
},
|
||||
})
|
||||
|
||||
const moreList = [
|
||||
{
|
||||
title: 'Share connections',
|
||||
value: 'Share connections',
|
||||
},
|
||||
{
|
||||
title: 'Suggest edits',
|
||||
value: 'Suggest edits',
|
||||
},
|
||||
{
|
||||
title: 'Report Bug',
|
||||
value: 'Report Bug',
|
||||
},
|
||||
]
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VCard title="Connection">
|
||||
<template #append>
|
||||
<div>
|
||||
<MoreBtn :menu-list="moreList" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<VCardText>
|
||||
<VList class="card-list">
|
||||
<VListItem
|
||||
v-for="data in props.connectionsData"
|
||||
:key="data.name"
|
||||
>
|
||||
<template #prepend>
|
||||
<VAvatar
|
||||
size="38"
|
||||
:image="data.avatar"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<VListItemTitle class="font-weight-medium">
|
||||
{{ data.name }}
|
||||
</VListItemTitle>
|
||||
<VListItemSubtitle>{{ data.connections }} Connections</VListItemSubtitle>
|
||||
|
||||
<template #append>
|
||||
<VBtn
|
||||
icon
|
||||
size="38"
|
||||
class="rounded"
|
||||
:variant="data.isFriend ? 'elevated' : 'tonal' "
|
||||
>
|
||||
<VIcon
|
||||
size="22"
|
||||
:icon="data.isFriend ? 'tabler-user-x' : 'tabler-user-check'"
|
||||
/>
|
||||
</VBtn>
|
||||
</template>
|
||||
</VListItem>
|
||||
|
||||
<VListItem>
|
||||
<VListItemTitle class="pt-2 text-center">
|
||||
<RouterLink :to="{ name: 'pages-user-profile-tab', params: { tab: 'connections' } }">
|
||||
<p class="mb-0">
|
||||
View all connections
|
||||
</p>
|
||||
</RouterLink>
|
||||
</VListItemTitle>
|
||||
</VListItem>
|
||||
</VList>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.card-list {
|
||||
--v-card-list-gap: 16px;
|
||||
}
|
||||
</style>
|
||||
258
resources/js/views/pages/user-profile/profile/ProjectList.vue
Normal file
258
resources/js/views/pages/user-profile/profile/ProjectList.vue
Normal file
@@ -0,0 +1,258 @@
|
||||
<script setup>
|
||||
import avatar1 from '@images/avatars/avatar-1.png'
|
||||
import avatar2 from '@images/avatars/avatar-2.png'
|
||||
import avatar3 from '@images/avatars/avatar-3.png'
|
||||
import avatar4 from '@images/avatars/avatar-4.png'
|
||||
import avatar5 from '@images/avatars/avatar-5.png'
|
||||
import avatar6 from '@images/avatars/avatar-6.png'
|
||||
import avatar7 from '@images/avatars/avatar-7.png'
|
||||
import avatar8 from '@images/avatars/avatar-8.png'
|
||||
import figma from '@images/icons/project-icons/figma.png'
|
||||
import html5 from '@images/icons/project-icons/html5.png'
|
||||
import python from '@images/icons/project-icons/python.png'
|
||||
import react from '@images/icons/project-icons/react.png'
|
||||
import sketch from '@images/icons/project-icons/sketch.png'
|
||||
import vue from '@images/icons/project-icons/vue.png'
|
||||
import xamarin from '@images/icons/project-icons/xamarin.png'
|
||||
|
||||
// Project Table Header
|
||||
const projectTableHeaders = [
|
||||
{
|
||||
title: 'PROJECT',
|
||||
key: 'project',
|
||||
},
|
||||
{
|
||||
title: 'LEADER',
|
||||
key: 'leader',
|
||||
},
|
||||
{
|
||||
title: 'Team',
|
||||
key: 'team',
|
||||
},
|
||||
{
|
||||
title: 'PROGRESS',
|
||||
key: 'progress',
|
||||
},
|
||||
{
|
||||
title: 'Action',
|
||||
key: 'Action',
|
||||
sortable: false,
|
||||
},
|
||||
]
|
||||
|
||||
const projects = [
|
||||
{
|
||||
logo: react,
|
||||
name: 'BGC eCommerce App',
|
||||
project: 'React Project',
|
||||
leader: 'Eileen',
|
||||
progress: 78,
|
||||
hours: '18:42',
|
||||
team: [
|
||||
avatar1,
|
||||
avatar8,
|
||||
avatar6,
|
||||
],
|
||||
extraMembers: 3,
|
||||
},
|
||||
{
|
||||
logo: figma,
|
||||
name: 'Falcon Logo Design',
|
||||
project: 'Figma Project',
|
||||
leader: 'Owen',
|
||||
progress: 25,
|
||||
hours: '20:42',
|
||||
team: [
|
||||
avatar5,
|
||||
avatar2,
|
||||
],
|
||||
},
|
||||
{
|
||||
logo: vue,
|
||||
name: 'Dashboard Design',
|
||||
project: 'Vuejs Project',
|
||||
leader: 'Keith',
|
||||
progress: 62,
|
||||
hours: '120:87',
|
||||
team: [
|
||||
avatar8,
|
||||
avatar2,
|
||||
avatar1,
|
||||
],
|
||||
},
|
||||
{
|
||||
logo: xamarin,
|
||||
name: 'Foodista mobile app',
|
||||
project: 'Xamarin Project',
|
||||
leader: 'Merline',
|
||||
progress: 8,
|
||||
hours: '120:87',
|
||||
team: [
|
||||
avatar3,
|
||||
avatar4,
|
||||
avatar7,
|
||||
],
|
||||
extraMembers: 8,
|
||||
},
|
||||
{
|
||||
logo: python,
|
||||
name: 'Dojo Email App',
|
||||
project: 'Python Project',
|
||||
leader: 'Harmonia',
|
||||
progress: 51,
|
||||
hours: '230:10',
|
||||
team: [
|
||||
avatar4,
|
||||
avatar3,
|
||||
avatar1,
|
||||
],
|
||||
extraMembers: 5,
|
||||
},
|
||||
{
|
||||
logo: sketch,
|
||||
name: 'Blockchain Website',
|
||||
project: 'Sketch Project',
|
||||
leader: 'Allyson',
|
||||
progress: 92,
|
||||
hours: '342:41',
|
||||
team: [
|
||||
avatar1,
|
||||
avatar8,
|
||||
],
|
||||
},
|
||||
{
|
||||
logo: html5,
|
||||
name: 'Hoffman Website',
|
||||
project: 'HTML Project',
|
||||
leader: 'Georgie',
|
||||
progress: 80,
|
||||
hours: '12:45',
|
||||
team: [
|
||||
avatar1,
|
||||
avatar8,
|
||||
avatar6,
|
||||
],
|
||||
},
|
||||
]
|
||||
|
||||
const search = ref('')
|
||||
|
||||
const options = ref({
|
||||
page: 1,
|
||||
itemsPerPage: 5,
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VCard>
|
||||
<VCardText class="d-flex justify-space-between align-center flex-wrap gap-4">
|
||||
<h5 class="text-h5">
|
||||
Project List
|
||||
</h5>
|
||||
<div style="inline-size: 272px;">
|
||||
<AppTextField
|
||||
v-model="search"
|
||||
placeholder="Search Project"
|
||||
/>
|
||||
</div>
|
||||
</VCardText>
|
||||
|
||||
<VDivider />
|
||||
<!-- 👉 User Project List Table -->
|
||||
|
||||
<!-- SECTION Datatable -->
|
||||
<VDataTable
|
||||
v-model:page="options.page"
|
||||
:headers="projectTableHeaders"
|
||||
:items-per-page="options.itemsPerPage"
|
||||
:items="projects"
|
||||
item-value="name"
|
||||
hide-default-footer
|
||||
:search="search"
|
||||
show-select
|
||||
class="text-no-wrap"
|
||||
>
|
||||
<!-- projects -->
|
||||
<template #item.project="{ item }">
|
||||
<div class="d-flex align-center gap-x-3">
|
||||
<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>
|
||||
<IconBtn>
|
||||
<VIcon icon="tabler-dots-vertical" />
|
||||
</IconBtn>
|
||||
</template>
|
||||
|
||||
<!-- TODO Refactor this after vuetify provides proper solution for removing default footer -->
|
||||
<template #bottom>
|
||||
<TablePagination
|
||||
v-model:page="options.page"
|
||||
:items-per-page="options.itemsPerPage"
|
||||
:total-items="projects.length"
|
||||
/>
|
||||
</template>
|
||||
</VDataTable>
|
||||
<!-- !SECTION -->
|
||||
</VCard>
|
||||
</template>
|
||||
81
resources/js/views/pages/user-profile/profile/Teams.vue
Normal file
81
resources/js/views/pages/user-profile/profile/Teams.vue
Normal file
@@ -0,0 +1,81 @@
|
||||
<script setup>
|
||||
const props = defineProps({
|
||||
teamsData: {
|
||||
type: Array,
|
||||
required: true,
|
||||
},
|
||||
})
|
||||
|
||||
const moreList = [
|
||||
{
|
||||
title: 'Share connections',
|
||||
value: 'Share connections',
|
||||
},
|
||||
{
|
||||
title: 'Suggest edits',
|
||||
value: 'Suggest edits',
|
||||
},
|
||||
{
|
||||
title: 'Report Bug',
|
||||
value: 'Report Bug',
|
||||
},
|
||||
]
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VCard title="Teams">
|
||||
<template #append>
|
||||
<div>
|
||||
<MoreBtn :menu-list="moreList" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<VCardText>
|
||||
<VList class="card-list">
|
||||
<VListItem
|
||||
v-for="data in props.teamsData"
|
||||
:key="data.title"
|
||||
>
|
||||
<template #prepend>
|
||||
<VAvatar
|
||||
size="38"
|
||||
:image="data.avatar"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<VListItemTitle class="font-weight-medium">
|
||||
{{ data.title }}
|
||||
</VListItemTitle>
|
||||
<VListItemSubtitle>{{ data.members }} Members</VListItemSubtitle>
|
||||
|
||||
<template #append>
|
||||
<VChip
|
||||
label
|
||||
:color="data.ChipColor"
|
||||
size="small"
|
||||
class="font-weight-medium"
|
||||
>
|
||||
{{ data.chipText }}
|
||||
</VChip>
|
||||
</template>
|
||||
</VListItem>
|
||||
|
||||
<VListItem>
|
||||
<VListItemTitle class="pt-2 text-center">
|
||||
<RouterLink :to="{ name: 'pages-user-profile-tab', params: { tab: 'teams' } }">
|
||||
<p class="mb-0">
|
||||
View all Teams
|
||||
</p>
|
||||
</RouterLink>
|
||||
</VListItemTitle>
|
||||
</VListItem>
|
||||
</VList>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.card-list {
|
||||
--v-card-list-gap: 16px;
|
||||
}
|
||||
</style>
|
||||
60
resources/js/views/pages/user-profile/profile/index.vue
Normal file
60
resources/js/views/pages/user-profile/profile/index.vue
Normal file
@@ -0,0 +1,60 @@
|
||||
<script setup>
|
||||
import About from './About.vue'
|
||||
import ActivityTimeline from './ActivityTimeline.vue'
|
||||
import Connection from './Connection.vue'
|
||||
import ProjectList from './ProjectList.vue'
|
||||
import Teams from './Teams.vue'
|
||||
|
||||
const router = useRoute('pages-user-profile-tab')
|
||||
const profileTabData = ref()
|
||||
|
||||
const fetchAboutData = async () => {
|
||||
if (router.params.tab === 'profile') {
|
||||
const data = await $api('/pages/profile', { query: { tab: router.params.tab } }).catch(err => console.log(err))
|
||||
|
||||
profileTabData.value = data
|
||||
}
|
||||
}
|
||||
|
||||
watch(router, fetchAboutData, { immediate: true })
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VRow v-if="profileTabData">
|
||||
<VCol
|
||||
md="4"
|
||||
cols="12"
|
||||
>
|
||||
<About :data="profileTabData" />
|
||||
</VCol>
|
||||
|
||||
<VCol
|
||||
cols="12"
|
||||
md="8"
|
||||
>
|
||||
<VRow>
|
||||
<VCol cols="12">
|
||||
<ActivityTimeline />
|
||||
</VCol>
|
||||
|
||||
<VCol
|
||||
cols="12"
|
||||
md="6"
|
||||
>
|
||||
<Connection :connections-data="profileTabData.connections" />
|
||||
</VCol>
|
||||
|
||||
<VCol
|
||||
cols="12"
|
||||
md="6"
|
||||
>
|
||||
<Teams :teams-data="profileTabData.teamsTech" />
|
||||
</VCol>
|
||||
|
||||
<VCol cols="12">
|
||||
<ProjectList />
|
||||
</VCol>
|
||||
</VRow>
|
||||
</VCol>
|
||||
</VRow>
|
||||
</template>
|
||||
161
resources/js/views/pages/user-profile/projects/index.vue
Normal file
161
resources/js/views/pages/user-profile/projects/index.vue
Normal file
@@ -0,0 +1,161 @@
|
||||
<script setup>
|
||||
const router = useRoute('pages-user-profile-tab')
|
||||
const projectData = ref([])
|
||||
|
||||
const fetchProjectData = async () => {
|
||||
if (router.params.tab === 'projects') {
|
||||
const data = await $api('/pages/profile', { query: { tab: router.params.tab } }).catch(err => console.log(err))
|
||||
|
||||
projectData.value = data
|
||||
}
|
||||
}
|
||||
|
||||
watch(router, fetchProjectData, { immediate: true })
|
||||
|
||||
const moreList = [
|
||||
{
|
||||
title: 'Rename Project',
|
||||
value: 'Rename Project',
|
||||
},
|
||||
{
|
||||
title: 'View Details',
|
||||
value: 'View Details',
|
||||
},
|
||||
{
|
||||
title: 'Add to favorites',
|
||||
value: 'Add to favorites',
|
||||
},
|
||||
{
|
||||
type: 'divider',
|
||||
class: 'my-2',
|
||||
},
|
||||
{
|
||||
title: 'Leave Project',
|
||||
value: 'Leave Project',
|
||||
class: 'text-error',
|
||||
},
|
||||
]
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VRow v-if="projectData">
|
||||
<VCol
|
||||
v-for="data in projectData"
|
||||
:key="data.title"
|
||||
cols="12"
|
||||
sm="6"
|
||||
lg="4"
|
||||
>
|
||||
<VCard>
|
||||
<VCardItem class="pb-4">
|
||||
<template #prepend>
|
||||
<VAvatar
|
||||
:image="data.avatar"
|
||||
size="38"
|
||||
class="me-2"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<VCardTitle>{{ data.title }}</VCardTitle>
|
||||
<span class="mb-0 text-body-1 d-flex align-center">
|
||||
<div class="font-weight-medium me-1">
|
||||
Client:
|
||||
</div>
|
||||
<div>{{ data.client }}</div>
|
||||
</span>
|
||||
|
||||
<template #append>
|
||||
<div class="mt-n2">
|
||||
<MoreBtn
|
||||
item-props
|
||||
:menu-list="moreList"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
</VCardItem>
|
||||
|
||||
<VCardText>
|
||||
<div class="d-flex align-center justify-space-between flex-wrap gap-x-2 gap-y-4">
|
||||
<div class="px-3 py-2 bg-var-theme-background rounded">
|
||||
<h6 class="text-base font-weight-medium">
|
||||
{{ data.budgetSpent }} <span class="text-body-1">/ {{ data.budget }}</span>
|
||||
</h6>
|
||||
<div>Total Budget</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h6 class="text-base font-weight-medium">
|
||||
Start Date: <span class="text-body-1">{{ data.startDate }}</span>
|
||||
</h6>
|
||||
<h6 class="text-base font-weight-medium">
|
||||
Deadline: <span class="text-body-1">{{ data.deadline }}</span>
|
||||
</h6>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p class="mt-4 mb-0 clamp-text">
|
||||
{{ data.description }}
|
||||
</p>
|
||||
</VCardText>
|
||||
|
||||
<VDivider />
|
||||
|
||||
<VCardText>
|
||||
<div class="d-flex align-center justify-space-between flex-wrap gap-2">
|
||||
<h6 class="text-base font-weight-medium">
|
||||
All Hours: <span class="text-body-1">
|
||||
{{ data.hours }}
|
||||
</span>
|
||||
</h6>
|
||||
|
||||
<VChip
|
||||
label
|
||||
:color="data.chipColor"
|
||||
size="small"
|
||||
>
|
||||
{{ data.daysLeft }} Days left
|
||||
</VChip>
|
||||
</div>
|
||||
|
||||
<div class="d-flex align-center justify-space-between flex-wrap text-caption text-medium-emphasis mt-4 mb-2">
|
||||
<span>Task: {{ data.tasks }}</span>
|
||||
<span>{{ Math.round((data.completedTask / data.totalTask) * 100) }}% Completed</span>
|
||||
</div>
|
||||
<VProgressLinear
|
||||
rounded
|
||||
rounded-bar
|
||||
height="8"
|
||||
:model-value="data.completedTask"
|
||||
:max="data.totalTask"
|
||||
color="primary"
|
||||
/>
|
||||
|
||||
<div class="d-flex align-center justify-space-between flex-wrap gap-2 mt-4">
|
||||
<div class="d-flex align-center">
|
||||
<div class="v-avatar-group me-3">
|
||||
<VAvatar
|
||||
v-for="avatar in data.avatarGroup"
|
||||
:key="avatar.name"
|
||||
:image="avatar.avatar"
|
||||
:size="32"
|
||||
/>
|
||||
</div>
|
||||
<span class="text-body-2 text-disabled">
|
||||
{{ data.members }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<span class="d-flex align-center">
|
||||
<VIcon
|
||||
icon="tabler-message-dots"
|
||||
class="me-1 text-disabled"
|
||||
size="24"
|
||||
/>
|
||||
<div class="text-disabled text-body-1">{{ data.comments }}</div>
|
||||
</span>
|
||||
</div>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
</VCol>
|
||||
</VRow>
|
||||
</template>
|
||||
118
resources/js/views/pages/user-profile/team/index.vue
Normal file
118
resources/js/views/pages/user-profile/team/index.vue
Normal file
@@ -0,0 +1,118 @@
|
||||
<script setup>
|
||||
const router = useRoute('pages-user-profile-tab')
|
||||
const teamData = ref([])
|
||||
|
||||
const fetchTeamData = async () => {
|
||||
if (router.params.tab === 'teams') {
|
||||
const data = await $api('/pages/profile', { query: { tab: router.params.tab } }).catch(err => console.log(err))
|
||||
|
||||
teamData.value = data
|
||||
}
|
||||
}
|
||||
|
||||
watch(router, fetchTeamData, { immediate: true })
|
||||
|
||||
const moreList = [
|
||||
{
|
||||
title: 'Rename Project',
|
||||
value: 'Rename Project',
|
||||
},
|
||||
{
|
||||
title: 'View Details',
|
||||
value: 'View Details',
|
||||
},
|
||||
{
|
||||
title: 'Add to favorites',
|
||||
value: 'Add to favorites',
|
||||
},
|
||||
{
|
||||
type: 'divider',
|
||||
class: 'my-2',
|
||||
},
|
||||
{
|
||||
title: 'Leave Project',
|
||||
value: 'Leave Project',
|
||||
class: 'text-error',
|
||||
},
|
||||
]
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VRow v-if="teamData">
|
||||
<VCol
|
||||
v-for="team in teamData"
|
||||
:key="team.title"
|
||||
cols="12"
|
||||
md="6"
|
||||
lg="4"
|
||||
>
|
||||
<VCard>
|
||||
<VCardItem
|
||||
class="pb-4"
|
||||
:title="team.title"
|
||||
>
|
||||
<template #prepend>
|
||||
<VAvatar
|
||||
size="38"
|
||||
:image="team?.avatar"
|
||||
/>
|
||||
</template>
|
||||
<template #append>
|
||||
<div>
|
||||
<IconBtn>
|
||||
<VIcon
|
||||
size="24"
|
||||
icon="tabler-star"
|
||||
class="text-disabled"
|
||||
/>
|
||||
</IconBtn>
|
||||
<MoreBtn
|
||||
:menu-list="moreList"
|
||||
item-props
|
||||
density="comfortable"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
</VCardItem>
|
||||
|
||||
<VCardText class="pb-4">
|
||||
<span class="text-base">{{ team.description }}</span>
|
||||
</VCardText>
|
||||
|
||||
<VCardText class="d-flex align-center">
|
||||
<div class="v-avatar-group">
|
||||
<VAvatar
|
||||
v-for="data in team.avatarGroup"
|
||||
:key="data.name"
|
||||
size="32"
|
||||
>
|
||||
<VImg :src="data.avatar" />
|
||||
|
||||
<VTooltip
|
||||
activator="parent"
|
||||
location="top"
|
||||
>
|
||||
{{ data.name }}
|
||||
</VTooltip>
|
||||
</VAvatar>
|
||||
</div>
|
||||
|
||||
<VSpacer />
|
||||
|
||||
<div class="d-flex align-center gap-2">
|
||||
<VChip
|
||||
v-for="data in team.chips"
|
||||
:key="data.title"
|
||||
label
|
||||
:color="data.color"
|
||||
size="small"
|
||||
class="font-weight-medium"
|
||||
>
|
||||
{{ data.title }}
|
||||
</VChip>
|
||||
</div>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
</VCol>
|
||||
</VRow>
|
||||
</template>
|
||||
Reference in New Issue
Block a user