Skip to main content

frontend-dashboard-patterns

Patrones completos para dashboards frontend vanilla JS: cliente API robusto, orquestación de carga, error boundaries, tabs con navegación, persistencia, fechas, colores, sparklines, Web Workers y debugging. Todo lo que necesitas para construir dashboards resilientes sin bundler.

Ir para a instalação

Informações da origem

Repositório
Ntizar/NtizarBrainMasterMind
Última atividade na origem
1 de julho de 2026 às 06:55
Idioma detectado do SKILL.md
espanhol
Estrelas
2
Forks
0

Opções de instalação

Por padrão, está selecionado o prompt que primeiro revisa a origem. Você pode mudar para um comando direto ou baixar uma cópia local.

Revise os arquivos de origem

Leia o SKILL.md e os arquivos complementares exibidos pelo SkillsMP antes de decidir se vai instalar.

Explorador de arquivos
53 arquivos

Exibindo SKILL.md

SKILL.md
Instruções da origem · Visualização somente leitura
name
frontend-dashboard-patterns
description
Patrones completos para dashboards frontend vanilla JS: cliente API robusto, orquestación de carga, error boundaries, tabs con navegación, persistencia, fechas, colores, sparklines, Web Workers y debugging. Todo lo que necesitas para construir dashboards resilientes sin bundler.
version
1.5.0
author
Hermes Agent
tags
["frontend","dashboard","patterns","vanilla-js","resilience","geodatos","leaflet","choropleth"]
# Frontend Dashboard Patterns — Colección Completa Patrones reutilizables para dashboards frontend vanilla JS sin bundler. Inspirados en ESIOS Dashboard y Ntizar Aurora. ## Tabla de Contenidos 1. [Cliente API Robusto](#1-cliente-api-robusto) — reintentos, circuit breaker, timeouts 2. [Orquestación de Carga](#2-orquestación-de-carga) — Promise.allSettled, anti-doble-carga, cache fallback 3. [Error Boundaries](#3-error-boundaries) — overlay global, errores por sección, retry 4. [Tabs con Navegación](#4-tabs-con-navegación) — hash navigation, lazy-loading, deep-linking 5. [Persistencia de Estado](#5-persistencia-de-estado) — localStorage con validación, expiración, corrupción 6. [Manejo de Fechas](#6-manejo-de-fechas) — UTC→local, zonas horarias, DST 7. [Sistema de Colores](#7-sistema-de-colores) — tokens CSS, modo oscuro, variables semánticas 8. [Sparklines con Plotly](#8-sparklines-con-plotly) — mini gráficos inline optimizados 9. [Web Workers + Comlink](#9-web-workers--comlink) — cálculos pesados sin bloquear UI 10. [Debugging Patterns](#10-debugging-patterns) — scope, lifecycle, DOM integrity, paréntesis desbalanceados, checklist página en blanco 11. [Aurora Design System](#11-aurora-design-system) — CSS puro, 11 packs opt-in, namespaced .nz, 5 skins 12. [Geodatos Choropleth](#12-geodatos-choropleth) — Leaflet + Canvas, TopoJSON, lazy loading geodatos 13. [GTFS Browser Parser](#13-gtfs-browser-parser) — parsing GTFS en navegador sin servidor 14. [Three.js 3D Scenes](#14-threejs-3d-scenes) — escenas 3D interactivas con texturas procedurales, partículas con identidad, zoom a partícula individual, raycasting, labels flotantes, WebSocket sync, deep linking 15. [Three.js Escenarios JSON](references/threejs-scenario-loading.md) — patrón para cargar escenarios desde JSON con validación de schema, normalización y conversión de parámetros a wave params del shader 16. [ESLint v10 Flat Config](#16-eslint-v10-flat-config) — flat config, globals, ignores 17. [Vite HTML Script Processing](#17-vite-html-script-processing) — IIFEs, post-build, rutas relativas 18. [Full-Stack SPA Audit Pattern](#18-full-stack-spa-audit-pattern) — auditar SPA con backend + frontend (Express + vanilla JS) 19. [Toast Notifications](#19-toast-notifications) — sistema de feedback UX con queue, animaciones y auto-dismiss 20. [Conservative Vanilla JS Modernization](#20-conservative-vanilla-js-modernization) — refactorizar ES5→ES6 en 6 fases sin frameworks, sin romper nada 21. [Data Integrity & Graceful Degradation](#21-data-integrity--graceful-degradation) — nunca inventar datos, fallback chains, empty states honestos, limitaciones de contenedores 22. [Hero Redesign Pattern](references/hero-redesign-pattern.md) — primera pantalla con datos reales + acciones rápidas, no hero vacío 23. [NaN Deploy Cache Pattern](references/nan-deploy-cache-pattern.md) — verificación de deploy, cache de Cloudflare, debugging "no cargan datos" 24. [switchTab Pattern — onclick + event listener](references/switchtab-pattern.md) — función switchTab para onclick inline + event listener, hero placement, quick panel en tab correcta 25. [Tab System con Sidebar](references/tab-system-sidebar-pattern.md) — Sistema completo de tabs con sidebar de navegación, hero, lazy-loading, persistencia de estado y toast notifications 25. [Vanilla JS SPA Module Extension](#25-vanilla-js-spa-module-extension) — añadir nuevos módulos a un dashboard SPA existente 26. [Single-File SPA con Aurora](#26-single-file-spa-con-aurora) — patrón completo de dashboard en un solo HTML: sidebar + tabs + hero + lazy-loading + localStorage + toasts. Base para proyectos como ContrataPúblico. 27. [Single-File SPA con datos grandes](#27-single-file-spa-con-datos-grandes) — patrón para embeber datasets grandes (JSON de cientos de KB) en SPAs de un solo archivo sin romper el deploy. 28. [Debugging `typeof LEY_DATA === 'undefined'`](references/single-file-spa-large-data.md) — checklist de 4 causas: `</script>` collision, strings con newlines, Content-Type, CSP. 29. [Migración Completa a Aurora](references/aurora-migration-pattern.md) — patrón de 5 fases para migrar un HTML existente con CSS custom propio al Aurora Design System (auditoría → packs → componentes → CSS mínimo → JS dinámico). Incluye mapeo de componentes, pitfalls de mesh/orbs/gradientes, y métricas objetivo. 30. [Three.js Particle Systems](#30-threejs-particle-systems) — sistemas de partículas con Three.js: pool reciclado, shaders custom, espuma, spray, humo, fuego. Partículas con vida limitada, tamaño variable, blending additive. --- ## 1. Cliente API Robusto Clase `ApiClient` con reintentos exponenciales (backoff + jitter), circuit breaker por endpoint, timeouts por operación, y clasificación de errores HTTP. **Reglas clave:** - No reintentar 4xx (excepto 429) - Circuit breaker: N fallos → abrir circuito T segundos → half-open → cerrar/reabrir - Timeout por request con AbortController - Integrar con `Promise.allSettled` para carga paralela tolerante a fallos **Ver:** `references/api-client-pattern.md` para código completo. --- ## 2. Orquestación de Carga Clase `DataOrchestrator` para cargar múltiples endpoints en paralelo con: - Anti-doble-carga (mínimo 3s entre cargas) - Estados de loading por sección - Fallback a datos cacheados - `Promise.allSettled` para tolerancia parcial **Ver:** `references/orquestacion-carga-pattern.md` para código completo. --- ## 3. Error Boundaries Patrón de resiliencia: - Overlay global cuando todo falla (network, 5xx) - Errores por sección para fallos parciales - `safeRender()` wrapper para que un error de render no rompa el resto - Timeout en servidor con `withTimeout()` wrapper - Clasificación de errores: 404, 502, 503, network, timeout → mensajes distintos **Ver:** `references/error-boundaries-pattern.md` para código completo. --- ## 4. Tabs con Navegación Clase `TabController` para: - Navegación por hash (`#demanda`) con deep-linking - Lazy-loading de contenido - Persistencia de última tab en localStorage - Navegación por teclado (ArrowLeft/ArrowRight) - Accesibilidad: `role="tab"`, `aria-selected` **Ver:** `references/tabs-navigation-pattern.md` para código completo. --- ## 5. Persistencia de Estado Clase `PersistStore` para localStorage con: - Validación de integridad al leer - Expiración automática (TTL configurable) - Control de tamaño (truncar arrays si exceden límite) - Manejo de `QuotaExceededError` - Recuperación ante datos corruptos - Opcional: `HybridStore` con sessionStorage + localStorage **Ver:** `references/persistence-pattern.md` para código completo. --- ## 6. Manejo de Fechas Patrones para fechas consistentes: - **NUNCA usar `new Date('YYYY-MM-DD')`** → se interpreta como UTC - Usar `new Date(year, month, day)` para fechas locales - `toLocaleString('es-ES')` para formateo con zona horaria del navegador - Detección de DST con `Intl.DateTimeFormat().resolvedOptions().timeZone` - Normalización de inputs de fecha - **Hora por defecto en `<input type="time">`**: siempre rellenar con la hora actual de la zona horaria del usuario, no dejar vacío: ```javascript el.value = new Date().toLocaleTimeString('es-ES', { hour:'2-digit', minute:'2-digit', timeZone:'Europe/Madrid', hour12:false }); ``` **Ver:** `references/dates-timezone-pattern.md` para código completo. ### 6.2 Retroactive Date Entry — Registro en días pasados Patrón para formularios de registro que permitan al usuario elegir **cualquier fecha**, no solo hoy. Necesario en apps de seguimiento (dieta, fitness, hábitos) donde el usuario puede olvidar registrar un día y necesita retroceder la fecha. **Implementación resumida (ver reference para código completo):** 1. **HTML** — añadir `<input type="date">` a cada tarjeta de registro, pre-rellenado con `today()` (helper `new Date().toLocaleDateString('sv-SE')`) 2. **Orden UX** — input date va **primero** en el layout (antes del valor), para que el usuario cambie primero el día 3. **JS** — la función de registro lee `inputFecha.value || ''` y lo pasa en el body del fetch 4. **Edición estimada** — añadir también input date en la caja de edición (comida y ejercicio estimados) 5. **Backend** — patrón `fecha || hoy()`: aceptar `fecha` opcional, usarla si viene, fallback a hoy si no 6. **UPSERT** — para tablas con lógica upsert por día (ej: pasos), usar la fecha recibida en el lookup, no `hoy()` ```javascript // Backend — patrón clave const { fecha, ... } = req.body; sql_run('INSERT INTO ... fecha VALUES ?', [req.userId, fecha || hoy(), ...]); // UPSERT — lookup con la fecha recibida const f = fecha || hoy(); const existing = sql_get('SELECT id FROM pasos WHERE usuario_id = ? AND fecha = ?', [req.userId, f]); ``` **Pitfalls específicos:** - El helper `today()` debe estar definido ANTES de construir los HTML templates. Ponerlo al inicio del script. - `sv-SE` locale es el que entienden los inputs `date` nativos. `toISOString().slice(0,10)` también funciona pero puede tener offset UTC. - La clave de todo el patrón es el backend con `fecha || hoy()` — sin eso, clientes viejos que no envían `fecha` se rompen. - Para pasos (UPSERT por día): si no se usa `f` en el `SELECT`, los pasos de ayer se actualizarían sobre los de hoy. **Ver:** `references/retroactive-date-entry.md` para código completo con todos los formularios, estimaciones editables y server-side. --- ## 7. Sistema de Colores Patrón de diseño centralizado: - Variables CSS semánticas (`--color-success`, `--color-danger`) - Variables de gráfico fijas (`--color-chart-1`...) para consistencia - Modo oscuro con `[data-theme="dark"]` - Toggle con localStorage + `prefers-color-scheme` fallback - Un solo archivo de configuración → cambios globales en un lugar **Ver:** `references/color-system-pattern.md` para código completo. --- ## 8. Sparklines con Plotly Mini gráficos inline optimizados: - Reducir datos a 50 puntos máx. antes de renderizar - Sin hover, sin ejes, sin leyenda → rendimiento máximo - `Plotly.purge()` al destruir para liberar memoria - Color condicional (verde si sube, rojo si baja) - Punto final destacado con marker más grande **Ver:** `references/sparklines-pattern.md` para código completo. --- ## 9. Web Workers + Comlink Cálculos pesados sin bloquear UI: - Spatial hashing para ray-casting eficiente - Precomputación + cache - `Comlink.transfer()` para arrays grandes (ArrayBuffer) - `visitToken` vs `Set` para evitar allocation por frame - Batch calculations para terrazas grandes **Ver:** `references/web-workers-pattern.md` para código completo. --- ### 🔥 REGEX-based removal de bloques de código es INFIABLE **2026-06-13 (MasterFit dieta):** Intenté eliminar código de dark mode con `re.sub` y un patrón regex que buscaba desde un comentario hasta `})();`. El regex eliminó el botón HTML pero **dejó fragmentos del IIFE abierto** (bloque `try { localStorage.getItem(DARK_MODE_KEY) ... } catch(e) {}`), lo que rompió la ejecución JS. `loadData()` quedó definida pero nunca llamada porque el bloque IIFE abierto cortaba el script. **Síntomas:** - HTML carga, CSS aplica, pero `typeof loadData === 'undefined'` - No hay errores en consola (el parser JS no falla, solo las funciones después del bloque roto no se definen) - Los datos existen en `database.json` pero no se muestran - Hero vacío, botones de navegación sin efecto **Causa:** Los bloques IIFE con `try { ... } catch(e) {}` anidados son difíciles de delimitar con regex. `re.sub(r'from_comment_to_closing', '', content)` deja fragmentos huérfanos que el parser JS ignora pero que cortan la ejecución. **Fix seguro — 3 pasos:** 1. **Identificar el bloque completo** — buscar el comentario que inicia (`// === DARK MODE TOGGLE ===`) y el cierre (`})();`) 2. **Eliminar con `content[:start] + content[end:]`** — NO usar `re.sub` 3. **Verificar que no queda ningún fragmento** — grep por `DARK_MODE_KEY`, `darkModeToggle`, `toggleDarkMode`, `nz-btn--secondary`, `mf-dark`, `data-nz-theme` **Regla:** Cuando elimines bloques de código, SIEMPRE verifica que no quedan fragmentos huérfanos. Los fragmentos de JS sueltos son bugs silenciosos: el parser no falla, pero las funciones después del fragmento no se definen. **Pitfall adicional:** Después de eliminar bloques grandes con `content[:start] + content[end:]`, verificar que el archivo no se truncó. Un archivo HTML de 120KB que queda en 28KB está **truncado** — se perdió todo el JS y la mayor parte del HTML. Siempre verificar `</html>` y `</body>` están presentes. **Verificación post-fix:** ```python with open('dashboard.html', 'r') as f: content = f.read() for term in ['darkModeToggle', 'DARK_MODE_KEY', 'toggleDarkMode', 'nz-btn--secondary', 'mf-dark', 'data-nz-theme']: if term in content: print(f"⚠️ {term} aún presente") # Verificar integridad del archivo assert '</html>' in content, "Archivo truncado — falta </html>" assert '</body>' in content, "Archivo truncado — falta </body>" assert 'function loadData()' in content, "loadData() eliminada" assert 'function renderDashboard' in content, "renderDashboard eliminada" ``` --- ### 🔥 Hero vacío en primera pantalla — UX crítica **2026-06-13 (MasterFit dieta):** El hero solo mostraba branding ("MasterFit", "Objetivo: 88 kg", avatar) sin ningún dato ni acción. El usuario dice "no se ve información relevante" — la primera pantalla DEBE mostrar: 1. **Datos reales** — peso actual, kg perdidos, ritmo semanal (o "sin datos" si no hay) 2. **Acciones rápidas** — botones para "Registrar" y "Hablar con IA" (las 2 acciones principales) **Patrón de hero correcto:** ```html <section class="nz-hero nz-hero--centered"> <div class="nz-hero__inner"> <div class="nz-hero__eyebrow">Dashboard de seguimiento</div> <h1 class="nz-hero__title nz-gradient-text">🏋️ MasterFit</h1> <p class="nz-hero__sub">Objetivo: <strong>88 kg</strong></p> <!-- Quick Status con datos reales --> <div id="heroQuickStatus"> <div class="nz-surface nz-surface--glass-soft"> <div>⚖️ Peso</div> <div id="heroPeso">--</div> </div> <div class="nz-surface nz-surface--glass-soft"> <div>📉 Perdido</div> <div id="heroPerdido">--</div> </div> <div class="nz-surface nz-surface--glass-soft"> <div>🔥 Ritmo</div> <div id="heroRitmo">--</div> </div> </div> <!-- Acciones rápidas --> <div class="nz-hero__cta"> <a class="nz-btn nz-btn--glass-liquid-brand" onclick="switchTab('registrar')">➕ Registrar</a> <a class="nz-btn nz-btn--glass-liquid-accent" onclick="switchTab('ia')">🤖 Hablar con IA</a> </div> </div> </section> ```
Ver no GitHub
Este SKILL.md e muito grande, entao o SkillsMP mostra aqui apenas a primeira secao. Ver no GitHub