Panel: un sistema de diseño propio para la administración de la tienda
He revisado las 66 pantallas del admin (≈17.000 líneas en src/app/(app)/admin y src/components/admin). Funciona bien, pero sus piezas vienen de la tienda y cada pantalla resuelve a mano lo que debería ser un componente. Esta propuesta separa el tema del admin, fija una escala densa para trabajo diario, añade los componentes que faltan y reorganiza el menú de 39 a 13 entradas.
Todo lo de esta página es interactivo y responde a estos tres controles: el color de marca es lo único que el admin toma de la tienda.
Qué he encontrado
Datos sacados del código actual de la rama tienda-fases-0-7. Lo bueno se conserva: el marco con menú agrupado, Ctrl K, contadores de pendientes, AdminHeader en 67 pantallas y una buena base de accesibilidad.
Cinco reglas para decidir
El inicio es una bandeja de trabajo antes que un informe. Cada número lleva a la lista ya filtrada.
Controles de 36 px (32 en compacto), texto base de 14 px y tablas de 48/38 px. Herramienta de trabajo, no escaparate.
Neutros para la estructura, marca para la acción principal y cinco tonos de estado. Nada de ámbar o rojo escritos a mano.
Si dos pantallas lo hacen, es un componente: filtros, selección masiva, confirmación, toast, campos.
Cambiar la plantilla de la tienda (Nórdico, Lujo…) no puede romper el panel. Solo se comparte el color de marca.
Todo alcanzable con teclado, contraste AA en ambos temas y el estado nunca solo por color: punto + texto.
El dashboard con el sistema aplicado
Tres pantallas navegables: Inicio, Pedidos (pestañas de vista, filtros, selección masiva) y Pedido #1284 (progreso, historial, reembolso con confirmación). Prueba ⌘K / Ctrl K, el modo oscuro y la densidad compacta. Datos de ejemplo.
Tokens semánticos, no colores
Dos capas: primitivas (solo dentro de ds.css) y tokens con nombre de función, que son lo único que usan los componentes. El tema oscuro se elige token a token, no se invierte.
Superficies, bordes y texto
Marca (viene de la tienda)
Estados
text-warning-fg / bg-warning-bg o directamente <Badge tone="warning">.bg-amber-100 text-amber-900 escrito en la pantalla: no cambia con el tema oscuro y hoy aparece 31 veces.Ocho roles tipográficos, sin tamaños sueltos
Inter con cifras tabulares en tablas e importes. Sin tamaños arbitrarios (text-[11px] aparece 11 veces hoy) ni cuatro variantes de interletrado para el mismo rótulo.
Base 4, cuatro radios, dos densidades
Hoy conviven 6 alturas de control (32–48 px), cinco radios y separaciones de página space-y-4/5/6/8. Se reduce a una escala cerrada.
| Cómoda | Compacta | |
|---|---|---|
| Control | 36 | 32 |
| Control sm | 30 | 26 |
| Fila de tabla | 48 | 38 |
| Relleno tarjeta | 20 | 16 |
| Margen página | 32 | 24 |
Preferencia por usuario. En móvil, los objetivos táctiles crecen a 44 px.
Elevación
Botones
Una sola acción primaria por zona. El tamaño por defecto del admin baja de 44 px (el de la tienda) a 36 px. Se añade la variante danger: hoy el diálogo de confirmación la fabrica sobrescribiendo clases.
Formularios
Etiqueta arriba, ayuda debajo, error con icono. Hoy hay 58 <input> sin componente (casillas, radios, interruptores hechos a mano): se crean Checkbox, Radio, Switch y Field.
Estados y badges
Un badge = punto + texto, nunca solo color. Forma redonda para el estado del pedido (el flujo), cuadrada para atributos secundarios (pago, canal). Los estados personalizados de la tienda usan custom con su propio color en el punto.
KPIs y gráficos
Etiqueta → valor → variación con signo y flecha (no solo color) → contexto → minigráfico. Una sola serie en color de marca; la comparación en gris discontinuo; tooltip con ratón y teclado (flechas).
Tablas y listas
Un único patrón de listado para todas las pantallas: pestañas de vista (filtros guardados con recuento) → barra de búsqueda y filtros en chips → tabla con cabecera fija, ordenación y selección → barra de acciones masivas flotante → paginación. Ver la demo de Pedidos.
| Producto | Estado | Stock | Precio | |
|---|---|---|---|---|
Camiseta de algodón orgánico 6 variantes · Ropa | Publicado | 132 | 24,90 € | |
Mochila urbana impermeable 2 variantes · Accesorios | Publicado | 2 | 89,00 € | |
Gorra bordada 1 variante · Accesorios | Borrador | 0 | 19,00 € |
Avisos y confirmaciones
Hoy hay 19 window.confirm() y 36 mensajes role="status" sueltos bajo los botones. Se sustituyen por un diálogo de confirmación que explica la consecuencia y por toasts globales (con «Deshacer» cuando se pueda).
Cuatro plantillas cubren las 66 pantallas
Cada pantalla elige una; así desaparecen los 68 px-6 py-6 con space-y distinto y los márgenes salen del marco.
Cómo llevarlo al código
Por fases, cada una entregable sola y sin romper pantallas. Todo genérico (nada de la tienda en src/).
- Bloque
[data-surface="admin"]englobals.csscon los tokens de esta página (claro y oscuro); la plantilla de la tienda solo aporta--brand. - Ampliar
tailwind.config.ts:success/warning/danger/info/violetcon-fg/-bg/-bd/-solid,surface-2,sunken,text-2/3, sombrasxs–lg, radiosxs–lg. - Sustituir los 31
amber-*y lostext-[11px].
Button: tamaño admin 36 px, variantesdangerydanger-soft, proploading.Badgecon proptone+ punto;OrderStatusBadgeusa los seis tonos y los estados personalizados su color.- Nuevos:
Field,Checkbox,Radio,Switch,Segmented,Tooltip,DropdownMenu,Dialog(Radix ya está instalado).
<Toaster>en el marco yuseConfirm(); retirar los 19window.confirmy los mensajes sueltos.
AdminShell: barra superior con migas, búsqueda, avisos, tema; menú de 13 entradas con subpantallas de la sección activa (admin-nav.tspasa a árbol).- Preferencias de tema y densidad guardadas por usuario.
AdminPage(resumen/lista/detalle/formulario) sustituye lospx-6 py-6.ListView: pestañas de vista, filtros en chips, selección y acciones masivas, paginación. Migrar Pedidos, Productos y Clientes primero.- Inicio rediseñado como en la demo; ficha de pedido con progreso e historial.
- E2E de las pantallas migradas en claro/oscuro y móvil;
npm run build; revisión de contraste AA con axe.
Archivos de esta propuesta: docs/design-system/admin/ (ds.css = tokens y componentes de referencia, dashboard.html = demo, esta página).