feat: WhatsApp Nucleo con Nuxt 4 + Baileys v7
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:
2025-12-02 17:54:31 -06:00
parent 327118440b
commit faedec47d7
62 changed files with 4489 additions and 92 deletions

View File

@@ -0,0 +1,59 @@
<template>
<UDashboardSidebar class="bg-[var(--wa-surface)] border-[var(--wa-border)]">
<template #header>
<div class="flex items-center gap-3 p-4">
<div class="w-10 h-10 rounded-full bg-[var(--wa-green-dark)] flex items-center justify-center">
<UIcon name="i-lucide-message-circle" class="w-6 h-6 text-white" />
</div>
<div class="flex flex-col">
<span class="font-semibold text-[var(--wa-text)]">WhatsApp Nucleo</span>
<span class="text-xs text-[var(--wa-text-muted)]">Multi-Instance Manager</span>
</div>
</div>
</template>
<template #body>
<UDashboardSidebarContent>
<UDashboardSidebarGroup>
<UDashboardSidebarItem
to="/"
icon="i-lucide-layout-dashboard"
label="Dashboard"
exact
/>
<UDashboardSidebarItem
to="/instances"
icon="i-lucide-smartphone"
label="Instancias"
/>
<UDashboardSidebarItem
to="/messages"
icon="i-lucide-message-square"
label="Mensajes"
/>
</UDashboardSidebarGroup>
<UDashboardSidebarGroup label="Integraciones">
<UDashboardSidebarItem
to="/webhooks"
icon="i-lucide-webhook"
label="Webhooks"
/>
<UDashboardSidebarItem
to="/api-docs"
icon="i-lucide-code"
label="API Docs"
/>
</UDashboardSidebarGroup>
<UDashboardSidebarGroup label="Sistema">
<UDashboardSidebarItem
to="/settings"
icon="i-lucide-settings"
label="Configuracion"
/>
</UDashboardSidebarGroup>
</UDashboardSidebarContent>
</template>
</UDashboardSidebar>
</template>

View File

@@ -0,0 +1,24 @@
<template>
<div class="flex items-center gap-2 px-3 py-1 rounded-full bg-[var(--wa-surface)] border border-[var(--wa-border)]">
<span
class="w-2 h-2 rounded-full"
:class="statusClass"
/>
<span class="text-sm text-[var(--wa-text-muted)]">
{{ connectedCount }} / {{ totalCount }} conectadas
</span>
</div>
</template>
<script setup lang="ts">
// TODO: Conectar con useInstances cuando esté implementado
const connectedCount = ref(0)
const totalCount = ref(0)
const statusClass = computed(() => {
if (totalCount.value === 0) return 'bg-gray-500'
if (connectedCount.value === totalCount.value) return 'bg-[var(--wa-green-light)]'
if (connectedCount.value === 0) return 'bg-red-500'
return 'bg-yellow-500'
})
</script>

View File

@@ -0,0 +1,36 @@
<template>
<UDropdownMenu v-if="user">
<UButton
variant="ghost"
class="rounded-full p-0"
>
<UAvatar
:src="user.avatar"
:alt="user.name || user.username"
size="sm"
/>
</UButton>
<template #content>
<div class="px-3 py-2 border-b border-[var(--wa-border)]">
<p class="font-medium text-[var(--wa-text)]">{{ user.name || user.username }}</p>
<p class="text-sm text-[var(--wa-text-muted)]">{{ user.email }}</p>
</div>
<UDropdownMenuItem
icon="i-lucide-user"
label="Mi Perfil"
@click="goToProfile"
/>
<UDropdownMenuItem
icon="i-lucide-log-out"
label="Cerrar Sesion"
@click="logout"
/>
</template>
</UDropdownMenu>
</template>
<script setup lang="ts">
const { user, logout, goToProfile } = useAuthentik()
</script>