138 lines
5.9 KiB
Vue
138 lines
5.9 KiB
Vue
<template>
|
|
<div class="flex flex-col gap-8">
|
|
<UCard class="brand-card border border-transparent backdrop-blur-sm">
|
|
<template #header>
|
|
<div class="flex flex-col gap-4 lg:flex-row lg:items-center lg:justify-between">
|
|
<div class="flex items-center gap-5">
|
|
<img
|
|
src="/logo.png"
|
|
alt="Analítica Núcleo"
|
|
class="h-16 w-16 rounded-full border border-[#ffe0a0]/40 shadow-lg shadow-[#c08040]/25"
|
|
/>
|
|
<div class="space-y-1">
|
|
<h1 class="text-3xl font-semibold tracking-tight text-[var(--brand-text)]">
|
|
Analítica Núcleo Data Studio
|
|
</h1>
|
|
<p class="text-sm text-[var(--brand-text-muted)]">
|
|
Bienvenido al panel principal. Selecciona una sección para comenzar a explorar tus datos Supabase.
|
|
</p>
|
|
</div>
|
|
</div>
|
|
<div class="flex flex-wrap gap-2">
|
|
<span class="brand-pill inline-flex items-center gap-2 rounded-full px-3 py-1 text-xs uppercase tracking-[0.18em]">
|
|
<span class="inline-block h-2 w-2 rounded-full bg-[#ffe0a0]"></span>
|
|
Solo lectura
|
|
</span>
|
|
<span class="brand-pill inline-flex items-center gap-2 rounded-full px-3 py-1 text-xs uppercase tracking-[0.18em]">
|
|
Multi-fuente
|
|
</span>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<div class="grid gap-6 md:grid-cols-2">
|
|
<UCard class="brand-card border border-transparent">
|
|
<template #header>
|
|
<div class="flex items-center gap-3">
|
|
<UIcon name="i-lucide-table" class="size-6 text-[#ffe0a0]" />
|
|
<div>
|
|
<h3 class="text-lg font-semibold text-[var(--brand-text)]">Explorador de datos</h3>
|
|
<p class="text-sm text-[var(--brand-text-muted)]">Consulta tablas, metadatos y registros filtrados.</p>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
<template #footer>
|
|
<NuxtLink to="/explorer" class="text-sm font-semibold text-[#ffe0a0] hover:underline">
|
|
Ir al explorador →
|
|
</NuxtLink>
|
|
</template>
|
|
</UCard>
|
|
|
|
<UCard class="brand-card border border-transparent">
|
|
<template #header>
|
|
<div class="flex items-center gap-3">
|
|
<UIcon name="i-lucide-bar-chart-3" class="size-6 text-[#ffe0a0]" />
|
|
<div>
|
|
<h3 class="text-lg font-semibold text-[var(--brand-text)]">Monitoreo rápido</h3>
|
|
<p class="text-sm text-[var(--brand-text-muted)]">Visualiza indicadores clave y estado general.</p>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
<div class="grid gap-3 md:grid-cols-2">
|
|
<div class="rounded-lg border border-[#3a2a16] bg-[#1c140c] px-4 py-3">
|
|
<p class="text-xs uppercase tracking-[0.28em] text-[var(--brand-text-muted)]">Tablas monitoreadas</p>
|
|
<p class="pt-2 text-2xl font-semibold text-[var(--brand-text)]">{{ metadataCount }}</p>
|
|
</div>
|
|
<div class="rounded-lg border border-[#3a2a16] bg-[#1c140c] px-4 py-3">
|
|
<p class="text-xs uppercase tracking-[0.28em] text-[var(--brand-text-muted)]">Última actividad</p>
|
|
<p class="pt-2 text-sm text-[var(--brand-text)]">{{ lastUpdatedText }}</p>
|
|
</div>
|
|
</div>
|
|
</UCard>
|
|
</div>
|
|
</UCard>
|
|
|
|
<section class="grid gap-6 md:grid-cols-3">
|
|
<UCard class="brand-card border border-transparent">
|
|
<template #header>
|
|
<div class="flex items-center gap-2">
|
|
<UIcon name="i-lucide-compass" class="size-5 text-[#ffe0a0]" />
|
|
<span class="text-sm font-semibold text-[var(--brand-text)]">Cómo empezar</span>
|
|
</div>
|
|
</template>
|
|
<ol class="list-decimal space-y-2 pl-4 text-sm text-[var(--brand-text-muted)]">
|
|
<li>Abre “Explorador de datos” desde la barra lateral.</li>
|
|
<li>Elige el tipo de consulta y ajusta los filtros.</li>
|
|
<li>Ejecuta la solicitud para revisar los resultados.</li>
|
|
</ol>
|
|
</UCard>
|
|
|
|
<UCard class="brand-card border border-transparent">
|
|
<template #header>
|
|
<div class="flex items-center gap-2">
|
|
<UIcon name="i-lucide-shield-check" class="size-5 text-[#ffe0a0]" />
|
|
<span class="text-sm font-semibold text-[var(--brand-text)]">Seguridad</span>
|
|
</div>
|
|
</template>
|
|
<p class="text-sm text-[var(--brand-text-muted)]">
|
|
Este panel opera con credenciales de solo lectura hacia Supabase. No se exponen operaciones de escritura
|
|
ni se almacenan datos sensibles en el cliente.
|
|
</p>
|
|
</UCard>
|
|
|
|
<UCard class="brand-card border border-transparent">
|
|
<template #header>
|
|
<div class="flex items-center gap-2">
|
|
<UIcon name="i-lucide-life-buoy" class="size-5 text-[#ffe0a0]" />
|
|
<span class="text-sm font-semibold text-[var(--brand-text)]">¿Necesitas ayuda?</span>
|
|
</div>
|
|
</template>
|
|
<p class="text-sm text-[var(--brand-text-muted)]">
|
|
Consulta la documentación interna o abre un ticket de soporte para integrar nuevas fuentes, automatizar
|
|
reportes o resolver incidentes.
|
|
</p>
|
|
</UCard>
|
|
</section>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { computed } from 'vue'
|
|
|
|
definePageMeta({
|
|
layout: 'dashboard',
|
|
title: 'Inicio'
|
|
})
|
|
|
|
const availableMetadata = useState('availableMetadataSummary', () => [])
|
|
const lastUpdated = useState<string>('dashboardLastUpdated', () => new Date().toISOString())
|
|
|
|
const metadataCount = computed(() => availableMetadata.value.length || '—')
|
|
|
|
const lastUpdatedText = computed(() => {
|
|
if (!lastUpdated.value) return 'Sin registros'
|
|
const date = new Date(lastUpdated.value)
|
|
return Number.isNaN(date.getTime()) ? lastUpdated.value : date.toLocaleString()
|
|
})
|
|
</script>
|