Files
analiticaNucleo/nuxt4-app/docs/DEVELOPER_GUIDE.md
josedario87 63c7043664
All checks were successful
build-and-deploy / build-and-deploy (push) Successful in 47s
Feat: Agregar botones de Copiar Texto y Copiar JSON
Implementa funcionalidad de copia en tres secciones del Informe:

📋 Funcionalidades agregadas:
1. Lista de Ingresos
   - Copiar Texto: Formato WhatsApp con emojis y legible
   - Copiar JSON: Formato estructurado para sistemas

2. Top 10 Clientes
   - Copiar Texto: Ranking formateado con métricas
   - Copiar JSON: Array de objetos con datos completos

3. Serie Temporal Acumulada
   - Copiar Texto: Evolución temporal con emojis
   - Copiar JSON: Datos completos para análisis

 Características:
- Botones con iconos (i-lucide-copy y i-lucide-code)
- Disabled cuando no hay datos disponibles
- Alertas de confirmación al copiar
- Formato texto optimizado para WhatsApp
- Incluye metadata: rango de fechas y timestamp

Uso:
- Copiar Texto → Compartir en WhatsApp/Telegram
- Copiar JSON → Integración con otros sistemas
2025-10-30 16:33:54 -06:00

10 KiB

Guía de Desarrollo - Sistema de Temas

Introducción

Esta guía está dirigida a desarrolladores que trabajan en Analítica Núcleo y necesitan entender cómo funciona el sistema de temas y cómo mantener la consistencia visual en toda la aplicación.

Principios Fundamentales

1. Siempre Usa Variables CSS

CORRECTO:

<div class="bg-[var(--brand-surface)] border-[var(--brand-border)] text-[var(--brand-text)]">
  Contenido
</div>

INCORRECTO:

<div class="bg-[#1f180f] border-[#3a2a16] text-[#fef9f0]">
  Contenido
</div>

INCORRECTO:

<div class="bg-gray-900 border-gray-800 text-white">
  Contenido
</div>

2. Usa las Clases Utilitarias de Marca

Para elementos comunes, usa las clases predefinidas en lugar de duplicar estilos:

<!--  CORRECTO -->
<div class="brand-card">
  <h2 class="brand-section-title">Título</h2>
  <div class="brand-divider"></div>
</div>

<!--  INCORRECTO -->
<div class="rounded-lg bg-gradient-to-br from-[#1f180f] to-[#14100b] border border-[#3a2a16]">
  <h2 class="text-lg font-semibold text-[#e0c080]">Título</h2>
  <div class="h-px bg-[#3a2a16] my-4"></div>
</div>

Variables de Tema Disponibles

Variable CSS Uso Ejemplo
--brand-bg Fondo principal de la aplicación bg-[var(--brand-bg)]
--brand-surface Fondos de elementos elevados (cards, modales) bg-[var(--brand-surface)]
--brand-border Bordes de elementos border-[var(--brand-border)]
--brand-primary Color principal (enlaces, botones) text-[var(--brand-primary)]
--brand-primary-strong Variante más intensa del primario bg-[var(--brand-primary-strong)]
--brand-accent Color de acento para highlights text-[var(--brand-accent)]
--brand-text Texto principal text-[var(--brand-text)]
--brand-text-muted Texto secundario/menos prominente text-[var(--brand-text-muted)]

Clases Utilitarias de Marca

.brand-shell

Contenedor principal para layouts con gradiente radial.

<div class="brand-shell">
  <!-- Contenido de la página -->
</div>

.brand-card

Tarjetas con estilos consistentes.

<div class="brand-card">
  <h3>Título de la Card</h3>
  <p>Contenido</p>
</div>

.brand-divider

Divisor horizontal decorativo.

<div class="brand-divider"></div>

.brand-chip y .brand-pill

Para pequeños tags o badges.

<span class="brand-chip">Estado</span>
<span class="brand-pill">Badge</span>

.brand-table

Estilos para tablas.

<table class="brand-table">
  <!-- ... -->
</table>

Patrones de Uso Común

Cards con Bordes y Sombras

<UCard class="brand-card border border-transparent">
  <template #header>
    <div class="flex items-center gap-2">
      <UIcon name="i-lucide-star" class="size-5 text-[var(--brand-accent)]" />
      <h3 class="text-[var(--brand-text)]">Título</h3>
    </div>
  </template>

  <p class="text-[var(--brand-text-muted)]">
    Descripción del contenido
  </p>
