Files
panel/resources/js/views/apps/user/view/UserBioPanel.vue
2025-08-04 16:33:07 +03:30

368 lines
9.3 KiB
Vue

<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>