Modularización de GKACHELE SaaS

This commit is contained in:
gkachele
2026-01-17 11:40:17 +01:00
commit b6820848b8
1338 changed files with 339275 additions and 0 deletions

View File

@@ -0,0 +1,247 @@
# 🧩 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