diff --git a/apps/web/src/lib/components/Sidebar.svelte b/apps/web/src/lib/components/Sidebar.svelte index f184db7..282c574 100644 --- a/apps/web/src/lib/components/Sidebar.svelte +++ b/apps/web/src/lib/components/Sidebar.svelte @@ -1,661 +1,621 @@
- -
- -
- {@render children?.()} -
+ +
+ +
+ {@render children?.()} +
- -
-
- - - Contato - - Suporte - - Privacidade -
-
-
-
- Logo -
-
-
-

- Governo do Estado de Pernambuco -

-

Secretaria de Esportes

-
-
-

- © {new Date().getFullYear()} - Todos os direitos reservados -

-
-
-
- - -
+ +
+
+ + + Contato + + Suporte + + Privacidade +
+
+
+
+ Logo +
+
+
+

Governo do Estado de Pernambuco

+

Secretaria de Esportes

+
+
+

+ © {new Date().getFullYear()} - Todos os direitos reservados +

+
+
+
+ + +
{#if loginModalStore.showModal} - - + + + + + {/if} {#if showAboutModal} - - + + + {/if} {#if currentUser.data} - - + + {/if} diff --git a/apps/web/src/lib/components/chat/ChatWidget.svelte b/apps/web/src/lib/components/chat/ChatWidget.svelte index 9180f2b..1c4b0d1 100644 --- a/apps/web/src/lib/components/chat/ChatWidget.svelte +++ b/apps/web/src/lib/components/chat/ChatWidget.svelte @@ -34,9 +34,10 @@ if (!usuario) return null; // Prioridade: fotoPerfilUrl > avatar > fallback com nome - if (usuario.fotoPerfil) { - return usuario.fotoPerfil; + if (usuario.fotoPerfilUrl) { + return usuario.fotoPerfilUrl; } + if (usuario.avatar) { return getAvatarUrl(usuario.avatar); } diff --git a/apps/web/src/lib/components/chat/SalaReuniaoManager.svelte b/apps/web/src/lib/components/chat/SalaReuniaoManager.svelte index fed2242..32eb20e 100644 --- a/apps/web/src/lib/components/chat/SalaReuniaoManager.svelte +++ b/apps/web/src/lib/components/chat/SalaReuniaoManager.svelte @@ -1,487 +1,440 @@ - e.target === e.currentTarget && onClose()} -> - - + +
+ +
+ +
diff --git a/apps/web/src/routes/(dashboard)/perfil/+page.svelte b/apps/web/src/routes/(dashboard)/perfil/+page.svelte index fddfd59..0a3ab0f 100644 --- a/apps/web/src/routes/(dashboard)/perfil/+page.svelte +++ b/apps/web/src/routes/(dashboard)/perfil/+page.svelte @@ -9,6 +9,7 @@ import { generateAvatarGallery } from '$lib/utils/avatars'; import type { Id } from '@sgse-app/backend/convex/_generated/dataModel'; import { X, Calendar } from 'lucide-svelte'; + import type { FunctionReturnType } from 'convex/server'; const client = useConvexClient(); const currentUser = useQuery(api.auth.getCurrentUser, {}); @@ -28,11 +29,6 @@ let avatarSelecionado = $state(''); let mostrarBotaoCamera = $state(false); - // Estados locais para atualização imediata - let fotoPerfilLocal = $state(null); - let avatarLocal = $state(null); - let perfilCarregado = $state(false); - // Estados para Minhas Férias let mostrarWizard = $state(false); let filtroStatusFerias = $state('todos'); @@ -47,29 +43,6 @@ // Galeria de avatares (30 avatares profissionais 3D realistas) const avatarGallery = generateAvatarGallery(30); - // Carregar perfil ao montar a página para garantir dados atualizados (apenas uma vez) - $effect(() => { - if (currentUser?.data && !perfilCarregado) { - perfilCarregado = true; - } - }); - - // Sincronizar com currentUser - atualiza automaticamente quando o usuário muda - $effect(() => { - const usuario = currentUser?.data; - if (usuario) { - // Atualizar foto de perfil (pode ser null ou string) - fotoPerfilLocal = usuario.fotoPerfil ?? null; - // Atualizar avatar (pode ser undefined ou string) - avatarLocal = usuario.avatar ?? null; - } else { - // Se não há usuário, limpar estados locais - fotoPerfilLocal = null; - avatarLocal = null; - perfilCarregado = false; // Reset para permitir recarregar quando houver usuário novamente - } - }); - // FuncionarioId disponível diretamente do usuário atual const funcionarioIdDisponivel = $derived(currentUser?.data?.funcionarioId ?? null); @@ -238,14 +211,6 @@ erroUpload = ''; try { - // 1. Criar preview local IMEDIATAMENTE para feedback visual - const reader = new FileReader(); - reader.onload = (e) => { - fotoPerfilLocal = e.target?.result as string; - avatarLocal = null; - }; - reader.readAsDataURL(file); - // 2. Gerar URL de upload const uploadUrl = await client.mutation(api.usuarios.uploadFotoPerfil, {}); @@ -271,12 +236,6 @@ // 5. Aguardar um pouco para garantir que o backend processou await new Promise((resolve) => setTimeout(resolve, 300)); - // 6. Atualizar localmente com a URL retornada pelo backend (ou pelo currentUser) - if (currentUser?.data?.fotoPerfil) { - fotoPerfilLocal = currentUser.data.fotoPerfil; - avatarLocal = null; - } - // 8. Limpar o input para permitir novo upload input.value = ''; @@ -299,12 +258,8 @@ } catch (e: unknown) { const errorMessage = e instanceof Error ? e.message : String(e); erroUpload = errorMessage || 'Erro ao fazer upload da foto'; - // Reverter mudança local se houver erro - fotoPerfilLocal = currentUser?.data?.fotoPerfil || null; - avatarLocal = currentUser?.data?.avatar || null; - } finally { - uploadandoFoto = false; } + uploadandoFoto = false; } async function handleSelecionarAvatar(avatarUrl: string) { @@ -312,25 +267,12 @@ erroUpload = ''; try { - // 1. Atualizar localmente IMEDIATAMENTE para feedback visual instantâneo - avatarLocal = avatarUrl; - fotoPerfilLocal = null; - // 2. Salvar avatar selecionado no backend await client.mutation(api.usuarios.atualizarPerfil, { avatar: avatarUrl, fotoPerfil: undefined // Remove foto se colocar avatar }); - // 3. Aguardar um pouco para garantir que o backend processou - await new Promise((resolve) => setTimeout(resolve, 300)); - - // 4. Garantir que os estados locais estão sincronizados com o usuário atual - if (currentUser?.data?.avatar) { - avatarLocal = currentUser.data.avatar; - fotoPerfilLocal = null; - } - // 6. Fechar modal após sucesso mostrarModalFoto = false; @@ -350,9 +292,6 @@ } catch (e: unknown) { const errorMessage = e instanceof Error ? e.message : String(e); erroUpload = errorMessage || 'Erro ao salvar avatar'; - // Reverter mudança local se houver erro - avatarLocal = currentUser?.data?.avatar || null; - fotoPerfilLocal = currentUser?.data?.fotoPerfil || null; } finally { uploadandoFoto = false; } @@ -391,6 +330,7 @@ onmouseenter={() => (mostrarBotaoCamera = true)} onmouseleave={() => (mostrarBotaoCamera = false)} > + s