Initial commit

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

View File

@@ -0,0 +1,106 @@
<script setup>
import themeselectionQr from '@images/pages/themeselection-qr.png'
const props = defineProps({
authCode: {
type: String,
required: false,
},
isDialogVisible: {
type: Boolean,
required: true,
},
})
const emit = defineEmits([
'update:isDialogVisible',
'submit',
])
const authCode = ref(structuredClone(toRaw(props.authCode)))
const formSubmit = () => {
if (authCode.value) {
emit('submit', authCode.value)
emit('update:isDialogVisible', false)
}
}
const resetAuthCode = () => {
authCode.value = structuredClone(toRaw(props.authCode))
emit('update:isDialogVisible', false)
}
</script>
<template>
<VDialog
:width="$vuetify.display.smAndDown ? 'auto' : 900"
:model-value="props.isDialogVisible"
@update:model-value="(val) => $emit('update:isDialogVisible', val)"
>
<!-- Dialog close btn -->
<DialogCloseBtn @click="$emit('update:isDialogVisible', false)" />
<VCard class="pa-2 pa-sm-10">
<VCardText>
<!-- 👉 Title -->
<h4 class="text-h4 text-center mb-6">
Add Authenticator App
</h4>
<h5 class="text-h5 mb-2">
Authenticator Apps
</h5>
<p class="text-body-1 mb-6">
Using an authenticator app like Google Authenticator, Microsoft Authenticator, Authy, or 1Password, scan the QR code. It will generate a 6 digit code for you to enter below.
</p>
<div class="mb-6">
<VImg
width="150"
:src="themeselectionQr"
class="mx-auto"
/>
</div>
<VAlert
title="ASDLKNASDA9AHS678dGhASD78AB"
text="If you are unable to scan the QR code, you can manually enter the secret key below."
variant="tonal"
color="warning"
/>
<VForm @submit.prevent="() => {}">
<AppTextField
v-model="authCode"
name="auth-code"
label="Enter Authentication Code"
placeholder="123 456"
class="mt-4 mb-6"
/>
<div class="d-flex justify-end flex-wrap gap-4">
<VBtn
color="secondary"
variant="tonal"
@click="resetAuthCode"
>
Cancel
</VBtn>
<VBtn
type="submit"
@click="formSubmit"
>
Continue
<VIcon
end
icon="tabler-arrow-right"
class="flip-in-rtl"
/>
</VBtn>
</div>
</VForm>
</VCardText>
</VCard>
</VDialog>
</template>

View File

@@ -0,0 +1,233 @@
<script setup>
import home from '@images/svg/home.svg'
import office from '@images/svg/office.svg'
const props = defineProps({
billingAddress: {
type: Object,
required: false,
default: () => ({
firstName: '',
lastName: '',
selectedCountry: null,
addressLine1: '',
addressLine2: '',
landmark: '',
contact: '',
country: null,
city: '',
state: '',
zipCode: null,
}),
},
isDialogVisible: {
type: Boolean,
required: true,
},
})
const emit = defineEmits([
'update:isDialogVisible',
'submit',
])
const billingAddress = ref(structuredClone(toRaw(props.billingAddress)))
const resetForm = () => {
emit('update:isDialogVisible', false)
billingAddress.value = structuredClone(toRaw(props.billingAddress))
}
const onFormSubmit = () => {
emit('update:isDialogVisible', false)
emit('submit', billingAddress.value)
}
const selectedAddress = ref('Home')
const addressTypes = [
{
icon: {
icon: home,
size: '28',
},
title: 'Home',
desc: 'Delivery Time (9am - 9pm)',
value: 'Home',
},
{
icon: {
icon: office,
size: '28',
},
title: 'Office',
desc: 'Delivery Time (9am - 5pm)',
value: 'Office',
},
]
</script>
<template>
<VDialog
:width="$vuetify.display.smAndDown ? 'auto' : 900 "
:model-value="props.isDialogVisible"
@update:model-value="val => $emit('update:isDialogVisible', val)"
>
<!-- 👉 Dialog close btn -->
<DialogCloseBtn @click="$emit('update:isDialogVisible', false)" />
<VCard
v-if="props.billingAddress"
class="pa-sm-10 pa-2"
>
<VCardText>
<!-- 👉 Title -->
<h4 class="text-h4 text-center mb-2">
{{ (props.billingAddress.addressLine1 || props.billingAddress.addressLine2) ? 'Edit' : 'Add New' }} Address
</h4>
<p class="text-body-1 text-center mb-6">
Add new address for express delivery
</p>
<div class="d-flex mb-6">
<CustomRadiosWithIcon
v-model:selected-radio="selectedAddress"
:radio-content="addressTypes"
:grid-column="{ sm: '6', cols: '12' }"
/>
</div>
<!-- 👉 Form -->
<VForm @submit.prevent="onFormSubmit">
<VRow>
<!-- 👉 First Name -->
<VCol
cols="12"
md="6"
>
<AppTextField
v-model="billingAddress.firstName"
label="First Name"
placeholder="John"
/>
</VCol>
<!-- 👉 Last Name -->
<VCol
cols="12"
md="6"
>
<AppTextField
v-model="billingAddress.lastName"
label="Last Name"
placeholder="Doe"
/>
</VCol>
<!-- 👉 Select Country -->
<VCol cols="12">
<AppSelect
v-model="billingAddress.selectedCountry"
label="Select Country"
placeholder="Select Country"
:items="['USA', 'Aus', 'Canada', 'NZ']"
/>
</VCol>
<!-- 👉 Address Line 1 -->
<VCol cols="12">
<AppTextField
v-model="billingAddress.addressLine1"
label="Address Line 1"
placeholder="12, Business Park"
/>
</VCol>
<!-- 👉 Address Line 2 -->
<VCol cols="12">
<AppTextField
v-model="billingAddress.addressLine2"
label="Address Line 2"
placeholder="Mall Road"
/>
</VCol>
<!-- 👉 Landmark -->
<VCol
cols="12"
md="6"
>
<AppTextField
v-model="billingAddress.landmark"
label="Landmark"
placeholder="Nr. Hard Rock Cafe"
/>
</VCol>
<!-- 👉 City -->
<VCol
cols="12"
md="6"
>
<AppTextField
v-model="billingAddress.city"
label="City"
placeholder="Los Angeles"
/>
</VCol>
<!-- 👉 State -->
<VCol
cols="12"
md="6"
>
<AppTextField
v-model="billingAddress.state"
label="State"
placeholder="California"
/>
</VCol>
<!-- 👉 Zip Code -->
<VCol
cols="12"
md="6"
>
<AppTextField
v-model="billingAddress.zipCode"
label="Zip Code"
placeholder="99950"
type="number"
/>
</VCol>
<VCol cols="12">
<VSwitch label="Use as a billing address?" />
</VCol>
<!-- 👉 Submit and Cancel button -->
<VCol
cols="12"
class="text-center"
>
<VBtn
type="submit"
class="me-3"
>
submit
</VBtn>
<VBtn
variant="tonal"
color="secondary"
@click="resetForm"
>
Cancel
</VBtn>
</VCol>
</VRow>
</VForm>
</VCardText>
</VCard>
</VDialog>
</template>

