fix: Correct incomplete $state initialization in multiple Svelte components and pages.
This commit is contained in:
@@ -1,8 +1,7 @@
|
||||
<script lang="ts">
|
||||
import { api } from '@sgse-app/backend/convex/_generated/api';
|
||||
import type { Id, Doc } from '@sgse-app/backend/convex/_generated/dataModel';
|
||||
import { useConvexClient, useQuery } from 'convex-svelte';
|
||||
import { formatDistanceToNow } from 'date-fns';
|
||||
import { ptBR } from 'date-fns/locale';
|
||||
import { abrirConversa } from '$lib/stores/chatStore';
|
||||
import NewConversationModal from './NewConversationModal.svelte';
|
||||
import UserAvatar from './UserAvatar.svelte';
|
||||
@@ -19,8 +18,8 @@
|
||||
// Buscar conversas (grupos e salas de reunião)
|
||||
const conversas = useQuery(api.chat.listarConversas, {});
|
||||
|
||||
const searchQuery = $state('');
|
||||
const activeTab = $state<'usuarios' | 'conversas'>('usuarios');
|
||||
let searchQuery = $state('');
|
||||
let activeTab = $state<'usuarios' | 'conversas'>('usuarios');
|
||||
|
||||
// Debug: monitorar carregamento de dados
|
||||
$effect(() => {
|
||||
@@ -29,7 +28,7 @@
|
||||
console.log('🆔 [ChatList] Meu ID:', meuPerfil?.data?._id || 'Não encontrado');
|
||||
if (usuarios?.data) {
|
||||
const meuId = meuPerfil?.data?._id;
|
||||
const meusDadosNaLista = usuarios.data.find((u: any) => u._id === meuId);
|
||||
const meusDadosNaLista = usuarios.data.find((u) => u._id === meuId);
|
||||
if (meusDadosNaLista) {
|
||||
console.warn(
|
||||
'⚠️ [ChatList] ATENÇÃO: Meu usuário está na lista do backend!',
|
||||
@@ -39,7 +38,7 @@
|
||||
}
|
||||
});
|
||||
|
||||
const usuariosFiltrados = $derived.by(() => {
|
||||
let usuariosFiltrados = $derived.by(() => {
|
||||
if (!usuarios?.data || !Array.isArray(usuarios.data)) return [];
|
||||
|
||||
// Se não temos o perfil ainda, retornar lista vazia para evitar mostrar usuários incorretos
|
||||
@@ -51,10 +50,10 @@
|
||||
const meuId = meuPerfil.data._id;
|
||||
|
||||
// Filtrar o próprio usuário da lista (filtro de segurança no frontend)
|
||||
let listaFiltrada = usuarios.data.filter((u: any) => u._id !== meuId);
|
||||
let listaFiltrada = usuarios.data.filter((u) => u._id !== meuId);
|
||||
|
||||
// Log se ainda estiver na lista após filtro (não deveria acontecer)
|
||||
const aindaNaLista = listaFiltrada.find((u: any) => u._id === meuId);
|
||||
const aindaNaLista = listaFiltrada.find((u) => u._id === meuId);
|
||||
if (aindaNaLista) {
|
||||
console.error('❌ [ChatList] ERRO: Meu usuário ainda está na lista após filtro!');
|
||||
}
|
||||
@@ -63,7 +62,7 @@
|
||||
if (searchQuery.trim()) {
|
||||
const query = searchQuery.toLowerCase();
|
||||
listaFiltrada = listaFiltrada.filter(
|
||||
(u: any) =>
|
||||
(u) =>
|
||||
u.nome?.toLowerCase().includes(query) ||
|
||||
u.email?.toLowerCase().includes(query) ||
|
||||
u.matricula?.toLowerCase().includes(query)
|
||||
@@ -71,7 +70,7 @@
|
||||
}
|
||||
|
||||
// Ordenar: Online primeiro, depois por nome
|
||||
return listaFiltrada.sort((a: any, b: any) => {
|
||||
return listaFiltrada.sort((a, b) => {
|
||||
const statusOrder = {
|
||||
online: 0,
|
||||
ausente: 1,
|
||||
@@ -87,22 +86,16 @@
|
||||
});
|
||||
});
|
||||
|
||||
function formatarTempo(timestamp: number | undefined): string {
|
||||
if (!timestamp) return '';
|
||||
try {
|
||||
return formatDistanceToNow(new Date(timestamp), {
|
||||
addSuffix: true,
|
||||
locale: ptBR
|
||||
});
|
||||
} catch {
|
||||
return '';
|
||||
}
|
||||
let processando = $state(false);
|
||||
let showNewConversationModal = $state(false);
|
||||
|
||||
interface Usuario {
|
||||
_id: Id<'usuarios'>;
|
||||
nome: string;
|
||||
[key: string]: unknown;
|
||||
}
|
||||
|
||||
let processando = $state(false);
|
||||
const showNewConversationModal = $state(false);
|
||||
|
||||
async function handleClickUsuario(usuario: any) {
|
||||
async function handleClickUsuario(usuario: Usuario) {
|
||||
if (processando) {
|
||||
console.log('⏳ Já está processando uma ação, aguarde...');
|
||||
return;
|
||||
@@ -122,7 +115,7 @@
|
||||
|
||||
// Abrir a conversa
|
||||
console.log('📂 Abrindo conversa...');
|
||||
abrirConversa(conversaId as any);
|
||||
abrirConversa(conversaId as Id<'conversas'>);
|
||||
|
||||
console.log('✅ Conversa aberta com sucesso!');
|
||||
} catch (error) {
|
||||
@@ -150,21 +143,28 @@
|
||||
}
|
||||
|
||||
// Filtrar conversas por tipo e busca
|
||||
const conversasFiltradas = $derived(() => {
|
||||
let conversasFiltradas = $derived.by(() => {
|
||||
if (!conversas?.data) return [];
|
||||
|
||||
let lista = conversas.data.filter((c: any) => c.tipo === 'grupo' || c.tipo === 'sala_reuniao');
|
||||
let lista = conversas.data.filter(
|
||||
(c: Doc<'conversas'>) => c.tipo === 'grupo' || c.tipo === 'sala_reuniao'
|
||||
);
|
||||
|
||||
// Aplicar busca
|
||||
if (searchQuery.trim()) {
|
||||
const query = searchQuery.toLowerCase();
|
||||
lista = lista.filter((c: any) => c.nome?.toLowerCase().includes(query));
|
||||
lista = lista.filter((c: Doc<'conversas'>) => c.nome?.toLowerCase().includes(query));
|
||||
}
|
||||
|
||||
return lista;
|
||||
});
|
||||
|
||||
function handleClickConversa(conversa: any) {
|
||||
interface Conversa {
|
||||
_id: Id<'conversas'>;
|
||||
[key: string]: unknown;
|
||||
}
|
||||
|
||||
function handleClickConversa(conversa: Conversa) {
|
||||
if (processando) return;
|
||||
try {
|
||||
processando = true;
|
||||
@@ -178,6 +178,7 @@
|
||||
}
|
||||
</script>
|
||||
|
||||
```
|
||||
<div class="flex h-full flex-col">
|
||||
<!-- Search bar -->
|
||||
<div class="border-base-300 border-b p-4">
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
let activeConversation = $state<string | null>(null);
|
||||
|
||||
// Função para obter a URL do avatar/foto do usuário logado
|
||||
const avatarUrlDoUsuario = $derived(() => {
|
||||
let avatarUrlDoUsuario = $derived(() => {
|
||||
const usuario = currentUser?.data;
|
||||
if (!usuario) return null;
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
let isDragging = $state(false);
|
||||
let dragStart = $state({ x: 0, y: 0 });
|
||||
let isAnimating = $state(false);
|
||||
const dragThreshold = $state(5); // Distância mínima em pixels para considerar arrastar
|
||||
let dragThreshold = $state(5); // Distância mínima em pixels para considerar arrastar
|
||||
let hasMoved = $state(false); // Flag para verificar se houve movimento durante o arrastar
|
||||
let shouldPreventClick = $state(false); // Flag para prevenir clique após arrastar
|
||||
|
||||
|
||||
@@ -39,10 +39,10 @@
|
||||
|
||||
// Token é passado automaticamente via interceptadores em +layout.svelte
|
||||
|
||||
const showScheduleModal = $state(false);
|
||||
const showSalaManager = $state(false);
|
||||
const showAdminMenu = $state(false);
|
||||
const showNotificacaoModal = $state(false);
|
||||
let showScheduleModal = $state(false);
|
||||
let showSalaManager = $state(false);
|
||||
let showAdminMenu = $state(false);
|
||||
let showNotificacaoModal = $state(false);
|
||||
let iniciandoChamada = $state(false);
|
||||
let chamadaAtiva = $state<Id<'chamadas'> | null>(null);
|
||||
|
||||
@@ -56,14 +56,14 @@
|
||||
const chamadaAtivaQuery = useQuery(api.chamadas.obterChamadaAtiva, {
|
||||
conversaId: conversaId as Id<'conversas'>
|
||||
});
|
||||
const chamadaAtual = $derived(chamadaAtivaQuery?.data);
|
||||
let chamadaAtual = $derived(chamadaAtivaQuery?.data);
|
||||
|
||||
const conversas = useQuery(api.chat.listarConversas, {});
|
||||
const isAdmin = useQuery(api.chat.verificarSeEhAdmin, {
|
||||
conversaId: conversaId as Id<'conversas'>
|
||||
});
|
||||
|
||||
const conversa = $derived(() => {
|
||||
let conversa = $derived(() => {
|
||||
console.log('🔍 [ChatWindow] Buscando conversa ID:', conversaId);
|
||||
console.log('📋 [ChatWindow] Conversas disponíveis:', conversas?.data);
|
||||
|
||||
@@ -248,7 +248,7 @@
|
||||
|
||||
// Verificar se usuário é anfitrião da chamada atual
|
||||
const meuPerfil = useQuery(api.auth.getCurrentUser, {});
|
||||
const souAnfitriao = $derived(
|
||||
let souAnfitriao = $derived(
|
||||
chamadaAtual && meuPerfil?.data ? chamadaAtual.criadoPor === meuPerfil.data._id : false
|
||||
);
|
||||
</script>
|
||||
|
||||
@@ -106,20 +106,20 @@
|
||||
}
|
||||
|
||||
// Obter conversa atual
|
||||
const conversa = $derived((): ConversaComParticipantes | null => {
|
||||
let conversa = $derived((): ConversaComParticipantes | null => {
|
||||
if (!conversas?.data) return null;
|
||||
return (conversas.data as ConversaComParticipantes[]).find((c) => c._id === conversaId) || null;
|
||||
});
|
||||
|
||||
// Obter participantes para menções (apenas grupos e salas)
|
||||
const participantesParaMencoes = $derived((): ParticipanteInfo[] => {
|
||||
let participantesParaMencoes = $derived((): ParticipanteInfo[] => {
|
||||
const c = conversa();
|
||||
if (!c || (c.tipo !== 'grupo' && c.tipo !== 'sala_reuniao')) return [];
|
||||
return c.participantesInfo || [];
|
||||
});
|
||||
|
||||
// Filtrar participantes para dropdown de menções
|
||||
const participantesFiltrados = $derived((): ParticipanteInfo[] => {
|
||||
let participantesFiltrados = $derived((): ParticipanteInfo[] => {
|
||||
if (!mentionQuery.trim()) return participantesParaMencoes().slice(0, 5);
|
||||
const query = mentionQuery.toLowerCase();
|
||||
return participantesParaMencoes()
|
||||
|
||||
@@ -395,7 +395,7 @@
|
||||
}
|
||||
|
||||
// Obter informações da conversa atual
|
||||
const conversaAtual = $derived(() => {
|
||||
let conversaAtual = $derived(() => {
|
||||
if (!conversas?.data) return null;
|
||||
return (conversas.data as any[]).find((c) => c._id === conversaId) || null;
|
||||
});
|
||||
|
||||
@@ -28,14 +28,14 @@
|
||||
// Usuário atual
|
||||
const currentUser = useQuery(api.auth.getCurrentUser, {});
|
||||
|
||||
const activeTab = $state<'individual' | 'grupo' | 'sala_reuniao'>('individual');
|
||||
const searchQuery = $state('');
|
||||
let activeTab = $state<'individual' | 'grupo' | 'sala_reuniao'>('individual');
|
||||
let searchQuery = $state('');
|
||||
let selectedUsers = $state<string[]>([]);
|
||||
const groupName = $state('');
|
||||
const salaReuniaoName = $state('');
|
||||
let groupName = $state('');
|
||||
let salaReuniaoName = $state('');
|
||||
let loading = $state(false);
|
||||
|
||||
const usuariosFiltrados = $derived(() => {
|
||||
let usuariosFiltrados = $derived(() => {
|
||||
if (!usuarios?.data) return [];
|
||||
|
||||
// Filtrar o próprio usuário
|
||||
|
||||
@@ -38,16 +38,16 @@
|
||||
let limpandoNotificacoes = $state(false);
|
||||
|
||||
// Helpers para obter valores das queries
|
||||
const count = $derived((typeof countQuery === 'number' ? countQuery : countQuery?.data) ?? 0);
|
||||
const todasNotificacoes = $derived(
|
||||
let count = $derived((typeof countQuery === 'number' ? countQuery : countQuery?.data) ?? 0);
|
||||
let todasNotificacoes = $derived(
|
||||
(Array.isArray(todasNotificacoesQuery)
|
||||
? todasNotificacoesQuery
|
||||
: todasNotificacoesQuery?.data) ?? []
|
||||
);
|
||||
|
||||
// Separar notificações lidas e não lidas
|
||||
const notificacoesNaoLidas = $derived(todasNotificacoes.filter((n) => !n.lida));
|
||||
const notificacoesLidas = $derived(todasNotificacoes.filter((n) => n.lida));
|
||||
let notificacoesNaoLidas = $derived(todasNotificacoes.filter((n) => !n.lida));
|
||||
let notificacoesLidas = $derived(todasNotificacoes.filter((n) => n.lida));
|
||||
|
||||
// Atualizar contador no store
|
||||
$effect(() => {
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
// Verificar se o usuário está autenticado antes de gerenciar presença
|
||||
const currentUser = useQuery(api.auth.getCurrentUser, {});
|
||||
const usuarioAutenticado = $derived(
|
||||
let usuarioAutenticado = $derived(
|
||||
currentUser?.data !== null && currentUser?.data !== undefined
|
||||
);
|
||||
|
||||
|
||||
@@ -18,21 +18,21 @@
|
||||
const conversas = useQuery(api.chat.listarConversas, {});
|
||||
const todosUsuariosQuery = useQuery(api.chat.listarTodosUsuarios, {});
|
||||
|
||||
const activeTab = $state<'participantes' | 'adicionar'>('participantes');
|
||||
let activeTab = $state<'participantes' | 'adicionar'>('participantes');
|
||||
let searchQuery = $state('');
|
||||
let loading = $state<string | null>(null);
|
||||
let error = $state<string | null>(null);
|
||||
|
||||
const conversa = $derived(() => {
|
||||
let conversa = $derived(() => {
|
||||
if (!conversas?.data) return null;
|
||||
return conversas.data.find((c: any) => c._id === conversaId);
|
||||
});
|
||||
|
||||
const todosUsuarios = $derived(() => {
|
||||
let todosUsuarios = $derived(() => {
|
||||
return todosUsuariosQuery?.data || [];
|
||||
});
|
||||
|
||||
const participantes = $derived(() => {
|
||||
let participantes = $derived(() => {
|
||||
try {
|
||||
const conv = conversa();
|
||||
const usuarios = todosUsuarios();
|
||||
@@ -76,11 +76,11 @@
|
||||
}
|
||||
});
|
||||
|
||||
const administradoresIds = $derived(() => {
|
||||
let administradoresIds = $derived(() => {
|
||||
return conversa()?.administradores || [];
|
||||
});
|
||||
|
||||
const usuariosDisponiveis = $derived(() => {
|
||||
let usuariosDisponiveis = $derived(() => {
|
||||
const usuarios = todosUsuarios();
|
||||
if (!usuarios || usuarios.length === 0) return [];
|
||||
const participantesIds = conversa()?.participantes || [];
|
||||
@@ -89,7 +89,7 @@
|
||||
);
|
||||
});
|
||||
|
||||
const usuariosFiltrados = $derived(() => {
|
||||
let usuariosFiltrados = $derived(() => {
|
||||
const disponiveis = usuariosDisponiveis();
|
||||
if (!searchQuery.trim()) return disponiveis;
|
||||
const query = searchQuery.toLowerCase();
|
||||
|
||||
@@ -61,7 +61,7 @@
|
||||
}
|
||||
};
|
||||
|
||||
const config = $derived(statusConfig[status]);
|
||||
let config = $derived(statusConfig[status]);
|
||||
</script>
|
||||
|
||||
<div
|
||||
|
||||
Reference in New Issue
Block a user