4.3 KiB
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:
GET /api/cms/pages→ 6 páginas (about, contact, cookies, privacy, shipping, terms). Ninguna coincide con los slugs del arrayTEMPLATES.TEMPLATESestá hardcoded conhome / products / categories / brands.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- Cuando NO existe CMS page para ese slug (caso actual para los 4 templates),
form.bodyqueda''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.bodyya 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
- Editar
apps/admin/src/app/(dashboard)/cms/page.tsx— añadirdefaultBodya cada template + actualizaropenTemplate. cd apps/admin && npx tsc --noEmit.cd apps/admin && npm run build.- Verificar manualmente (build OK suficiente — la lógica es trivial).
- Cerrar gates.