122 lines
3.7 KiB
Svelte
122 lines
3.7 KiB
Svelte
<script lang="ts">
|
|
import { api } from '@sgse-app/backend/convex/_generated/api';
|
|
import { useQuery } from 'convex-svelte';
|
|
import type { FunctionReference } from 'convex/server';
|
|
import { goto } from '$app/navigation';
|
|
import { resolve } from '$app/paths';
|
|
import { page } from '$app/state';
|
|
import { LogIn, Settings, User, UserCog } from 'lucide-svelte';
|
|
import { authClient } from '$lib/auth';
|
|
import NotificationBell from '$lib/components/chat/NotificationBell.svelte';
|
|
|
|
let currentPath = $derived(page.url.pathname);
|
|
|
|
const currentUser = useQuery(api.auth.getCurrentUser as FunctionReference<'query'>, {});
|
|
|
|
// Função para obter a URL do avatar/foto do usuário
|
|
let avatarUrlDoUsuario = $derived.by(() => {
|
|
if (!currentUser.data) return null;
|
|
|
|
// Prioridade: fotoPerfilUrl > avatar > fallback com nome
|
|
if (currentUser.data.fotoPerfilUrl) {
|
|
return currentUser.data.fotoPerfilUrl;
|
|
}
|
|
|
|
if (currentUser.data.avatar) {
|
|
return currentUser.data.avatar;
|
|
}
|
|
|
|
// Fallback: retornar null para usar o ícone User do Lucide
|
|
return null;
|
|
});
|
|
|
|
function goToLogin(redirectTo?: string) {
|
|
const target = redirectTo || currentPath || '/';
|
|
goto(`${resolve('/login')}?redirect=${encodeURIComponent(target)}`);
|
|
}
|
|
|
|
async function handleLogout() {
|
|
const result = await authClient.signOut();
|
|
if (result.error) {
|
|
console.error('Sign out error:', result.error);
|
|
}
|
|
goto(resolve('/home'));
|
|
}
|
|
</script>
|
|
|
|
<div class="flex items-center gap-3">
|
|
{#if currentUser.data}
|
|
<!-- Nome e Perfil -->
|
|
<div class="hidden flex-col items-end lg:flex">
|
|
<span class="text-base-content text-sm leading-tight font-semibold"
|
|
>{currentUser.data.nome}</span
|
|
>
|
|
<span class="text-base-content/60 text-xs leading-tight">{currentUser.data.role?.nome}</span>
|
|
</div>
|
|
|
|
<div class="dropdown dropdown-end">
|
|
<!-- Botão de Perfil com Avatar -->
|
|
<button
|
|
type="button"
|
|
tabindex="0"
|
|
class="btn avatar ring-base-200 hover:ring-primary/50 h-10 w-10 p-0 ring-2 ring-offset-2 transition-all"
|
|
aria-label="Menu do usuário"
|
|
>
|
|
<div class="h-full w-full overflow-hidden rounded-full">
|
|
{#if avatarUrlDoUsuario}
|
|
<img
|
|
src={avatarUrlDoUsuario}
|
|
alt={currentUser.data?.nome || 'Usuário'}
|
|
class="h-full w-full object-cover"
|
|
/>
|
|
{:else}
|
|
<div class="bg-primary/10 text-primary flex h-full w-full items-center justify-center">
|
|
<User class="h-5 w-5" />
|
|
</div>
|
|
{/if}
|
|
</div>
|
|
</button>
|
|
|
|
<!-- svelte-ignore a11y_no_noninteractive_tabindex -->
|
|
<ul
|
|
tabindex="0"
|
|
class="dropdown-content menu bg-base-100 rounded-box ring-base-content/5 z-1 mt-3 w-56 p-2 shadow-xl ring-1"
|
|
>
|
|
<li class="menu-title border-base-200 mb-2 border-b px-4 py-2">
|
|
<span class="text-base-content font-bold">{currentUser.data?.nome}</span>
|
|
<span class="text-base-content/60 text-xs font-normal">{currentUser.data.email}</span>
|
|
</li>
|
|
<li>
|
|
<a href={resolve('/perfil')} class="active:bg-primary/10 active:text-primary"
|
|
><UserCog class="mr-2 h-4 w-4" /> Meu Perfil</a
|
|
>
|
|
</li>
|
|
<li>
|
|
<a href={resolve('/alterar-senha')} class="active:bg-primary/10 active:text-primary"
|
|
><Settings class="mr-2 h-4 w-4" /> Alterar Senha</a
|
|
>
|
|
</li>
|
|
<div class="divider my-1"></div>
|
|
<li>
|
|
<button type="button" onclick={handleLogout} class="text-error hover:bg-error/10"
|
|
><LogIn class="mr-2 h-4 w-4 rotate-180" /> Sair</button
|
|
>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
|
|
<!-- Sino de notificações -->
|
|
<div class="relative">
|
|
<NotificationBell />
|
|
</div>
|
|
{:else}
|
|
<button
|
|
type="button"
|
|
class="btn btn-primary btn-sm rounded-full px-6"
|
|
onclick={() => goToLogin()}
|
|
>
|
|
Entrar
|
|
</button>
|
|
{/if}
|
|
</div>
|