Files
panel/resources/js/layouts/components/UserProfile.vue
2025-08-04 16:33:07 +03:30

204 lines
4.9 KiB
Vue
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<script setup>
import { PerfectScrollbar } from 'vue3-perfect-scrollbar'
const router = useRouter()
const ability = useAbility()
// TODO: Get type from backend
const userData = useCookie('userData')
const logout = async () => {
// Remove "accessToken" from cookie
useCookie('accessToken').value = null
// Remove "userData" from cookie
userData.value = null
// Redirect to login page
await router.push('/login')
// We had to remove abilities in then block because if we don't nav menu items mutation is visible while redirecting user to login page
// Remove "userAbilities" from cookie
useCookie('userAbilityRules').value = null
// Reset ability to initial ability
ability.update([])
}
const userProfileList = [
{ type: 'divider' },
{
type: 'navItem',
icon: 'tabler-user',
title: 'Profile',
to: {
name: 'apps-user-view-id',
params: { id: 21 },
},
},
{
type: 'navItem',
icon: 'tabler-settings',
title: 'Settings',
to: {
name: 'pages-account-settings-tab',
params: { tab: 'account' },
},
},
{
type: 'navItem',
icon: 'tabler-file-dollar',
title: 'Billing Plan',
to: {
name: 'pages-account-settings-tab',
params: { tab: 'billing-plans' },
},
badgeProps: {
color: 'error',
content: '4',
},
},
{ type: 'divider' },
{
type: 'navItem',
icon: 'tabler-currency-dollar',
title: 'Pricing',
to: { name: 'pages-pricing' },
},
{
type: 'navItem',
icon: 'tabler-question-mark',
title: 'FAQ',
to: { name: 'pages-faq' },
},
]
</script>
<template>
<VBadge
v-if="userData"
dot
bordered
location="bottom right"
offset-x="1"
offset-y="2"
color="success"
>
<VAvatar
size="38"
class="cursor-pointer"
:color="!(userData && userData.avatar) ? 'primary' : undefined"
:variant="!(userData && userData.avatar) ? 'tonal' : undefined"
>
<VImg
v-if="userData && userData.avatar"
:src="userData.avatar"
/>
<VIcon
v-else
icon="tabler-user"
/>
<!-- SECTION Menu -->
<VMenu
activator="parent"
width="240"
location="bottom end"
offset="12px"
>
<VList>
<VListItem>
<div class="d-flex gap-2 align-center">
<VListItemAction>
<VBadge
dot
location="bottom right"
offset-x="3"
offset-y="3"
color="success"
bordered
>
<VAvatar
:color="!(userData && userData.avatar) ? 'primary' : undefined"
:variant="!(userData && userData.avatar) ? 'tonal' : undefined"
>
<VImg
v-if="userData && userData.avatar"
:src="userData.avatar"
/>
<VIcon
v-else
icon="tabler-user"
/>
</VAvatar>
</VBadge>
</VListItemAction>
<div>
<h6 class="text-h6 font-weight-medium">
{{ userData.fullName || userData.username }}
</h6>
<VListItemSubtitle class="text-capitalize text-disabled">
{{ userData.role }}
</VListItemSubtitle>
</div>
</div>
</VListItem>
<PerfectScrollbar :options="{ wheelPropagation: false }">
<template
v-for="item in userProfileList"
:key="item.title"
>
<VListItem
v-if="item.type === 'navItem'"
:to="item.to"
>
<template #prepend>
<VIcon
:icon="item.icon"
size="22"
/>
</template>
<VListItemTitle>{{ item.title }}</VListItemTitle>
<template
v-if="item.badgeProps"
#append
>
<VBadge
rounded="sm"
class="me-3"
v-bind="item.badgeProps"
/>
</template>
</VListItem>
<VDivider
v-else
class="my-2"
/>
</template>
<div class="px-4 py-2">
<VBtn
block
size="small"
color="error"
append-icon="tabler-logout"
@click="logout"
>
Logout
</VBtn>
</div>
</PerfectScrollbar>
</VList>
</VMenu>
<!-- !SECTION -->
</VAvatar>
</VBadge>
</template>