View File

@@ -0,0 +1,95 @@
<script setup>
const props = defineProps({
isDialogVisible: {
type: Boolean,
required: true,
},
permissionName: {
type: String,
required: false,
default: '',
},
})
const emit = defineEmits([
'update:isDialogVisible',
'update:permissionName',
])
const currentPermissionName = ref('')
const onReset = () => {
emit('update:isDialogVisible', false)
currentPermissionName.value = ''
}
const onSubmit = () => {
emit('update:isDialogVisible', false)
emit('update:permissionName', currentPermissionName.value)
}
watch(() => props, () => {
currentPermissionName.value = props.permissionName
})
</script>
<template>
<VDialog
:width="$vuetify.display.smAndDown ? 'auto' : 600"
:model-value="props.isDialogVisible"
@update:model-value="onReset"
>
<!-- 👉 dialog close btn -->
<DialogCloseBtn @click="onReset" />
<VCard class="pa-2 pa-sm-10">
<VCardText>
<!-- 👉 Title -->
<h4 class="text-h4 text-center mb-2">
{{ props.permissionName ? 'Edit' : 'Add' }} Permission
</h4>
<p class="text-body-1 text-center mb-6">
{{ props.permissionName ? 'Edit' : 'Add' }} permission as per your requirements.
</p>
<!-- 👉 Form -->
<VForm>
<VAlert
type="warning"
title="Warning!"
variant="tonal"
class="mb-6"
>
<template #text>
By {{ props.permissionName ? 'editing' : 'adding' }} the permission name, you might break the system permissions functionality.
</template>
</VAlert>
<!-- 👉 Role name -->
<div class="d-flex gap-4 mb-6 flex-wrap flex-column flex-sm-row">
<AppTextField
v-model="currentPermissionName"
placeholder="Enter Permission Name"
/>
<VBtn @click="onSubmit">
{{ props.permissionName ? 'Update' : 'Add' }}
</VBtn>
</div>
<VCheckbox label="Set as core permission" />
</VForm>
</VCardText>
</VCard>
</VDialog>
</template>
<style lang="scss">
.permission-table {
td {
border-block-end: 1px solid rgba(var(--v-border-color), var(--v-border-opacity));
padding-block: 0.5rem;
padding-inline: 0;
}
}
</style>

View File

@@ -0,0 +1,282 @@
<script setup>
import { VForm } from 'vuetify/components/VForm'
const props = defineProps({
rolePermissions: {
type: Object,
required: false,
default: () => ({
name: '',
permissions: [],
}),
},
isDialogVisible: {
type: Boolean,
required: true,
},
})
const emit = defineEmits([
'update:isDialogVisible',
'update:rolePermissions',
])
const permissions = ref([
{
name: 'User Management',
read: false,
write: false,
create: false,
},
{
name: 'Content Management',
read: false,
write: false,
create: false,
},
{
name: 'Disputes Management',
read: false,
write: false,
create: false,
},
{
name: 'Database Management',
read: false,
write: false,
create: false,
},
{
name: 'Financial Management',
read: false,
write: false,
create: false,
},
{
name: 'Reporting',
read: false,
write: false,
create: false,
},
{
name: 'API Control',
read: false,
write: false,
create: false,
},
{
name: 'Repository Management',
read: false,
write: false,
create: false,
},
{
name: 'Payroll',
read: false,
write: false,
create: false,
},
])
const isSelectAll = ref(false)
const role = ref('')
const refPermissionForm = ref()
const checkedCount = computed(() => {
let counter = 0
permissions.value.forEach(permission => {
Object.entries(permission).forEach(([key, value]) => {
if (key !== 'name' && value)
counter++
})
})
return counter
})
const isIndeterminate = computed(() => checkedCount.value > 0 && checkedCount.value < permissions.value.length * 3)
watch(isSelectAll, val => {
permissions.value = permissions.value.map(permission => ({
...permission,
read: val,
write: val,
create: val,
}))
})
watch(isIndeterminate, () => {
if (!isIndeterminate.value)
isSelectAll.value = false
})
watch(permissions, () => {
if (checkedCount.value === permissions.value.length * 3)
isSelectAll.value = true
}, { deep: true })
watch(() => props, () => {
if (props.rolePermissions && props.rolePermissions.permissions.length) {
role.value = props.rolePermissions.name
permissions.value = permissions.value.map(permission => {
const rolePermission = props.rolePermissions?.permissions.find(item => item.name === permission.name)
if (rolePermission) {
return {
...permission,
...rolePermission,
}
}
return permission
})
}
})
const onSubmit = () => {
const rolePermissions = {
name: role.value,
permissions: permissions.value,
}
emit('update:rolePermissions', rolePermissions)
emit('update:isDialogVisible', false)
isSelectAll.value = false
refPermissionForm.value?.reset()
}
const onReset = () => {
emit('update:isDialogVisible', false)
isSelectAll.value = false
refPermissionForm.value?.reset()
}
</script>
<template>
<VDialog
:width="$vuetify.display.smAndDown ? 'auto' : 900"
:model-value="props.isDialogVisible"
@update:model-value="onReset"
>
<!-- 👉 Dialog close btn -->
<DialogCloseBtn @click="onReset" />
<VCard class="pa-sm-10 pa-2">
<VCardText>
<!-- 👉 Title -->
<h4 class="text-h4 text-center mb-2">
{{ props.rolePermissions.name ? 'Edit' : 'Add New' }} Role
</h4>
<p class="text-body-1 text-center mb-6">
Set Role Permissions
</p>
<!-- 👉 Form -->
<VForm ref="refPermissionForm">
<!-- 👉 Role name -->
<AppTextField
v-model="role"
label="Role Name"
placeholder="Enter Role Name"
/>
<h5 class="text-h5 my-6">
Role Permissions
</h5>
<!-- 👉 Role Permissions -->
<VTable class="permission-table text-no-wrap mb-6">
<!-- 👉 Admin -->
<tr>
<td>
<h6 class="text-h6">
Administrator Access
</h6>
</td>
<td colspan="3">
<div class="d-flex justify-end">
<VCheckbox
v-model="isSelectAll"
v-model:indeterminate="isIndeterminate"
label="Select All"
/>
</div>
</td>
</tr>
<!-- 👉 Other permission loop -->
<template
v-for="permission in permissions"
:key="permission.name"
>
<tr>
<td>
<h6 class="text-h6">
{{ permission.name }}
</h6>
</td>
<td>
<div class="d-flex justify-end">
<VCheckbox
v-model="permission.read"
label="Read"
/>
</div>
</td>
<td>
<div class="d-flex justify-end">
<VCheckbox
v-model="permission.write"
label="Write"
/>
</div>
</td>
<td>
<div class="d-flex justify-end">
<VCheckbox
v-model="permission.create"
label="Create"
/>
</div>
</td>
</tr>
</template>
</VTable>
<!-- 👉 Actions button -->
<div class="d-flex align-center justify-center gap-4">
<VBtn @click="onSubmit">
Submit
</VBtn>
<VBtn
color="secondary"
variant="tonal"
@click="onReset"
>
Cancel
</VBtn>
</div>
</VForm>
</VCardText>
</VCard>
</VDialog>
</template>
<style lang="scss">
.permission-table {
td {
border-block-end: 1px solid rgba(var(--v-border-color), var(--v-border-opacity));
padding-block: 0.5rem;
.v-checkbox {
min-inline-size: 4.75rem;
}
&:not(:first-child) {
padding-inline: 0.5rem;
}
.v-label {
white-space: nowrap;
}
}
}
</style>

