Files
mercadodevida/work/artifacts/F-128/architect.md
2026-08-21 18:00:22 +02:00

4.3 KiB

F-128 — CMS plantillas: contenido por defecto editable

Diagnóstico

En /admin/cms, el operador reporta que al pulsar "Editar" sobre una plantilla (Home, Productos, Categorías, Marcas), el formulario se abre con el campo body vacío, sin contenido para modificar.

Reproducción:

  1. GET /api/cms/pages → 6 páginas (about, contact, cookies, privacy, shipping, terms). Ninguna coincide con los slugs del array TEMPLATES.
  2. TEMPLATES está hardcoded con home / products / categories / brands.
  3. openTemplate(tpl) (cms/page.tsx:69):
    const existing = items.find(p => p.slug === tpl.slug);
    if (existing) { openEdit(existing); return; }
    setEditing(null);
    setForm({ slug: tpl.slug, title: tpl.defaultTitle, body: '' });  // ← body vacío
    
  4. Cuando NO existe CMS page para ese slug (caso actual para los 4 templates), form.body queda '' y el botón Guardar está disabled (!form.body).

Resultado: el operador abre una plantilla → no puede editar nada porque no hay contenido previo. Tendría que crear el contenido desde cero (pero el botón Guardar está disabled por el body vacío, así que tampoco puede).

Diseño

Añadir defaultBody a cada template (HTML por defecto, listo para Lexical) y pre-rellenar form.body cuando se abre una plantilla sin página existente.

Cambios

apps/admin/src/app/(dashboard)/cms/page.tsx:

 const TEMPLATES = [
-  { slug: 'home', label: 'Home', route: '/', icon: '🏠',
-    defaultTitle: 'Bienvenido a Mercado de Vida',
-    hint: 'Sección de bienvenida destacada en la página de inicio.' },
+  { slug: 'home', label: 'Home', route: '/', icon: '🏠',
+    defaultTitle: 'Bienvenido a Mercado de Vida',
+    hint: 'Sección de bienvenida destacada en la página de inicio.',
+    defaultBody: '<h2>Bienvenido a Mercado de Vida</h2><p>Productos naturales, ecológicos y de comercio justo. Envío a toda la península en 24-48h.</p>' },
   { slug: 'products', label: 'Productos', route: '/products', icon: '🛒',
-    defaultTitle: 'Nuestros productos',
-    hint: 'Texto introductorio del listado de productos.' },
+    defaultTitle: 'Nuestros productos',
+    hint: 'Texto introductorio del listado de productos.',
+    defaultBody: '<p>Descubre nuestra selección de productos naturales y ecológicos. Filtra por categoría, marca o atributo (vegano, sin gluten, bio...).</p>' },
   { slug: 'categories', label: 'Categorías', route: '/categories', icon: '🗂️',
-    defaultTitle: 'Nuestras categorías',
-    hint: 'Texto introductorio del listado de categorías.' },
+    defaultTitle: 'Nuestras categorías',
+    hint: 'Texto introductorio del listado de categorías.',
+    defaultBody: '<p>Explora todas nuestras categorías: alimentación, cosmética, limpieza del hogar y más.</p>' },
   { slug: 'brands', label: 'Marcas', route: '/brands', icon: '🏷️',
-    defaultTitle: 'Nuestras marcas',
-    hint: 'Texto introductorio del listado de marcas.' },
+    defaultTitle: 'Nuestras marcas',
+    hint: 'Texto introductorio del listado de marcas.',
+    defaultBody: '<p>Trabajamos con marcas comprometidas con la producción ecológica y el comercio justo.</p>' },
 ];

openTemplate:

 const openTemplate = (tpl: typeof TEMPLATES[number]) => {
   const existing = items.find(p => p.slug === tpl.slug);
   if (existing) { openEdit(existing); return; }
   setEditing(null);
-  setForm({ slug: tpl.slug, title: tpl.defaultTitle, body: '' });
+  setForm({ slug: tpl.slug, title: tpl.defaultTitle, body: tpl.defaultBody });
   setShowForm(true);
 };

Por qué defaultBody y no crear la página automáticamente

  • El operador todavía debe poder editar el contenido antes de guardar. Si auto-creamos la página con el contenido por defecto, cualquier apertura accidental del template ensucia la DB.
  • Con el body pre-rellenado, el botón Guardar se habilita (porque form.body ya no es vacío) y el operador puede ajustar el contenido y guardarlo cuando quiera.

No tocar el backend

El backend ya devuelve el body correctamente. No requiere cambios ni migración.

Plan

  1. Editar apps/admin/src/app/(dashboard)/cms/page.tsx — añadir defaultBody a cada template + actualizar openTemplate.
  2. cd apps/admin && npx tsc --noEmit.
  3. cd apps/admin && npm run build.
  4. Verificar manualmente (build OK suficiente — la lógica es trivial).
  5. Cerrar gates.