Files
gkachele-saas/memoria/SISTEMA_BLOQUES_EDITABLES.md
2026-01-17 11:40:17 +01:00

248 lines
6.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 🧩 Sistema de Bloques Editables - GKACHELE™
**© 2025 GKACHELE™. Todos los derechos reservados.**
**Hash:** `gkachele-bloques-editables-20250115-001`
---
## 📋 OBJETIVO
Implementar sistema completo de bloques editables similar a WordPress Gutenberg:
- ✅ Añadir/eliminar bloques (videos, imágenes, texto, redes sociales)
- ✅ Mover bloques (drag & drop)
- ✅ Edición inline (click con lápiz) + sidebar
- ✅ Iconos de redes sociales automáticos
- ✅ Mapa embed sin API key
- ✅ Todo sincronizado en tiempo real
---
## 🎯 FUNCIONALIDADES REQUERIDAS
### 1. Añadir Bloques
- Botón " Añadir Bloque" en sidebar
- Tipos: Video (YouTube/Vimeo), Imagen, Texto, Redes Sociales, Mapa
- Cada bloque se añade al preview y al sidebar
### 2. Eliminar Bloques
- Botón "🗑️" en cada bloque del preview
- Confirmación antes de eliminar
- Sincronización automática
### 3. Mover Bloques
- Drag & drop usando HTML5 Drag API
- Indicadores visuales al arrastrar
- Guardado automático del orden
### 4. Redes Sociales con Iconos
- Al añadir URL de red social, mostrar icono automático
- Iconos: Facebook, Instagram, Twitter/X, WhatsApp, YouTube
- Usar Font Awesome o SVG inline
### 5. Mapa Embed
- Campo para URL de Google Maps (compartir → insertar mapa)
- Renderizar iframe sin necesidad de API key
- Validación de URL
### 6. Edición Híbrida
- Click en elemento → editar inline (modal)
- Cambios en sidebar → actualizar preview
- Bidireccional siempre
---
## 🔧 IMPLEMENTACIÓN
### Estructura de Datos
```json
{
"blocks": [
{
"id": "block_1234567890",
"type": "video",
"content": {
"url": "https://www.youtube.com/embed/...",
"title": "Video Tutorial"
},
"order": 0
},
{
"id": "block_1234567891",
"type": "redes_sociales",
"content": {
"facebook": "https://facebook.com/...",
"instagram": "https://instagram.com/..."
},
"order": 1
},
{
"id": "block_1234567892",
"type": "mapa",
"content": {
"url": "https://www.google.com/maps/embed?pb=..."
},
"order": 2
}
]
}
```
### Backend (app.py)
```python
# Endpoint para añadir bloque
@app.route('/api/customizer/add-block', methods=['POST'])
def add_block():
# Añadir nuevo bloque a content_json['blocks']
pass
# Endpoint para eliminar bloque
@app.route('/api/customizer/remove-block', methods=['POST'])
def remove_block():
# Eliminar bloque por ID
pass
# Endpoint para reordenar bloques
@app.route('/api/customizer/reorder-blocks', methods=['POST'])
def reorder_blocks():
# Actualizar orden de bloques
pass
```
### Frontend (customizer.html)
```javascript
// Añadir bloque
function addBlock(type) {
const blockId = 'block_' + Date.now();
const newBlock = {
id: blockId,
type: type,
content: getDefaultContentForType(type),
order: blocks.length
};
// Añadir a preview y sidebar
renderBlock(newBlock);
saveBlocks();
}
// Eliminar bloque
function removeBlock(blockId) {
if (confirm('¿Eliminar este bloque?')) {
// Remover del DOM y del array
saveBlocks();
}
}
// Drag & Drop
function initDragDrop() {
document.querySelectorAll('.gk-block').forEach(block => {
block.draggable = true;
block.addEventListener('dragstart', handleDragStart);
block.addEventListener('dragover', handleDragOver);
block.addEventListener('drop', handleDrop);
});
}
```
### Template (template.html)
```html
<!-- Renderizar bloques dinámicamente -->
{% if blocks %}
{% for block in blocks|sort(attribute='order') %}
{% if block.type == 'video' %}
<div class="gk-block" data-block-id="{{ block.id }}" draggable="true">
<button class="gk-block-delete" onclick="removeBlock('{{ block.id }}')">🗑️</button>
<iframe src="{{ block.content.url }}" frameborder="0"></iframe>
</div>
{% elif block.type == 'redes_sociales' %}
<div class="gk-block" data-block-id="{{ block.id }}" draggable="true">
<button class="gk-block-delete" onclick="removeBlock('{{ block.id }}')">🗑️</button>
<div class="social-icons">
{% if block.content.facebook %}
<a href="{{ block.content.facebook }}"><i class="fab fa-facebook"></i></a>
{% endif %}
<!-- Más redes... -->
</div>
</div>
{% elif block.type == 'mapa' %}
<div class="gk-block" data-block-id="{{ block.id }}" draggable="true">
<button class="gk-block-delete" onclick="removeBlock('{{ block.id }}')">🗑️</button>
<iframe src="{{ block.content.url }}" width="100%" height="450" frameborder="0"></iframe>
</div>
{% endif %}
{% endfor %}
{% endif %}
```
---
## 📝 CHECKLIST
- [ ] Sistema de bloques en backend (añadir/eliminar/reordenar)
- [ ] UI para añadir bloques en sidebar
- [ ] Renderizado de bloques en template
- [ ] Drag & drop funcional
- [ ] Iconos de redes sociales (Font Awesome o SVG)
- [ ] Mapa embed sin API
- [ ] Edición inline de bloques
- [ ] Sincronización bidireccional
- [ ] Guardado automático
- [ ] Indicadores visuales (hover, drag)
---
## 🎨 ESTILOS
```css
.gk-block {
position: relative;
margin: 20px 0;
padding: 15px;
border: 2px dashed transparent;
transition: all 0.3s;
}
.gk-block:hover {
border-color: var(--primary);
}
.gk-block.dragging {
opacity: 0.5;
}
.gk-block-delete {
position: absolute;
top: 10px;
right: 10px;
background: #d63638;
color: white;
border: none;
padding: 5px 10px;
border-radius: 4px;
cursor: pointer;
opacity: 0;
transition: opacity 0.2s;
}
.gk-block:hover .gk-block-delete {
opacity: 1;
}
```
---
## 🔗 REFERENCIAS
- WordPress Gutenberg: Sistema de bloques
- Elementor: Drag & drop visual
- Google Maps Embed: Sin API key necesario
---
**Última actualización:** 2025-01-15
**Estado:** En desarrollo