View File

@@ -0,0 +1,117 @@
<script setup>
import americanExDark from '@images/icons/payments/img/ae-dark.png'
import americanExLight from '@images/icons/payments/img/american-express.png'
import dcDark from '@images/icons/payments/img/dc-dark.png'
import dcLight from '@images/icons/payments/img/dc-light.png'
import jcbDark from '@images/icons/payments/img/jcb-dark.png'
import jcbLight from '@images/icons/payments/img/jcb-light.png'
import masterCardDark from '@images/icons/payments/img/master-dark.png'
import masterCardLight from '@images/icons/payments/img/mastercard.png'
import visaDark from '@images/icons/payments/img/visa-dark.png'
import visaLight from '@images/icons/payments/img/visa-light.png'
const props = defineProps({
isDialogVisible: {
type: Boolean,
required: true,
},
})
const emit = defineEmits(['update:isDialogVisible'])
const visa = useGenerateImageVariant(visaLight, visaDark)
const masterCard = useGenerateImageVariant(masterCardLight, masterCardDark)
const americanEx = useGenerateImageVariant(americanExLight, americanExDark)
const jcb = useGenerateImageVariant(jcbLight, jcbDark)
const dc = useGenerateImageVariant(dcLight, dcDark)
const dialogVisibleUpdate = val => {
emit('update:isDialogVisible', val)
}
const paymentMethodsData = [
{
title: 'Visa',
type: 'Credit Card',
img: visa,
},
{
title: 'American Express',
type: 'Credit Card',
img: americanEx,
},
{
title: 'Mastercard',
type: 'Credit Card',
img: masterCard,
},
{
title: 'JCB',
type: 'Credit Card',
img: jcb,
},
{
title: 'Diners Club',
type: 'Credit Card',
img: dc,
},
]
</script>
<template>
<VDialog
:model-value="props.isDialogVisible"
:width="$vuetify.display.smAndDown ? 'auto' : 750"
@update:model-value="dialogVisibleUpdate"
>
<!-- 👉 dialog close btn -->
<DialogCloseBtn @click="emit('update:isDialogVisible', false)" />
<VCard class="pa-2 pa-sm-10">
<VCardText>
<!-- 👉 Title -->
<h4 class="text-h4 text-center mb-2">
Add payment methods
</h4>
<p class="text-body-1 text-center mb-6">
Supported payment methods
</p>
<div
v-for="(item, index) in paymentMethodsData"
:key="index"
>
<div class="d-flex justify-space-between align-center py-4 gap-x-4">
<div class="d-flex align-center">
<VImg
:src="item.img.value"
height="30"
width="50"
class="me-4"
/>
<h6 class="text-h6">
{{ item.title }}
</h6>
</div>
<div class="d-none d-sm-block text-body-1">
{{ item.type }}
</div>
</div>
<VDivider v-if="index !== paymentMethodsData.length - 1" />
</div>
</VCardText>
</VCard>
</VDialog>
</template>
<style lang="scss">
.refer-link-input {
.v-field--appended {
padding-inline-end: 0;
}
.v-field__append-inner {
padding-block-start: 0.125rem;
}
}
</style>

View File

@@ -0,0 +1,146 @@
<script setup>
const props = defineProps({
cardDetails: {
type: Object,
required: false,
default: () => ({
number: '',
name: '',
expiry: '',
cvv: '',
isPrimary: false,
type: '',
}),
},
isDialogVisible: {
type: Boolean,
required: true,
},
})
const emit = defineEmits([
'submit',
'update:isDialogVisible',
])
const cardDetails = ref(structuredClone(toRaw(props.cardDetails)))
watch(() => props, () => {
cardDetails.value = structuredClone(toRaw(props.cardDetails))
})
const formSubmit = () => {
emit('submit', cardDetails.value)
}
const dialogModelValueUpdate = val => {
emit('update:isDialogVisible', val)
}
</script>
<template>
<VDialog
:width="$vuetify.display.smAndDown ? 'auto' : 600"
:model-value="props.isDialogVisible"
@update:model-value="dialogModelValueUpdate"
>
<!-- Dialog close btn -->
<DialogCloseBtn @click="dialogModelValueUpdate(false)" />
<VCard class="pa-2 pa-sm-10">
<!-- 👉 Title -->
<VCardItem class="text-center">
<VCardTitle>
<h4 class="text-h4 mb-2">
{{ props.cardDetails.name ? 'Edit Card' : 'Add New Card' }}
</h4>
</VCardTitle>
<p class="text-body-1 mb-0">
{{ props.cardDetails.name ? 'Edit your saved card details' : 'Add card for future billing' }}
</p>
</VCardItem>
<VCardText class="pt-6">
<VForm @submit.prevent="() => {}">
<VRow>
<!-- 👉 Card Number -->
<VCol cols="12">
<AppTextField
v-model="cardDetails.number"
label="Card Number"
placeholder="1356 3215 6548 7898"
type="number"
/>
</VCol>
<!-- 👉 Card Name -->
<VCol
cols="12"
md="6"
>
<AppTextField
v-model="cardDetails.name"
label="Name"
placeholder="John Doe"
/>
</VCol>
<!-- 👉 Card Expiry -->
<VCol
cols="12"
md="3"
>
<AppTextField
v-model="cardDetails.expiry"
label="Expiry Date"
placeholder="MM/YY"
/>
</VCol>
<!-- 👉 Card CVV -->
<VCol
cols="12"
md="3"
>
<AppTextField
v-model="cardDetails.cvv"
type="number"
label="CVV Code"
placeholder="654"
/>
</VCol>
<!-- 👉 Card Primary Set -->
<VCol cols="12">
<VSwitch
v-model="cardDetails.isPrimary"
label="Save Card for future billing?"
/>
</VCol>
<!-- 👉 Card actions -->
<VCol
cols="12"
class="text-center"
>
<VBtn
class="me-4"
type="submit"
@click="formSubmit"
>
Submit
</VBtn>
<VBtn
color="secondary"
variant="tonal"
@click="$emit('update:isDialogVisible', false)"
>
Cancel
</VBtn>
</VCol>
</VRow>
</VForm>
</VCardText>
</VCard>
</VDialog>
</template>

View File

