158 lines
4.1 KiB
Vue
158 lines
4.1 KiB
Vue
<template>
|
|
<v-menu
|
|
v-model="menu"
|
|
:close-on-content-click="false"
|
|
location="top end"
|
|
offset="8"
|
|
origin="bottom right"
|
|
transition="slide-y-transition"
|
|
>
|
|
<template v-slot:activator="{ props: menuProps }">
|
|
<div
|
|
v-bind="menuProps"
|
|
class="d-flex align-center cursor-pointer pa-2 rounded-lg hover-bg"
|
|
>
|
|
<v-avatar size="40">
|
|
<v-img
|
|
:src="user.picture"
|
|
:alt="`${user.name} Profile`"
|
|
></v-img>
|
|
<v-badge
|
|
dot
|
|
color="orange"
|
|
location="bottom right"
|
|
offset-x="2"
|
|
offset-y="2"
|
|
></v-badge>
|
|
</v-avatar>
|
|
|
|
<div v-show="!rail" class="ml-3 flex-grow-1">
|
|
<div class="text-subtitle-2 font-weight-bold">
|
|
{{ user.name }}
|
|
</div>
|
|
<div class="text-caption text-grey">
|
|
{{ user.email }}
|
|
</div>
|
|
</div>
|
|
|
|
<v-btn v-show="!rail" icon size="small" variant="text">
|
|
<v-icon size="20">mdi-dots-vertical</v-icon>
|
|
</v-btn>
|
|
</div>
|
|
</template>
|
|
|
|
<v-card width="300" elevation="8" rounded="lg">
|
|
<v-card-text class="pa-4">
|
|
<div class="d-flex align-center mb-4">
|
|
<v-avatar size="48">
|
|
<v-img :src="user.picture"></v-img>
|
|
</v-avatar>
|
|
<div class="ml-3">
|
|
<div class="text-subtitle-1 font-weight-bold">
|
|
{{ user.name }}
|
|
</div>
|
|
<div class="text-caption text-grey">
|
|
{{ user.email }}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<v-list density="compact" class="pa-0">
|
|
<v-list-item
|
|
prepend-icon="mdi-cog-outline"
|
|
class="px-2 rounded-lg"
|
|
link
|
|
@click="handleAction('setting')"
|
|
>
|
|
<v-list-item-title class="text-body-2">Setting</v-list-item-title>
|
|
</v-list-item>
|
|
|
|
<v-list-item
|
|
prepend-icon="mdi-help-circle-outline"
|
|
class="px-2 rounded-lg"
|
|
link
|
|
@click="handleAction('help')"
|
|
>
|
|
<v-list-item-title class="text-body-2">Bantuan</v-list-item-title>
|
|
</v-list-item>
|
|
|
|
<v-divider class="my-2"></v-divider>
|
|
|
|
<v-list-item
|
|
prepend-icon="mdi-logout"
|
|
class="px-2 rounded-lg text-red"
|
|
link
|
|
@click="signOut"
|
|
:disabled="isLoggingOut"
|
|
>
|
|
<v-list-item-title class="text-body-2">
|
|
{{ isLoggingOut ? 'Log out...' : 'Log out' }}
|
|
</v-list-item-title>
|
|
</v-list-item>
|
|
</v-list>
|
|
|
|
<div class="text-caption text-grey mt-3 text-center">
|
|
v2.5.18 · Terms & Conditions
|
|
</div>
|
|
</v-card-text>
|
|
</v-card>
|
|
</v-menu>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { ref } from 'vue';
|
|
|
|
// --- PROPS & EMITS ---
|
|
const props = defineProps({
|
|
user: {
|
|
type: Object,
|
|
// Diubah menjadi required: false dengan default yang aman
|
|
required: false,
|
|
default: () => ({
|
|
name: 'Guest',
|
|
email: 'guest@rssa.com',
|
|
picture: 'https://i.pravatar.cc/150?img=33'
|
|
})
|
|
},
|
|
rail: {
|
|
type: Boolean,
|
|
default: true
|
|
}
|
|
});
|
|
const emit = defineEmits(['logout']); // Hanya emit logout
|
|
|
|
// --- STATE ---
|
|
const menu = ref(false);
|
|
const isLoggingOut = ref(false);
|
|
|
|
// --- METHODS ---
|
|
const signOut = () => {
|
|
if (isLoggingOut.value) return;
|
|
isLoggingOut.value = true;
|
|
menu.value = false;
|
|
|
|
// Memicu event untuk ditangani oleh komponen induk (SideBar)
|
|
emit('logout');
|
|
// Biarkan parent yang mengurus redirect/state global
|
|
setTimeout(() => isLoggingOut.value = false, 1000);
|
|
};
|
|
|
|
const handleAction = (action) => {
|
|
console.log(`[PopupSidebar] Action: ${action} triggered.`);
|
|
// TODO: Tambahkan logika navigasi/fungsi di sini, misal: router.push('/settings')
|
|
menu.value = false;
|
|
};
|
|
</script>
|
|
|
|
<style scoped>
|
|
/* Tambahkan kembali style yang relevan untuk aktivator di sini */
|
|
.hover-bg:hover {
|
|
background-color: #f5f5f5;
|
|
}
|
|
.cursor-pointer {
|
|
cursor: pointer;
|
|
}
|
|
.text-red {
|
|
color: rgb(244, 67, 54) !important;
|
|
}
|
|
</style> |