- renombrar openspec/ a _openspec/ (carpeta auxiliar) - mover specs de features a changes/ - crear specs base: arquitectura-limpia, estandares-codigo, nomenclatura - migrar _planificacion/ con design-system y roi-theme-template - agregar especificacion recaptcha anti-spam (proposal, tasks, spec) - corregir rutas y referencias en todas las specs Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
361 lines
10 KiB
Markdown
361 lines
10 KiB
Markdown
# 👁️ VISTA PREVIA EN TIEMPO REAL
|
|
|
|
## Estructura HTML del Preview
|
|
|
|
```html
|
|
<div class="col-12">
|
|
<div class="card shadow-sm mb-3" style="border-left: 4px solid #FF8600;">
|
|
<div class="card-body">
|
|
<h5 class="fw-bold mb-3" style="color: #1e3a5f;">
|
|
<i class="bi bi-eye me-2" style="color: #FF8600;"></i>
|
|
Vista Previa en Tiempo Real
|
|
</h5>
|
|
|
|
<!-- IMPORTANTE: Usar las MISMAS clases que el componente real -->
|
|
<div id="componentPreview" class="[clases-del-componente-real]">
|
|
<!-- HTML IDÉNTICO al del front-end -->
|
|
</div>
|
|
|
|
<div class="d-flex justify-content-between align-items-center mt-3">
|
|
<small class="text-muted">
|
|
<i class="bi bi-info-circle me-1"></i>
|
|
Los cambios se reflejan en tiempo real
|
|
</small>
|
|
<div class="btn-group btn-group-sm" role="group">
|
|
<button type="button" class="btn btn-outline-secondary active" id="previewDesktop">
|
|
<i class="bi bi-display"></i> Desktop
|
|
</button>
|
|
<button type="button" class="btn btn-outline-secondary" id="previewMobile">
|
|
<i class="bi bi-phone"></i> Mobile
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
```
|
|
|
|
**Características clave:**
|
|
- ✅ Border-left ORANGE (#FF8600) - NO navy
|
|
- ✅ Clases IDÉNTICAS al componente del front-end
|
|
- ✅ HTML IDÉNTICO al front-end
|
|
- ✅ Botones Desktop/Mobile para cambiar el ancho
|
|
|
|
---
|
|
|
|
## Reglas Críticas para Vista Previa
|
|
|
|
### ❌ LO QUE NO DEBES HACER
|
|
|
|
#### 1. NO usar inline styles que sobreescriban el CSS real
|
|
|
|
```html
|
|
<!-- ❌ MAL: Inline styles que sobreescriben el CSS real -->
|
|
<div id="preview" class="component" style="padding: 10px; color: blue;">
|
|
<!-- Esto NO se verá igual al front-end -->
|
|
</div>
|
|
```
|
|
|
|
#### 2. NO crear CSS específico para el preview que no existe en el front-end
|
|
|
|
```css
|
|
/* ❌ MAL: CSS específico para el preview que no existe en el front-end */
|
|
#componentPreview {
|
|
padding: 20px;
|
|
font-size: 16px;
|
|
background-color: #f0f0f0;
|
|
}
|
|
```
|
|
|
|
#### 3. NO modificar la estructura HTML del componente
|
|
|
|
```html
|
|
<!-- ❌ MAL: HTML diferente al front-end -->
|
|
<div id="preview" class="my-custom-wrapper">
|
|
<div class="component">
|
|
<!-- Estructura diferente -->
|
|
</div>
|
|
</div>
|
|
```
|
|
|
|
---
|
|
|
|
### ✅ LO QUE DEBES HACER
|
|
|
|
#### 1. Usar EXACTAMENTE las mismas clases que el front-end
|
|
|
|
```html
|
|
<!-- ✅ BIEN: Usar EXACTAMENTE las mismas clases que el front-end -->
|
|
<div id="topBarPreview" class="top-notification-bar">
|
|
<div class="container">
|
|
<div class="notification-content">
|
|
<!-- Estructura IDÉNTICA al front-end -->
|
|
</div>
|
|
</div>
|
|
</div>
|
|
```
|
|
|
|
#### 2. Cargar el CSS del front-end en el admin
|
|
|
|
```html
|
|
<!-- ✅ BIEN: Cargar el CSS real del front-end -->
|
|
<link rel="stylesheet" href="../../Css/style.css">
|
|
```
|
|
|
|
#### 3. Solo aplicar estilos si es ABSOLUTAMENTE necesario con !important
|
|
|
|
```css
|
|
/* ✅ BIEN: Solo si el CSS del front-end no se aplica correctamente */
|
|
#componentPreview.top-notification-bar {
|
|
/* Solo agregar si es necesario para el contexto del admin */
|
|
border: 1px solid #e9ecef; /* Border para debugging visual */
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Ejemplo Completo: Top Bar Preview
|
|
|
|
### HTML del Front-end (Original)
|
|
|
|
```html
|
|
<div class="top-notification-bar">
|
|
<div class="container">
|
|
<div class="notification-content">
|
|
<i class="bi bi-megaphone-fill notification-icon"></i>
|
|
<span class="notification-text">
|
|
<strong class="notification-highlight">Nuevo:</strong>
|
|
Accede a más de 200,000 APUs actualizados.
|
|
</span>
|
|
<a href="/catalogo" class="notification-link">
|
|
Ver Catálogo →
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
```
|
|
|
|
### HTML del Preview (Admin) ✅ CORRECTO
|
|
|
|
```html
|
|
<!-- ✅ IDÉNTICO al front-end -->
|
|
<div id="topBarPreview" class="top-notification-bar">
|
|
<div class="container">
|
|
<div class="notification-content">
|
|
<i class="bi bi-megaphone-fill notification-icon" id="previewIcon"></i>
|
|
<span class="notification-text">
|
|
<strong class="notification-highlight" id="previewHighlight">Nuevo:</strong>
|
|
<span id="previewMessage">Accede a más de 200,000 APUs actualizados.</span>
|
|
</span>
|
|
<a href="/catalogo" class="notification-link" id="previewLink">
|
|
Ver Catálogo →
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
```
|
|
|
|
**Diferencias permitidas:**
|
|
- ✅ IDs agregados para manipulación con JavaScript (`id="previewIcon"`, `id="previewMessage"`, etc.)
|
|
- ✅ Clases CSS IDÉNTICAS al front-end
|
|
- ✅ Estructura HTML IDÉNTICA
|
|
|
|
---
|
|
|
|
## CSS para Vista Previa
|
|
|
|
### Principio: NO sobreescribir estilos del front-end
|
|
|
|
```css
|
|
/* REGLA DE ORO: NO sobreescribir estilos del front-end */
|
|
/* Solo agregar si es absolutamente necesario */
|
|
|
|
/* ✅ Permitido: Border para distinguir visualmente el preview en el admin */
|
|
#topBarPreview {
|
|
border: 1px solid #e9ecef;
|
|
border-radius: 0.375rem;
|
|
}
|
|
|
|
/* ❌ NO permitido: Sobreescribir propiedades del componente */
|
|
#topBarPreview {
|
|
padding: 20px !important; /* ❌ Esto hará que no se vea igual */
|
|
font-size: 18px !important; /* ❌ Esto hará que no se vea igual */
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## JavaScript para updatePreview()
|
|
|
|
### Patrón Básico
|
|
|
|
```javascript
|
|
/**
|
|
* Actualiza la vista previa en tiempo real
|
|
*/
|
|
function updatePreview() {
|
|
const preview = document.getElementById('topBarPreview');
|
|
if (!preview) return;
|
|
|
|
// REGLA: Solo modificar propiedades que el usuario puede cambiar
|
|
// NO modificar padding, margins, o estructura del HTML
|
|
|
|
// 1. Actualizar colores
|
|
const bgColor = document.getElementById('bgColor').value;
|
|
const textColor = document.getElementById('textColor').value;
|
|
preview.style.backgroundColor = bgColor;
|
|
preview.style.color = textColor;
|
|
|
|
// 2. Actualizar texto
|
|
const highlightText = document.getElementById('highlightText').value;
|
|
const messageText = document.getElementById('messageText').value;
|
|
document.getElementById('previewHighlight').textContent = highlightText;
|
|
document.getElementById('previewMessage').textContent = messageText;
|
|
|
|
// 3. Actualizar link
|
|
const showLink = document.getElementById('showLink').checked;
|
|
const linkElement = document.getElementById('previewLink');
|
|
linkElement.style.display = showLink ? 'inline-block' : 'none';
|
|
|
|
if (showLink) {
|
|
const linkText = document.getElementById('linkText').value;
|
|
const linkUrl = document.getElementById('linkUrl').value;
|
|
const linkTarget = document.getElementById('linkTarget').value;
|
|
linkElement.textContent = linkText;
|
|
linkElement.href = linkUrl;
|
|
linkElement.target = linkTarget;
|
|
}
|
|
|
|
// 4. Mostrar/ocultar icono
|
|
const showIcon = document.getElementById('showIcon').checked;
|
|
const iconElement = document.getElementById('previewIcon');
|
|
iconElement.style.display = showIcon ? 'inline-block' : 'none';
|
|
|
|
// 5. Cambiar clase del icono
|
|
const iconClass = document.getElementById('iconClass').value;
|
|
iconElement.className = iconClass + ' notification-icon';
|
|
}
|
|
```
|
|
|
|
### Conectar updatePreview() a Todos los Campos
|
|
|
|
```javascript
|
|
function initializeEventListeners() {
|
|
// Lista de campos que deben actualizar el preview
|
|
const fields = [
|
|
'bgColor',
|
|
'textColor',
|
|
'highlightColor',
|
|
'highlightText',
|
|
'messageText',
|
|
'showLink',
|
|
'linkText',
|
|
'linkUrl',
|
|
'linkTarget',
|
|
'showIcon',
|
|
'iconClass',
|
|
'fontSize'
|
|
];
|
|
|
|
// Conectar event listeners
|
|
fields.forEach(fieldId => {
|
|
const element = document.getElementById(fieldId);
|
|
if (element) {
|
|
if (element.type === 'checkbox') {
|
|
element.addEventListener('change', updatePreview);
|
|
} else {
|
|
element.addEventListener('input', updatePreview);
|
|
}
|
|
}
|
|
});
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Botones Desktop/Mobile
|
|
|
|
### HTML
|
|
|
|
```html
|
|
<div class="btn-group btn-group-sm" role="group">
|
|
<button type="button" class="btn btn-outline-secondary active" id="previewDesktop">
|
|
<i class="bi bi-display"></i> Desktop
|
|
</button>
|
|
<button type="button" class="btn btn-outline-secondary" id="previewMobile">
|
|
<i class="bi bi-phone"></i> Mobile
|
|
</button>
|
|
</div>
|
|
```
|
|
|
|
### JavaScript
|
|
|
|
```javascript
|
|
const btnDesktop = document.getElementById('previewDesktop');
|
|
const btnMobile = document.getElementById('previewMobile');
|
|
const preview = document.getElementById('topBarPreview');
|
|
|
|
btnDesktop.addEventListener('click', function() {
|
|
// Activar botón
|
|
this.classList.add('active');
|
|
btnMobile.classList.remove('active');
|
|
|
|
// Cambiar ancho del preview
|
|
preview.style.maxWidth = '100%';
|
|
preview.style.margin = '0';
|
|
});
|
|
|
|
btnMobile.addEventListener('click', function() {
|
|
// Activar botón
|
|
this.classList.add('active');
|
|
btnDesktop.classList.remove('active');
|
|
|
|
// Cambiar ancho del preview (simular mobile)
|
|
preview.style.maxWidth = '375px';
|
|
preview.style.margin = '0 auto';
|
|
});
|
|
```
|
|
|
|
---
|
|
|
|
## Checklist de Vista Previa
|
|
|
|
Antes de considerar completa la vista previa, verificar:
|
|
|
|
- [ ] HTML del preview es IDÉNTICO al front-end
|
|
- [ ] Se usan las MISMAS clases CSS que el componente real
|
|
- [ ] Se carga el archivo CSS del front-end (`../../Css/style.css`)
|
|
- [ ] NO hay inline styles que sobreescriban propiedades del componente
|
|
- [ ] La función `updatePreview()` está conectada a todos los campos
|
|
- [ ] Los botones Desktop/Mobile funcionan correctamente
|
|
- [ ] El preview se ve IDÉNTICO al componente en el sitio real
|
|
|
|
---
|
|
|
|
## Debugging de Vista Previa
|
|
|
|
### Problema: El preview no se ve igual al front-end
|
|
|
|
**Solución:**
|
|
|
|
1. Abrir DevTools (F12)
|
|
2. Inspeccionar el elemento del preview
|
|
3. Verificar que se cargan los estilos correctos:
|
|
|
|
```
|
|
Computed Styles →
|
|
padding: 0.5rem 0 (debe venir de style.css)
|
|
background-color: rgb(14, 35, 55) (debe venir del inline style del preview)
|
|
```
|
|
|
|
4. Si hay estilos incorrectos:
|
|
- Verificar que `style.css` esté cargado
|
|
- Verificar que las clases CSS sean idénticas
|
|
- Verificar que no haya inline styles conflictivos
|
|
|
|
---
|
|
|
|
## Volver al Índice
|
|
|
|
[← Volver al README](README.md)
|