@@ -0,0 +1,165 @@
<script setup>
const props = defineProps({
confirmationQuestion: {
type: String,
required: true,
},
isDialogVisible: {
type: Boolean,
required: true,
},
confirmTitle: {
type: String,
required: true,
},
confirmMsg: {
type: String,
required: true,
},
cancelTitle: {
type: String,
required: true,
},
cancelMsg: {
type: String,
required: true,
},
})
const emit = defineEmits([
'update:isDialogVisible',
'confirm',
])
const unsubscribed = ref(false)
const cancelled = ref(false)
const updateModelValue = val => {
emit('update:isDialogVisible', val)
}
const onConfirmation = () => {
emit('confirm', true)
updateModelValue(false)
unsubscribed.value = true
}
const onCancel = () => {
emit('confirm', false)
emit('update:isDialogVisible', false)
cancelled.value = true
}
</script>
<template>
<!-- 👉 Confirm Dialog -->
<VDialog
max-width="500"
:model-value="props.isDialogVisible"
@update:model-value="updateModelValue"
>
<VCard class="text-center px-10 py-6">
<VCardText>
<VBtn
icon
variant="outlined"
color="warning"
class="my-4"
style=" block-size: 88px;inline-size: 88px; pointer-events: none;"
>
<span class="text-5xl">!</span>
</VBtn>
<h6 class="text-lg font-weight-medium">
{{ props.confirmationQuestion }}
</h6>
</VCardText>
<VCardText class="d-flex align-center justify-center gap-2">
<VBtn
variant="elevated"
@click="onConfirmation"
>
Confirm
</VBtn>
<VBtn
color="secondary"
variant="tonal"
@click="onCancel"
>
Cancel
</VBtn>
</VCardText>
</VCard>
</VDialog>
<!-- Unsubscribed -->
<VDialog
v-model="unsubscribed"
max-width="500"
>
<VCard>
<VCardText class="text-center px-10 py-6">
<VBtn
icon
variant="outlined"
color="success"
class="my-4"
style=" block-size: 88px;inline-size: 88px; pointer-events: none;"
>
<VIcon
icon="tabler-check"
size="38"
/>
</VBtn>
<h1 class="text-h4 mb-4">
{{ props.confirmTitle }}
</h1>
<p>{{ props.confirmMsg }}</p>
<VBtn
color="success"
@click="unsubscribed = false"
>
Ok
</VBtn>
</VCardText>
</VCard>
</VDialog>
<!-- Cancelled -->
<VDialog
v-model="cancelled"
max-width="500"
>
<VCard>
<VCardText class="text-center px-10 py-6">
<VBtn
icon
variant="outlined"
color="error"
class="my-4"
style=" block-size: 88px;inline-size: 88px; pointer-events: none;"
>
<span class="text-5xl font-weight-light">X</span>
</VBtn>
<h1 class="text-h4 mb-4">
{{ props.cancelTitle }}
</h1>
<p>{{ props.cancelMsg }}</p>
<VBtn
color="success"
@click="cancelled = false"
>
Ok
</VBtn>
</VCardText>
</VCard>
</VDialog>
</template>

View File

@@ -0,0 +1,463 @@
<script setup>
import laptopGirl from '@images/illustrations/laptop-girl.png'
const props = defineProps({
isDialogVisible: {
type: Boolean,
required: true,
},
})
const emit = defineEmits([
'update:isDialogVisible',
'updatedData',
])
const currentStep = ref(0)
const createApp = [
{
icon: 'tabler-file-text',
title: 'DETAILS',
subtitle: 'Enter Details',
},
{
icon: 'tabler-id',
title: 'FRAMEWORKS',
subtitle: 'Select Framework',
},
{
icon: 'tabler-database',
title: 'DATABASE',
subtitle: 'Select Database',
},
{
icon: 'tabler-credit-card',
title: 'BILLING',
subtitle: 'Payment Details',
},
{
icon: 'tabler-check',
title: 'SUBMIT',
subtitle: 'Submit',
},
]
const categories = [
{
icon: 'tabler-file-text',
color: 'info',
title: 'CRM Application',
subtitle: 'Scales with any business',
slug: 'crm-application',
},
{
icon: 'tabler-shopping-cart',
color: 'success',
title: 'Ecommerce Platforms',
subtitle: 'Grow Your Business With App',
slug: 'ecommerce-application',
},
{
icon: 'tabler-device-laptop',
color: 'error',
title: 'Online Learning platform',
subtitle: 'Start learning today',
slug: 'online-learning-application',
},
]
const frameworks = [
{
icon: 'tabler-brand-react-native',
color: 'info',
title: 'React Native',
subtitle: 'Create truly native apps',
slug: 'react-framework',
},
{
icon: 'tabler-brand-angular',
color: 'error',
title: 'Angular',
subtitle: 'Most suited for your application',
slug: 'angular-framework',
},
{
icon: 'tabler-brand-vue',
color: 'success',
title: 'Vue',
subtitle: 'JS web frameworks',
slug: 'js-framework',
},
{
icon: 'tabler-brand-html5',
color: 'warning',
title: 'HTML',
subtitle: 'Progressive Framework',
slug: 'html-framework',
},
]
const databases = [
{
icon: 'tabler-brand-firebase',
color: 'error',
title: 'Firebase',
subtitle: 'Cloud Firestore',
slug: 'firebase-database',
},
{
icon: 'tabler-brand-amazon',
color: 'warning',
title: 'AWS',
subtitle: 'Amazon Fast NoSQL Database',
slug: 'aws-database',
},
{
icon: 'tabler-database',
color: 'info',
title: 'MySQL',
subtitle: 'Basic MySQL database',
slug: 'mysql-database',
},
]
const createAppData = ref({
category: 'crm-application',
framework: 'js-framework',
database: 'firebase-database',
cardNumber: null,
cardName: '',
cardExpiry: '',
cardCvv: '',
isSave: true,
})
const dialogVisibleUpdate = val => {
emit('update:isDialogVisible', val)
currentStep.value = 0
}
watch(() => props, () => {
if (!props.isDialogVisible)
currentStep.value = 0
})
const onSubmit = () => {
// eslint-disable-next-line no-alert
alert('submitted...!!')
emit('updatedData', createAppData.value)
}
</script>
<template>
<VDialog
:model-value="props.isDialogVisible"
max-width="900"
min-height="590"
@update:model-value="dialogVisibleUpdate"
>
<!-- 👉 dialog close btn -->
<DialogCloseBtn
size="small"
@click="emit('update:isDialogVisible', false)"
/>
<VCard
class="create-app-dialog"
min-height="590"
>
<VCardText class="pa-5 pa-sm-16">
<!-- 👉 Title -->
<h4 class="text-h4 text-center mb-2">
Create App
</h4>
<p class="text-body-1 text-center mb-6">
Provide data with this form to create your app.
</p>
<VRow>
<VCol
cols="12"
sm="5"
md="4"
lg="3"
>
<AppStepper
v-model:current-step="currentStep"
direction="vertical"
:items="createApp"
icon-size="22"
class="stepper-icon-step-bg"
/>
</VCol>
<VCol
cols="12"
sm="7"
md="8"
lg="9"
>
<VWindow
v-model="currentStep"
class="disable-tab-transition stepper-content"
>
<!-- 👉 category -->
<VWindowItem>
<AppTextField
label="Application Name"
placeholder="Application Name"
/>
<h5 class="text-h5 mt-6 mb-4">
Category
</h5>
<VRadioGroup v-model="createAppData.category">
<VList class="card-list">
<VListItem
v-for="category in categories"
:key="category.title"
@click="createAppData.category = category.slug"
>
<template #prepend>
<VAvatar
size="46"
rounded
variant="tonal"
:color="category.color"
>
<VIcon
:icon="category.icon"
size="30"
/>
</VAvatar>
</template>
<VListItemTitle>
<h6 class="text-h6 mb-1">
{{ category.title }}
</h6>
</VListItemTitle>
<VListItemSubtitle>
{{ category.subtitle }}
</VListItemSubtitle>
<template #append>
<VRadio :value="category.slug" />
</template>
</VListItem>
</VList>
</VRadioGroup>
</VWindowItem>
<!-- 👉 Frameworks -->
<VWindowItem>
<h5 class="text-h5 mb-4">
Select Framework
</h5>
<VRadioGroup v-model="createAppData.framework">
<VList class="card-list">
<VListItem
v-for="framework in frameworks"
:key="framework.title"
@click="createAppData.framework = framework.slug"
>
<template #prepend>
<VAvatar
size="46"
rounded
variant="tonal"
:color="framework.color"
>
<VIcon
:icon="framework.icon"
size="30"
/>
</VAvatar>
</template>
<VListItemTitle>
<h6 class="text-h6 mb-1">
{{ framework.title }}
</h6>
</VListItemTitle>
<VListItemSubtitle>
{{ framework.subtitle }}
</VListItemSubtitle>
<template #append>
<VRadio :value="framework.slug" />
</template>
</VListItem>
</VList>
</VRadioGroup>
</VWindowItem>
<!-- 👉 Database Engine -->
<VWindowItem>
<AppTextField
label="Database Name"
placeholder="UserDB"
/>
<h5 class="text-h5 mt-6 mb-4">
Select Database Engine
</h5>
<VRadioGroup v-model="createAppData.database">
<VList class="card-list">
<VListItem
v-for="database in databases"
:key="database.title"
@click="createAppData.database = database.slug"
>
<template #prepend>
<VAvatar
size="46"
rounded
variant="tonal"
:color="database.color"
>
<VIcon
:icon="database.icon"
size="30"
/>
</VAvatar>
</template>
<VListItemTitle>
<h6 class="text-h6 mb-1">
{{ database.title }}
</h6>
</VListItemTitle>
<VListItemSubtitle>
{{ database.subtitle }}
</VListItemSubtitle>
<template #append>
<VRadio :value="database.slug" />
</template>
</VListItem>
</VList>
</VRadioGroup>
</VWindowItem>
<!-- 👉 Billing form -->
<VWindowItem>
<h6 class="text-h6 mb-6">
Payment Details
</h6>
<VForm>
<VRow>
<VCol cols="12">
<AppTextField
v-model="createAppData.cardNumber"
label="Card Number"
placeholder="1234 1234 1234 1234"
type="number"
/>
</VCol>
<VCol
cols="12"
md="6"
>
<AppTextField
v-model="createAppData.cardName"
label="Name on Card"
placeholder="John Doe"
/>
</VCol>
<VCol
cols="6"
md="3"
>
<AppTextField
v-model="createAppData.cardExpiry"
label="Expiry"
placeholder="MM/YY"
/>
</VCol>
<VCol
cols="6"
md="3"
>
<AppTextField
v-model="createAppData.cardCvv"
label="CVV"
placeholder="123"
/>
</VCol>
<VCol cols="12">
<VSwitch
v-model="createAppData.isSave"
label="Save Card for future billing?"
/>
</VCol>
</VRow>
</VForm>
</VWindowItem>
<VWindowItem class="text-center">
<h5 class="text-h5 mb-1">
Submit
</h5>
<p class="text-sm mb-4">
Submit to kickstart your project.
</p>
<VImg
:src="laptopGirl"
width="176"
class="mx-auto"
/>
</VWindowItem>
</VWindow>
<div class="d-flex justify-space-between mt-6">
<VBtn
variant="tonal"
color="secondary"
:disabled="currentStep === 0"
@click="currentStep--"
>
<VIcon
icon="tabler-arrow-left"
start
class="flip-in-rtl"
/>
Previous
</VBtn>
<VBtn
v-if="createApp.length - 1 === currentStep"
color="success"
@click="onSubmit"
>
submit
</VBtn>
<VBtn
v-else
@click="currentStep++"
>
Next
<VIcon
icon="tabler-arrow-right"
end
class="flip-in-rtl"
/>
</VBtn>
</div>
</VCol>
</VRow>
</VCardText>
</VCard>
</VDialog>
</template>
<style lang="scss">
.stepper-content .card-list {
--v-card-list-gap: 16px;
}
</style>

