feat: WhatsApp Nucleo con Nuxt 4 + Baileys v7
Some checks failed
Build and Deploy / build-and-deploy (push) Failing after 6m46s
Some checks failed
Build and Deploy / build-and-deploy (push) Failing after 6m46s
Reemplazo completo de Evolution API por implementación directa con Baileys. Características: - Dashboard completo con Nuxt UI v4 - Soporte para múltiples instancias de WhatsApp - Conexión via QR code o pairing code - Persistencia de mensajes en PostgreSQL - API REST para integraciones externas - Webhooks con firma HMAC - SSE para actualizaciones en tiempo real - Autenticación con Authentik
This commit is contained in:
116
app/pages/messages/index.vue
Normal file
116
app/pages/messages/index.vue
Normal file
@@ -0,0 +1,116 @@
|
||||
<template>
|
||||
<div class="space-y-6">
|
||||
<!-- Header -->
|
||||
<div class="flex items-center justify-between">
|
||||
<div>
|
||||
<h1 class="text-2xl font-bold text-[var(--wa-text)]">Mensajes</h1>
|
||||
<p class="text-[var(--wa-text-muted)]">Vista de conversaciones de todas las instancias</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Instance Selector -->
|
||||
<div class="flex items-center gap-4">
|
||||
<USelectMenu
|
||||
v-model="selectedInstance"
|
||||
:items="instanceOptions"
|
||||
placeholder="Seleccionar instancia"
|
||||
class="w-64"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- Chat Interface -->
|
||||
<div class="grid grid-cols-12 gap-4 h-[calc(100vh-300px)]">
|
||||
<!-- Chat List -->
|
||||
<div class="col-span-4 instance-card overflow-hidden flex flex-col">
|
||||
<div class="p-4 border-b border-[var(--wa-border)]">
|
||||
<UInput
|
||||
v-model="searchQuery"
|
||||
placeholder="Buscar conversacion..."
|
||||
icon="i-lucide-search"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="flex-1 overflow-y-auto">
|
||||
<div v-if="chats.length === 0" class="p-8 text-center">
|
||||
<UIcon name="i-lucide-message-square" class="w-12 h-12 text-[var(--wa-text-muted)] mx-auto mb-3" />
|
||||
<p class="text-[var(--wa-text-muted)]">No hay conversaciones</p>
|
||||
</div>
|
||||
|
||||
<div v-else>
|
||||
<ChatItem
|
||||
v-for="chat in filteredChats"
|
||||
:key="chat.id"
|
||||
:chat="chat"
|
||||
:active="selectedChat?.id === chat.id"
|
||||
@click="selectedChat = chat"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Message View -->
|
||||
<div class="col-span-8 instance-card overflow-hidden flex flex-col">
|
||||
<div v-if="!selectedChat" class="flex-1 flex items-center justify-center">
|
||||
<div class="text-center">
|
||||
<UIcon name="i-lucide-message-circle" class="w-16 h-16 text-[var(--wa-text-muted)] mx-auto mb-4" />
|
||||
<p class="text-[var(--wa-text-muted)]">Selecciona una conversacion</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<template v-else>
|
||||
<!-- Chat Header -->
|
||||
<div class="p-4 border-b border-[var(--wa-border)] flex items-center gap-3">
|
||||
<UAvatar :alt="selectedChat.name" size="md" />
|
||||
<div>
|
||||
<p class="font-medium text-[var(--wa-text)]">{{ selectedChat.name }}</p>
|
||||
<p class="text-sm text-[var(--wa-text-muted)]">{{ selectedChat.jid }}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Messages -->
|
||||
<div class="flex-1 overflow-y-auto p-4 space-y-2">
|
||||
<MessageBubble
|
||||
v-for="message in messages"
|
||||
:key="message.id"
|
||||
:message="message"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- Input -->
|
||||
<div class="p-4 border-t border-[var(--wa-border)]">
|
||||
<MessageInput @send="handleSendMessage" />
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
definePageMeta({
|
||||
layout: 'dashboard',
|
||||
title: 'Mensajes',
|
||||
icon: 'i-lucide-message-square'
|
||||
})
|
||||
|
||||
const selectedInstance = ref(null)
|
||||
const searchQuery = ref('')
|
||||
const selectedChat = ref<any>(null)
|
||||
|
||||
// TODO: Conectar con API real
|
||||
const instanceOptions = ref<any[]>([])
|
||||
const chats = ref<any[]>([])
|
||||
const messages = ref<any[]>([])
|
||||
|
||||
const filteredChats = computed(() => {
|
||||
if (!searchQuery.value) return chats.value
|
||||
return chats.value.filter(chat =>
|
||||
chat.name.toLowerCase().includes(searchQuery.value.toLowerCase())
|
||||
)
|
||||
})
|
||||
|
||||
const handleSendMessage = async (content: string) => {
|
||||
console.log('Sending:', content)
|
||||
// TODO: Implementar envio de mensajes
|
||||
}
|
||||
</script>
|
||||
Reference in New Issue
Block a user