</UCard>

Botones con Hover Personalizado

<button class="px-4 py-2 rounded-lg bg-[var(--brand-surface)] border border-[var(--brand-border)] text-[var(--brand-text)] hover:bg-[var(--brand-primary)]/10 hover:border-[var(--brand-primary)] transition-colors">
  Botón
</button>

Inputs y Formularios

<UInput
  v-model="value"
  placeholder="Ingresa un valor"
  :ui="{
    base: 'bg-[var(--brand-surface)] border-[var(--brand-border)] text-[var(--brand-text)]',
    placeholder: 'placeholder:text-[var(--brand-text-muted)]'
  }"
/>
<NuxtLink
  to="/perfil"
  class="text-[var(--brand-accent)] hover:text-[var(--brand-primary)] hover:underline transition-colors"
>
  Ver perfil 
</NuxtLink>

Personalización de Componentes Nuxt UI

Muchos componentes de Nuxt UI aceptan la prop :ui para personalización:

<UButton
  :ui="{
    base: 'bg-[var(--brand-surface)] hover:bg-[var(--brand-primary)]/10',
    padding: { sm: 'px-2.5 py-2' }
  }"
>
  Botón Personalizado
</UButton>

Composable useTheme()

Para manipular el tema programáticamente, usa el composable useTheme():

<script setup lang="ts">
const { theme, applyTheme, saveTheme, resetTheme, exportTheme, importTheme } = useTheme()

// Modificar un color
theme.value.primary = '#ff5733'

// Aplicar cambios
applyTheme()

// Guardar en localStorage
saveTheme()

// Resetear a valores por defecto
resetTheme()

// Exportar tema como JSON
const jsonTheme = exportTheme()

// Importar tema desde JSON
const success = importTheme(jsonString, true) // true = guardar automáticamente
</script>

Checklist Pre-Commit

Antes de hacer commit de tu código, verifica:

  • No hay colores hardcoded (#ffffff, #000000, etc.)
  • No hay clases gray-scale genéricas (bg-gray-900, text-gray-500, etc.)
  • Todos los fondos usan --brand-bg o --brand-surface
  • Todos los bordes usan --brand-border
  • Todo el texto usa --brand-text o --brand-text-muted
  • Los elementos interactivos usan --brand-primary o --brand-accent
  • Los hover states usan transparencias (ej: hover:bg-[var(--brand-primary)]/10)
  • Se usan clases utilitarias cuando sea posible (.brand-card, .brand-shell, etc.)

Casos Especiales

Colores Semánticos (Success, Error, Warning)

Para colores que NO son parte del tema (éxito, error, advertencia), puedes usar colores de Tailwind:

<!-- Estados semánticos - OK usar colores fijos -->
<div class="text-green-400">Éxito</div>
<div class="text-red-400">Error</div>
<div class="text-yellow-400">Advertencia</div>
<div class="text-blue-400">Info</div>

<!-- Pero el fondo y borde deben respetar el tema -->
<div class="bg-[var(--brand-surface)] border-green-600/30 text-green-400">
  Operación exitosa
</div>

Iconos

Los iconos deben usar colores del tema:

<!--  CORRECTO -->
<UIcon name="i-lucide-star" class="size-5 text-[var(--brand-primary)]" />
<UIcon name="i-lucide-info" class="size-4 text-[var(--brand-accent)]" />
<UIcon name="i-lucide-chevron-right" class="size-4 text-[var(--brand-text-muted)]" />

<!--  INCORRECTO -->
<UIcon name="i-lucide-star" class="size-5 text-amber-500" />
<UIcon name="i-lucide-info" class="size-4 text-blue-400" />

Imágenes y Avatares con Bordes

<img
  src="/logo.png"
  class="rounded-full border-2 border-[var(--brand-accent)]/40 shadow-lg shadow-[var(--brand-primary-strong)]/25"
/>

<UAvatar
  src="https://example.com/avatar.jpg"
  :ui="{
    wrapper: 'ring-2 ring-[var(--brand-primary)]/40'
  }"
/>

Hover y Focus States

Siempre usa transparencias para hover states para que funcionen con cualquier tema:

<!--  CORRECTO - Usa transparencia -->
<button class="hover:bg-[var(--brand-primary)]/10 focus:ring-2 focus:ring-[var(--brand-primary)]/50">
  Botón
</button>

<!--  INCORRECTO - Color sólido -->
<button class="hover:bg-[#e0c080] focus:ring-2 focus:ring-[#c08040]">
  Botón
</button>

Ejemplos de Migración

Antes (Incorrecto)

<template>
  <div class="bg-gray-900 border border-gray-800">
    <h2 class="text-white font-bold">Título</h2>
    <p class="text-gray-400 mt-2">
      Descripción
    </p>
    <button class="mt-4 px-4 py-2 bg-blue-600 hover:bg-blue-700 text-white rounded-lg">
      Acción
    </button>
  </div>
</template>

Después (Correcto)

<template>
  <div class="bg-[var(--brand-surface)] border border-[var(--brand-border)]">
    <h2 class="text-[var(--brand-text)] font-bold">Título</h2>
    <p class="text-[var(--brand-text-muted)] mt-2">
      Descripción
    </p>
    <UButton
      class="mt-4"
      :ui="{
        base: 'bg-[var(--brand-primary)] hover:bg-[var(--brand-primary-strong)]'
      }"
    >
      Acción
    </UButton>
  </div>
</template>

Errores Comunes y Soluciones

Error 1: Mezclar Variables con Hardcoded Colors

No hagas esto:

<div class="bg-[#1f180f] text-[var(--brand-text)]">
  Contenido
</div>

Haz esto:

<div class="bg-[var(--brand-surface)] text-[var(--brand-text)]">
  Contenido
</div>

Error 2: No Considerar el Contraste

Asegúrate de que el texto tenga suficiente contraste sobre su fondo:

Mal contraste:

<div class="bg-[var(--brand-surface)]">
  <span class="text-[var(--brand-text-muted)]">Texto importante</span>
</div>

Buen contraste:

<div class="bg-[var(--brand-surface)]">
  <span class="text-[var(--brand-text)]">Texto importante</span>
</div>

Error 3: Duplicar Estilos en Lugar de Usar Clases

Duplicación:

<div class="rounded-lg bg-gradient-to-br from-[var(--brand-surface)] to-[var(--brand-bg)] border border-[var(--brand-border)] p-6 shadow-xl">
  Card 1
</div>
<div class="rounded-lg bg-gradient-to-br from-[var(--brand-surface)] to-[var(--brand-bg)] border border-[var(--brand-border)] p-6 shadow-xl">
  Card 2
</div>

Reutilización:

<div class="brand-card">Card 1</div>
<div class="brand-card">Card 2</div>

Testing del Tema

Para probar que tu componente respeta el tema:

  1. Ve a /settings
  2. Cambia el tema a "Azul Corporativo" o "Verde Natural"
  3. Navega a tu componente
  4. Verifica que todos los colores cambien correctamente
  5. Verifica que no haya elementos con colores hardcoded que no cambiaron

Recursos Adicionales

  • Documentación del usuario: THEME_CUSTOMIZATION.md
  • Composable de temas: app/composables/useTheme.ts
  • Variables CSS: app/assets/css/main.css
  • Configuración de Nuxt UI: app.config.ts

Preguntas Frecuentes

¿Puedo usar colores de Tailwind como bg-blue-500?

Solo para estados semánticos (éxito, error, advertencia) que NO forman parte del tema. Para todo lo demás, usa las variables de tema.

¿Cómo personalizo un componente de Nuxt UI?

Usa la prop :ui con las variables de tema:

<UCard :ui="{ base: 'bg-[var(--brand-surface)]' }">
  Contenido
</UCard>

¿Qué hago si necesito un color que no está en el tema?

Primero pregunta: ¿realmente necesito un color nuevo, o puedo usar uno existente? Si es absolutamente necesario, propón agregar una nueva variable al sistema de temas en lugar de hardcodear el color.

¿Cómo manejo dark mode?

No necesitas manejarlo manualmente. Las variables CSS ya están optimizadas para dark mode. Solo usa las variables y funcionará automáticamente.


Última actualización: 2025-10-30 Mantenedor: Claude Code para Núcleo Río Frío Versión: 1.0.0