View File

@@ -0,0 +1,90 @@
<script setup>
const props = defineProps({
mobileNumber: {
type: String,
required: false,
},
isDialogVisible: {
type: Boolean,
required: true,
},
})
const emit = defineEmits([
'update:isDialogVisible',
'submit',
])
const phoneNumber = ref(structuredClone(toRaw(props.mobileNumber)))
const formSubmit = () => {
if (phoneNumber.value) {
emit('submit', phoneNumber.value)
emit('update:isDialogVisible', false)
}
}
const resetPhoneNumber = () => {
phoneNumber.value = structuredClone(toRaw(props.mobileNumber))
emit('update:isDialogVisible', false)
}
const dialogModelValueUpdate = val => {
emit('update:isDialogVisible', val)
}
</script>
<template>
<VDialog
:width="$vuetify.display.smAndDown ? 'auto' : 900"
:model-value="props.isDialogVisible"
@update:model-value="dialogModelValueUpdate"
>
<!-- Dialog close btn -->
<DialogCloseBtn @click="dialogModelValueUpdate(false)" />
<VCard class="pa-2 pa-sm-10">
<VCardText>
<!-- 👉 Title -->
<h5 class="text-h5 mb-2">
Verify Your Mobile Number for SMS
</h5>
<p class="text-body-1 mb-6">
Enter your mobile phone number with country code and we will send you a verification code.
</p>
<VForm @submit.prevent="() => {}">
<AppTextField
v-model="phoneNumber"
name="mobile"
label="Phone Number"
placeholder="+1 123 456 7890"
type="number"
class="mb-6"
/>
<div class="d-flex flex-wrap justify-end gap-4">
<VBtn
color="secondary"
variant="tonal"
@click="resetPhoneNumber"
>
Cancel
</VBtn>
<VBtn
type="submit"
@click="formSubmit"
>
continue
<VIcon
end
icon="tabler-arrow-right"
class="flip-in-rtl"
/>
</VBtn>
</div>
</VForm>
</VCardText>
</VCard>
</VDialog>
</template>

View File

