Initial commit
This commit is contained in:
367
resources/js/views/apps/user/view/UserBioPanel.vue
Normal file
367
resources/js/views/apps/user/view/UserBioPanel.vue
Normal file
@@ -0,0 +1,367 @@
|
||||
<script setup>
|
||||
const props = defineProps({
|
||||
userData: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
})
|
||||
|
||||
const standardPlan = {
|
||||
plan: 'Standard',
|
||||
price: 99,
|
||||
benefits: [
|
||||
'10 Users',
|
||||
'Up to 10GB storage',
|
||||
'Basic Support',
|
||||
],
|
||||
}
|
||||
|
||||
const isUserInfoEditDialogVisible = ref(false)
|
||||
const isUpgradePlanDialogVisible = ref(false)
|
||||
|
||||
const resolveUserRoleVariant = role => {
|
||||
if (role === 'subscriber')
|
||||
return {
|
||||
color: 'warning',
|
||||
icon: 'tabler-user',
|
||||
}
|
||||
if (role === 'author')
|
||||
return {
|
||||
color: 'success',
|
||||
icon: 'tabler-circle-check',
|
||||
}
|
||||
if (role === 'maintainer')
|
||||
return {
|
||||
color: 'primary',
|
||||
icon: 'tabler-chart-pie-2',
|
||||
}
|
||||
if (role === 'editor')
|
||||
return {
|
||||
color: 'info',
|
||||
icon: 'tabler-pencil',
|
||||
}
|
||||
if (role === 'admin')
|
||||
return {
|
||||
color: 'secondary',
|
||||
icon: 'tabler-server-2',
|
||||
}
|
||||
|
||||
return {
|
||||
color: 'primary',
|
||||
icon: 'tabler-user',
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VRow>
|
||||
<!-- SECTION User Details -->
|
||||
<VCol cols="12">
|
||||
<VCard v-if="props.userData">
|
||||
<VCardText class="text-center pt-12">
|
||||
<!-- 👉 Avatar -->
|
||||
<VAvatar
|
||||
rounded
|
||||
:size="100"
|
||||
:color="!props.userData.avatar ? 'primary' : undefined"
|
||||
:variant="!props.userData.avatar ? 'tonal' : undefined"
|
||||
>
|
||||
<VImg
|
||||
v-if="props.userData.avatar"
|
||||
:src="props.userData.avatar"
|
||||
/>
|
||||
<span
|
||||
v-else
|
||||
class="text-5xl font-weight-medium"
|
||||
>
|
||||
{{ avatarText(props.userData.fullName) }}
|
||||
</span>
|
||||
</VAvatar>
|
||||
|
||||
<!-- 👉 User fullName -->
|
||||
<h5 class="text-h5 mt-4">
|
||||
{{ props.userData.fullName }}
|
||||
</h5>
|
||||
|
||||
<!-- 👉 Role chip -->
|
||||
<VChip
|
||||
label
|
||||
:color="resolveUserRoleVariant(props.userData.role).color"
|
||||
size="small"
|
||||
class="text-capitalize mt-4"
|
||||
>
|
||||
{{ props.userData.role }}
|
||||
</VChip>
|
||||
</VCardText>
|
||||
|
||||
<VCardText>
|
||||
<div class="d-flex justify-space-around gap-x-6 gap-y-2 flex-wrap mb-6">
|
||||
<!-- 👉 Done task -->
|
||||
<div class="d-flex align-center me-8">
|
||||
<VAvatar
|
||||
:size="40"
|
||||
rounded
|
||||
color="primary"
|
||||
variant="tonal"
|
||||
class="me-4"
|
||||
>
|
||||
<VIcon
|
||||
icon="tabler-checkbox"
|
||||
size="24"
|
||||
/>
|
||||
</VAvatar>
|
||||
<div>
|
||||
<h5 class="text-h5">
|
||||
{{ `${(props.userData.taskDone / 1000).toFixed(2)}k` }}
|
||||
</h5>
|
||||
|
||||
<span class="text-sm">Task Done</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 👉 Done Project -->
|
||||
<div class="d-flex align-center me-4">
|
||||
<VAvatar
|
||||
:size="38"
|
||||
rounded
|
||||
color="primary"
|
||||
variant="tonal"
|
||||
class="me-4"
|
||||
>
|
||||
<VIcon
|
||||
icon="tabler-briefcase"
|
||||
size="24"
|
||||
/>
|
||||
</VAvatar>
|
||||
<div>
|
||||
<h5 class="text-h5">
|
||||
{{ kFormatter(props.userData.projectDone) }}
|
||||
</h5>
|
||||
<span class="text-sm">Project Done</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 👉 Details -->
|
||||
<h5 class="text-h5">
|
||||
Details
|
||||
</h5>
|
||||
|
||||
<VDivider class="my-4" />
|
||||
|
||||
<!-- 👉 User Details list -->
|
||||
<VList class="card-list mt-2">
|
||||
<VListItem>
|
||||
<VListItemTitle>
|
||||
<h6 class="text-h6">
|
||||
Username:
|
||||
<div class="d-inline-block text-body-1">
|
||||
{{ props.userData.fullName }}
|
||||
</div>
|
||||
</h6>
|
||||
</VListItemTitle>
|
||||
</VListItem>
|
||||
|
||||
<VListItem>
|
||||
<VListItemTitle>
|
||||
<span class="text-h6">
|
||||
Billing Email:
|
||||
</span>
|
||||
<span class="text-body-1">
|
||||
{{ props.userData.email }}
|
||||
</span>
|
||||
</VListItemTitle>
|
||||
</VListItem>
|
||||
|
||||
<VListItem>
|
||||
<VListItemTitle>
|
||||
<h6 class="text-h6">
|
||||
Status:
|
||||
<div class="d-inline-block text-body-1 text-capitalize">
|
||||
{{ props.userData.status }}
|
||||
</div>
|
||||
</h6>
|
||||
</VListItemTitle>
|
||||
</VListItem>
|
||||
|
||||
<VListItem>
|
||||
<VListItemTitle>
|
||||
<h6 class="text-h6">
|
||||
Role:
|
||||
<div class="d-inline-block text-capitalize text-body-1">
|
||||
{{ props.userData.role }}
|
||||
</div>
|
||||
</h6>
|
||||
</VListItemTitle>
|
||||
</VListItem>
|
||||
|
||||
<VListItem>
|
||||
<VListItemTitle>
|
||||
<h6 class="text-h6">
|
||||
Tax ID:
|
||||
<div class="d-inline-block text-body-1">
|
||||
{{ props.userData.taxId }}
|
||||
</div>
|
||||
</h6>
|
||||
</VListItemTitle>
|
||||
</VListItem>
|
||||
|
||||
<VListItem>
|
||||
<VListItemTitle>
|
||||
<h6 class="text-h6">
|
||||
Contact:
|
||||
<div class="d-inline-block text-body-1">
|
||||
{{ props.userData.contact }}
|
||||
</div>
|
||||
</h6>
|
||||
</VListItemTitle>
|
||||
</VListItem>
|
||||
|
||||
<VListItem>
|
||||
<VListItemTitle>
|
||||
<h6 class="text-h6">
|
||||
Language:
|
||||
<div class="d-inline-block text-body-1">
|
||||
{{ props.userData.language }}
|
||||
</div>
|
||||
</h6>
|
||||
</VListItemTitle>
|
||||
</VListItem>
|
||||
|
||||
<VListItem>
|
||||
<VListItemTitle>
|
||||
<h6 class="text-h6">
|
||||
Country:
|
||||
<div class="d-inline-block text-body-1">
|
||||
{{ props.userData.country }}
|
||||
</div>
|
||||
</h6>
|
||||
</VListItemTitle>
|
||||
</VListItem>
|
||||
</VList>
|
||||
</VCardText>
|
||||
|
||||
<!-- 👉 Edit and Suspend button -->
|
||||
<VCardText class="d-flex justify-center gap-x-4">
|
||||
<VBtn
|
||||
variant="elevated"
|
||||
@click="isUserInfoEditDialogVisible = true"
|
||||
>
|
||||
Edit
|
||||
</VBtn>
|
||||
|
||||
<VBtn
|
||||
variant="tonal"
|
||||
color="error"
|
||||
>
|
||||
Suspend
|
||||
</VBtn>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
</VCol>
|
||||
<!-- !SECTION -->
|
||||
|
||||
<!-- SECTION Current Plan -->
|
||||
<VCol cols="12">
|
||||
<VCard>
|
||||
<VCardText class="d-flex">
|
||||
<!-- 👉 Standard Chip -->
|
||||
<VChip
|
||||
label
|
||||
color="primary"
|
||||
size="small"
|
||||
class="font-weight-medium"
|
||||
>
|
||||
Popular
|
||||
</VChip>
|
||||
|
||||
<VSpacer />
|
||||
|
||||
<!-- 👉 Current Price -->
|
||||
<div class="d-flex align-center">
|
||||
<sup class="text-h5 text-primary mt-1">$</sup>
|
||||
<h1 class="text-h1 text-primary">
|
||||
99
|
||||
</h1>
|
||||
<sub class="mt-3"><h6 class="text-h6 font-weight-regular mb-n1">/ month</h6></sub>
|
||||
</div>
|
||||
</VCardText>
|
||||
|
||||
<VCardText>
|
||||
<!-- 👉 Price Benefits -->
|
||||
<VList class="card-list">
|
||||
<VListItem
|
||||
v-for="benefit in standardPlan.benefits"
|
||||
:key="benefit"
|
||||
>
|
||||
<div class="d-flex align-center gap-x-2">
|
||||
<VIcon
|
||||
size="10"
|
||||
color="secondary"
|
||||
icon="tabler-circle-filled"
|
||||
/>
|
||||
<div class="text-medium-emphasis">
|
||||
{{ benefit }}
|
||||
</div>
|
||||
</div>
|
||||
</VListItem>
|
||||
</VList>
|
||||
|
||||
<!-- 👉 Days -->
|
||||
<div class="my-6">
|
||||
<div class="d-flex justify-space-between mb-1">
|
||||
<h6 class="text-h6">
|
||||
Days
|
||||
</h6>
|
||||
<h6 class="text-h6">
|
||||
26 of 30 Days
|
||||
</h6>
|
||||
</div>
|
||||
|
||||
<!-- 👉 Progress -->
|
||||
<VProgressLinear
|
||||
rounded
|
||||
rounded-bar
|
||||
:model-value="65"
|
||||
color="primary"
|
||||
/>
|
||||
|
||||
<p class="mt-1">
|
||||
4 days remaining
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- 👉 Upgrade Plan -->
|
||||
<div class="d-flex gap-4">
|
||||
<VBtn
|
||||
block
|
||||
@click="isUpgradePlanDialogVisible = true"
|
||||
>
|
||||
Upgrade Plan
|
||||
</VBtn>
|
||||
</div>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
</VCol>
|
||||
<!-- !SECTION -->
|
||||
</VRow>
|
||||
|
||||
<!-- 👉 Edit user info dialog -->
|
||||
<UserInfoEditDialog
|
||||
v-model:is-dialog-visible="isUserInfoEditDialogVisible"
|
||||
:user-data="props.userData"
|
||||
/>
|
||||
|
||||
<!-- 👉 Upgrade plan dialog -->
|
||||
<UserUpgradePlanDialog v-model:is-dialog-visible="isUpgradePlanDialogVisible" />
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.card-list {
|
||||
--v-card-list-gap: 0.5rem;
|
||||
}
|
||||
|
||||
.text-capitalize {
|
||||
text-transform: capitalize !important;
|
||||
}
|
||||
</style>
|
||||
261
resources/js/views/apps/user/view/UserInvoiceTable.vue
Normal file
261
resources/js/views/apps/user/view/UserInvoiceTable.vue
Normal file
@@ -0,0 +1,261 @@
|
||||
<script setup>
|
||||
const searchQuery = ref('')
|
||||
const selectedStatus = ref()
|
||||
|
||||
// Data table options
|
||||
const itemsPerPage = ref(10)
|
||||
const page = ref(1)
|
||||
const sortBy = ref()
|
||||
const orderBy = ref()
|
||||
|
||||
const updateOptions = options => {
|
||||
sortBy.value = options.sortBy[0]?.key
|
||||
orderBy.value = options.sortBy[0]?.order
|
||||
}
|
||||
|
||||
const isLoading = ref(false)
|
||||
|
||||
// 👉 headers
|
||||
const headers = [
|
||||
{
|
||||
title: '#',
|
||||
key: 'id',
|
||||
},
|
||||
{
|
||||
title: 'Status',
|
||||
key: 'trending',
|
||||
sortable: false,
|
||||
},
|
||||
{
|
||||
title: 'Total',
|
||||
key: 'total',
|
||||
},
|
||||
{
|
||||
title: 'Issued Date',
|
||||
key: 'date',
|
||||
},
|
||||
{
|
||||
title: 'Actions',
|
||||
key: 'actions',
|
||||
sortable: false,
|
||||
},
|
||||
]
|
||||
|
||||
const {
|
||||
data: invoiceData,
|
||||
execute: fetchInvoices,
|
||||
} = await useApi(createUrl('/apps/invoice', {
|
||||
query: {
|
||||
q: searchQuery,
|
||||
status: selectedStatus,
|
||||
itemsPerPage,
|
||||
page,
|
||||
sortBy,
|
||||
orderBy,
|
||||
},
|
||||
}))
|
||||
|
||||
const invoices = computed(() => invoiceData.value?.invoices)
|
||||
const totalInvoices = computed(() => invoiceData.value?.totalInvoices)
|
||||
|
||||
const resolveInvoiceStatusVariantAndIcon = status => {
|
||||
if (status === 'Partial Payment')
|
||||
return {
|
||||
variant: 'success',
|
||||
icon: 'tabler-check',
|
||||
}
|
||||
if (status === 'Paid')
|
||||
return {
|
||||
variant: 'warning',
|
||||
icon: 'tabler-chart-pie',
|
||||
}
|
||||
if (status === 'Downloaded')
|
||||
return {
|
||||
variant: 'info',
|
||||
icon: 'tabler-arrow-down',
|
||||
}
|
||||
if (status === 'Draft')
|
||||
return {
|
||||
variant: 'primary',
|
||||
icon: 'tabler-folder',
|
||||
}
|
||||
if (status === 'Sent')
|
||||
return {
|
||||
variant: 'secondary',
|
||||
icon: 'tabler-mail',
|
||||
}
|
||||
if (status === 'Past Due')
|
||||
return {
|
||||
variant: 'error',
|
||||
icon: 'tabler-info-circle',
|
||||
}
|
||||
|
||||
return {
|
||||
variant: 'secondary',
|
||||
icon: 'tabler-x',
|
||||
}
|
||||
}
|
||||
|
||||
const computedMoreList = computed(() => {
|
||||
return paramId => [
|
||||
{
|
||||
title: 'Download',
|
||||
value: 'download',
|
||||
prependIcon: 'tabler-download',
|
||||
},
|
||||
{
|
||||
title: 'Edit',
|
||||
value: 'edit',
|
||||
prependIcon: 'tabler-pencil',
|
||||
to: {
|
||||
name: 'apps-invoice-edit-id',
|
||||
params: { id: paramId },
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'Duplicate',
|
||||
value: 'duplicate',
|
||||
prependIcon: 'tabler-layers-intersect',
|
||||
},
|
||||
]
|
||||
})
|
||||
|
||||
const deleteInvoice = async id => {
|
||||
await $api(`/apps/invoice/${ id }`, { method: 'DELETE' })
|
||||
fetchInvoices()
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<section v-if="invoices">
|
||||
<VCard id="invoice-list">
|
||||
<VCardText>
|
||||
<div class="d-flex align-center justify-space-between flex-wrap gap-4">
|
||||
<div class="text-h5">
|
||||
Invoice List
|
||||
</div>
|
||||
<div class="d-flex align-center gap-x-4">
|
||||
<AppSelect
|
||||
:model-value="itemsPerPage"
|
||||
:items="[
|
||||
{ value: 10, title: '10' },
|
||||
{ value: 25, title: '25' },
|
||||
{ value: 50, title: '50' },
|
||||
{ value: 100, title: '100' },
|
||||
{ value: -1, title: 'All' },
|
||||
]"
|
||||
style="inline-size: 6.25rem;"
|
||||
@update:model-value="itemsPerPage = parseInt($event, 10)"
|
||||
/>
|
||||
|
||||
<!-- 👉 Export invoice -->
|
||||
<VBtn
|
||||
append-icon="tabler-upload"
|
||||
variant="tonal"
|
||||
color="secondary"
|
||||
>
|
||||
Export
|
||||
</VBtn>
|
||||
</div>
|
||||
</div>
|
||||
</VCardText>
|
||||
|
||||
<VDivider />
|
||||
|
||||
<!-- SECTION Datatable -->
|
||||
<VDataTableServer
|
||||
v-model:items-per-page="itemsPerPage"
|
||||
v-model:page="page"
|
||||
:loading="isLoading"
|
||||
:items-length="totalInvoices"
|
||||
:headers="headers"
|
||||
:items="invoices"
|
||||
item-value="total"
|
||||
class="text-no-wrap text-sm rounded-0"
|
||||
@update:options="updateOptions"
|
||||
>
|
||||
<!-- id -->
|
||||
<template #item.id="{ item }">
|
||||
<RouterLink :to="{ name: 'apps-invoice-preview-id', params: { id: item.id } }">
|
||||
#{{ item.id }}
|
||||
</RouterLink>
|
||||
</template>
|
||||
|
||||
<!-- trending -->
|
||||
<template #item.trending="{ item }">
|
||||
<VTooltip>
|
||||
<template #activator="{ props }">
|
||||
<VAvatar
|
||||
:size="28"
|
||||
v-bind="props"
|
||||
:color="resolveInvoiceStatusVariantAndIcon(item.invoiceStatus).variant"
|
||||
variant="tonal"
|
||||
>
|
||||
<VIcon
|
||||
:size="16"
|
||||
:icon="resolveInvoiceStatusVariantAndIcon(item.invoiceStatus).icon"
|
||||
/>
|
||||
</VAvatar>
|
||||
</template>
|
||||
<p class="mb-0">
|
||||
{{ item.invoiceStatus }}
|
||||
</p>
|
||||
<p class="mb-0">
|
||||
Balance: {{ item.balance }}
|
||||
</p>
|
||||
<p class="mb-0">
|
||||
Due date: {{ item.dueDate }}
|
||||
</p>
|
||||
</VTooltip>
|
||||
</template>
|
||||
|
||||
<!-- Total -->
|
||||
<template #item.total="{ item }">
|
||||
${{ item.total }}
|
||||
</template>
|
||||
|
||||
<!-- issued Date -->
|
||||
<template #item.date="{ item }">
|
||||
{{ item.issuedDate }}
|
||||
</template>
|
||||
|
||||
<!-- Actions -->
|
||||
<template #item.actions="{ item }">
|
||||
<IconBtn @click="deleteInvoice(item.id)">
|
||||
<VIcon icon="tabler-trash" />
|
||||
</IconBtn>
|
||||
|
||||
<IconBtn :to="{ name: 'apps-invoice-preview-id', params: { id: item.id } }">
|
||||
<VIcon icon="tabler-eye" />
|
||||
</IconBtn>
|
||||
|
||||
<MoreBtn
|
||||
:menu-list="computedMoreList(item.id)"
|
||||
color="undefined"
|
||||
item-props
|
||||
/>
|
||||
</template>
|
||||
<template #bottom>
|
||||
<TablePagination
|
||||
v-model:page="page"
|
||||
:items-per-page="itemsPerPage"
|
||||
:total-items="totalInvoices"
|
||||
/>
|
||||
</template>
|
||||
</VDataTableServer>
|
||||
<!-- !SECTION -->
|
||||
</VCard>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
#invoice-list {
|
||||
.invoice-list-actions {
|
||||
inline-size: 8rem;
|
||||
}
|
||||
|
||||
.invoice-list-search {
|
||||
inline-size: 12rem;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
424
resources/js/views/apps/user/view/UserTabAccount.vue
Normal file
424
resources/js/views/apps/user/view/UserTabAccount.vue
Normal file
@@ -0,0 +1,424 @@
|
||||
<script setup>
|
||||
import UserInvoiceTable from './UserInvoiceTable.vue'
|
||||
import avatar1 from '@images/avatars/avatar-1.png'
|
||||
import avatar2 from '@images/avatars/avatar-2.png'
|
||||
import avatar3 from '@images/avatars/avatar-3.png'
|
||||
import avatar4 from '@images/avatars/avatar-4.png'
|
||||
import avatar5 from '@images/avatars/avatar-5.png'
|
||||
import avatar6 from '@images/avatars/avatar-6.png'
|
||||
import avatar7 from '@images/avatars/avatar-7.png'
|
||||
import avatar8 from '@images/avatars/avatar-8.png'
|
||||
import figma from '@images/icons/project-icons/figma.png'
|
||||
import html5 from '@images/icons/project-icons/html5.png'
|
||||
import pdf from '@images/icons/project-icons/pdf.png'
|
||||
import python from '@images/icons/project-icons/python.png'
|
||||
import react from '@images/icons/project-icons/react.png'
|
||||
import sketch from '@images/icons/project-icons/sketch.png'
|
||||
import vue from '@images/icons/project-icons/vue.png'
|
||||
import xamarin from '@images/icons/project-icons/xamarin.png'
|
||||
|
||||
const projectTableHeaders = [
|
||||
{
|
||||
title: 'PROJECT',
|
||||
key: 'project',
|
||||
},
|
||||
{
|
||||
title: 'LEADER',
|
||||
key: 'leader',
|
||||
},
|
||||
{
|
||||
title: 'Team',
|
||||
key: 'team',
|
||||
},
|
||||
{
|
||||
title: 'PROGRESS',
|
||||
key: 'progress',
|
||||
},
|
||||
{
|
||||
title: 'Action',
|
||||
key: 'Action',
|
||||
sortable: false,
|
||||
},
|
||||
]
|
||||
|
||||
const search = ref('')
|
||||
|
||||
const options = ref({
|
||||
itemsPerPage: 5,
|
||||
page: 1,
|
||||
})
|
||||
|
||||
const projects = [
|
||||
{
|
||||
logo: react,
|
||||
name: 'BGC eCommerce App',
|
||||
project: 'React Project',
|
||||
leader: 'Eileen',
|
||||
progress: 78,
|
||||
hours: '18:42',
|
||||
team: [
|
||||
avatar1,
|
||||
avatar8,
|
||||
avatar6,
|
||||
],
|
||||
extraMembers: 3,
|
||||
},
|
||||
{
|
||||
logo: figma,
|
||||
name: 'Falcon Logo Design',
|
||||
project: 'Figma Project',
|
||||
leader: 'Owen',
|
||||
progress: 25,
|
||||
hours: '20:42',
|
||||
team: [
|
||||
avatar5,
|
||||
avatar2,
|
||||
],
|
||||
},
|
||||
{
|
||||
logo: vue,
|
||||
name: 'Dashboard Design',
|
||||
project: 'Vuejs Project',
|
||||
leader: 'Keith',
|
||||
progress: 62,
|
||||
hours: '120:87',
|
||||
team: [
|
||||
avatar8,
|
||||
avatar2,
|
||||
avatar1,
|
||||
],
|
||||
},
|
||||
{
|
||||
logo: xamarin,
|
||||
name: 'Foodista mobile app',
|
||||
project: 'Xamarin Project',
|
||||
leader: 'Merline',
|
||||
progress: 8,
|
||||
hours: '120:87',
|
||||
team: [
|
||||
avatar3,
|
||||
avatar4,
|
||||
avatar7,
|
||||
],
|
||||
extraMembers: 8,
|
||||
},
|
||||
{
|
||||
logo: python,
|
||||
name: 'Dojo Email App',
|
||||
project: 'Python Project',
|
||||
leader: 'Harmonia',
|
||||
progress: 51,
|
||||
hours: '230:10',
|
||||
team: [
|
||||
avatar4,
|
||||
avatar3,
|
||||
avatar1,
|
||||
],
|
||||
extraMembers: 5,
|
||||
},
|
||||
{
|
||||
logo: sketch,
|
||||
name: 'Blockchain Website',
|
||||
project: 'Sketch Project',
|
||||
leader: 'Allyson',
|
||||
progress: 92,
|
||||
hours: '342:41',
|
||||
team: [
|
||||
avatar1,
|
||||
avatar8,
|
||||
],
|
||||
},
|
||||
{
|
||||
logo: html5,
|
||||
name: 'Hoffman Website',
|
||||
project: 'HTML Project',
|
||||
leader: 'Georgie',
|
||||
progress: 80,
|
||||
hours: '12:45',
|
||||
team: [
|
||||
avatar1,
|
||||
avatar8,
|
||||
avatar6,
|
||||
],
|
||||
},
|
||||
]
|
||||
|
||||
const moreList = [
|
||||
{
|
||||
title: 'Download',
|
||||
value: 'Download',
|
||||
},
|
||||
{
|
||||
title: 'Delete',
|
||||
value: 'Delete',
|
||||
},
|
||||
{
|
||||
title: 'View',
|
||||
value: 'View',
|
||||
},
|
||||
]
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VRow>
|
||||
<VCol cols="12">
|
||||
<VCard>
|
||||
<VCardText class="d-flex justify-space-between align-center flex-wrap gap-4">
|
||||
<h5 class="text-h5">
|
||||
User's Projects List
|
||||
</h5>
|
||||
|
||||
<div style="inline-size: 250px;">
|
||||
<AppTextField
|
||||
v-model="search"
|
||||
placeholder="Search Project"
|
||||
/>
|
||||
</div>
|
||||
</VCardText>
|
||||
<VDivider />
|
||||
<!-- 👉 User Project List Table -->
|
||||
|
||||
<!-- SECTION Datatable -->
|
||||
|
||||
<VDataTable
|
||||
v-model:page="options.page"
|
||||
:headers="projectTableHeaders"
|
||||
:items-per-page="options.itemsPerPage"
|
||||
:items="projects"
|
||||
item-value="name"
|
||||
hide-default-footer
|
||||
:search="search"
|
||||
show-select
|
||||
class="text-no-wrap"
|
||||
>
|
||||
<!-- projects -->
|
||||
<template #item.project="{ item }">
|
||||
<div class="d-flex align-center gap-x-3">
|
||||
<VAvatar
|
||||
:size="34"
|
||||
:image="item.logo"
|
||||
/>
|
||||
<div>
|
||||
<h6 class="text-h6 text-no-wrap">
|
||||
{{ item.name }}
|
||||
</h6>
|
||||
<div class="text-body-2">
|
||||
{{ item.project }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template #item.leader="{ item }">
|
||||
<div class="text-base text-high-emphasis">
|
||||
{{ item.leader }}
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- Team -->
|
||||
<template #item.team="{ item }">
|
||||
<div class="d-flex">
|
||||
<div class="v-avatar-group">
|
||||
<VAvatar
|
||||
v-for="(data, index) in item.team"
|
||||
:key="index"
|
||||
size="26"
|
||||
>
|
||||
<VImg :src="data" />
|
||||
</VAvatar>
|
||||
<VAvatar
|
||||
v-if="item.extraMembers"
|
||||
:color="$vuetify.theme.current.dark ? '#373b50' : '#eeedf0'"
|
||||
:size="26"
|
||||
>
|
||||
<div class="text-caption text-high-emphasis">
|
||||
+{{ item.extraMembers }}
|
||||
</div>
|
||||
</VAvatar>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- Progress -->
|
||||
<template #item.progress="{ item }">
|
||||
<div class="d-flex align-center gap-3">
|
||||
<div class="flex-grow-1">
|
||||
<VProgressLinear
|
||||
:height="6"
|
||||
:model-value="item.progress"
|
||||
color="primary"
|
||||
rounded
|
||||
/>
|
||||
</div>
|
||||
<div class="text-body-1 text-high-emphasis">
|
||||
{{ item.progress }}%
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- Action -->
|
||||
<template #item.Action>
|
||||
<MoreBtn :menu-list="moreList" />
|
||||
</template>
|
||||
|
||||
<!-- TODO Refactor this after vuetify provides proper solution for removing default footer -->
|
||||
<template #bottom>
|
||||
<TablePagination
|
||||
v-model:page="options.page"
|
||||
:items-per-page="options.itemsPerPage"
|
||||
:total-items="projects.length"
|
||||
/>
|
||||
</template>
|
||||
</VDataTable>
|
||||
<!-- !SECTION -->
|
||||
</VCard>
|
||||
</VCol>
|
||||
|
||||
<VCol cols="12">
|
||||
<!-- 👉 User Activity timeline -->
|
||||
<VCard title="User Activity Timeline">
|
||||
<VCardText>
|
||||
<VTimeline
|
||||
side="end"
|
||||
align="start"
|
||||
line-inset="8"
|
||||
truncate-line="start"
|
||||
density="compact"
|
||||
>
|
||||
<!-- SECTION Timeline Item: Flight -->
|
||||
<VTimelineItem
|
||||
dot-color="primary"
|
||||
size="x-small"
|
||||
>
|
||||
<!-- 👉 Header -->
|
||||
<div class="d-flex justify-space-between align-center gap-2 flex-wrap mb-2">
|
||||
<span class="app-timeline-title">
|
||||
12 Invoices have been paid
|
||||
</span>
|
||||
<span class="app-timeline-meta">12 min ago</span>
|
||||
</div>
|
||||
|
||||
<!-- 👉 Content -->
|
||||
<div class="app-timeline-text mt-1">
|
||||
Invoices have been paid to the company
|
||||
</div>
|
||||
|
||||
<div class="d-inline-flex align-center timeline-chip mt-2">
|
||||
<img
|
||||
:src="pdf"
|
||||
height="20"
|
||||
class="me-2"
|
||||
alt="img"
|
||||
>
|
||||
<span class="app-timeline-text font-weight-medium">
|
||||
invoice.pdf
|
||||
</span>
|
||||
</div>
|
||||
</VTimelineItem>
|
||||
<!-- !SECTION -->
|
||||
|
||||
<!-- SECTION Timeline Item: Interview Schedule -->
|
||||
<VTimelineItem
|
||||
size="x-small"
|
||||
dot-color="success"
|
||||
>
|
||||
<!-- 👉 Header -->
|
||||
<div class="d-flex justify-space-between align-center flex-wrap mb-2">
|
||||
<div class="app-timeline-title">
|
||||
Client Meeting
|
||||
</div>
|
||||
<span class="app-timeline-meta">45 min ago</span>
|
||||
</div>
|
||||
|
||||
<div class="app-timeline-text mt-1">
|
||||
Project meeting with john @10:15am
|
||||
</div>
|
||||
|
||||
<!-- 👉 Person -->
|
||||
<div class="d-flex justify-space-between align-center flex-wrap">
|
||||
<!-- 👉 Avatar & Personal Info -->
|
||||
<div class="d-flex align-center mt-2">
|
||||
<VAvatar
|
||||
size="32"
|
||||
class="me-2"
|
||||
:image="avatar1"
|
||||
/>
|
||||
<div class="d-flex flex-column">
|
||||
<p class="text-sm font-weight-medium text-medium-emphasis mb-0">
|
||||
Lester McCarthy (Client)
|
||||
</p>
|
||||
<span class="text-sm">CEO of Pixinvent</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</VTimelineItem>
|
||||
<!-- !SECTION -->
|
||||
|
||||
<!-- SECTION Design Review -->
|
||||
<VTimelineItem
|
||||
size="x-small"
|
||||
dot-color="info"
|
||||
>
|
||||
<!-- 👉 Header -->
|
||||
<div class="d-flex justify-space-between align-center flex-wrap mb-2">
|
||||
<span class="app-timeline-title">
|
||||
Create a new project for client
|
||||
</span>
|
||||
<span class="app-timeline-meta">2 Day Ago</span>
|
||||
</div>
|
||||
|
||||
<!-- 👉 Content -->
|
||||
<p class="app-timeline-text mt-1 mb-2">
|
||||
6 team members in a project
|
||||
</p>
|
||||
|
||||
<div class="v-avatar-group demo-avatar-group">
|
||||
<VAvatar :size="40">
|
||||
<VImg :src="avatar1" />
|
||||
<VTooltip
|
||||
activator="parent"
|
||||
location="top"
|
||||
>
|
||||
John Doe
|
||||
</VTooltip>
|
||||
</VAvatar>
|
||||
|
||||
<VAvatar :size="40">
|
||||
<VImg :src="avatar2" />
|
||||
<VTooltip
|
||||
activator="parent"
|
||||
location="top"
|
||||
>
|
||||
Jennie Obrien
|
||||
</VTooltip>
|
||||
</VAvatar>
|
||||
|
||||
<VAvatar :size="40">
|
||||
<VImg :src="avatar3" />
|
||||
<VTooltip
|
||||
activator="parent"
|
||||
location="top"
|
||||
>
|
||||
Peter Harper
|
||||
</VTooltip>
|
||||
</VAvatar>
|
||||
|
||||
<VAvatar
|
||||
:size="40"
|
||||
:color="$vuetify.theme.current.dark ? '#373b50' : '#eeedf0'"
|
||||
>
|
||||
+3
|
||||
</VAvatar>
|
||||
</div>
|
||||
</VTimelineItem>
|
||||
<!-- !SECTION -->
|
||||
</VTimeline>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
</VCol>
|
||||
|
||||
<VCol cols="12">
|
||||
<UserInvoiceTable />
|
||||
</VCol>
|
||||
</VRow>
|
||||
</template>
|
||||
425
resources/js/views/apps/user/view/UserTabBillingsPlans.vue
Normal file
425
resources/js/views/apps/user/view/UserTabBillingsPlans.vue
Normal file
@@ -0,0 +1,425 @@
|
||||
<script setup>
|
||||
import americanExpress from '@images/icons/payments/american-express.png'
|
||||
import mastercard from '@images/icons/payments/mastercard.png'
|
||||
import visa from '@images/icons/payments/visa.png'
|
||||
|
||||
const isUpgradePlanDialogVisible = ref(false)
|
||||
const currentCardDetails = ref()
|
||||
const isCardEditDialogVisible = ref(false)
|
||||
const isCardAddDialogVisible = ref(false)
|
||||
const isEditAddressDialogVisible = ref(false)
|
||||
|
||||
const openEditCardDialog = cardDetails => {
|
||||
currentCardDetails.value = cardDetails
|
||||
isCardEditDialogVisible.value = true
|
||||
}
|
||||
|
||||
const creditCards = [
|
||||
{
|
||||
name: 'Tom McBride',
|
||||
number: '4851234567899865',
|
||||
expiry: '12/24',
|
||||
isPrimary: true,
|
||||
isExpired: false,
|
||||
type: 'mastercard',
|
||||
cvv: '123',
|
||||
image: mastercard,
|
||||
},
|
||||
{
|
||||
name: 'Mildred Wagner',
|
||||
number: '5531234567895678',
|
||||
expiry: '02/24',
|
||||
isPrimary: false,
|
||||
isExpired: false,
|
||||
type: 'visa',
|
||||
cvv: '456',
|
||||
image: visa,
|
||||
},
|
||||
{
|
||||
name: 'Lester Jennings',
|
||||
number: '5531234567890002',
|
||||
expiry: '08/20',
|
||||
isPrimary: false,
|
||||
isExpired: true,
|
||||
type: 'visa',
|
||||
cvv: '456',
|
||||
image: americanExpress,
|
||||
},
|
||||
]
|
||||
|
||||
const currentAddress = {
|
||||
companyName: 'Pixinvent',
|
||||
billingEmail: 'gertrude@gmail.com',
|
||||
taxID: 'TAX-875623',
|
||||
vatNumber: 'SDF754K77',
|
||||
address: '100 Water Plant Avenue, Building 1303 Wake Island',
|
||||
contact: '+1(609) 933-44-22',
|
||||
country: 'USA',
|
||||
state: 'Queensland',
|
||||
zipCode: 403114,
|
||||
}
|
||||
|
||||
const currentBillingAddress = {
|
||||
firstName: 'Shamus',
|
||||
lastName: 'Tuttle',
|
||||
selectedCountry: 'USA',
|
||||
addressLine1: '45 Rocker Terrace',
|
||||
addressLine2: 'Latheronwheel',
|
||||
landmark: 'KW5 8NW, London',
|
||||
contact: '+1 (609) 972-22-22',
|
||||
country: 'USA',
|
||||
city: 'London',
|
||||
state: 'London',
|
||||
zipCode: 110001,
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VRow>
|
||||
<!-- 👉 Current Plan -->
|
||||
<VCol cols="12">
|
||||
<VCard title="Current Plan">
|
||||
<VCardText>
|
||||
<VRow>
|
||||
<VCol
|
||||
cols="12"
|
||||
md="6"
|
||||
order-md="1"
|
||||
order="2"
|
||||
>
|
||||
<h6 class="text-h6 mb-1">
|
||||
Your Current Plan is Basic
|
||||
</h6>
|
||||
<p>
|
||||
A simple start for everyone
|
||||
</p>
|
||||
|
||||
<h6 class="text-h6 mb-1">
|
||||
Active until Dec 09, 2021
|
||||
</h6>
|
||||
<p>
|
||||
We will send you a notification upon Subscription expiration
|
||||
</p>
|
||||
|
||||
<h6 class="text-h6 mb-1">
|
||||
<span class="d-inline-block me-2">$99 Per Month</span>
|
||||
<VChip
|
||||
color="primary"
|
||||
size="small"
|
||||
label
|
||||
>
|
||||
Popular
|
||||
</VChip>
|
||||
</h6>
|
||||
<p class="mb-0">
|
||||
Standard plan for small to medium businesses
|
||||
</p>
|
||||
</VCol>
|
||||
|
||||
<VCol
|
||||
cols="12"
|
||||
md="6"
|
||||
order-md="2"
|
||||
order="1"
|
||||
>
|
||||
<!-- 👉 Alert -->
|
||||
<VAlert
|
||||
color="warning"
|
||||
variant="tonal"
|
||||
>
|
||||
<VAlertTitle class="mb-1">
|
||||
We need your attention!
|
||||
</VAlertTitle>
|
||||
<div class="text-base">
|
||||
Your plan requires update
|
||||
</div>
|
||||
</VAlert>
|
||||
|
||||
<!-- 👉 Progress -->
|
||||
<div class="d-flex justify-space-between font-weight-bold mt-4 mb-2">
|
||||
<h6 class="text-h6">
|
||||
Days
|
||||
</h6>
|
||||
<h6 class="text-h6">
|
||||
26 of 30 Days
|
||||
</h6>
|
||||
</div>
|
||||
|
||||
<VProgressLinear
|
||||
rounded
|
||||
color="primary"
|
||||
:height="10"
|
||||
:model-value="75"
|
||||
/>
|
||||
<p class="text-sm mt-1">
|
||||
Your plan requires update
|
||||
</p>
|
||||
</VCol>
|
||||
|
||||
<VCol
|
||||
cols="12"
|
||||
order="3"
|
||||
>
|
||||
<div class="d-flex flex-wrap gap-4">
|
||||
<VBtn @click="isUpgradePlanDialogVisible = true">
|
||||
upgrade plan
|
||||
</VBtn>
|
||||
|
||||
<VBtn
|
||||
color="error"
|
||||
variant="tonal"
|
||||
>
|
||||
Cancel Subscription
|
||||
</VBtn>
|
||||
</div>
|
||||
</VCol>
|
||||
</VRow>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
</VCol>
|
||||
|
||||
<!-- 👉 Payment Methods -->
|
||||
<VCol cols="12">
|
||||
<VCard title="Payment Methods">
|
||||
<template #append>
|
||||
<VBtn
|
||||
prepend-icon="tabler-plus"
|
||||
size="small"
|
||||
@click="isCardAddDialogVisible = !isCardAddDialogVisible"
|
||||
>
|
||||
Add Card
|
||||
</VBtn>
|
||||
</template>
|
||||
|
||||
<VCardText class="d-flex flex-column gap-y-4">
|
||||
<VCard
|
||||
v-for="card in creditCards"
|
||||
:key="card.name"
|
||||
border
|
||||
flat
|
||||
>
|
||||
<VCardText class="d-flex flex-sm-row flex-column gap-6 justify-space-between">
|
||||
<div class="text-no-wrap">
|
||||
<img
|
||||
:src="card.image"
|
||||
:height="25"
|
||||
>
|
||||
<div class="my-2 d-flex gap-x-2 align-center">
|
||||
<h6 class="text-h6">
|
||||
{{ card.name }}
|
||||
</h6>
|
||||
<VChip
|
||||
v-if="card.isPrimary || card.isExpired"
|
||||
label
|
||||
:color="card.isPrimary ? 'primary' : card.isExpired ? 'error' : 'secondary'"
|
||||
size="small"
|
||||
>
|
||||
{{ card.isPrimary ? 'Popular' : card.isExpired ? 'Expired' : '' }}
|
||||
</VChip>
|
||||
</div>
|
||||
<div class="text-body-1">
|
||||
**** **** **** {{ card.number.substring(card.number.length - 4) }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="d-flex flex-column text-sm-end gap-y-4">
|
||||
<div class="order-sm-0 order-1">
|
||||
<VBtn
|
||||
variant="tonal"
|
||||
size="small"
|
||||
class="me-4"
|
||||
@click="openEditCardDialog(card)"
|
||||
>
|
||||
Edit
|
||||
</VBtn>
|
||||
<VBtn
|
||||
color="error"
|
||||
variant="tonal"
|
||||
size="small"
|
||||
>
|
||||
Delete
|
||||
</VBtn>
|
||||
</div>
|
||||
|
||||
<div class="order-sm-1 order-0 text-sm">
|
||||
Card expires at {{ card.expiry }}
|
||||
</div>
|
||||
</div>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
</VCol>
|
||||
|
||||
<VCol cols="12">
|
||||
<!-- 👉 Billing Address -->
|
||||
<VCard title="Billing Address">
|
||||
<template #append>
|
||||
<VBtn
|
||||
size="small"
|
||||
prepend-icon="tabler-plus"
|
||||
@click="isEditAddressDialogVisible = !isEditAddressDialogVisible"
|
||||
>
|
||||
Edit Address
|
||||
</VBtn>
|
||||
</template>
|
||||
|
||||
<VCardText>
|
||||
<VRow>
|
||||
<VCol
|
||||
cols="12"
|
||||
lg="6"
|
||||
>
|
||||
<VTable class="billing-address-table">
|
||||
<tr>
|
||||
<td>
|
||||
<h6 class="text-h6 text-no-wrap mb-2">
|
||||
Company Name:
|
||||
</h6>
|
||||
</td>
|
||||
<td>
|
||||
<p class="text-body-1 mb-2">
|
||||
{{ currentAddress.companyName }}
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<h6 class="text-h6 text-no-wrap mb-2">
|
||||
Billing Email:
|
||||
</h6>
|
||||
</td>
|
||||
<td>
|
||||
<p class="text-body-1 mb-2">
|
||||
{{ currentAddress.billingEmail }}
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<h6 class="text-h6 text-no-wrap mb-2">
|
||||
Tax ID:
|
||||
</h6>
|
||||
</td>
|
||||
<td>
|
||||
<p class="text-body-1 mb-2">
|
||||
{{ currentAddress.taxID }}
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<h6 class="text-h6 text-no-wrap mb-2">
|
||||
VAT Number:
|
||||
</h6>
|
||||
</td>
|
||||
<td>
|
||||
<p class="text-body-1 mb-2">
|
||||
{{ currentAddress.vatNumber }}
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="d-flex align-baseline">
|
||||
<h6 class="text-h6 text-no-wrap">
|
||||
Billing Address:
|
||||
</h6>
|
||||
</td>
|
||||
<td>
|
||||
<p class="text-body-1 mb-2">
|
||||
{{ currentAddress.address }}
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</VTable>
|
||||
</VCol>
|
||||
|
||||
<VCol
|
||||
cols="12"
|
||||
lg="6"
|
||||
>
|
||||
<VTable class="billing-address-table">
|
||||
<tr>
|
||||
<td>
|
||||
<h6 class="text-h6 text-no-wrap mb-2">
|
||||
Contact:
|
||||
</h6>
|
||||
</td>
|
||||
<td>
|
||||
<p class="text-body-1 mb-2">
|
||||
{{ currentAddress.contact }}
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<h6 class="text-h6 text-no-wrap mb-2">
|
||||
Country:
|
||||
</h6>
|
||||
</td>
|
||||
<td>
|
||||
<p class="text-body-1 mb-2">
|
||||
{{ currentAddress.country }}
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<h6 class="text-h6 text-no-wrap mb-2">
|
||||
State:
|
||||
</h6>
|
||||
</td>
|
||||
<td>
|
||||
<p class="text-body-1 mb-2">
|
||||
{{ currentAddress.state }}
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<h6 class="text-h6 text-no-wrap mb-2">
|
||||
Zip Code:
|
||||
</h6>
|
||||
</td>
|
||||
<td>
|
||||
<p class="text-body-1 mb-2">
|
||||
{{ currentAddress.zipCode }}
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</VTable>
|
||||
</VCol>
|
||||
</VRow>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
</VCol>
|
||||
</VRow>
|
||||
|
||||
<!-- 👉 Edit Card Dialog -->
|
||||
<CardAddEditDialog
|
||||
v-model:is-dialog-visible="isCardEditDialogVisible"
|
||||
:card-details="currentCardDetails"
|
||||
/>
|
||||
|
||||
<!-- 👉 Add Card Dialog -->
|
||||
<CardAddEditDialog v-model:is-dialog-visible="isCardAddDialogVisible" />
|
||||
|
||||
<!-- 👉 Edit Address dialog -->
|
||||
<AddEditAddressDialog
|
||||
v-model:is-dialog-visible="isEditAddressDialogVisible"
|
||||
:billing-address="currentBillingAddress"
|
||||
/>
|
||||
|
||||
<!-- 👉 Upgrade plan dialog -->
|
||||
<UserUpgradePlanDialog v-model:is-dialog-visible="isUpgradePlanDialogVisible" />
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
.billing-address-table {
|
||||
tr {
|
||||
td:first-child {
|
||||
inline-size: 148px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
181
resources/js/views/apps/user/view/UserTabConnections.vue
Normal file
181
resources/js/views/apps/user/view/UserTabConnections.vue
Normal file
@@ -0,0 +1,181 @@
|
||||
<script setup>
|
||||
import asana from '@images/icons/brands/asana.png'
|
||||
import behance from '@images/icons/brands/behance.png'
|
||||
import dribbble from '@images/icons/brands/dribbble.png'
|
||||
import facebook from '@images/icons/brands/facebook.png'
|
||||
import github from '@images/icons/brands/github.png'
|
||||
import google from '@images/icons/brands/google.png'
|
||||
import linkedin from '@images/icons/brands/linkedin.png'
|
||||
import mailchimp from '@images/icons/brands/mailchimp.png'
|
||||
import slack from '@images/icons/brands/slack.png'
|
||||
import twitter from '@images/icons/brands/twitter.png'
|
||||
|
||||
const connectedAccounts = ref([
|
||||
{
|
||||
img: google,
|
||||
title: 'Google',
|
||||
text: 'Calendar and contacts',
|
||||
connected: true,
|
||||
},
|
||||
{
|
||||
img: slack,
|
||||
title: 'Slack',
|
||||
text: 'Communication',
|
||||
connected: false,
|
||||
},
|
||||
{
|
||||
img: github,
|
||||
title: 'GitHub',
|
||||
text: 'Manage your Git repositories',
|
||||
connected: true,
|
||||
},
|
||||
{
|
||||
img: mailchimp,
|
||||
title: 'Mailchimp',
|
||||
text: 'Email marketing service',
|
||||
connected: false,
|
||||
},
|
||||
{
|
||||
img: asana,
|
||||
title: 'Asana',
|
||||
text: 'Communication',
|
||||
connected: false,
|
||||
},
|
||||
])
|
||||
|
||||
const socialAccounts = ref([
|
||||
{
|
||||
img: facebook,
|
||||
title: 'Facebook',
|
||||
connected: false,
|
||||
},
|
||||
{
|
||||
img: twitter,
|
||||
title: 'Twitter',
|
||||
link: 'https://twitter.com/pixinvents',
|
||||
username: '@Pixinvent',
|
||||
connected: true,
|
||||
},
|
||||
{
|
||||
img: linkedin,
|
||||
title: 'LinkedIn',
|
||||
link: 'https://www.linkedin.com/company/pixinvent',
|
||||
username: '@Pixinvent',
|
||||
connected: true,
|
||||
},
|
||||
{
|
||||
img: dribbble,
|
||||
title: 'Dribbble',
|
||||
connected: false,
|
||||
},
|
||||
{
|
||||
img: behance,
|
||||
title: 'Behance',
|
||||
connected: false,
|
||||
},
|
||||
])
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VRow>
|
||||
<!-- 👉 connected accounts -->
|
||||
<VCol cols="12">
|
||||
<VCard
|
||||
title="Connected Accounts"
|
||||
subtitle="Display content from your connected accounts on your site"
|
||||
>
|
||||
<VCardText>
|
||||
<VList class="card-list">
|
||||
<VListItem
|
||||
v-for="account in connectedAccounts"
|
||||
:key="account.title"
|
||||
:subtitle="account.text"
|
||||
>
|
||||
<template #title>
|
||||
<h6 class="text-h6">
|
||||
{{ account.title }}
|
||||
</h6>
|
||||
</template>
|
||||
<template #prepend>
|
||||
<VAvatar
|
||||
start
|
||||
:size="36"
|
||||
:image="account.img"
|
||||
class="me-1"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<template #append>
|
||||
<VSwitch
|
||||
v-model="account.connected"
|
||||
density="compact"
|
||||
class="me-1"
|
||||
/>
|
||||
</template>
|
||||
</VListItem>
|
||||
</VList>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
</VCol>
|
||||
|
||||
<!-- 👉 social accounts -->
|
||||
<VCol cols="12">
|
||||
<VCard
|
||||
title="Social Accounts"
|
||||
subtitle="Display content from social accounts on your site"
|
||||
>
|
||||
<VCardText>
|
||||
<VList class="card-list">
|
||||
<VListItem
|
||||
v-for="(account) in socialAccounts"
|
||||
:key="account.title"
|
||||
>
|
||||
<h6 class="text-h6">
|
||||
{{ account.title }}
|
||||
</h6>
|
||||
<template #prepend>
|
||||
<VAvatar
|
||||
start
|
||||
size="36"
|
||||
rounded="0"
|
||||
class="me-1"
|
||||
:image="account.img"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<VListItemSubtitle v-if="account.connected">
|
||||
<a
|
||||
:href="account.link"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
{{ account.username }}
|
||||
</a>
|
||||
</VListItemSubtitle>
|
||||
|
||||
<VListItemSubtitle v-else>
|
||||
Not connected
|
||||
</VListItemSubtitle>
|
||||
|
||||
<template #append>
|
||||
<IconBtn
|
||||
variant="tonal"
|
||||
:color="account.connected ? 'error' : 'secondary'"
|
||||
class="rounded"
|
||||
>
|
||||
<VIcon :icon="account.connected ? 'tabler-trash' : 'tabler-link'" />
|
||||
</IconBtn>
|
||||
</template>
|
||||
</VListItem>
|
||||
</VList>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
</VCol>
|
||||
</VRow>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.card-list {
|
||||
--v-card-list-gap: 16px;
|
||||
}
|
||||
</style>
|
||||
89
resources/js/views/apps/user/view/UserTabNotifications.vue
Normal file
89
resources/js/views/apps/user/view/UserTabNotifications.vue
Normal file
@@ -0,0 +1,89 @@
|
||||
<script setup>
|
||||
const notifications = ref([
|
||||
{
|
||||
type: 'New for you',
|
||||
email: true,
|
||||
browser: false,
|
||||
app: false,
|
||||
},
|
||||
{
|
||||
type: 'Account activity',
|
||||
email: false,
|
||||
browser: true,
|
||||
app: true,
|
||||
},
|
||||
{
|
||||
type: 'A new browser used to sign in',
|
||||
email: true,
|
||||
browser: true,
|
||||
app: true,
|
||||
},
|
||||
{
|
||||
type: 'A new device is linked',
|
||||
email: false,
|
||||
browser: true,
|
||||
app: false,
|
||||
},
|
||||
])
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VCard
|
||||
class="user-tab-notification"
|
||||
title="Notifications"
|
||||
subtitle="You will receive notification for the below selected items."
|
||||
>
|
||||
<VCardText class="px-0">
|
||||
<VDivider />
|
||||
<VTable class="text-no-wrap">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">
|
||||
TYPE
|
||||
</th>
|
||||
<th scope="col">
|
||||
EMAIL
|
||||
</th>
|
||||
<th scope="col">
|
||||
BROWSER
|
||||
</th>
|
||||
<th scope="col">
|
||||
APP
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
<tr
|
||||
v-for="notification in notifications"
|
||||
:key="notification.type"
|
||||
>
|
||||
<td class="text-high-emphasis">
|
||||
{{ notification.type }}
|
||||
</td>
|
||||
<td>
|
||||
<VCheckbox v-model="notification.email" />
|
||||
</td>
|
||||
<td>
|
||||
<VCheckbox v-model="notification.browser" />
|
||||
</td>
|
||||
<td>
|
||||
<VCheckbox v-model="notification.app" />
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</VTable>
|
||||
<VDivider />
|
||||
</VCardText>
|
||||
|
||||
<VCardText class="d-flex flex-wrap gap-4">
|
||||
<VBtn>Save changes</VBtn>
|
||||
<VBtn
|
||||
color="secondary"
|
||||
variant="tonal"
|
||||
>
|
||||
Discard
|
||||
</VBtn>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
</template>
|
||||
188
resources/js/views/apps/user/view/UserTabSecurity.vue
Normal file
188
resources/js/views/apps/user/view/UserTabSecurity.vue
Normal file
@@ -0,0 +1,188 @@
|
||||
<script setup>
|
||||
const isNewPasswordVisible = ref(false)
|
||||
const isConfirmPasswordVisible = ref(false)
|
||||
const smsVerificationNumber = ref('+1(968) 819-2547')
|
||||
const isTwoFactorDialogOpen = ref(false)
|
||||
|
||||
const recentDeviceHeader = [
|
||||
{
|
||||
title: 'BROWSER',
|
||||
key: 'browser',
|
||||
},
|
||||
{
|
||||
title: 'DEVICE',
|
||||
key: 'device',
|
||||
},
|
||||
{
|
||||
title: 'LOCATION',
|
||||
key: 'location',
|
||||
},
|
||||
{
|
||||
title: 'RECENT ACTIVITY',
|
||||
key: 'activity',
|
||||
},
|
||||
]
|
||||
|
||||
const recentDevices = [
|
||||
{
|
||||
browser: ' Chrome on Windows',
|
||||
icon: 'tabler-brand-windows',
|
||||
color: 'info',
|
||||
device: 'HP Spectre 360',
|
||||
location: 'Switzerland',
|
||||
activity: '10, July 2021 20:07',
|
||||
},
|
||||
{
|
||||
browser: 'Chrome on Android',
|
||||
icon: 'tabler-brand-android',
|
||||
color: 'success',
|
||||
device: 'Oneplus 9 Pro',
|
||||
location: 'Dubai',
|
||||
activity: '14, July 2021 15:15',
|
||||
},
|
||||
{
|
||||
browser: 'Chrome on macOS',
|
||||
icon: 'tabler-brand-apple',
|
||||
color: 'secondary',
|
||||
device: 'Apple iMac',
|
||||
location: 'India',
|
||||
activity: '16, July 2021 16:17',
|
||||
},
|
||||
{
|
||||
browser: 'Chrome on iPhone',
|
||||
icon: 'tabler-device-mobile',
|
||||
color: 'error',
|
||||
device: 'iPhone 12x',
|
||||
location: 'Australia',
|
||||
activity: '13, July 2021 10:10',
|
||||
},
|
||||
]
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VRow>
|
||||
<VCol cols="12">
|
||||
<!-- 👉 Change password -->
|
||||
<VCard title="Change Password">
|
||||
<VCardText>
|
||||
<VAlert
|
||||
closable
|
||||
variant="tonal"
|
||||
color="warning"
|
||||
class="mb-4"
|
||||
title="Ensure that these requirements are met"
|
||||
text="Minimum 8 characters long, uppercase & symbol"
|
||||
/>
|
||||
|
||||
<VForm @submit.prevent="() => { }">
|
||||
<VRow>
|
||||
<VCol
|
||||
cols="12"
|
||||
md="6"
|
||||
>
|
||||
<AppTextField
|
||||
label="New Password"
|
||||
placeholder="············"
|
||||
:type="isNewPasswordVisible ? 'text' : 'password'"
|
||||
:append-inner-icon="isNewPasswordVisible ? 'tabler-eye-off' : 'tabler-eye'"
|
||||
@click:append-inner="isNewPasswordVisible = !isNewPasswordVisible"
|
||||
/>
|
||||
</VCol>
|
||||
<VCol
|
||||
cols="12"
|
||||
md="6"
|
||||
>
|
||||
<AppTextField
|
||||
label="Confirm Password"
|
||||
autocomplete="confirm-password"
|
||||
placeholder="············"
|
||||
:type="isConfirmPasswordVisible ? 'text' : 'password'"
|
||||
:append-inner-icon="isConfirmPasswordVisible ? 'tabler-eye-off' : 'tabler-eye'"
|
||||
@click:append-inner="isConfirmPasswordVisible = !isConfirmPasswordVisible"
|
||||
/>
|
||||
</VCol>
|
||||
|
||||
<VCol cols="12">
|
||||
<VBtn type="submit">
|
||||
Change Password
|
||||
</VBtn>
|
||||
</VCol>
|
||||
</VRow>
|
||||
</VForm>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
</VCol>
|
||||
|
||||
<VCol cols="12">
|
||||
<!-- 👉 Two step verification -->
|
||||
<VCard
|
||||
title="Two-steps verification"
|
||||
subtitle="Keep your account secure with authentication step."
|
||||
>
|
||||
<VCardText>
|
||||
<div class="text-h6 mb-1">
|
||||
SMS
|
||||
</div>
|
||||
<AppTextField placeholder="+1(968) 819-2547">
|
||||
<template #append>
|
||||
<IconBtn color="secondary">
|
||||
<VIcon
|
||||
icon="tabler-edit"
|
||||
size="22"
|
||||
/>
|
||||
</IconBtn>
|
||||
<IconBtn color="secondary">
|
||||
<VIcon
|
||||
icon="tabler-user-plus"
|
||||
size="22"
|
||||
/>
|
||||
</IconBtn>
|
||||
</template>
|
||||
</AppTextField>
|
||||
|
||||
<p class="mb-0 mt-4">
|
||||
Two-factor authentication adds an additional layer of security to your account by requiring more than just a password to log in. <a
|
||||
href="javascript:void(0)"
|
||||
class="text-decoration-none"
|
||||
>Learn more</a>.
|
||||
</p>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
</VCol>
|
||||
|
||||
<VCol cols="12">
|
||||
<!-- 👉 Recent devices -->
|
||||
|
||||
<VCard title="Recent devices">
|
||||
<VDivider />
|
||||
<VDataTable
|
||||
:items="recentDevices"
|
||||
:headers="recentDeviceHeader"
|
||||
hide-default-footer
|
||||
class="text-no-wrap"
|
||||
>
|
||||
<template #item.browser="{ item }">
|
||||
<div class="d-flex align-center gap-x-4">
|
||||
<VIcon
|
||||
:icon="item.icon"
|
||||
:color="item.color"
|
||||
:size="22"
|
||||
/>
|
||||
<div class="text-body-1 text-high-emphasis">
|
||||
{{ item.browser }}
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<!-- TODO Refactor this after vuetify provides proper solution for removing default footer -->
|
||||
<template #bottom />
|
||||
</VDataTable>
|
||||
</VCard>
|
||||
</VCol>
|
||||
</VRow>
|
||||
|
||||
<!-- 👉 Enable One Time Password Dialog -->
|
||||
<TwoFactorAuthDialog
|
||||
v-model:is-dialog-visible="isTwoFactorDialogOpen"
|
||||
:sms-code="smsVerificationNumber"
|
||||
/>
|
||||
</template>
|
||||
Reference in New Issue
Block a user