Files
My-KOPKB/fe/src/components/account-dropdown/AccountTrigger.vue
T
2026-07-01 13:05:21 +08:00

74 lines
2.6 KiB
Vue

<script setup lang="ts">
import { Lucide } from '@/components/ui/lucide'
import { useAuthStore } from '@/stores/auth'
interface Props {
class?: string
innerClass?: any
avatarClass?: string
textClass?: string
}
const props = defineProps<Props>()
const open = defineModel<boolean>('open', { default: false })
const authStore = useAuthStore()
function handleClick(event: MouseEvent) {
if (!window.matchMedia('(max-width: 1279px)').matches) return
event.stopPropagation()
open.value = !open.value
}
</script>
<template>
<div :class="['side-menu__account group/profile transition-[width]', props.class]">
<div :class="['flex cursor-pointer items-center transition', props.innerClass]" @click="handleClick">
<div :class="[
'relative flex-none overflow-hidden rounded-full border-4',
props.avatarClass ?? 'h-10 w-10 border-background/20 dark:border-foreground/20',
]">
<img v-if="authStore.userImageUrl" class="absolute top-0 h-full w-full object-cover"
:src="authStore.userImageUrl" :alt="authStore.userName" />
<div v-else
class="bg-primary text-primary-foreground absolute inset-0 flex items-center justify-center text-sm font-medium">
{{ authStore.userName }}
</div>
</div>
<div class="ms-3 flex w-full items-center gap-3 overflow-hidden transition-opacity
group-[.side-menu--collapsed]:group-hover:opacity-100
xl:group-[.side-menu--collapsed]:opacity-0">
<div :class="['flex-1 min-w-0', props.textClass]">
<!-- Name + Active Role -->
<div class="flex items-center gap-2">
<div class="truncate font-semibold text-sm">
{{ authStore.userName }}
</div>
<span class="shrink-0 rounded-full bg-green-500 px-2 py-0.5 text-[10px] font-medium text-white">
{{ authStore.userActiveRole }}
</span>
</div>
<!-- Position -->
<div class="mt-0.5 truncate text-xs text-slate-500">
<span class="font-medium text-slate-600">Jawatan:</span>
{{ authStore.userPosition }}
</div>
<!-- Roles Summary -->
<div class="mt-2 flex items-center gap-1 text-[11px] text-slate-500">
<Lucide icon="Shield" class="h-3 w-3" />
<span class="truncate">
{{authStore.roles.map(role => role.name).join(' • ')}}
</span>
</div>
</div>
<Lucide icon="ChevronRight"
class="h-4 w-4 flex-none text-slate-400 transition-transform group-hover:translate-x-1" />
</div>
</div>
<slot />
</div>
</template>