@@ -0,0 +1,159 @@
<script setup>
import americanExDark from '@images/icons/payments/img/ae-dark.png'
import americanExLight from '@images/icons/payments/img/american-express.png'
import dcDark from '@images/icons/payments/img/dc-dark.png'
import dcLight from '@images/icons/payments/img/dc-light.png'
import jcbDark from '@images/icons/payments/img/jcb-dark.png'
import jcbLight from '@images/icons/payments/img/jcb-light.png'
import masterCardDark from '@images/icons/payments/img/master-dark.png'
import masterCardLight from '@images/icons/payments/img/mastercard.png'
import visaDark from '@images/icons/payments/img/visa-dark.png'
import visaLight from '@images/icons/payments/img/visa-light.png'
const props = defineProps({
isDialogVisible: {
type: Boolean,
required: true,
},
})
const emit = defineEmits(['update:isDialogVisible'])
const visa = useGenerateImageVariant(visaLight, visaDark)
const masterCard = useGenerateImageVariant(masterCardLight, masterCardDark)
const americanEx = useGenerateImageVariant(americanExLight, americanExDark)
const jcb = useGenerateImageVariant(jcbLight, jcbDark)
const dc = useGenerateImageVariant(dcLight, dcDark)
const dialogVisibleUpdate = val => {
emit('update:isDialogVisible', val)
}
const paymentProvidersData = [
{
title: 'Adyen',
providers: [
visa,
masterCard,
americanEx,
jcb,
dc,
],
},
{
title: '2Checkout',
providers: [
visa,
americanEx,
jcb,
dc,
],
},
{
title: 'Airpay',
providers: [
visa,
americanEx,
masterCard,
jcb,
],
},
{
title: 'Authorize.net',
providers: [
americanEx,
jcb,
dc,
],
},
{
title: 'Bambora',
providers: [
masterCard,
americanEx,
jcb,
],
},
{
title: 'Bambora',
providers: [
visa,
masterCard,
americanEx,
jcb,
dc,
],
},
{
title: 'Chase Paymentech (Orbital)',
providers: [
visa,
americanEx,
jcb,
dc,
],
},
{
title: 'Checkout.com',
providers: [
visa,
masterCard,
],
},
]
</script>
<template>
<VDialog
:model-value="props.isDialogVisible"
:width="$vuetify.display.smAndDown ? 'auto' : 900"
@update:model-value="dialogVisibleUpdate"
>
<DialogCloseBtn @click="emit('update:isDialogVisible', false)" />
<VCard class="pa-2 pa-sm-10">
<VCardText>
<!-- 👉 Title -->
<h4 class="text-h4 text-center mb-2">
Select Payment Providers
</h4>
<p class="text-body-1 text-center mb-6">
Third-party payment providers
</p>
<div
v-for="(item, index) in paymentProvidersData"
:key="index"
>
<div class="d-flex flex-column flex-sm-row justify-space-between gap-4 flex-wrap py-4">
<h6 class="text-h6">
{{ item.title }}
</h6>
<div class="d-flex gap-4 flex-wrap">
<img
v-for="(img, iterator) in item.providers"
:key="iterator"
:src="img.value"
height="30"
width="50"
>
</div>
</div>
<VDivider v-if="index !== paymentProvidersData.length - 1" />
</div>
</VCardText>
</VCard>
</VDialog>
</template>
<style lang="scss">
.refer-link-input {
.v-field--appended {
padding-inline-end: 0;
}
.v-field__append-inner {
padding-block-start: 0.125rem;
}
}
</style>

View File

@@ -0,0 +1,31 @@
<script setup>
const props = defineProps({
isDialogVisible: {
type: Boolean,
required: true,
},
})
const emit = defineEmits(['update:isDialogVisible'])
const dialogVisibleUpdate = val => {
emit('update:isDialogVisible', val)
}
</script>
<template>
<VDialog
:model-value="props.isDialogVisible"
:width="$vuetify.display.smAndDown ? 'auto' : 1200"
@update:model-value="dialogVisibleUpdate"
>
<!-- 👉 Dialog close btn -->
<DialogCloseBtn @click="$emit('update:isDialogVisible', false)" />
<VCard class="pricing-dialog pa-2 pa-sm-10">
<VCardText>
<AppPricing md="4" />
</VCardText>
</VCard>
</VDialog>
</template>

View File

@@ -0,0 +1,178 @@
<script setup>
import keyboard from '@images/svg/keyboard.svg'
import paper from '@images/svg/paper-send.svg'
import rocket from '@images/svg/rocket.svg'
import { themeConfig } from '@themeConfig'
const props = defineProps({
isDialogVisible: {
type: Boolean,
required: true,
},
})
const emit = defineEmits(['update:isDialogVisible'])
const dialogVisibleUpdate = val => {
emit('update:isDialogVisible', val)
}
const referAndEarnSteps = [
{
icon: paper,
title: 'Send Invitation 👍🏻',
subtitle: 'Send your referral link to your friend',
},
{
icon: keyboard,
title: 'Registration 😎',
subtitle: 'Let them register to our services',
},
{
icon: rocket,
title: 'Free Trial 🎉',
subtitle: 'Your friend will get 30 days free trial',
},
]
</script>
<template>
<VDialog
:model-value="props.isDialogVisible"
:width="$vuetify.display.smAndDown ? 'auto' : 800"
@update:model-value="dialogVisibleUpdate"
>
<!-- 👉 Dialog close btn -->
<DialogCloseBtn @click="$emit('update:isDialogVisible', false)" />
<VCard class="pa-2 pa-sm-10">
<VCardText>
<h4 class="text-h4 text-center mb-2">
Refer & Earn
</h4>
<p class="text-body-1 mb-6 text-center">
Invite your friend to <span class="text-capitalize">{{ themeConfig.app.title }}</span>, if they sign up, you and your friend will get 30 days free trial
</p>
<VRow class="text-center mt-8">
<VCol
v-for="step in referAndEarnSteps"
:key="step.title"
cols="12"
sm="4"
>
<VAvatar
variant="tonal"
size="88"
color="primary"
rounded
>
<VIcon
size="40"
:icon="step.icon"
/>
</VAvatar>
<h5 class="text-h5 mt-4 mb-2">
{{ step.title }}
</h5>
<div>{{ step.subtitle }}</div>
</VCol>
</VRow>
<VDivider class="mt-12 mb-6" />
<h5 class="text-h5 mb-6">
Invite your friends
</h5>
<VForm
class="d-flex align-center flex-wrap gap-4"
@submit.prevent="() => {}"
>
<AppTextField
placeholder="johnDoe@gmail.com"
label="Enter your friend's email address and invite them to join Vuexy 😍"
/>
<VBtn
class="align-self-end"
type="submit"
>
Send
</VBtn>
</VForm>
<h5 class="text-h5 my-6">
Share the referral link
</h5>
<VForm
class="d-flex align-center flex-wrap gap-4"
@submit.prevent="() => {}"
>
<AppTextField
placeholder="http://pixinvent.link"
label="You can also copy and send it or share it on your social media. 🚀"
class="refer-link-input"
>
<template #append-inner>
<VBtn variant="text">
Copy link
</VBtn>
</template>
</AppTextField>
<div class="d-flex align-self-end gap-1">
<VBtn
icon
class="rounded"
color="#3B5998"
size="38"
>
<VIcon
color="white"
icon="tabler-brand-facebook"
size="22"
/>
</VBtn>
<VBtn
icon
class="rounded"
color="#55ACEE"
size="38"
>
<VIcon
color="white"
icon="tabler-brand-twitter"
size="22"
/>
</VBtn>
<VBtn
icon
class="rounded"
color="#007BB6"
size="38"
>
<VIcon
color="white"
icon="tabler-brand-linkedin"
size="22"
/>
</VBtn>
</div>
</VForm>
</VCardText>
</VCard>
</VDialog>
</template>
<style lang="scss">
.refer-link-input {
.v-field--appended {
padding-inline-end: 0;
}
}
</style>

