Merge remote-tracking branch 'origin' into feat-pedidos
This commit is contained in:
@@ -1,11 +1,14 @@
|
||||
<script lang="ts">
|
||||
import { useQuery, useConvexClient } from 'convex-svelte';
|
||||
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 { abrirConversa } from '$lib/stores/chatStore';
|
||||
import NewConversationModal from './NewConversationModal.svelte';
|
||||
import UserAvatar from './UserAvatar.svelte';
|
||||
import { formatDistanceToNow } from 'date-fns';
|
||||
import { ptBR } from 'date-fns/locale';
|
||||
import UserStatusBadge from './UserStatusBadge.svelte';
|
||||
import UserAvatar from './UserAvatar.svelte';
|
||||
import NewConversationModal from './NewConversationModal.svelte';
|
||||
import { Search, Plus, MessageSquare, Users, UsersRound } from 'lucide-svelte';
|
||||
import type { Id, Doc } from '@sgse-app/backend/convex/_generated/dataModel';
|
||||
|
||||
const client = useConvexClient();
|
||||
|
||||
@@ -86,16 +89,22 @@
|
||||
});
|
||||
});
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
async function handleClickUsuario(usuario: Usuario) {
|
||||
async function handleClickUsuario(usuario: any) {
|
||||
if (processando) {
|
||||
console.log('⏳ Já está processando uma ação, aguarde...');
|
||||
return;
|
||||
@@ -178,7 +187,6 @@
|
||||
}
|
||||
</script>
|
||||
|
||||
```
|
||||
<div class="flex h-full flex-col">
|
||||
<!-- Search bar -->
|
||||
<div class="border-base-300 border-b p-4">
|
||||
@@ -188,21 +196,16 @@
|
||||
placeholder="Buscar usuários (nome, email, matrícula)..."
|
||||
class="input input-bordered w-full pl-10"
|
||||
bind:value={searchQuery}
|
||||
aria-label="Buscar usuários ou conversas"
|
||||
aria-describedby="search-help"
|
||||
/>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke-width="1.5"
|
||||
stroke="currentColor"
|
||||
class="text-base-content/50 absolute top-1/2 left-3 h-5 w-5 -translate-y-1/2"
|
||||
<span id="search-help" class="sr-only"
|
||||
>Digite para buscar usuários por nome, email ou matrícula</span
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
d="m21 21-5.197-5.197m0 0A7.5 7.5 0 1 0 5.196 5.196a7.5 7.5 0 0 0 10.607 10.607Z"
|
||||
/>
|
||||
</svg>
|
||||
<Search
|
||||
class="text-base-content/50 absolute top-1/2 left-3 h-5 w-5 -translate-y-1/2"
|
||||
strokeWidth={1.5}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -222,7 +225,7 @@
|
||||
class={`tab flex-1 ${activeTab === 'conversas' ? 'tab-active' : ''}`}
|
||||
onclick={() => (activeTab = 'conversas')}
|
||||
>
|
||||
💬 Conversas ({conversasFiltradas().length})
|
||||
💬 Conversas ({conversasFiltradas.length})
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -235,16 +238,7 @@
|
||||
title="Nova conversa (grupo ou sala de reunião)"
|
||||
aria-label="Nova conversa"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke-width="2"
|
||||
stroke="currentColor"
|
||||
class="mr-1 h-4 w-4"
|
||||
>
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M12 4.5v15m7.5-7.5h-15" />
|
||||
</svg>
|
||||
<Plus class="mr-1 h-4 w-4" strokeWidth={2} />
|
||||
Nova Conversa
|
||||
</button>
|
||||
</div>
|
||||
@@ -263,34 +257,24 @@
|
||||
: 'cursor-pointer'}"
|
||||
onclick={() => handleClickUsuario(usuario)}
|
||||
disabled={processando}
|
||||
aria-label="Abrir conversa com {usuario.nome}"
|
||||
aria-describedby="usuario-status-{usuario._id}"
|
||||
>
|
||||
<!-- Ícone de mensagem -->
|
||||
<div
|
||||
class="flex h-10 w-10 shrink-0 items-center justify-center rounded-xl transition-all duration-300 hover:scale-110"
|
||||
style="background: linear-gradient(135deg, rgba(102, 126, 234, 0.1) 0%, rgba(118, 75, 162, 0.1) 100%); border: 1px solid rgba(102, 126, 234, 0.2);"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
class="text-primary h-5 w-5"
|
||||
>
|
||||
<path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z" />
|
||||
<path d="M9 10h.01M15 10h.01" />
|
||||
</svg>
|
||||
<MessageSquare class="text-primary h-5 w-5" strokeWidth={2} />
|
||||
</div>
|
||||
|
||||
<!-- Avatar -->
|
||||
<div class="relative shrink-0">
|
||||
<UserAvatar
|
||||
avatar={usuario.avatar}
|
||||
fotoPerfilUrl={usuario.fotoPerfilUrl}
|
||||
nome={usuario.nome}
|
||||
size="md"
|
||||
userId={usuario._id}
|
||||
/>
|
||||
<!-- Status badge -->
|
||||
<div class="absolute right-0 bottom-0">
|
||||
@@ -321,6 +305,9 @@
|
||||
{usuario.statusMensagem || usuario.email}
|
||||
</p>
|
||||
</div>
|
||||
<span id="usuario-status-{usuario._id}" class="sr-only">
|
||||
Status: {getStatusLabel(usuario.statusPresenca)}
|
||||
</span>
|
||||
</div>
|
||||
</button>
|
||||
{/each}
|
||||
@@ -332,27 +319,14 @@
|
||||
{:else}
|
||||
<!-- Nenhum usuário encontrado -->
|
||||
<div class="flex h-full flex-col items-center justify-center px-4 text-center">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke-width="1.5"
|
||||
stroke="currentColor"
|
||||
class="text-base-content/30 mb-4 h-16 w-16"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
d="M15 19.128a9.38 9.38 0 0 0 2.625.372 9.337 9.337 0 0 0 4.121-.952 4.125 4.125 0 0 0-7.533-2.493M15 19.128v-.003c0-1.113-.285-2.16-.786-3.07M15 19.128v.106A12.318 12.318 0 0 1 8.624 21c-2.331 0-4.512-.645-6.374-1.766l-.001-.109a6.375 6.375 0 0 1 11.964-3.07M12 6.375a3.375 3.375 0 1 1-6.75 0 3.375 3.375 0 0 1 6.75 0Zm8.25 2.25a2.625 2.625 0 1 1-5.25 0 2.625 2.625 0 0 1 5.25 0Z"
|
||||
/>
|
||||
</svg>
|
||||
<UsersRound class="text-base-content/30 mb-4 h-16 w-16" strokeWidth={1.5} />
|
||||
<p class="text-base-content/70">Nenhum usuário encontrado</p>
|
||||
</div>
|
||||
{/if}
|
||||
{:else}
|
||||
<!-- Lista de conversas (grupos e salas) -->
|
||||
{#if conversas?.data && conversasFiltradas().length > 0}
|
||||
{#each conversasFiltradas() as conversa (conversa._id)}
|
||||
{#if conversas?.data && conversasFiltradas.length > 0}
|
||||
{#each conversasFiltradas as conversa (conversa._id)}
|
||||
<button
|
||||
type="button"
|
||||
class="hover:bg-base-200 border-base-300 flex w-full items-center gap-3 border-b px-4 py-3 text-left transition-colors {processando
|
||||
@@ -369,35 +343,9 @@
|
||||
: 'from-primary/20 to-secondary/20 border-primary/30 border bg-linear-to-br'}"
|
||||
>
|
||||
{#if conversa.tipo === 'sala_reuniao'}
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke-width="2"
|
||||
stroke="currentColor"
|
||||
class="h-5 w-5 text-blue-500"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
d="M15 19.128a9.38 9.38 0 0 0 2.625.372 9.337 9.337 0 0 0 4.121-.952 4.125 4.125 0 0 0-7.533-2.493M15 19.128v-.003c0-1.113-.285-2.16-.786-3.07M15 19.128v.106A12.318 12.318 0 0 1 8.624 21c-2.331 0-4.512-.645-6.374-1.766l-.001-.109a6.375 6.375 0 0 1 11.964-3.07M12 6.375a3.375 3.375 0 1 1-6.75 0 3.375 3.375 0 0 1 6.75 0Zm8.25 2.25a2.625 2.625 0 1 1-5.25 0 2.625 2.625 0 0 1 5.25 0Z"
|
||||
/>
|
||||
</svg>
|
||||
<UsersRound class="h-5 w-5 text-blue-500" strokeWidth={2} />
|
||||
{:else}
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke-width="2"
|
||||
stroke="currentColor"
|
||||
class="text-primary h-5 w-5"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
d="M18 18.72a9.094 9.094 0 0 0 3.741-.479 3 3 0 0 0-4.682-2.72m.94 3.198.001.031c0 .225-.012.447-.037.666A11.944 11.944 0 0 1 12 21c-2.17 0-4.207-.576-5.963-1.584A6.062 6.062 0 0 1 6 18.719m12 0a5.971 5.971 0 0 0-.941-3.197m0 0A5.995 5.995 0 0 0 12 12.75a5.995 5.995 0 0 0-5.058 2.772m0 0a3 3 0 0 0-4.681 2.72 8.986 8.986 0 0 0 3.74.477m.94-3.197a5.971 5.971 0 0 0-.94 3.197M15 6.75a3 3 0 1 1-6 0 3 3 0 0 1 6 0Zm6 3a2.25 2.25 0 1 1-4.5 0 2.25 2.25 0 0 1 4.5 0Zm-13.5 0a2.25 2.25 0 1 1-4.5 0 2.25 2.25 0 0 1 4.5 0Z"
|
||||
/>
|
||||
</svg>
|
||||
<Users class="text-primary h-5 w-5" strokeWidth={2} />
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
@@ -440,20 +388,7 @@
|
||||
{:else}
|
||||
<!-- Nenhuma conversa encontrada -->
|
||||
<div class="flex h-full flex-col items-center justify-center px-4 text-center">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke-width="1.5"
|
||||
stroke="currentColor"
|
||||
class="text-base-content/30 mb-4 h-16 w-16"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
d="M20.25 8.511c.884.284 1.5 1.128 1.5 2.097v4.286c0 1.136-.847 2.1-1.98 2.193-.34.027-.68.052-1.02.072v3.091l-3-3c-1.354 0-2.694-.055-4.02-.163a2.115 2.115 0 0 1-.825-.242m9.345-8.334a2.126 2.126 0 0 0-.476-.095 48.64 48.64 0 0 0-8.048 0c-1.131.094-1.976 1.057-1.976 2.192v4.286c0 .837.46 1.58 1.155 1.951m9.345-8.334V6.637c0-1.621-1.152-3.026-2.76-3.235A48.455 48.455 0 0 0 11.25 3c-2.115 0-4.198.137-6.24.402-1.608.209-2.76 1.614-2.76 3.235v6.226c0 1.621 1.152 3.026 2.76 3.235.577.075 1.157.14 1.74.194V21l4.155-4.155"
|
||||
/>
|
||||
</svg>
|
||||
<MessageSquare class="text-base-content/30 mb-4 h-16 w-16" strokeWidth={1.5} />
|
||||
<p class="text-base-content/70 mb-2 font-medium">Nenhuma conversa encontrada</p>
|
||||
<p class="text-base-content/50 text-sm">Crie um grupo ou sala de reunião para começar</p>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user