All checks were successful
build-and-deploy / build-and-deploy (push) Successful in 1m3s
- Script en scripts/scrape-baileys-docs.ts - Genera docs/baileys-api-reference.md con 6433 lineas - 79 secciones: interfaces, types, functions, variables, enums - Referencia completa para desarrollo de mensajes
96 lines
2.8 KiB
Vue
96 lines
2.8 KiB
Vue
<template>
|
|
<div class="min-h-screen bg-gray-900 text-gray-100">
|
|
<!-- Sidebar -->
|
|
<aside
|
|
:class="[
|
|
'fixed inset-y-0 left-0 z-50 w-64 bg-gray-800 border-r border-gray-700 transform transition-transform duration-200 ease-in-out lg:translate-x-0',
|
|
sidebarOpen ? 'translate-x-0' : '-translate-x-full'
|
|
]"
|
|
>
|
|
<div class="flex items-center justify-between h-16 px-4 border-b border-gray-700">
|
|
<div class="flex items-center gap-2">
|
|
<UIcon name="i-lucide-message-circle" class="w-6 h-6 text-green-500" />
|
|
<span class="text-lg font-semibold">WhatsApp Nucleo</span>
|
|
</div>
|
|
<UButton
|
|
icon="i-lucide-x"
|
|
variant="ghost"
|
|
color="neutral"
|
|
class="lg:hidden"
|
|
@click="sidebarOpen = false"
|
|
/>
|
|
</div>
|
|
|
|
<nav class="p-4 space-y-2">
|
|
<NuxtLink
|
|
v-for="item in menuItems"
|
|
:key="item.to"
|
|
:to="item.to"
|
|
class="flex items-center gap-3 px-3 py-2 rounded-lg transition-colors"
|
|
:class="[
|
|
route.path === item.to
|
|
? 'bg-green-600 text-white'
|
|
: 'text-gray-300 hover:bg-gray-700'
|
|
]"
|
|
>
|
|
<UIcon :name="item.icon" class="w-5 h-5" />
|
|
<span>{{ item.label }}</span>
|
|
</NuxtLink>
|
|
</nav>
|
|
</aside>
|
|
|
|
<!-- Main content -->
|
|
<div class="lg:pl-64">
|
|
<!-- Header -->
|
|
<header class="sticky top-0 z-40 flex items-center justify-between h-16 px-4 bg-gray-800 border-b border-gray-700">
|
|
<div class="flex items-center gap-4">
|
|
<UButton
|
|
icon="i-lucide-menu"
|
|
variant="ghost"
|
|
color="neutral"
|
|
class="lg:hidden"
|
|
@click="sidebarOpen = true"
|
|
/>
|
|
<h1 class="text-lg font-semibold">{{ pageTitle }}</h1>
|
|
</div>
|
|
|
|
<div class="flex items-center gap-2">
|
|
<ConnectionStatus />
|
|
<UserMenu />
|
|
</div>
|
|
</header>
|
|
|
|
<!-- Page content -->
|
|
<main class="p-4 lg:p-6">
|
|
<slot />
|
|
</main>
|
|
</div>
|
|
|
|
<!-- Mobile overlay -->
|
|
<div
|
|
v-if="sidebarOpen"
|
|
class="fixed inset-0 z-40 bg-black/50 lg:hidden"
|
|
@click="sidebarOpen = false"
|
|
/>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
const route = useRoute()
|
|
const sidebarOpen = ref(false)
|
|
|
|
const pageTitle = computed(() => (route.meta.title as string) || 'Dashboard')
|
|
|
|
const menuItems = [
|
|
{ to: '/', label: 'Instancias', icon: 'i-lucide-smartphone' },
|
|
{ to: '/messages', label: 'Mensajes', icon: 'i-lucide-message-square' },
|
|
{ to: '/webhooks', label: 'Webhooks', icon: 'i-lucide-webhook' },
|
|
{ to: '/debug', label: 'Debug', icon: 'i-lucide-bug' },
|
|
]
|
|
|
|
// Close sidebar on route change (mobile)
|
|
watch(() => route.path, () => {
|
|
sidebarOpen.value = false
|
|
})
|
|
</script>
|