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:
54
app/components/common/MetricCard.vue
Normal file
54
app/components/common/MetricCard.vue
Normal file
@@ -0,0 +1,54 @@
|
||||
<template>
|
||||
<div class="instance-card p-6">
|
||||
<div class="flex items-center justify-between mb-4">
|
||||
<div
|
||||
class="w-10 h-10 rounded-lg flex items-center justify-center"
|
||||
:class="iconBgClass"
|
||||
>
|
||||
<UIcon :name="icon" class="w-5 h-5" :class="iconClass" />
|
||||
</div>
|
||||
<div v-if="total" class="text-sm text-[var(--wa-text-muted)]">
|
||||
de {{ total }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="text-2xl font-bold text-[var(--wa-text)]">{{ value }}</div>
|
||||
<div class="text-sm text-[var(--wa-text-muted)]">{{ title }}</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
interface Props {
|
||||
title: string
|
||||
value: number | string
|
||||
total?: number
|
||||
icon: string
|
||||
color?: 'green' | 'blue' | 'purple' | 'amber' | 'red'
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
color: 'green'
|
||||
})
|
||||
|
||||
const iconBgClass = computed(() => {
|
||||
const classes: Record<string, string> = {
|
||||
green: 'bg-green-500/20',
|
||||
blue: 'bg-blue-500/20',
|
||||
purple: 'bg-purple-500/20',
|
||||
amber: 'bg-amber-500/20',
|
||||
red: 'bg-red-500/20'
|
||||
}
|
||||
return classes[props.color]
|
||||
})
|
||||
|
||||
const iconClass = computed(() => {
|
||||
const classes: Record<string, string> = {
|
||||
green: 'text-green-500',
|
||||
blue: 'text-blue-500',
|
||||
purple: 'text-purple-500',
|
||||
amber: 'text-amber-500',
|
||||
red: 'text-red-500'
|
||||
}
|
||||
return classes[props.color]
|
||||
})
|
||||
</script>
|
||||
42
app/components/common/StatusBadge.vue
Normal file
42
app/components/common/StatusBadge.vue
Normal file
@@ -0,0 +1,42 @@
|
||||
<template>
|
||||
<span
|
||||
class="px-2 py-1 rounded-full text-xs font-medium"
|
||||
:class="badgeClass"
|
||||
>
|
||||
{{ label }}
|
||||
</span>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
interface Props {
|
||||
status: 'connected' | 'disconnected' | 'connecting' | 'qr_ready' | 'pairing'
|
||||
}
|
||||
|
||||
const props = defineProps<Props>()
|
||||
|
||||
const statusConfig: Record<string, { label: string; class: string }> = {
|
||||
connected: {
|
||||
label: 'Conectado',
|
||||
class: 'bg-green-500/20 text-green-400'
|
||||
},
|
||||
disconnected: {
|
||||
label: 'Desconectado',
|
||||
class: 'bg-red-500/20 text-red-400'
|
||||
},
|
||||
connecting: {
|
||||
label: 'Conectando...',
|
||||
class: 'bg-blue-500/20 text-blue-400'
|
||||
},
|
||||
qr_ready: {
|
||||
label: 'Escanear QR',
|
||||
class: 'bg-amber-500/20 text-amber-400'
|
||||
},
|
||||
pairing: {
|
||||
label: 'Emparejando...',
|
||||
class: 'bg-purple-500/20 text-purple-400'
|
||||
}
|
||||
}
|
||||
|
||||
const label = computed(() => statusConfig[props.status]?.label || props.status)
|
||||
const badgeClass = computed(() => statusConfig[props.status]?.class || 'bg-gray-500/20 text-gray-400')
|
||||
</script>
|
||||
Reference in New Issue
Block a user