70 lines
2.7 KiB
Vue
70 lines
2.7 KiB
Vue
<script setup lang="ts">
|
|
import type { DropdownItem } from '~/types/dropdown';
|
|
import { assert } from '~~/utils/assert';
|
|
|
|
const triplit = useTriplitClient();
|
|
const { user, signOut } = useAuth();
|
|
|
|
// to prevent the user details from going blank for a
|
|
// single frame when the user logs out (yes I am that
|
|
// particular)
|
|
const cachedUser = ref(user.value);
|
|
|
|
watch(user, () => {
|
|
if (user.value === null) return;
|
|
|
|
cachedUser.value = user.value;
|
|
})
|
|
|
|
const { toggle: toggleSettings } = useSettings();
|
|
|
|
const { isHovered } = useSidenavContext();
|
|
|
|
const profileOpen = ref(false);
|
|
|
|
const handleLogout = async () => {
|
|
await signOut();
|
|
assert('disconnect' in triplit);
|
|
triplit.disconnect();
|
|
|
|
await navigateTo('/auth/login');
|
|
};
|
|
|
|
const profileItems: DropdownItem[] = [
|
|
{ label: 'Settings', icon: 'mynaui:cog-four', onClick: toggleSettings },
|
|
{
|
|
label: 'Log out',
|
|
icon: 'mynaui:logout',
|
|
divider: true,
|
|
onClick: handleLogout,
|
|
},
|
|
];
|
|
</script>
|
|
|
|
<template>
|
|
<header class="flex items-center justify-between overflow-hidden">
|
|
<Dropdown class="overflow-hidden" v-model="profileOpen" :items="profileItems" placement="left"
|
|
verticality="descending" width="100%">
|
|
<template #trigger="{ toggle }">
|
|
<button aria-label="open user dropdown"
|
|
class="flex items-center gap-1.5 pr-2 rounded-xl hover:bg-[var(--color-highlight)] focus-visible:bg-[var(--color-highlight)] cursor-pointer transition-colors max-w-full"
|
|
@click="toggle">
|
|
<div
|
|
:class="['w-[28px] h-[28px] flex-shrink-0 rounded-lg overflow-hidden bg-[var(--color-neutral)] flex items-center justify-center', user?.image ? '' : 'border border-[var(--color-highlight-high)]']">
|
|
<img v-if="cachedUser?.image" :src="cachedUser.image" class="w-full h-full object-cover" />
|
|
<Icon v-else name="mynaui:user" class="w-4 h-4 text-[var(--color-muted)]" />
|
|
</div>
|
|
<span
|
|
class="text-sm font-medium text-ellipsis overflow-hidden text-[var(--color-text)] whitespace-nowrap">{{
|
|
cachedUser?.name
|
|
}}</span>
|
|
<div :class="['transform-origin-left-center flex-shrink-0 w-4 h-4 text-[var(--color-muted)] transition-all duration-200 ease-[cubic-bezier(0.5,_1,_0.89,_1)] overflow-hidden transform-origin-center-left',
|
|
isHovered ? 'opacity-100 scale-100' : 'opacity-0 scale-40'
|
|
]">
|
|
<Icon class="text-4" name="mynaui:chevron-down" />
|
|
</div>
|
|
</button>
|
|
</template>
|
|
</Dropdown>
|
|
</header>
|
|
</template> |