View File

@@ -0,0 +1,186 @@
<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'
const props = defineProps({
isDialogVisible: {
type: Boolean,
required: true,
},
})
const emit = defineEmits(['update:isDialogVisible'])
const dialogVisibleUpdate = val => {
emit('update:isDialogVisible', val)
}
const membersList = [
{
avatar: avatar1,
name: 'Lester Palmer',
email: 'jerrod98@gmail.com',
permission: 'Can Edit',
},
{
avatar: avatar2,
name: 'Mattie Blair',
email: 'prudence.boehm@yahoo.com',
permission: 'Owner',
},
{
avatar: avatar3,
name: 'Marvin Wheeler',
email: 'rumet@jujpejah.net',
permission: 'Can Comment',
},
{
avatar: avatar4,
name: 'Nannie Ford',
email: 'negza@nuv.io',
permission: 'Can View',
},
{
avatar: avatar5,
name: 'Julian Murphy',
email: 'lunebame@umdomgu.net',
permission: 'Can Edit',
},
{
avatar: avatar6,
name: 'Sophie Gilbert',
email: 'ha@sugit.gov',
permission: 'Can View',
},
{
avatar: avatar7,
name: 'Chris Watkins',
email: 'zokap@mak.org',
permission: 'Can Comment',
},
{
avatar: avatar8,
name: 'Adelaide Nichols',
email: 'ujinomu@jigo.com',
permission: 'Can Edit',
},
]
</script>
<template>
<VDialog
:model-value="props.isDialogVisible"
:width="$vuetify.display.smAndDown ? 'auto' : 900"
@update:model-value="dialogVisibleUpdate"
>
<!-- 👉 Dialog close btn -->
<DialogCloseBtn @click="$emit('update:isDialogVisible', false)" />
<VCard class="share-project-dialog pa-2 pa-sm-10">
<VCardText>
<h4 class="text-h4 text-center mb-2">
Share Project
</h4>
<p class="text-body-1 text-center mb-6">
Share project with a team members
</p>
<AppAutocomplete
label="Add Members"
:items="membersList"
item-title="name"
item-value="name"
placeholder="Add project members..."
>
<template #item="{ props: listItemProp, item }">
<VListItem v-bind="listItemProp">
<template #prepend>
<VAvatar
:image="item.raw.avatar"
size="30"
/>
</template>
</VListItem>
</template>
</AppAutocomplete>
<h5 class="text-h5 mb-4 mt-6">
8 Members
</h5>
<VList class="card-list">
<VListItem
v-for="member in membersList"
:key="member.name"
>
<template #prepend>
<VAvatar :image="member.avatar" />
</template>
<VListItemTitle>
{{ member.name }}
</VListItemTitle>
<VListItemSubtitle>
{{ member.email }}
</VListItemSubtitle>
<template #append>
<VBtn
variant="text"
color="secondary"
:icon="$vuetify.display.xs"
>
<span class="d-none d-sm-block me-1">{{ member.permission }}</span>
<VIcon icon="tabler-chevron-down" />
<VMenu activator="parent">
<VList :selected="[member.permission]">
<VListItem
v-for="(item, index) in ['Owner', 'Can Edit', 'Can Comment', 'Can View']"
:key="index"
:value="item"
>
<VListItemTitle>{{ item }}</VListItemTitle>
</VListItem>
</VList>
</VMenu>
</VBtn>
</template>
</VListItem>
</VList>
<div class="d-flex align-center justify-center justify-sm-space-between flex-wrap gap-3 mt-6">
<h6 class="text-h6 font-weight-medium d-flex align-start">
<VIcon
icon="tabler-users"
class="me-2"
size="20"
/>
<div>Public to Vuexy - Pixinvent</div>
</h6>
<VBtn
class="text-capitalize"
prepend-icon="tabler-link"
>
Copy Project Link
</VBtn>
</div>
</VCardText>
</VCard>
</VDialog>
</template>
<style lang="scss">
.share-project-dialog {
.card-list {
--v-card-list-gap: 1rem;
}
}
</style>

View File

@@ -0,0 +1,123 @@
<script setup>
const props = defineProps({
isDialogVisible: {
type: Boolean,
required: true,
default: false,
},
smsCode: {
type: String,
required: false,
default: '',
},
authAppCode: {
type: String,
required: false,
default: '',
},
})
const emit = defineEmits(['update:isDialogVisible'])
const authMethods = [
{
icon: 'tabler-settings',
title: 'Authenticator Apps',
desc: 'Get code from an app like Google Authenticator or Microsoft Authenticator.',
value: 'authApp',
},
{
icon: 'tabler-message',
title: 'SMS',
desc: 'We will send a code via SMS if you need to use your backup login method.',
value: 'sms',
},
]
const selectedMethod = ref('authApp')
const isAuthAppDialogVisible = ref(false)
const isSmsDialogVisible = ref(false)
const openSelectedMethodDialog = () => {
if (selectedMethod.value === 'authApp') {
isAuthAppDialogVisible.value = true
isSmsDialogVisible.value = false
emit('update:isDialogVisible', false)
}
if (selectedMethod.value === 'sms') {
isAuthAppDialogVisible.value = false
isSmsDialogVisible.value = true
emit('update:isDialogVisible', false)
}
}
</script>
<template>
<VDialog
:width="$vuetify.display.smAndDown ? 'auto' : 800"
:model-value="props.isDialogVisible"
@update:model-value="(val) => $emit('update:isDialogVisible', val)"
>
<!-- Dialog close btn -->
<DialogCloseBtn @click="$emit('update:isDialogVisible', false)" />
<VCard class="pa-2 pa-sm-10">
<VCardText>
<!-- 👉 Title -->
<div class="mb-6">
<h4 class="text-h4 text-center mb-2">
Select Authentication Method
</h4>
<p class="text-body-1 text-center mb-6">
You also need to select a method by which the proxy authenticates to the directory serve.
</p>
<CustomRadios
v-model:selected-radio="selectedMethod"
:radio-content="authMethods"
:grid-column="{ cols: '12' }"
>
<template #default="items">
<div class="d-flex flex-column">
<div class="d-flex gap-1 mb-2">
<VIcon
:icon="items.item.icon"
size="20"
class="text-high-emphasis"
/>
<h6 class="text-h6">
{{ items.item.title }}
</h6>
</div>
<p class="text-body-2 mb-0">
{{ items.item.desc }}
</p>
</div>
</template>
</CustomRadios>
</div>
<div class="d-flex gap-4 justify-center">
<VBtn @click="openSelectedMethodDialog">
submit
</VBtn>
<VBtn
color="secondary"
variant="tonal"
@click="$emit('update:isDialogVisible', false)"
>
Cancel
</VBtn>
</div>
</VCardText>
</VCard>
</VDialog>
<AddAuthenticatorAppDialog
v-model:is-dialog-visible="isAuthAppDialogVisible"
:auth-code="props.authAppCode"
/>
<EnableOneTimePasswordDialog
v-model:is-dialog-visible="isSmsDialogVisible"
:mobile-number="props.smsCode"
/>
</template>

