first commit
This commit is contained in:
114
resources/js/components/dialogs/AddAuthenticatorAppDialog.vue
Normal file
114
resources/js/components/dialogs/AddAuthenticatorAppDialog.vue
Normal file
@@ -0,0 +1,114 @@
|
||||
<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
|
||||
max-width="900"
|
||||
:model-value="props.isDialogVisible"
|
||||
@update:model-value="(val) => $emit('update:isDialogVisible', val)"
|
||||
>
|
||||
<VCard class="pa-sm-11 pa-3">
|
||||
<!-- 👉 dialog close btn -->
|
||||
<DialogCloseBtn
|
||||
variant="text"
|
||||
size="default"
|
||||
@click="resetAuthCode"
|
||||
/>
|
||||
|
||||
<VCardText class="pt-5">
|
||||
<h4 class="text-h4 text-center mb-6">
|
||||
Add Authenticator App
|
||||
</h4>
|
||||
<h5 class="text-h5 font-weight-medium mb-2">
|
||||
Authenticator Apps
|
||||
</h5>
|
||||
|
||||
<p class="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="my-6">
|
||||
<VImg
|
||||
width="150"
|
||||
:src="themeselectionQr"
|
||||
class="mx-auto"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<VAlert
|
||||
color="warning"
|
||||
variant="tonal"
|
||||
class="my-4"
|
||||
>
|
||||
<template #title>
|
||||
ASDLKNASDA9AHS678dGhASD78AB
|
||||
</template>
|
||||
If you're having trouble using the QR code, select manual entry on your app
|
||||
</VAlert>
|
||||
|
||||
<VForm @submit.prevent="() => {}">
|
||||
<VTextField
|
||||
v-model="authCode"
|
||||
name="auth-code"
|
||||
label="Enter Authentication Code"
|
||||
placeholder="123 456"
|
||||
class="mb-8"
|
||||
/>
|
||||
|
||||
<div class="d-flex justify-end flex-wrap gap-4">
|
||||
<VBtn
|
||||
color="secondary"
|
||||
variant="outlined"
|
||||
@click="resetAuthCode"
|
||||
>
|
||||
Cancel
|
||||
</VBtn>
|
||||
|
||||
<VBtn
|
||||
type="submit"
|
||||
@click="formSubmit"
|
||||
>
|
||||
Submit
|
||||
<VIcon
|
||||
end
|
||||
icon="ri-check-line"
|
||||
class="flip-in-rtl"
|
||||
/>
|
||||
</VBtn>
|
||||
</div>
|
||||
</VForm>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
</VDialog>
|
||||
</template>
|
234
resources/js/components/dialogs/AddEditAddressDialog.vue
Normal file
234
resources/js/components/dialogs/AddEditAddressDialog.vue
Normal file
@@ -0,0 +1,234 @@
|
||||
<script setup>
|
||||
const props = defineProps({
|
||||
billingAddress: {
|
||||
type: Object,
|
||||
required: false,
|
||||
default: () => ({
|
||||
firstName: '',
|
||||
lastName: '',
|
||||
selectedCountry: null,
|
||||
addressLine1: '',
|
||||
addressLine2: '',
|
||||
landmark: '',
|
||||
contact: '',
|
||||
country: null,
|
||||
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 = [
|
||||
{
|
||||
title: 'Home',
|
||||
desc: 'Delivery Time (7am - 9pm)',
|
||||
value: 'Home',
|
||||
icon: 'ri-home-smile-2-line',
|
||||
},
|
||||
{
|
||||
title: 'Office',
|
||||
desc: 'Delivery Time (10am - 6pm)',
|
||||
value: 'Office',
|
||||
icon: 'ri-building-line',
|
||||
},
|
||||
]
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VDialog
|
||||
:width="$vuetify.display.smAndDown ? 'auto' : 900 "
|
||||
:model-value="props.isDialogVisible"
|
||||
@update:model-value="val => $emit('update:isDialogVisible', val)"
|
||||
>
|
||||
<VCard
|
||||
v-if="props.billingAddress"
|
||||
class="pa-sm-11 pa-3"
|
||||
>
|
||||
<VCardText class="pt-5">
|
||||
<!-- 👉 dialog close btn -->
|
||||
<DialogCloseBtn
|
||||
variant="text"
|
||||
size="default"
|
||||
@click="resetForm"
|
||||
/>
|
||||
|
||||
<!-- 👉 Title -->
|
||||
<div class="text-center mb-6">
|
||||
<h4 class="text-h4 mb-2">
|
||||
{{ props.billingAddress.firstName ? 'Edit' : 'Add New' }} Address
|
||||
</h4>
|
||||
|
||||
<p class="text-body-1">
|
||||
Add Address for future billing
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<CustomRadios
|
||||
v-model:selected-radio="selectedAddress"
|
||||
:radio-content="addressTypes"
|
||||
:grid-column="{ sm: '6', cols: '12' }"
|
||||
class="mb-5"
|
||||
>
|
||||
<template #default="items">
|
||||
<div class="d-flex flex-column">
|
||||
<div class="d-flex mb-2 align-center gap-x-1">
|
||||
<VIcon
|
||||
:icon="items.item.icon"
|
||||
size="20"
|
||||
/>
|
||||
<div class="text-body-1 font-weight-medium text-high-emphasis">
|
||||
{{ items.item.title }}
|
||||
</div>
|
||||
</div>
|
||||
<p class="text-body-2 mb-0">
|
||||
{{ items.item.desc }}
|
||||
</p>
|
||||
</div>
|
||||
</template>
|
||||
</CustomRadios>
|
||||
<!-- 👉 Form -->
|
||||
<VForm @submit.prevent="onFormSubmit">
|
||||
<VRow>
|
||||
<!-- 👉 First Name -->
|
||||
<VCol
|
||||
cols="12"
|
||||
md="6"
|
||||
>
|
||||
<VTextField
|
||||
v-model="billingAddress.firstName"
|
||||
label="First Name"
|
||||
placeholder="John"
|
||||
/>
|
||||
</VCol>
|
||||
|
||||
<!-- 👉 Last Name -->
|
||||
<VCol
|
||||
cols="12"
|
||||
md="6"
|
||||
>
|
||||
<VTextField
|
||||
v-model="billingAddress.lastName"
|
||||
label="Last Name"
|
||||
placeholder="Doe"
|
||||
/>
|
||||
</VCol>
|
||||
|
||||
<!-- 👉 Select country -->
|
||||
|
||||
<VCol cols="12">
|
||||
<VSelect
|
||||
v-model="billingAddress.selectedCountry"
|
||||
label="Select Country"
|
||||
placeholder="Select Country"
|
||||
:items="['USA', 'Canada', 'NZ', 'Aus']"
|
||||
/>
|
||||
</VCol>
|
||||
|
||||
<!-- 👉 Address Line 1 -->
|
||||
|
||||
<VCol cols="12">
|
||||
<VTextField
|
||||
v-model="billingAddress.addressLine1"
|
||||
label="Address Line 1"
|
||||
placeholder="1, New Street"
|
||||
/>
|
||||
</VCol>
|
||||
|
||||
<!-- 👉 Address Line 2 -->
|
||||
|
||||
<VCol cols="12">
|
||||
<VTextField
|
||||
v-model="billingAddress.addressLine2"
|
||||
label="Address Line 2"
|
||||
placeholder="Near hospital"
|
||||
/>
|
||||
</VCol>
|
||||
|
||||
<!-- 👉 Landmark -->
|
||||
|
||||
<VCol cols="12">
|
||||
<VTextField
|
||||
v-model="billingAddress.landmark"
|
||||
label="Landmark & City"
|
||||
placeholder="Near hospital, New York"
|
||||
/>
|
||||
</VCol>
|
||||
|
||||
<!-- 👉 State -->
|
||||
<VCol
|
||||
cols="12"
|
||||
md="6"
|
||||
>
|
||||
<VTextField
|
||||
v-model="billingAddress.state"
|
||||
label="State/Province"
|
||||
placeholder="New York"
|
||||
/>
|
||||
</VCol>
|
||||
|
||||
<!-- 👉 Zip Code -->
|
||||
<VCol
|
||||
cols="12"
|
||||
md="6"
|
||||
>
|
||||
<VTextField
|
||||
v-model="billingAddress.zipCode"
|
||||
label="Zip Code"
|
||||
placeholder="123123"
|
||||
type="number"
|
||||
/>
|
||||
</VCol>
|
||||
|
||||
<VCol cols="12">
|
||||
<VSwitch label="Make this default shipping address" />
|
||||
</VCol>
|
||||
|
||||
<!-- 👉 Submit and Cancel button -->
|
||||
<VCol
|
||||
cols="12"
|
||||
class="text-center"
|
||||
>
|
||||
<VBtn
|
||||
type="submit"
|
||||
class="me-3"
|
||||
>
|
||||
submit
|
||||
</VBtn>
|
||||
|
||||
<VBtn
|
||||
variant="outlined"
|
||||
color="secondary"
|
||||
@click="resetForm"
|
||||
>
|
||||
Cancel
|
||||
</VBtn>
|
||||
</VCol>
|
||||
</VRow>
|
||||
</VForm>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
</VDialog>
|
||||
</template>
|
101
resources/js/components/dialogs/AddEditPermissionDialog.vue
Normal file
101
resources/js/components/dialogs/AddEditPermissionDialog.vue
Normal file
@@ -0,0 +1,101 @@
|
||||
<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"
|
||||
>
|
||||
<VCard class="pa-sm-8 pa-5">
|
||||
<!-- 👉 dialog close btn -->
|
||||
<DialogCloseBtn
|
||||
variant="text"
|
||||
size="default"
|
||||
@click="onReset"
|
||||
/>
|
||||
|
||||
<VCardText class="mt-5">
|
||||
<!-- 👉 Title -->
|
||||
<div class="text-center mb-6">
|
||||
<h4 class="text-h4 mb-2">
|
||||
{{ props.permissionName ? 'Edit' : 'Add' }} Permission
|
||||
</h4>
|
||||
|
||||
<p class="text-body-1">
|
||||
{{ props.permissionName ? 'Edit' : 'Add' }} permission as per your requirements.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- 👉 Form -->
|
||||
<VForm>
|
||||
<VAlert
|
||||
type="warning"
|
||||
title="Warning!"
|
||||
variant="tonal"
|
||||
class="mb-6"
|
||||
>
|
||||
By editing the permission name, you might break the system permissions functionality. Please ensure you're absolutely certain before proceeding.
|
||||
</VAlert>
|
||||
|
||||
<!-- 👉 Role name -->
|
||||
<div class="d-flex align-center gap-4 mb-4">
|
||||
<VTextField
|
||||
v-model="currentPermissionName"
|
||||
density="compact"
|
||||
placeholder="Enter Permission Name"
|
||||
/>
|
||||
|
||||
<VBtn @click="onSubmit">
|
||||
Update
|
||||
</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>
|
294
resources/js/components/dialogs/AddEditRoleDialog.vue
Normal file
294
resources/js/components/dialogs/AddEditRoleDialog.vue
Normal file
@@ -0,0 +1,294 @@
|
||||
<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',
|
||||
])
|
||||
|
||||
|
||||
// 👉 Permission List
|
||||
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)
|
||||
|
||||
// select all
|
||||
watch(isSelectAll, val => {
|
||||
permissions.value = permissions.value.map(permission => ({
|
||||
...permission,
|
||||
read: val,
|
||||
write: val,
|
||||
create: val,
|
||||
}))
|
||||
})
|
||||
|
||||
// if Indeterminate is false, then set isSelectAll to false
|
||||
watch(isIndeterminate, () => {
|
||||
if (!isIndeterminate.value)
|
||||
isSelectAll.value = false
|
||||
})
|
||||
|
||||
// if all permissions are checked, then set isSelectAll to true
|
||||
watch(permissions, () => {
|
||||
if (checkedCount.value === permissions.value.length * 3)
|
||||
isSelectAll.value = true
|
||||
}, { deep: true })
|
||||
|
||||
// if rolePermissions is not empty, then set permissions
|
||||
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"
|
||||
>
|
||||
<VCard class="pa-sm-8 pa-5">
|
||||
<!-- 👉 dialog close btn -->
|
||||
<DialogCloseBtn
|
||||
variant="text"
|
||||
size="default"
|
||||
@click="onReset"
|
||||
/>
|
||||
|
||||
<VCardText class="mt-5">
|
||||
<!-- 👉 Title -->
|
||||
<div class="text-center mb-6">
|
||||
<h4 class="text-h4 mb-2">
|
||||
{{ props.rolePermissions.name ? 'Edit' : 'Add' }} Role
|
||||
</h4>
|
||||
|
||||
<p class="text-body-1">
|
||||
{{ props.rolePermissions.name ? 'Edit' : 'Add' }} Role
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- 👉 Form -->
|
||||
<VForm ref="refPermissionForm">
|
||||
<!-- 👉 Role name -->
|
||||
<VTextField
|
||||
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">
|
||||
<!-- 👉 Admin -->
|
||||
<tr>
|
||||
<td class="text-h6">
|
||||
Administrator Access
|
||||
</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 class="text-h6">
|
||||
{{ permission.name }}
|
||||
</td>
|
||||
<td style="inline-size: 5.75rem;">
|
||||
<div class="d-flex justify-end">
|
||||
<VCheckbox
|
||||
v-model="permission.read"
|
||||
label="Read"
|
||||
/>
|
||||
</div>
|
||||
</td>
|
||||
<td style="inline-size: 5.75rem;">
|
||||
<div class="d-flex justify-end">
|
||||
<VCheckbox
|
||||
v-model="permission.write"
|
||||
label="Write"
|
||||
/>
|
||||
</div>
|
||||
</td>
|
||||
<td style="inline-size: 5.75rem;">
|
||||
<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-3 mt-6">
|
||||
<VBtn @click="onSubmit">
|
||||
Submit
|
||||
</VBtn>
|
||||
|
||||
<VBtn
|
||||
color="secondary"
|
||||
variant="outlined"
|
||||
@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>
|
122
resources/js/components/dialogs/AddPaymentMethodDialog.vue
Normal file
122
resources/js/components/dialogs/AddPaymentMethodDialog.vue
Normal file
@@ -0,0 +1,122 @@
|
||||
<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"
|
||||
max-width="900"
|
||||
@update:model-value="dialogVisibleUpdate"
|
||||
>
|
||||
<VCard class="refer-and-earn-dialog">
|
||||
<!-- 👉 dialog close btn -->
|
||||
<DialogCloseBtn
|
||||
variant="text"
|
||||
size="default"
|
||||
@click="emit('update:isDialogVisible', false)"
|
||||
/>
|
||||
|
||||
<VCardText class="pa-8 pa-sm-16">
|
||||
<div class="mb-6">
|
||||
<h4 class="text-h4 text-center mb-2">
|
||||
Add payment methods
|
||||
</h4>
|
||||
<p class="text-sm-body-1 text-center">
|
||||
Supported payment methods
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<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"
|
||||
/>
|
||||
<div class="text-body-1 font-weight-medium text-high-emphasis">
|
||||
{{ item.title }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="d-none d-sm-block text-body-1">
|
||||
{{ item.type }}
|
||||
</div>
|
||||
</div>
|
||||
<VDivider v-show="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>
|
143
resources/js/components/dialogs/CardAddEditDialog.vue
Normal file
143
resources/js/components/dialogs/CardAddEditDialog.vue
Normal file
@@ -0,0 +1,143 @@
|
||||
<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)
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VDialog
|
||||
:width="$vuetify.display.smAndDown ? 'auto' : 600"
|
||||
:model-value="props.isDialogVisible"
|
||||
@update:model-value="val => $emit('update:isDialogVisible', val)"
|
||||
>
|
||||
<VCard class="pa-sm-11 pa-3">
|
||||
<!-- 👉 dialog close btn -->
|
||||
<DialogCloseBtn
|
||||
variant="text"
|
||||
size="default"
|
||||
@click="$emit('update:isDialogVisible', false)"
|
||||
/>
|
||||
|
||||
<VCardText class="pt-5">
|
||||
<!-- 👉 Title -->
|
||||
<div class="text-center mb-6">
|
||||
<h4 class="text-h4 mb-2">
|
||||
{{ props.cardDetails.name ? 'Edit Card' : 'Add New Card' }}
|
||||
</h4>
|
||||
<div class="text-body-1">
|
||||
{{ props.cardDetails.name ? 'Edit your saved card details' : 'Add your saved card details' }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<VForm @submit.prevent="() => {}">
|
||||
<VRow>
|
||||
<!-- 👉 Card Number -->
|
||||
<VCol cols="12">
|
||||
<VTextField
|
||||
v-model="cardDetails.number"
|
||||
label="Card Number"
|
||||
placeholder="1234 1234 1234 1234"
|
||||
/>
|
||||
</VCol>
|
||||
|
||||
<!-- 👉 Card Name -->
|
||||
<VCol
|
||||
cols="12"
|
||||
md="6"
|
||||
>
|
||||
<VTextField
|
||||
v-model="cardDetails.name"
|
||||
label="Name"
|
||||
placeholder="John Doe"
|
||||
/>
|
||||
</VCol>
|
||||
|
||||
<!-- 👉 Card Expiry -->
|
||||
<VCol
|
||||
cols="6"
|
||||
md="3"
|
||||
>
|
||||
<VTextField
|
||||
v-model="cardDetails.expiry"
|
||||
label="Expiry"
|
||||
placeholder="MM/YY"
|
||||
/>
|
||||
</VCol>
|
||||
|
||||
<!-- 👉 Card CVV -->
|
||||
<VCol
|
||||
cols="6"
|
||||
md="3"
|
||||
>
|
||||
<VTextField
|
||||
v-model="cardDetails.cvv"
|
||||
type="number"
|
||||
label="CVV"
|
||||
placeholder="123"
|
||||
/>
|
||||
</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="outlined"
|
||||
@click="$emit('update:isDialogVisible', false)"
|
||||
>
|
||||
Cancel
|
||||
</VBtn>
|
||||
</VCol>
|
||||
</VRow>
|
||||
</VForm>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
</VDialog>
|
||||
</template>
|
164
resources/js/components/dialogs/ConfirmDialog.vue
Normal file
164
resources/js/components/dialogs/ConfirmDialog.vue
Normal file
@@ -0,0 +1,164 @@
|
||||
<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"
|
||||
size="x-large"
|
||||
>
|
||||
<span class="text-4xl">!</span>
|
||||
</VBtn>
|
||||
|
||||
<h6 class="text-lg font-weight-medium">
|
||||
{{ props.confirmationQuestion }}
|
||||
</h6>
|
||||
</VCardText>
|
||||
|
||||
<VCardText class="d-flex align-center justify-center gap-4">
|
||||
<VBtn
|
||||
variant="elevated"
|
||||
@click="onConfirmation"
|
||||
>
|
||||
Confirm
|
||||
</VBtn>
|
||||
|
||||
<VBtn
|
||||
color="secondary"
|
||||
variant="outlined"
|
||||
@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"
|
||||
size="x-large"
|
||||
>
|
||||
<span class="text-xl">
|
||||
<VIcon icon="ri-check-line" />
|
||||
</span>
|
||||
</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"
|
||||
size="x-large"
|
||||
>
|
||||
<span class="text-2xl 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>
|
446
resources/js/components/dialogs/CreateAppDialog.vue
Normal file
446
resources/js/components/dialogs/CreateAppDialog.vue
Normal file
@@ -0,0 +1,446 @@
|
||||
<script setup>
|
||||
import illustrationJohn from '@images/pages/illustration-john.png'
|
||||
import angularIcon from '@images/icons/brands/angular.png'
|
||||
import laravelIcon from '@images/icons/brands/laravel.png'
|
||||
import reactIcon from '@images/icons/brands/react.png'
|
||||
import vueIcon from '@images/icons/brands/vue.png'
|
||||
import awsIcon from '@images/icons/brands/aws.png'
|
||||
import firebaseIcon from '@images/icons/brands/firebase.png'
|
||||
import mysqlIcon from '@images/icons/brands/mysql.png'
|
||||
|
||||
const props = defineProps({
|
||||
isDialogVisible: {
|
||||
type: Boolean,
|
||||
required: true,
|
||||
},
|
||||
})
|
||||
|
||||
const emit = defineEmits([
|
||||
'update:isDialogVisible',
|
||||
'updatedData',
|
||||
])
|
||||
|
||||
const currentStep = ref(0)
|
||||
|
||||
const createApp = [
|
||||
{
|
||||
icon: 'ri-file-text-line',
|
||||
title: 'Details',
|
||||
subtitle: 'Enter Details',
|
||||
},
|
||||
{
|
||||
icon: 'ri-star-smile-line',
|
||||
title: 'Frameworks',
|
||||
subtitle: 'Select Framework',
|
||||
},
|
||||
{
|
||||
icon: 'ri-pie-chart-2-line',
|
||||
title: 'Database',
|
||||
subtitle: 'Select Database',
|
||||
},
|
||||
{
|
||||
icon: 'ri-bank-card-line',
|
||||
title: 'Billing',
|
||||
subtitle: 'Payment Details',
|
||||
},
|
||||
{
|
||||
icon: 'ri-check-double-line',
|
||||
title: 'Submit',
|
||||
subtitle: 'submit',
|
||||
},
|
||||
]
|
||||
|
||||
const categories = [
|
||||
{
|
||||
icon: 'ri-bar-chart-box-line',
|
||||
color: 'info',
|
||||
title: 'CRM Application',
|
||||
subtitle: 'Scales with any business',
|
||||
slug: 'crm-application',
|
||||
},
|
||||
{
|
||||
icon: 'ri-shopping-cart-line',
|
||||
color: 'success',
|
||||
title: 'Ecommerce Platforms',
|
||||
subtitle: 'Grow Your Business With App',
|
||||
slug: 'ecommerce-application',
|
||||
},
|
||||
{
|
||||
icon: 'ri-video-upload-line',
|
||||
color: 'error',
|
||||
title: 'Online Learning platform',
|
||||
subtitle: 'Start learning today',
|
||||
slug: 'online-learning-application',
|
||||
},
|
||||
]
|
||||
|
||||
const frameworks = [
|
||||
{
|
||||
icon: reactIcon,
|
||||
color: 'info',
|
||||
title: 'React Native',
|
||||
subtitle: 'Create truly native apps',
|
||||
slug: 'react-framework',
|
||||
},
|
||||
{
|
||||
icon: angularIcon,
|
||||
color: 'error',
|
||||
title: 'Angular',
|
||||
subtitle: 'Most suited for your application',
|
||||
slug: 'angular-framework',
|
||||
},
|
||||
{
|
||||
icon: vueIcon,
|
||||
color: 'success',
|
||||
title: 'Vue',
|
||||
subtitle: 'Progressive Framework',
|
||||
slug: 'vue-framework',
|
||||
},
|
||||
{
|
||||
icon: laravelIcon,
|
||||
color: 'warning',
|
||||
title: 'Laravel',
|
||||
subtitle: 'PHP web frameworks',
|
||||
slug: 'laravel-framework',
|
||||
},
|
||||
]
|
||||
|
||||
const databases = [
|
||||
{
|
||||
icon: firebaseIcon,
|
||||
color: 'warning',
|
||||
title: 'Firebase',
|
||||
subtitle: 'Cloud Firestore',
|
||||
slug: 'firebase-database',
|
||||
},
|
||||
{
|
||||
icon: awsIcon,
|
||||
color: 'secondary',
|
||||
title: 'AWS',
|
||||
subtitle: 'Amazon Fast NoSQL Database',
|
||||
slug: 'aws-database',
|
||||
},
|
||||
{
|
||||
icon: mysqlIcon,
|
||||
color: 'info',
|
||||
title: 'MySQL',
|
||||
subtitle: 'Basic MySQL database',
|
||||
slug: 'mysql-database',
|
||||
},
|
||||
]
|
||||
|
||||
const createAppData = ref({
|
||||
category: 'crm-application',
|
||||
framework: 'vue-framework',
|
||||
database: 'firebase-database',
|
||||
cardNumber: null,
|
||||
cardName: '',
|
||||
cardExpiry: '',
|
||||
cardCvv: '',
|
||||
isSave: false,
|
||||
})
|
||||
|
||||
const dialogVisibleUpdate = val => {
|
||||
emit('update:isDialogVisible', val)
|
||||
currentStep.value = 0
|
||||
}
|
||||
|
||||
watch(props, () => {
|
||||
if (!props.isDialogVisible)
|
||||
currentStep.value = 0
|
||||
})
|
||||
|
||||
const onSubmit = () => {
|
||||
alert('submitted...!!')
|
||||
emit('updatedData', createAppData.value)
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VDialog
|
||||
:model-value="props.isDialogVisible"
|
||||
max-width="900"
|
||||
@update:model-value="dialogVisibleUpdate"
|
||||
>
|
||||
<VCard class="create-app-dialog pa-sm-11 pa-3">
|
||||
<!-- 👉 dialog close btn -->
|
||||
<DialogCloseBtn
|
||||
variant="text"
|
||||
size="default"
|
||||
@click="emit('update:isDialogVisible', false)"
|
||||
/>
|
||||
|
||||
<VCardText class="pt-5">
|
||||
<div class="text-center mb-6">
|
||||
<h4 class="text-h4 text-center mb-2">
|
||||
Create App
|
||||
</h4>
|
||||
<div class="text-body-1">
|
||||
Provide data with this form to create your app.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<VRow>
|
||||
<VCol
|
||||
cols="12"
|
||||
sm="5"
|
||||
md="4"
|
||||
>
|
||||
<AppStepper
|
||||
v-model:current-step="currentStep"
|
||||
direction="vertical"
|
||||
:items="createApp"
|
||||
icon-size="24"
|
||||
class="stepper-icon-step-bg"
|
||||
/>
|
||||
</VCol>
|
||||
|
||||
<VCol
|
||||
cols="12"
|
||||
sm="7"
|
||||
md="8"
|
||||
>
|
||||
<VWindow
|
||||
v-model="currentStep"
|
||||
class="disable-tab-transition stepper-content"
|
||||
>
|
||||
<!-- 👉 category -->
|
||||
<VWindowItem>
|
||||
<VTextField
|
||||
label="Application Name"
|
||||
placeholder="myRider"
|
||||
/>
|
||||
|
||||
<h5 class="text-h5 mb-4 mt-8">
|
||||
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"
|
||||
:icon="category.icon"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<VListItemTitle class="font-weight-medium mb-1">
|
||||
{{ category.title }}
|
||||
</VListItemTitle>
|
||||
<VListItemSubtitle class="text-body-2 me-2">
|
||||
{{ 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"
|
||||
>
|
||||
<img :src="framework.icon">
|
||||
</VAvatar>
|
||||
</template>
|
||||
<VListItemTitle class="mb-1 font-weight-medium">
|
||||
{{ framework.title }}
|
||||
</VListItemTitle>
|
||||
<VListItemSubtitle class="me-2">
|
||||
{{ framework.subtitle }}
|
||||
</VListItemSubtitle>
|
||||
<template #append>
|
||||
<VRadio :value="framework.slug" />
|
||||
</template>
|
||||
</VListItem>
|
||||
</VList>
|
||||
</VRadioGroup>
|
||||
</VWindowItem>
|
||||
|
||||
<!-- 👉 Database Engine -->
|
||||
<VWindowItem>
|
||||
<VTextField
|
||||
label="Database Name"
|
||||
placeholder="userDB"
|
||||
/>
|
||||
|
||||
<h5 class="text-h5 mt-8 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"
|
||||
>
|
||||
<img :src="database.icon">
|
||||
</VAvatar>
|
||||
</template>
|
||||
<VListItemTitle class="mb-1 font-weight-medium">
|
||||
{{ database.title }}
|
||||
</VListItemTitle>
|
||||
<VListItemSubtitle class="me-2">
|
||||
{{ database.subtitle }}
|
||||
</VListItemSubtitle>
|
||||
<template #append>
|
||||
<VRadio :value="database.slug" />
|
||||
</template>
|
||||
</VListItem>
|
||||
</VList>
|
||||
</VRadioGroup>
|
||||
</VWindowItem>
|
||||
|
||||
<!-- 👉 Billing form -->
|
||||
<VWindowItem>
|
||||
<VForm>
|
||||
<VRow>
|
||||
<VCol cols="12">
|
||||
<VTextField
|
||||
v-model="createAppData.cardNumber"
|
||||
label="Card Number"
|
||||
placeholder="1234 1234 1234 1234"
|
||||
type="number"
|
||||
/>
|
||||
</VCol>
|
||||
|
||||
<VCol
|
||||
cols="12"
|
||||
md="6"
|
||||
>
|
||||
<VTextField
|
||||
v-model="createAppData.cardName"
|
||||
label="Name on Card"
|
||||
placeholder="John Doe"
|
||||
/>
|
||||
</VCol>
|
||||
|
||||
<VCol
|
||||
cols="6"
|
||||
md="3"
|
||||
>
|
||||
<VTextField
|
||||
v-model="createAppData.cardExpiry"
|
||||
label="Expiry"
|
||||
placeholder="MM/YY"
|
||||
/>
|
||||
</VCol>
|
||||
|
||||
<VCol
|
||||
cols="6"
|
||||
md="3"
|
||||
>
|
||||
<VTextField
|
||||
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-2">
|
||||
Submit 🥳
|
||||
</h5>
|
||||
<p class="text-body-2 mb-4">
|
||||
Submit to kickstart your project.
|
||||
</p>
|
||||
|
||||
<VImg
|
||||
:src="illustrationJohn"
|
||||
width="252"
|
||||
class="mx-auto"
|
||||
/>
|
||||
</VWindowItem>
|
||||
</VWindow>
|
||||
|
||||
<div class="d-flex justify-space-between mt-6">
|
||||
<VBtn
|
||||
variant="outlined"
|
||||
color="secondary"
|
||||
:disabled="currentStep === 0"
|
||||
@click="currentStep--"
|
||||
>
|
||||
<VIcon
|
||||
icon="ri-arrow-left-line"
|
||||
start
|
||||
class="flip-in-rtl"
|
||||
/>
|
||||
Previous
|
||||
</VBtn>
|
||||
|
||||
<VBtn
|
||||
v-if="createApp.length - 1 === currentStep"
|
||||
color="success"
|
||||
append-icon="ri-check-line"
|
||||
@click="onSubmit"
|
||||
>
|
||||
submit
|
||||
</VBtn>
|
||||
|
||||
<VBtn
|
||||
v-else
|
||||
@click="currentStep++"
|
||||
>
|
||||
Next
|
||||
|
||||
<VIcon
|
||||
icon="ri-arrow-right-line"
|
||||
end
|
||||
class="flip-in-rtl"
|
||||
/>
|
||||
</VBtn>
|
||||
</div>
|
||||
</VCol>
|
||||
</VRow>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
</VDialog>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
.stepper-content .card-list {
|
||||
--v-card-list-gap: 1rem;
|
||||
}
|
||||
</style>
|
@@ -0,0 +1,91 @@
|
||||
<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)
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VDialog
|
||||
max-width="900"
|
||||
:model-value="props.isDialogVisible"
|
||||
@update:model-value="(val) => $emit('update:isDialogVisible', val)"
|
||||
>
|
||||
<VCard class="pa-5 pa-sm-11">
|
||||
<!-- 👉 dialog close btn -->
|
||||
<DialogCloseBtn
|
||||
variant="text"
|
||||
size="default"
|
||||
@click="resetPhoneNumber"
|
||||
/>
|
||||
|
||||
<VCardText class="pt-5">
|
||||
<div class="mb-6">
|
||||
<h5 class="text-h5 mb-2">
|
||||
Verify Your Mobile Number for SMS
|
||||
</h5>
|
||||
|
||||
<div>
|
||||
Enter your mobile phone number with country code and we will send you a verification code.
|
||||
</div>
|
||||
</div>
|
||||
<VForm @submit.prevent="() => {}">
|
||||
<VTextField
|
||||
v-model="phoneNumber"
|
||||
name="mobile"
|
||||
label="Phone Number"
|
||||
placeholder="+1 123 456 7890"
|
||||
class="mb-8"
|
||||
/>
|
||||
|
||||
<div class="d-flex flex-wrap justify-end gap-3">
|
||||
<VBtn
|
||||
color="secondary"
|
||||
variant="outlined"
|
||||
@click="resetPhoneNumber"
|
||||
>
|
||||
Cancel
|
||||
</VBtn>
|
||||
<VBtn
|
||||
color="success"
|
||||
type="submit"
|
||||
@click="formSubmit"
|
||||
>
|
||||
Submit
|
||||
<VIcon
|
||||
end
|
||||
icon="ri-check-line"
|
||||
class="flip-in-rtl"
|
||||
/>
|
||||
</VBtn>
|
||||
</div>
|
||||
</VForm>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
</VDialog>
|
||||
</template>
|
165
resources/js/components/dialogs/PaymentProvidersDialog.vue
Normal file
165
resources/js/components/dialogs/PaymentProvidersDialog.vue
Normal file
@@ -0,0 +1,165 @@
|
||||
<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"
|
||||
max-width="900"
|
||||
@update:model-value="dialogVisibleUpdate"
|
||||
>
|
||||
<VCard class="refer-and-earn-dialog pa-3 pa-sm-11">
|
||||
<!-- 👉 dialog close btn -->
|
||||
<DialogCloseBtn
|
||||
variant="text"
|
||||
size="default"
|
||||
@click="emit('update:isDialogVisible', false)"
|
||||
/>
|
||||
|
||||
<VCardText class="pt-5">
|
||||
<div class="mb-6">
|
||||
<h4 class="text-h4 text-center mb-2">
|
||||
Select Payment Providers
|
||||
</h4>
|
||||
<p class="text-sm-body-1 text-center">
|
||||
Third-party payment providers
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-for="(item, index) in paymentProvidersData"
|
||||
:key="index"
|
||||
>
|
||||
<div class="d-flex flex-column flex-sm-row justify-space-between align-sm-center align-start gap-4 flex-wrap py-4">
|
||||
<div class="text-high-emphasis font-weight-medium">
|
||||
{{ item.title }}
|
||||
</div>
|
||||
<div class="d-flex gap-x-4 gap-y-2 flex-wrap">
|
||||
<img
|
||||
v-for="(img, iterator) in item.providers"
|
||||
:key="iterator"
|
||||
:src="img.value"
|
||||
height="30"
|
||||
width="50"
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<VDivider v-show="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>
|
50
resources/js/components/dialogs/PricingPlanDialog.vue
Normal file
50
resources/js/components/dialogs/PricingPlanDialog.vue
Normal file
@@ -0,0 +1,50 @@
|
||||
<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"
|
||||
class="v-dialog-xl"
|
||||
@update:model-value="dialogVisibleUpdate"
|
||||
>
|
||||
<VCard class="pricing-dialog pa-2 pa-sm-11">
|
||||
<!-- 👉 dialog close btn -->
|
||||
<DialogCloseBtn
|
||||
variant="text"
|
||||
size="default"
|
||||
@click="emit('update:isDialogVisible', false)"
|
||||
/>
|
||||
|
||||
<VCardText class="pt-5">
|
||||
<AppPricing
|
||||
title="Pricing Plan"
|
||||
md="4"
|
||||
cols="12"
|
||||
>
|
||||
<template #heading>
|
||||
<h4 class="text-h4 pb-2">
|
||||
Pricing Plans
|
||||
</h4>
|
||||
</template>
|
||||
<template #subtitle>
|
||||
<div class="text-body-1">
|
||||
All plans include 40+ advanced tools and features to boost your product. Choose the best plan to fit your needs.
|
||||
</div>
|
||||
</template>
|
||||
</AppPricing>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
</VDialog>
|
||||
</template>
|
186
resources/js/components/dialogs/ReferAndEarnDialog.vue
Normal file
186
resources/js/components/dialogs/ReferAndEarnDialog.vue
Normal file
@@ -0,0 +1,186 @@
|
||||
<script setup>
|
||||
const props = defineProps({
|
||||
isDialogVisible: {
|
||||
type: Boolean,
|
||||
required: true,
|
||||
},
|
||||
})
|
||||
|
||||
const emit = defineEmits(['update:isDialogVisible'])
|
||||
|
||||
const dialogVisibleUpdate = val => {
|
||||
emit('update:isDialogVisible', val)
|
||||
}
|
||||
|
||||
const referAndEarnSteps = [
|
||||
{
|
||||
icon: 'ri-send-plane-2-line',
|
||||
title: 'Send Invitation 👍🏻',
|
||||
subtitle: 'Send your referral link to your friend',
|
||||
},
|
||||
{
|
||||
icon: 'ri-pages-line',
|
||||
title: 'Registration 😎',
|
||||
subtitle: 'Let them register to our services',
|
||||
},
|
||||
{
|
||||
icon: 'ri-gift-line',
|
||||
title: 'Free Trial 🎉',
|
||||
subtitle: 'Your friend will get 30 days free trial',
|
||||
},
|
||||
]
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VDialog
|
||||
:model-value="props.isDialogVisible"
|
||||
max-width="900"
|
||||
@update:model-value="dialogVisibleUpdate"
|
||||
>
|
||||
<VCard class="refer-and-earn-dialog pa-sm-11 pa-3">
|
||||
<!-- 👉 dialog close btn -->
|
||||
<DialogCloseBtn
|
||||
variant="text"
|
||||
size="default"
|
||||
@click="emit('update:isDialogVisible', false)"
|
||||
/>
|
||||
|
||||
<VCardText class="pt-5">
|
||||
<div class="text-center pb-3">
|
||||
<h4 class="text-h4 pb-2">
|
||||
Refer & Earn
|
||||
</h4>
|
||||
|
||||
<div class="text-body-1">
|
||||
Invite your friend to Materio, if they sign up, you and your friend will get 30 days free trial
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<VRow class="text-center my-6">
|
||||
<VCol
|
||||
v-for="step in referAndEarnSteps"
|
||||
:key="step.title"
|
||||
cols="12"
|
||||
sm="4"
|
||||
>
|
||||
<div>
|
||||
<VAvatar
|
||||
variant="tonal"
|
||||
size="88"
|
||||
color="primary"
|
||||
class="mb-4"
|
||||
>
|
||||
<VIcon
|
||||
size="40"
|
||||
:icon="step.icon"
|
||||
/>
|
||||
</VAvatar>
|
||||
|
||||
<div class="text-body-1 font-weight-medium mb-2 text-high-emphasis">
|
||||
{{ step.title }}
|
||||
</div>
|
||||
|
||||
<div class="text-body-1">
|
||||
{{ step.subtitle }}
|
||||
</div>
|
||||
</div>
|
||||
</VCol>
|
||||
</VRow>
|
||||
|
||||
<VDivider class="mt-9 mb-6" />
|
||||
|
||||
<h5 class="text-h5 mb-5">
|
||||
Invite your friends
|
||||
</h5>
|
||||
|
||||
<p class="mb-2">
|
||||
Enter your friend's email address and invite them to join Materio 😍
|
||||
</p>
|
||||
<VForm
|
||||
class="d-flex align-center gap-4 mb-6"
|
||||
@submit.prevent="() => {}"
|
||||
>
|
||||
<VTextField
|
||||
placeholder="johnDoe@gmail.com"
|
||||
density="compact"
|
||||
/>
|
||||
|
||||
<VBtn type="submit">
|
||||
Submit
|
||||
</VBtn>
|
||||
</VForm>
|
||||
|
||||
<h5 class="text-h5 mb-5">
|
||||
Share the referral link
|
||||
</h5>
|
||||
|
||||
<p class="mb-2">
|
||||
You can also copy and send it or share it on your social media. 🚀
|
||||
</p>
|
||||
<VForm
|
||||
class="d-flex align-center flex-wrap gap-4"
|
||||
@submit.prevent="() => {}"
|
||||
>
|
||||
<VTextField
|
||||
placeholder="http://referral.link"
|
||||
class="refer-link-input"
|
||||
density="compact"
|
||||
>
|
||||
<template #append-inner>
|
||||
<VBtn variant="text">
|
||||
COPY LINK
|
||||
</VBtn>
|
||||
</template>
|
||||
</VTextField>
|
||||
|
||||
<div class="d-flex gap-1">
|
||||
<VBtn
|
||||
icon
|
||||
class="rounded"
|
||||
color="#3B5998"
|
||||
>
|
||||
<VIcon
|
||||
color="white"
|
||||
icon="ri-facebook-circle-line"
|
||||
/>
|
||||
</VBtn>
|
||||
|
||||
<VBtn
|
||||
icon
|
||||
class="rounded"
|
||||
color="#55ACEE"
|
||||
>
|
||||
<VIcon
|
||||
color="white"
|
||||
icon="ri-twitter-line"
|
||||
/>
|
||||
</VBtn>
|
||||
|
||||
<VBtn
|
||||
icon
|
||||
class="rounded"
|
||||
color="#007BB6"
|
||||
>
|
||||
<VIcon
|
||||
color="white"
|
||||
icon="ri-linkedin-line"
|
||||
/>
|
||||
</VBtn>
|
||||
</div>
|
||||
</VForm>
|
||||
</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>
|
204
resources/js/components/dialogs/ShareProjectDialog.vue
Normal file
204
resources/js/components/dialogs/ShareProjectDialog.vue
Normal file
@@ -0,0 +1,204 @@
|
||||
<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"
|
||||
max-width="900"
|
||||
@update:model-value="dialogVisibleUpdate"
|
||||
>
|
||||
<VCard class="share-project-dialog pa-sm-11 pa-3">
|
||||
<!-- 👉 dialog close btn -->
|
||||
<DialogCloseBtn
|
||||
size="default"
|
||||
variant="text"
|
||||
@click="emit('update:isDialogVisible', false)"
|
||||
/>
|
||||
<VCardText class="pt-5">
|
||||
<div class="text-center mb-6">
|
||||
<h4 class="text-h4 mb-2">
|
||||
Share Project
|
||||
</h4>
|
||||
<p class="text-body-1">
|
||||
Share project with the team members
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="mb-6">
|
||||
<h5 class="text-h5 mb-2">
|
||||
Add Members
|
||||
</h5>
|
||||
<VAutocomplete
|
||||
:items="membersList"
|
||||
item-title="name"
|
||||
item-value="name"
|
||||
density="compact"
|
||||
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>
|
||||
</VAutocomplete>
|
||||
</div>
|
||||
|
||||
<h6 class="text-h6 mb-4">
|
||||
8 Members
|
||||
</h6>
|
||||
|
||||
<VList class="card-list mb-6">
|
||||
<VListItem
|
||||
v-for="member in membersList"
|
||||
:key="member.name"
|
||||
>
|
||||
<template #prepend>
|
||||
<VAvatar :image="member.avatar" />
|
||||
</template>
|
||||
|
||||
<VListItemTitle class="text-high-emphasis">
|
||||
{{ member.name }}
|
||||
</VListItemTitle>
|
||||
<VListItemSubtitle>
|
||||
{{ member.email }}
|
||||
</VListItemSubtitle>
|
||||
|
||||
<template #append>
|
||||
<VBtn
|
||||
variant="text"
|
||||
color="secondary"
|
||||
:icon="$vuetify.display.xs"
|
||||
>
|
||||
<template v-if="!$vuetify.display.xs">
|
||||
{{ member.permission }}
|
||||
</template>
|
||||
<VIcon
|
||||
end
|
||||
icon="ri-arrow-down-s-line"
|
||||
size="16"
|
||||
:class="$vuetify.display.xs ? 'ms-0' : ''"
|
||||
/>
|
||||
|
||||
<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 justify-space-between align-center flex-wrap gap-3">
|
||||
<div class="text-body-1 text-high-emphasis font-weight-medium d-flex align-center">
|
||||
<VIcon
|
||||
icon="ri-group-line"
|
||||
size="20"
|
||||
class="me-2"
|
||||
/>
|
||||
<span>Public to Master - ThemeSelection</span>
|
||||
</div>
|
||||
|
||||
<VBtn
|
||||
variant="outlined"
|
||||
prepend-icon="ri-link"
|
||||
size="small"
|
||||
>
|
||||
Copy Project Link
|
||||
</VBtn>
|
||||
</div>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
</VDialog>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
.share-project-dialog {
|
||||
.card-list {
|
||||
--v-card-list-gap: 1rem;
|
||||
}
|
||||
}
|
||||
</style>
|
149
resources/js/components/dialogs/TwoFactorAuthDialog.vue
Normal file
149
resources/js/components/dialogs/TwoFactorAuthDialog.vue
Normal file
@@ -0,0 +1,149 @@
|
||||
<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: 'ri-settings-4-line',
|
||||
title: 'Authenticator Apps',
|
||||
desc: 'Get code from an app like Google Authenticator or Microsoft Authenticator.',
|
||||
value: 'authApp',
|
||||
},
|
||||
{
|
||||
icon: 'ri-wechat-line',
|
||||
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
|
||||
max-width="800"
|
||||
:model-value="props.isDialogVisible"
|
||||
@update:model-value="(val) => $emit('update:isDialogVisible', val)"
|
||||
>
|
||||
<VCard class="pa-sm-11 pa-3">
|
||||
<!-- 👉 dialog close btn -->
|
||||
<DialogCloseBtn
|
||||
variant="text"
|
||||
size="default"
|
||||
@click="$emit('update:isDialogVisible', false)"
|
||||
/>
|
||||
|
||||
<VCardText class="pt-5">
|
||||
<div class="mb-6">
|
||||
<div class="text-center mb-6">
|
||||
<h4 class="text-h4 mb-2">
|
||||
Select Authentication Method
|
||||
</h4>
|
||||
<div class="text-body-1">
|
||||
You also need to select a method by which the proxy authenticates to the directory serve.
|
||||
</div>
|
||||
</div>
|
||||
<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 mb-2 align-center gap-x-1">
|
||||
<VIcon
|
||||
:icon="items.item.icon"
|
||||
size="20"
|
||||
/>
|
||||
<div class="text-body-1 font-weight-medium text-high-emphasis">
|
||||
{{ items.item.title }}
|
||||
</div>
|
||||
</div>
|
||||
<p class="text-body-2 mb-0">
|
||||
{{ items.item.desc }}
|
||||
</p>
|
||||
</div>
|
||||
</template>
|
||||
</CustomRadios>
|
||||
</div>
|
||||
|
||||
<div class="text-end">
|
||||
<VBtn @click="openSelectedMethodDialog">
|
||||
continue
|
||||
<VIcon
|
||||
end
|
||||
icon="ri-arrow-right-line"
|
||||
class="flip-in-rtl"
|
||||
/>
|
||||
</VBtn>
|
||||
</div>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
</VDialog>
|
||||
|
||||
<AddAuthenticatorAppDialog
|
||||
v-model:isDialogVisible="isAuthAppDialogVisible"
|
||||
:auth-code="props.authAppCode"
|
||||
/>
|
||||
<EnableOneTimePasswordDialog
|
||||
v-model:isDialogVisible="isSmsDialogVisible"
|
||||
:mobile-number="props.smsCode"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
.auth-method-card {
|
||||
&.card-list .v-list-item {
|
||||
padding-block: 20px !important;
|
||||
padding-inline: 30px !important;
|
||||
}
|
||||
|
||||
&.responsive-card {
|
||||
.v-list-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.5rem;
|
||||
text-align: center;
|
||||
|
||||
.v-list-item__prepend {
|
||||
svg {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
228
resources/js/components/dialogs/UserInfoEditDialog.vue
Normal file
228
resources/js/components/dialogs/UserInfoEditDialog.vue
Normal file
@@ -0,0 +1,228 @@
|
||||
<script setup>
|
||||
const props = defineProps({
|
||||
userData: {
|
||||
type: Object,
|
||||
required: false,
|
||||
default: () => ({
|
||||
avatar: '',
|
||||
company: '',
|
||||
contact: '',
|
||||
country: null,
|
||||
currentPlan: '',
|
||||
email: '',
|
||||
fullName: '',
|
||||
id: 0,
|
||||
role: '',
|
||||
status: null,
|
||||
username: '',
|
||||
language: [],
|
||||
projectDone: 0,
|
||||
taskDone: 0,
|
||||
taxId: '',
|
||||
}),
|
||||
},
|
||||
isDialogVisible: {
|
||||
type: Boolean,
|
||||
required: true,
|
||||
},
|
||||
})
|
||||
|
||||
const emit = defineEmits([
|
||||
'submit',
|
||||
'update:isDialogVisible',
|
||||
])
|
||||
|
||||
const userData = ref(structuredClone(toRaw(props.userData)))
|
||||
|
||||
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 dialogVisibleUpdate = val => {
|
||||
emit('update:isDialogVisible', val)
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VDialog
|
||||
:width="$vuetify.display.smAndDown ? 'auto' : 900 "
|
||||
:model-value="props.isDialogVisible"
|
||||
@update:model-value="dialogVisibleUpdate"
|
||||
>
|
||||
<VCard class="pa-sm-11 pa-3">
|
||||
<!-- 👉 dialog close btn -->
|
||||
<DialogCloseBtn
|
||||
variant="text"
|
||||
size="default"
|
||||
@click="onFormReset"
|
||||
/>
|
||||
|
||||
<VCardText class="pt-5">
|
||||
<div class="text-center pb-6">
|
||||
<h4 class="text-h4 mb-2">
|
||||
Edit User Information
|
||||
</h4>
|
||||
<div class="text-body-1">
|
||||
Updating user details will receive a privacy audit.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 👉 Form -->
|
||||
<VForm
|
||||
class="mt-4"
|
||||
@submit.prevent="onFormSubmit"
|
||||
>
|
||||
<VRow>
|
||||
<!-- 👉 First Name -->
|
||||
<VCol
|
||||
cols="12"
|
||||
md="6"
|
||||
>
|
||||
<VTextField
|
||||
v-model="userData.fullName.split(' ')[0]"
|
||||
label="First Name"
|
||||
placeholder="John"
|
||||
/>
|
||||
</VCol>
|
||||
|
||||
<!-- 👉 Last Name -->
|
||||
<VCol
|
||||
cols="12"
|
||||
md="6"
|
||||
>
|
||||
<VTextField
|
||||
v-model="userData.fullName.split(' ')[1]"
|
||||
label="Last Name"
|
||||
placeholder="doe"
|
||||
/>
|
||||
</VCol>
|
||||
|
||||
<!-- 👉 User Name -->
|
||||
|
||||
<VCol cols="12">
|
||||
<VTextField
|
||||
v-model="userData.username"
|
||||
label="Username"
|
||||
placeholder="John Doe"
|
||||
/>
|
||||
</VCol>
|
||||
|
||||
<!-- 👉 Billing Email -->
|
||||
<VCol
|
||||
cols="12"
|
||||
md="6"
|
||||
>
|
||||
<VTextField
|
||||
v-model="userData.email"
|
||||
label="Billing Email"
|
||||
placeholder="johndoe@email.com"
|
||||
/>
|
||||
</VCol>
|
||||
|
||||
<!-- 👉 Status -->
|
||||
<VCol
|
||||
cols="12"
|
||||
md="6"
|
||||
>
|
||||
<VSelect
|
||||
v-model="userData.status"
|
||||
:items="['Active', 'Inactive', 'Pending']"
|
||||
label="Status"
|
||||
placeholder="Status"
|
||||
/>
|
||||
</VCol>
|
||||
|
||||
<!-- 👉 Tax Id -->
|
||||
<VCol
|
||||
cols="12"
|
||||
md="6"
|
||||
>
|
||||
<VTextField
|
||||
v-model="userData.taxId"
|
||||
label="Tax Id"
|
||||
placeholder="Tax-3456789"
|
||||
/>
|
||||
</VCol>
|
||||
|
||||
<!-- 👉 Contact -->
|
||||
<VCol
|
||||
cols="12"
|
||||
md="6"
|
||||
>
|
||||
<VTextField
|
||||
v-model="userData.contact"
|
||||
label="Contact"
|
||||
placeholder="+1 9876543210"
|
||||
/>
|
||||
</VCol>
|
||||
|
||||
<!-- 👉 Language -->
|
||||
<VCol
|
||||
cols="12"
|
||||
md="6"
|
||||
>
|
||||
<VSelect
|
||||
v-model="userData.language"
|
||||
:items="['English', 'Spanish', 'French']"
|
||||
label="Language"
|
||||
placeholder="English"
|
||||
chips
|
||||
closable-chips
|
||||
multiple
|
||||
/>
|
||||
</VCol>
|
||||
|
||||
<!-- 👉 Country -->
|
||||
<VCol
|
||||
cols="12"
|
||||
md="6"
|
||||
>
|
||||
<VSelect
|
||||
v-model="userData.country"
|
||||
:items="['United States', 'United Kingdom', 'France']"
|
||||
label="Country"
|
||||
placeholder="United States"
|
||||
/>
|
||||
</VCol>
|
||||
|
||||
<!-- 👉 Switch -->
|
||||
<VCol cols="12">
|
||||
<VSwitch
|
||||
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="outlined"
|
||||
@click="onFormReset"
|
||||
>
|
||||
Cancel
|
||||
</VBtn>
|
||||
</VCol>
|
||||
</VRow>
|
||||
</VForm>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
</VDialog>
|
||||
</template>
|
114
resources/js/components/dialogs/UserUpgradePlanDialog.vue
Normal file
114
resources/js/components/dialogs/UserUpgradePlanDialog.vue
Normal file
@@ -0,0 +1,114 @@
|
||||
<script setup>
|
||||
const props = defineProps({
|
||||
isDialogVisible: {
|
||||
type: Boolean,
|
||||
required: true,
|
||||
},
|
||||
})
|
||||
|
||||
const emit = defineEmits(['update:isDialogVisible'])
|
||||
|
||||
const selectedPlan = ref('basic')
|
||||
|
||||
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)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<!-- 👉 upgrade plan -->
|
||||
<VDialog
|
||||
:width="$vuetify.display.smAndDown ? 'auto' : 650"
|
||||
:model-value="props.isDialogVisible"
|
||||
@update:model-value="val => $emit('update:isDialogVisible', val)"
|
||||
>
|
||||
<VCard class="py-sm-11 py-3">
|
||||
<!-- 👉 dialog close btn -->
|
||||
<DialogCloseBtn
|
||||
variant="text"
|
||||
size="default"
|
||||
@click="$emit('update:isDialogVisible', false)"
|
||||
/>
|
||||
|
||||
<VCardItem class="text-center pb-10">
|
||||
<div class="text-center">
|
||||
<h4 class="text-h4 mb-2">
|
||||
Upgrade Plan
|
||||
</h4>
|
||||
<div class="text-body-1">
|
||||
Choose the best plan for user.
|
||||
</div>
|
||||
</div>
|
||||
</VCardItem>
|
||||
|
||||
<VCardText class="d-flex justify-space-between flex-column flex-sm-row gap-4 px-15">
|
||||
<VSelect
|
||||
v-model="selectedPlan"
|
||||
:items="plansList"
|
||||
density="compact"
|
||||
label="Choose a plan"
|
||||
placeholder="Basic"
|
||||
/>
|
||||
<VBtn>
|
||||
Upgrade
|
||||
</VBtn>
|
||||
</VCardText>
|
||||
|
||||
<VDivider class="mb-5" />
|
||||
|
||||
<VCardText class="px-15">
|
||||
<p class="font-weight-medium mb-2">
|
||||
User current plan is standard plan
|
||||
</p>
|
||||
<div class="d-flex justify-space-between flex-wrap">
|
||||
<div class="d-flex align-center me-3">
|
||||
<sup class="text-base text-primary">$</sup>
|
||||
<h1 class="text-h1 text-primary">
|
||||
99
|
||||
</h1>
|
||||
<sub class="text-body-2 mt-3">/month</sub>
|
||||
</div>
|
||||
<VBtn
|
||||
color="error"
|
||||
variant="outlined"
|
||||
class="mt-3"
|
||||
@click="isConfirmDialogVisible = true"
|
||||
>
|
||||
Cancel Subscription
|
||||
</VBtn>
|
||||
</div>
|
||||
</VCardText>
|
||||
|
||||
<!-- 👉 Confirm Dialog -->
|
||||
<ConfirmDialog
|
||||
v-model:isDialogVisible="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>
|
Reference in New Issue
Block a user