View File

@@ -0,0 +1,224 @@
<script setup>
const props = defineProps({
userData: {
type: Object,
required: false,
default: () => ({
id: 0,
fullName: '',
company: '',
role: '',
username: '',
country: '',
contact: '',
email: '',
currentPlan: '',
status: '',
avatar: '',
taskDone: null,
projectDone: null,
taxId: '',
language: '',
}),
},
isDialogVisible: {
type: Boolean,
required: true,
},
})
const emit = defineEmits([
'submit',
'update:isDialogVisible',
])
const userData = ref(structuredClone(toRaw(props.userData)))
const isUseAsBillingAddress = ref(false)
watch(() => props, () => {
userData.value = structuredClone(toRaw(props.userData))
})
const onFormSubmit = () => {
emit('update:isDialogVisible', false)
emit('submit', userData.value)
}
const onFormReset = () => {
userData.value = structuredClone(toRaw(props.userData))
emit('update:isDialogVisible', false)
}
const dialogModelValueUpdate = val => {
emit('update:isDialogVisible', val)
}
</script>
<template>
<VDialog
:width="$vuetify.display.smAndDown ? 'auto' : 900"
:model-value="props.isDialogVisible"
@update:model-value="dialogModelValueUpdate"
>
<!-- Dialog close btn -->
<DialogCloseBtn @click="dialogModelValueUpdate(false)" />
<VCard class="pa-sm-10 pa-2">
<VCardText>
<!-- 👉 Title -->
<h4 class="text-h4 text-center mb-2">
Edit User Information
</h4>
<p class="text-body-1 text-center mb-6">
Updating user details will receive a privacy audit.
</p>
<!-- 👉 Form -->
<VForm
class="mt-6"
@submit.prevent="onFormSubmit"
>
<VRow>
<!-- 👉 First Name -->
<VCol
cols="12"
md="6"
>
<AppTextField
v-model="userData.fullName.split(' ')[0]"
label="First Name"
placeholder="John"
/>
</VCol>
<!-- 👉 Last Name -->
<VCol
cols="12"
md="6"
>
<AppTextField
v-model="userData.fullName.split(' ')[1]"
label="Last Name"
placeholder="Doe"
/>
</VCol>
<!-- 👉 Username -->
<VCol cols="12">
<AppTextField
v-model="userData.username"
label="Username"
placeholder="john.doe.007"
/>
</VCol>
<!-- 👉 Billing Email -->
<VCol
cols="12"
md="6"
>
<AppTextField
v-model="userData.email"
label="Email"
placeholder="johndoe@email.com"
/>
</VCol>
<!-- 👉 Status -->
<VCol
cols="12"
md="6"
>
<AppSelect
v-model="userData.status"
label="Status"
placeholder="Active"
:items="['Active', 'Inactive', 'Pending']"
/>
</VCol>
<!-- 👉 Tax Id -->
<VCol
cols="12"
md="6"
>
<AppTextField
v-model="userData.taxId"
label="Tax ID"
placeholder="123456789"
/>
</VCol>
<!-- 👉 Contact -->
<VCol
cols="12"
md="6"
>
<AppTextField
v-model="userData.contact"
label="Phone Number"
placeholder="+1 9876543210"
/>
</VCol>
<!-- 👉 Language -->
<VCol
cols="12"
md="6"
>
<AppSelect
v-model="userData.language"
closable-chips
chips
multiple
label="Language"
placeholder="English"
:items="['English', 'Spanish', 'French']"
/>
</VCol>
<!-- 👉 Country -->
<VCol
cols="12"
md="6"
>
<AppSelect
v-model="userData.country"
label="Country"
placeholder="United States"
:items="['United States', 'United Kingdom', 'France']"
/>
</VCol>
<!-- 👉 Switch -->
<VCol cols="12">
<VSwitch
v-model="isUseAsBillingAddress"
density="compact"
label="Use as a billing address?"
/>
</VCol>
<!-- 👉 Submit and Cancel -->
<VCol
cols="12"
class="d-flex flex-wrap justify-center gap-4"
>
<VBtn type="submit">
Submit
</VBtn>
<VBtn
color="secondary"
variant="tonal"
@click="onFormReset"
>
Cancel
</VBtn>
</VCol>
</VRow>
</VForm>
</VCardText>
</VCard>
</VDialog>
</template>

View File

@@ -0,0 +1,114 @@
<script setup>
const props = defineProps({
isDialogVisible: {
type: Boolean,
required: true,
},
})
const emit = defineEmits(['update:isDialogVisible'])
const selectedPlan = ref('standard')
const plansList = [
{
desc: 'Standard - $99/month',
title: 'Standard',
value: 'standard',
},
{
desc: 'Basic - $0/month',
title: 'Basic',
value: 'basic',
},
{
desc: 'Enterprise - $499/month',
title: 'Enterprise',
value: 'enterprice',
},
{
desc: 'Company - $999/month',
title: 'Company',
value: 'company',
},
]
const isConfirmDialogVisible = ref(false)
const dialogModelValueUpdate = val => {
emit('update:isDialogVisible', val)
}
</script>
<template>
<!-- 👉 upgrade plan -->
<VDialog
:width="$vuetify.display.smAndDown ? 'auto' : 650"
:model-value="props.isDialogVisible"
@update:model-value="dialogModelValueUpdate"
>
<!-- Dialog close btn -->
<DialogCloseBtn @click="dialogModelValueUpdate(false)" />
<VCard class="pa-2 pa-sm-10">
<VCardText>
<!-- 👉 Title -->
<h4 class="text-h4 text-center mb-2">
Upgrade Plan
</h4>
<p class="text-body-1 text-center mb-6">
Choose the best plan for user.
</p>
<div class="d-flex justify-space-between flex-column flex-sm-row gap-4">
<AppSelect
v-model="selectedPlan"
:items="plansList"
label="Choose a plan"
placeholder="Basic"
/>
<VBtn
class="align-self-end"
:block="$vuetify.display.xs"
>
Upgrade
</VBtn>
</div>
<VDivider class="my-6" />
<p class="text-body-1 mb-1">
User current plan is standard plan
</p>
<div class="d-flex justify-space-between align-center flex-wrap">
<div class="d-flex align-center gap-1 me-3">
<sup class="text-body-1 text-primary">$</sup>
<h1 class="text-h1 text-primary">
99
</h1>
<sub class="text-body-2 mt-5">
/ month
</sub>
</div>
<VBtn
color="error"
variant="tonal"
@click="isConfirmDialogVisible = true"
>
Cancel Subscription
</VBtn>
</div>
</VCardText>
<!-- 👉 Confirm Dialog -->
<ConfirmDialog
v-model:is-dialog-visible="isConfirmDialogVisible"
cancel-title="Cancelled"
confirm-title="Unsubscribed!"
confirm-msg="Your subscription cancelled successfully."
confirmation-question="Are you sure to cancel your subscription?"
cancel-msg="Unsubscription Cancelled!!"
/>
</VCard>
</VDialog>
</template>