Files
gkachele-saas/demo/themes/restaurante-moderno/template.html
2026-01-17 11:40:17 +01:00

1394 lines
57 KiB
HTML
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.
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{ site_name or 'Restaurante' }}</title>
<script>
// Script para click to edit y actualización en tiempo real
(function () {
if (window.parent !== window) {
// Estamos en un iframe
let currentContent = {};
// Escuchar actualizaciones de contenido desde el padre
window.addEventListener('message', function (e) {
if (e.data && e.data.type === 'update-content') {
currentContent = e.data.content || {};
updateDOMWithContent(currentContent);
} else if (e.data && e.data.type === 'add-block') {
addBlockToDOM(e.data.block);
} else if (e.data && e.data.type === 'remove-block') {
removeBlockFromDOM(e.data.block_id);
} else if (e.data && e.data.type === 'reorder-blocks') {
reorderBlocksInDOM(e.data.blockIds);
}
});
function addBlockToDOM(block) {
const section = document.createElement('section');
section.className = 'section gk-block';
section.dataset.blockId = block.id;
section.dataset.type = block.type; // Useful for styling or debugging
section.style.position = 'relative';
let contentHTML = '<div class="container">';
if (block.type === 'texto') {
contentHTML += `
<div class="gk-block-content">
<h2 class="gk-editable" data-editable="blocks.${block.id}.content.titulo" data-type="text" title="Click para editar">${block.content.titulo || 'Nuevo Título'}</h2>
<p class="gk-editable" data-editable="blocks.${block.id}.content.contenido" data-type="textarea" title="Click para editar">${block.content.contenido || 'Contenido del bloque...'}</p>
</div>`;
} else if (block.type === 'imagen') {
contentHTML += `
<div class="gk-block-content" style="text-align:center;">
<img src="${block.content.url || 'https://via.placeholder.com/800x400'}" style="max-width:100%; border-radius:10px;">
</div>`;
} else if (block.type === 'video') {
contentHTML += `
<div class="gk-block-content">
<p style="text-align:center; padding:50px; background:#eee;">Video Placeholder (Configurar URL en Customizer)</p>
</div>
`;
} else if (block.type === 'mapa') {
contentHTML += `
<div class="gk-block-content">
<p style="text-align:center; padding:50px; background:#eee;">Mapa Placeholder</p>
</div>
`;
}
contentHTML += '</div>';
// Add Delete Button (Client side only mostly)
contentHTML += `
<div class="gk-block-actions">
<button class="gk-block-action-btn" onclick="window.editBlockFromPreview('${block.id}')" title="Editar bloque">✏️ Editar</button>
<button class="gk-block-action-btn delete" onclick="window.removeBlockFromPreview('${block.id}')" title="Eliminar bloque">🗑️ Eliminar</button>
</div>
`;
section.innerHTML = contentHTML;
let wrapper = document.querySelector('.dynamic-blocks-wrapper');
if (!wrapper) {
wrapper = document.createElement('div');
wrapper.className = 'dynamic-blocks-wrapper';
const footer = document.querySelector('footer');
footer.parentNode.insertBefore(wrapper, footer);
}
wrapper.appendChild(section);
}
function removeBlockFromDOM(id) {
const el = document.querySelector(`.gk-block[data-block-id="${id}"]`);
if (el) el.remove();
}
function reorderBlocksInDOM(ids) {
const wrapper = document.querySelector('.dynamic-blocks-wrapper');
if (!wrapper) return;
ids.forEach(id => {
const el = wrapper.querySelector(`.gk-block[data-block-id="${id}"]`);
if (el) wrapper.appendChild(el);
});
}
// Función para actualizar el DOM con nuevo contenido
function updateDOMWithContent(content) {
// Actualizar site_name
const siteNameEl = document.querySelector('[data-editable="site_name"]');
if (siteNameEl && content.site_name) {
siteNameEl.textContent = content.site_name;
}
// Actualizar hero_title
const heroTitleEl = document.querySelector('[data-editable="hero_title"]');
if (heroTitleEl && content.hero_title) {
heroTitleEl.textContent = content.hero_title;
}
// Actualizar hero_description
const heroDescEl = document.querySelector('[data-editable="hero_description"]');
if (heroDescEl && content.hero_description) {
heroDescEl.textContent = content.hero_description;
}
// Actualizar horarios
if (content.horarios) {
const horariosEls = {
'horarios.lunes_viernes': document.querySelector('[data-editable="horarios.lunes_viernes"]'),
'horarios.sabados': document.querySelector('[data-editable="horarios.sabados"]'),
'horarios.domingos': document.querySelector('[data-editable="horarios.domingos"]')
};
if (horariosEls['horarios.lunes_viernes'] && content.horarios.lunes_viernes) {
horariosEls['horarios.lunes_viernes'].textContent = content.horarios.lunes_viernes;
}
if (horariosEls['horarios.sabados'] && content.horarios.sabados) {
horariosEls['horarios.sabados'].textContent = content.horarios.sabados;
}
if (horariosEls['horarios.domingos'] && content.horarios.domingos) {
horariosEls['horarios.domingos'].textContent = content.horarios.domingos;
}
}
// Actualizar contacto
const contactoEls = {
'direccion': document.querySelector('[data-editable="direccion"]'),
'telefono': document.querySelector('[data-editable="telefono"]'),
'email': document.querySelector('[data-editable="email"]'),
'capacidad': document.querySelector('[data-editable="capacidad"]')
};
if (contactoEls.direccion && content.direccion) contactoEls.direccion.textContent = content.direccion;
if (contactoEls.telefono && content.telefono) contactoEls.telefono.textContent = content.telefono;
if (contactoEls.email && content.email) contactoEls.email.textContent = content.email;
if (contactoEls.capacidad && content.capacidad) contactoEls.capacidad.textContent = content.capacidad;
// Actualizar especialidad culinaria
if (content.especialidad_culinaria) {
const especialidadTitulo = document.querySelector('.especialidad-text h2');
const especialidadDesc = document.querySelector('.especialidad-text p');
const especialidadImg = document.querySelector('.especialidad-image img');
if (especialidadTitulo && content.especialidad_culinaria.titulo) especialidadTitulo.textContent = content.especialidad_culinaria.titulo;
if (especialidadDesc && content.especialidad_culinaria.descripcion) especialidadDesc.textContent = content.especialidad_culinaria.descripcion;
if (especialidadImg && content.especialidad_culinaria.imagen) especialidadImg.src = content.especialidad_culinaria.imagen;
}
// Actualizar mapa automáticamente desde dirección
if (content.mapa_url) {
const mapaIframe = document.querySelector('.mapa-container iframe');
const mapPlaceholder = document.getElementById('map-placeholder');
if (mapaIframe) {
mapaIframe.src = content.mapa_url;
mapaIframe.parentElement.style.display = 'block';
if (mapPlaceholder) mapPlaceholder.style.display = 'none';
}
} else if (content.direccion) {
// Generar mapa desde dirección si no hay mapa_url
const encodedAddress = encodeURIComponent(content.direccion);
const mapUrl = `https://www.google.com/maps?q=${encodedAddress}&output=embed`;
const mapaIframe = document.querySelector('.mapa-container iframe');
const mapPlaceholder = document.getElementById('map-placeholder');
if (mapaIframe) {
mapaIframe.src = mapUrl;
mapaIframe.parentElement.style.display = 'block';
if (mapPlaceholder) mapPlaceholder.style.display = 'none';
}
}
// Actualizar menu_items dinámicamente
if (content.menu_items && Object.keys(content.menu_items).length > 0) {
const menuContainer = document.getElementById('menu-items-container');
if (menuContainer) {
menuContainer.innerHTML = '';
Object.keys(content.menu_items).forEach(itemId => {
const item = content.menu_items[itemId];
const menuItemDiv = document.createElement('div');
menuItemDiv.className = 'menu-item';
menuItemDiv.dataset.itemId = itemId;
menuItemDiv.innerHTML = `
<h3 class="gk-editable" data-editable="menu_items.${itemId}.nombre" data-type="text" title="Click para editar">${item.nombre || 'Plato Especial'}</h3>
<p class="gk-editable" data-editable="menu_items.${itemId}.descripcion" data-type="textarea" title="Click para editar">${item.descripcion || 'Descripción del plato...'}</p>
<div class="menu-price gk-editable" data-editable="menu_items.${itemId}.precio" data-type="text" title="Click para editar">$${item.precio || '0.00'}</div>
`;
menuContainer.appendChild(menuItemDiv);
});
}
}
// Actualizar WhatsApp flotante
if (content.redes_sociales && content.redes_sociales.whatsapp) {
const whatsappBtn = document.getElementById('whatsapp-float-btn');
if (whatsappBtn) {
whatsappBtn.href = `https://wa.me/${content.redes_sociales.whatsapp}`;
whatsappBtn.style.display = 'flex';
}
} else {
const whatsappBtn = document.getElementById('whatsapp-float-btn');
if (whatsappBtn) whatsappBtn.style.display = 'none';
}
// Actualizar colores CSS
if (content.colors) {
const root = document.documentElement;
if (content.colors.primary) root.style.setProperty('--primary', content.colors.primary);
if (content.colors.secondary) root.style.setProperty('--secondary', content.colors.secondary);
if (content.colors.accent) root.style.setProperty('--accent', content.colors.accent);
if (content.colors.text) root.style.setProperty('--text', content.colors.text);
}
// Actualizar WhatsApp Flotante
const waFloat = document.getElementById('whatsapp-float-btn');
if (waFloat) {
if (content.redes_sociales && content.redes_sociales.whatsapp) {
waFloat.style.display = 'flex';
waFloat.href = `https://wa.me/${content.redes_sociales.whatsapp}`;
} else {
waFloat.style.display = 'none';
}
}
// Actualizar Mapa (Auto-generado si no hay URL pero hay dirección)
const mapContainer = document.querySelector('.mapa-container');
const mapIframe = mapContainer ? mapContainer.querySelector('iframe') : null;
const mapPlaceholder = document.getElementById('map-placeholder');
if (mapContainer && mapIframe) {
let mapUrl = content.mapa_url;
// Si no hay URL explícita, intentar generar desde dirección
if (!mapUrl && content.direccion) {
mapUrl = `https://maps.google.com/maps?q=${encodeURIComponent(content.direccion)}&t=&z=15&ie=UTF8&iwloc=&output=embed`;
}
if (mapUrl) {
mapContainer.style.display = 'block';
if (mapPlaceholder) mapPlaceholder.style.display = 'none';
if (mapIframe.src !== mapUrl) mapIframe.src = mapUrl;
} else {
mapContainer.style.display = 'none';
if (mapPlaceholder) mapPlaceholder.style.display = 'block';
}
}
// Actualizar Redes Sociales
if (content.redes_sociales) {
updateSocialLink('facebook', content.redes_sociales.facebook);
updateSocialLink('instagram', content.redes_sociales.instagram);
updateSocialLink('tiktok', content.redes_sociales.tiktok);
updateSocialLink('linkedin', content.redes_sociales.linkedin);
updateSocialLink('youtube', content.redes_sociales.youtube);
}
}
function updateSocialLink(network, url) {
const links = document.querySelectorAll(`a[data-social="${network}"]`);
links.forEach(link => {
if (url) {
link.style.display = 'inline-flex';
link.href = url;
} else {
link.style.display = 'none';
}
});
}
}
// Click to edit
document.addEventListener('DOMContentLoaded', function () {
const editables = document.querySelectorAll('.gk-editable');
editables.forEach(el => {
el.addEventListener('click', function (e) {
e.preventDefault();
e.stopPropagation();
const field = this.dataset.editable;
const type = this.dataset.type || 'text';
const value = this.textContent.trim();
// Enviar mensaje al padre
window.parent.postMessage({
type: 'gk-edit-field',
field: field,
value: value,
type_field: type
}, '*');
});
});
});
})();
</script>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link
href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;700&family=Playfair+Display:wght@400;600;700&display=swap"
rel="stylesheet">
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
:root {
--primary: {
{
colors.primary if colors else '#c94d4d'
}
}
;
--secondary: {
{
colors.secondary if colors else '#d97757'
}
}
;
--accent: {
{
colors.accent if colors else '#f4a261'
}
}
;
--text-dark: {
{
colors.text if colors else '#2c2c2c'
}
}
;
--text-light: #666;
--bg-light: #fafafa;
--white: #ffffff;
--gradient-hero: linear-gradient(135deg, rgba(201, 77, 77, 0.95) 0%, rgba(217, 119, 87, 0.95) 100%);
--shadow-soft: 0 4px 20px rgba(0, 0, 0, 0.08);
--shadow-hover: 0 8px 30px rgba(0, 0, 0, 0.15);
--transition-smooth: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}
body {
font-family: 'Roboto', sans-serif;
color: var(--text-dark);
line-height: 1.6;
overflow-x: hidden;
}
h1,
h2,
h3,
h4,
h5,
h6 {
font-family: 'Playfair Display', serif;
font-weight: 600;
line-height: 1.2;
}
.section {
padding: 80px 20px;
position: relative;
}
.container {
max-width: 1200px;
margin: 0 auto;
}
/* Header / Navigation */
header {
background: rgba(255, 255, 255, 0.98);
backdrop-filter: blur(10px);
box-shadow: var(--shadow-soft);
position: fixed;
width: 100%;
top: 0;
z-index: 1000;
transition: var(--transition-smooth);
}
header.scrolled {
box-shadow: 0 2px 15px rgba(0, 0, 0, 0.1);
}
nav {
display: flex;
justify-content: space-between;
align-items: center;
padding: 20px 40px;
}
.logo {
font-family: 'Playfair Display', serif;
font-size: 32px;
color: var(--primary);
font-weight: 700;
letter-spacing: -0.5px;
transition: var(--transition-smooth);
}
.logo:hover {
transform: scale(1.05);
}
.nav-links {
display: flex;
list-style: none;
gap: 35px;
}
.nav-links a {
text-decoration: none;
color: var(--text-dark);
font-weight: 500;
font-size: 15px;
position: relative;
transition: var(--transition-smooth);
padding: 5px 0;
}
.nav-links a::after {
content: '';
position: absolute;
bottom: 0;
left: 0;
width: 0;
height: 2px;
background: var(--primary);
transition: width 0.3s ease;
}
.nav-links a:hover {
color: var(--primary);
}
.nav-links a:hover::after {
width: 100%;
}
/* Hero Section */
.hero {
background: var(--gradient-hero);
background-size: cover;
background-position: center;
color: var(--white);
text-align: center;
padding: 180px 20px 120px;
margin-top: 80px;
position: relative;
overflow: hidden;
}
.hero::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: linear-gradient(135deg, rgba(201, 77, 77, 0.92) 0%, rgba(217, 119, 87, 0.92) 100%);
z-index: 1;
}
.hero .container {
position: relative;
z-index: 2;
}
.hero h1 {
font-size: 72px;
margin-bottom: 25px;
color: var(--white);
text-shadow: 0 2px 20px rgba(0, 0, 0, 0.2);
animation: fadeInUp 0.8s ease-out;
}
.hero p {
font-size: 22px;
margin-bottom: 40px;
opacity: 0.98;
font-weight: 300;
letter-spacing: 0.5px;
animation: fadeInUp 0.8s ease-out 0.2s both;
}
.btn {
display: inline-block;
padding: 18px 45px;
background: var(--white);
color: var(--primary);
text-decoration: none;
border-radius: 50px;
font-weight: 600;
font-size: 16px;
transition: var(--transition-smooth);
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2);
animation: fadeInUp 0.8s ease-out 0.4s both;
}
.btn:hover {
transform: translateY(-3px);
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.3);
background: var(--accent);
color: var(--white);
}
@keyframes fadeInUp {
from {
opacity: 0;
transform: translateY(30px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
/* Menu Section */
.menu {
background: var(--white);
}
.section-title {
text-align: center;
font-size: 42px;
color: var(--primary);
margin-bottom: 60px;
}
.menu-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 30px;
margin-top: 40px;
}
.menu-item {
background: var(--white);
padding: 35px;
border-radius: 15px;
transition: var(--transition-smooth);
border: 1px solid rgba(0, 0, 0, 0.05);
position: relative;
overflow: hidden;
}
.menu-item::before {
content: '';
position: absolute;
top: 0;
left: -100%;
width: 100%;
height: 100%;
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.3), transparent);
transition: left 0.5s;
}
.menu-item:hover::before {
left: 100%;
}
.menu-item:hover {
transform: translateY(-8px);
box-shadow: var(--shadow-hover);
border-color: var(--primary);
}
.menu-item h3 {
color: var(--primary);
margin-bottom: 10px;
font-size: 24px;
}
.menu-item p {
color: var(--text-light);
margin-bottom: 15px;
}
.menu-price {
font-size: 26px;
font-weight: 700;
color: var(--primary);
margin-top: 15px;
display: inline-block;
padding: 8px 20px;
background: rgba(201, 77, 77, 0.1);
border-radius: 25px;
}
/* Horarios Section */
.horarios {
background: var(--bg-light);
}
.horarios-content {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 30px;
text-align: center;
}
.horario-item {
background: var(--white);
padding: 35px;
border-radius: 15px;
box-shadow: var(--shadow-soft);
transition: var(--transition-smooth);
border: 1px solid rgba(0, 0, 0, 0.05);
}
.horario-item:hover {
transform: translateY(-5px);
box-shadow: var(--shadow-hover);
}
.horario-item h3 {
color: var(--primary);
margin-bottom: 15px;
}
.horario-item p {
color: var(--text-light);
font-size: 18px;
}
/* Reservas Section */
.reservas {
background: var(--white);
}
.reservas-content {
max-width: 600px;
margin: 0 auto;
text-align: center;
}
.reservas-form {
display: grid;
gap: 20px;
margin-top: 40px;
}
.form-group {
text-align: left;
}
.form-group label {
display: block;
margin-bottom: 8px;
color: var(--text-dark);
font-weight: 500;
}
.form-group input,
.form-group textarea,
.form-group select {
width: 100%;
padding: 14px 18px;
border: 2px solid #e8e8e8;
border-radius: 10px;
font-family: 'Roboto', sans-serif;
font-size: 16px;
transition: var(--transition-smooth);
background: var(--white);
}
.form-group input:focus,
.form-group textarea:focus,
.form-group select:focus {
outline: none;
border-color: var(--primary);
box-shadow: 0 0 0 3px rgba(201, 77, 77, 0.1);
}
.btn-primary {
background: var(--primary);
color: var(--white);
border: none;
padding: 16px 45px;
font-size: 18px;
font-weight: 600;
cursor: pointer;
border-radius: 50px;
transition: var(--transition-smooth);
box-shadow: 0 4px 15px rgba(201, 77, 77, 0.3);
}
.btn-primary:hover {
background: var(--secondary);
transform: translateY(-2px);
box-shadow: 0 6px 20px rgba(201, 77, 77, 0.4);
}
/* Especialidad Culinaria Section */
.especialidad {
background: var(--gradient-hero);
color: var(--white);
position: relative;
overflow: hidden;
}
.especialidad::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: linear-gradient(135deg, rgba(201, 77, 77, 0.95) 0%, rgba(217, 119, 87, 0.95) 100%);
z-index: 1;
}
.especialidad .container {
position: relative;
z-index: 2;
}
.especialidad-content {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 50px;
align-items: center;
}
.especialidad-text h2 {
color: var(--white);
margin-bottom: 20px;
}
.especialidad-text p {
font-size: 18px;
opacity: 0.95;
line-height: 1.8;
}
.especialidad-image {
text-align: center;
}
.especialidad-image img {
max-width: 100%;
border-radius: 10px;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3);
}
/* Contacto Section */
.contacto {
background: var(--bg-light);
}
.contacto-content {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 50px;
}
.contacto-info h3 {
color: var(--primary);
margin-bottom: 20px;
}
.contacto-info p {
color: var(--text-light);
margin-bottom: 15px;
font-size: 16px;
}
.contacto-info strong {
color: var(--text-dark);
}
.redes-sociales {
margin-top: 30px;
}
.redes-sociales a {
display: inline-block;
margin-right: 15px;
color: var(--primary);
font-size: 24px;
transition: transform 0.3s;
}
.redes-sociales a:hover {
transform: scale(1.2);
}
/* Footer */
footer {
background: var(--text-dark);
color: var(--white);
text-align: center;
padding: 40px 20px;
}
/* Responsive */
@media (max-width: 768px) {
.hero h1 {
font-size: 42px;
}
.nav-links {
display: none;
}
.especialidad-content,
.contacto-content {
grid-template-columns: 1fr;
}
.section {
padding: 60px 20px;
}
}
/* Estilos para elementos editables (solo en customizer) */
.gk-editable {
position: relative;
cursor: pointer;
transition: all 0.2s ease;
}
.gk-editable:hover {
outline: 2px dashed var(--primary);
outline-offset: 2px;
background: rgba(201, 77, 77, 0.05);
}
.gk-editable::after {
content: '✏️ Editar';
position: absolute;
top: -28px;
left: 50%;
transform: translateX(-50%);
font-size: 11px;
opacity: 0;
transition: opacity 0.2s;
background: #2271b1;
color: white;
padding: 4px 8px;
border-radius: 3px;
z-index: 10000;
white-space: nowrap;
pointer-events: none;
font-weight: 600;
}
.gk-editable:hover::after {
opacity: 1;
}
/* Botones de acción en bloques (como WordPress) */
.gk-block-actions {
position: absolute;
top: 10px;
right: 10px;
display: flex;
gap: 5px;
opacity: 0;
transition: opacity 0.2s;
z-index: 1000;
}
.gk-block:hover .gk-block-actions {
opacity: 1;
}
.gk-block-action-btn {
background: #2271b1;
color: white;
border: none;
padding: 6px 10px;
border-radius: 3px;
cursor: pointer;
font-size: 12px;
font-weight: 600;
transition: background 0.2s;
}
.gk-block-action-btn:hover {
background: #135e96;
}
.gk-block-action-btn.delete {
background: #d63638;
}
.gk-block-action-btn.delete:hover {
background: #b32d2e;
}
/* WhatsApp Flotante */
.whatsapp-float {
position: fixed;
bottom: 30px;
right: 30px;
background-color: #25d366;
color: white;
width: 60px;
height: 60px;
border-radius: 50%;
text-align: center;
font-size: 30px;
box-shadow: 2px 2px 10px rgba(0, 0, 0, 0.2);
z-index: 9999;
display: flex;
align-items: center;
justify-content: center;
text-decoration: none;
transition: all 0.3s ease;
}
.whatsapp-float:hover {
transform: scale(1.1);
box-shadow: 2px 5px 15px rgba(0, 0, 0, 0.3);
background-color: #20ba5a;
color: white;
}
/* Blocks Styling */
.gk-block {
position: relative;
margin: 20px 0;
transition: all 0.2s ease;
}
.gk-block:hover {
outline: 2px dashed var(--primary);
outline-offset: 5px;
}
.gk-block:hover .gk-block-delete {
opacity: 1 !important;
}
.gk-block[draggable="true"] {
cursor: move;
}
.gk-block.dragging {
opacity: 0.5;
background: #f9f9f9;
}
</style>
</head>
<body>
<!-- Header -->
<header>
<nav>
<div class="logo gk-editable" data-editable="site_name" data-type="text" title="Click para editar">{{
site_name or 'Restaurante' }}</div>
<ul class="nav-links">
<li><a href="#inicio">Inicio</a></li>
<li><a href="#menu">Menú</a></li>
<li><a href="#horarios">Horarios</a></li>
<li><a href="#reservas">Reservas</a></li>
<li><a href="#contacto">Contacto</a></li>
</ul>
</nav>
</header>
<!-- Hero Section -->
<section id="inicio" class="section hero">
<div class="container">
<h1 data-editable="hero_title" data-type="text" class="gk-editable" title="Click para editar">{{ hero_title
or 'Bienvenido a Nuestro Restaurante' }}</h1>
<p data-editable="hero_description" data-type="textarea" class="gk-editable" title="Click para editar">{{
hero_description or 'Sabores auténticos que despiertan tus sentidos' }}</p>
<a href="#reservas" class="btn">Reservar Mesa</a>
</div>
</section>
<!-- Menu Section -->
<section id="menu" class="section menu">
<div class="container">
<h2 class="section-title">Nuestro Menú</h2>
<div class="menu-grid" id="menu-items-container">
{% if menu_items and menu_items|length > 0 %}
{% for item_id, item in menu_items.items() %}
<div class="menu-item" data-item-id="{{ item_id }}">
<h3 class="gk-editable" data-editable="menu_items.{{ item_id }}.nombre" data-type="text"
title="Click para editar">{{ item.nombre if item.nombre else 'Plato Especial' }}</h3>
<p class="gk-editable" data-editable="menu_items.{{ item_id }}.descripcion" data-type="textarea"
title="Click para editar">{{ item.descripcion if item.descripcion else 'Descripción del plato
con ingredientes frescos y sabores únicos.' }}</p>
<div class="menu-price gk-editable" data-editable="menu_items.{{ item_id }}.precio" data-type="text"
title="Click para editar">${{ item.precio if item.precio else '25.00' }}</div>
</div>
{% endfor %}
{% else %}
<div class="menu-item" data-item-id="1">
<h3 class="gk-editable" data-editable="menu_items.1.nombre" data-type="text"
title="Click para editar">Plato Especial 1</h3>
<p class="gk-editable" data-editable="menu_items.1.descripcion" data-type="textarea"
title="Click para editar">Descripción del plato con ingredientes frescos y sabores únicos.</p>
<div class="menu-price gk-editable" data-editable="menu_items.1.precio" data-type="text"
title="Click para editar">$25.00</div>
</div>
<div class="menu-item" data-item-id="2">
<h3 class="gk-editable" data-editable="menu_items.2.nombre" data-type="text"
title="Click para editar">Plato Especial 2</h3>
<p class="gk-editable" data-editable="menu_items.2.descripcion" data-type="textarea"
title="Click para editar">Descripción del plato con ingredientes frescos y sabores únicos.</p>
<div class="menu-price gk-editable" data-editable="menu_items.2.precio" data-type="text"
title="Click para editar">$28.00</div>
</div>
<div class="menu-item" data-item-id="3">
<h3 class="gk-editable" data-editable="menu_items.3.nombre" data-type="text"
title="Click para editar">Plato Especial 3</h3>
<p class="gk-editable" data-editable="menu_items.3.descripcion" data-type="textarea"
title="Click para editar">Descripción del plato con ingredientes frescos y sabores únicos.</p>
<div class="menu-price gk-editable" data-editable="menu_items.3.precio" data-type="text"
title="Click para editar">$30.00</div>
</div>
<div class="menu-item" data-item-id="4">
<h3 class="gk-editable" data-editable="menu_items.4.nombre" data-type="text"
title="Click para editar">Plato Especial 4</h3>
<p class="gk-editable" data-editable="menu_items.4.descripcion" data-type="textarea"
title="Click para editar">Descripción del plato con ingredientes frescos y sabores únicos.</p>
<div class="menu-price gk-editable" data-editable="menu_items.4.precio" data-type="text"
title="Click para editar">$32.00</div>
</div>
{% endif %}
</div>
{% if menu_url %}
<div style="text-align: center; margin-top: 40px;">
<a href="{{ menu_url }}" class="btn" target="_blank">Ver Menú Completo</a>
</div>
{% endif %}
</div>
</section>
<!-- Horarios Section -->
<section id="horarios" class="section horarios">
<div class="container">
<h2 class="section-title">Horarios de Atención</h2>
<div class="horarios-content">
<div class="horario-item">
<h3>Lunes - Viernes</h3>
<p class="gk-editable" data-editable="horarios.lunes_viernes" data-type="text"
title="Click para editar">{{ horarios.lunes_viernes or '12:00 PM - 10:00 PM' }}</p>
</div>
<div class="horario-item">
<h3>Sábados</h3>
<p class="gk-editable" data-editable="horarios.sabados" data-type="text" title="Click para editar">
{{ horarios.sabados or '12:00 PM - 11:00 PM' }}</p>
</div>
<div class="horario-item">
<h3>Domingos</h3>
<p class="gk-editable" data-editable="horarios.domingos" data-type="text" title="Click para editar">
{{ horarios.domingos or '12:00 PM - 9:00 PM' }}</p>
</div>
</div>
</div>
</section>
<!-- Reservas Section -->
<section id="reservas" class="section reservas">
<div class="container">
<h2 class="section-title">Reserva tu Mesa</h2>
<div class="reservas-content">
<p style="color: var(--text-light); margin-bottom: 30px;">
Completa el formulario y nos pondremos en contacto contigo para confirmar tu reserva.
</p>
<form class="reservas-form">
<div class="form-group">
<label>Nombre Completo</label>
<input type="text" name="nombre" required>
</div>
<div class="form-group">
<label>Teléfono</label>
<input type="tel" name="telefono" required>
</div>
<div class="form-group">
<label>Email</label>
<input type="email" name="email" required>
</div>
<div class="form-group">
<label>Fecha</label>
<input type="date" name="fecha" required>
</div>
<div class="form-group">
<label>Hora</label>
<input type="time" name="hora" required>
</div>
<div class="form-group">
<label>Número de Personas</label>
<select name="personas" required>
<option value="1">1 persona</option>
<option value="2">2 personas</option>
<option value="3">3 personas</option>
<option value="4">4 personas</option>
<option value="5+">5 o más personas</option>
</select>
</div>
<div class="form-group">
<label>Mensaje (opcional)</label>
<textarea name="mensaje" rows="4"></textarea>
</div>
<button type="submit" class="btn-primary">Enviar Reserva</button>
</form>
</div>
</div>
</section>
<!-- Especialidad Culinaria Section -->
<section class="section especialidad">
<div class="container">
<div class="especialidad-content">
<div class="especialidad-text">
<h2>{{ especialidad_culinaria.titulo or 'Nuestra Especialidad' }}</h2>
<p>{{ especialidad_culinaria.descripcion or 'Cada plato es una obra de arte culinaria, preparado con
ingredientes frescos y técnicas tradicionales que honran la autenticidad de nuestros sabores.'
}}</p>
</div>
<div class="especialidad-image">
<img src="{{ especialidad_culinaria.imagen or 'https://via.placeholder.com/500x400?text=Especialidad' }}"
alt="Especialidad Culinaria">
</div>
</div>
</div>
</section>
<!-- Contacto Section -->
<section id="contacto" class="section contacto">
<div class="container">
<h2 class="section-title">Contacto</h2>
<div class="contacto-content">
<div class="contacto-info">
<h3>Información de Contacto</h3>
<p><strong>Dirección:</strong> <span class="gk-editable" data-editable="direccion" data-type="text"
title="Click para editar">{{ direccion or 'Calle Principal 123, Ciudad' }}</span></p>
<p><strong>Teléfono:</strong> <span class="gk-editable" data-editable="telefono" data-type="text"
title="Click para editar">{{ telefono or '+34 123 456 789' }}</span></p>
<p><strong>Email:</strong> <span class="gk-editable" data-editable="email" data-type="email"
title="Click para editar">{{ email or 'contacto@restaurante.com' }}</span></p>
{% if capacidad %}
<p><strong>Capacidad:</strong> <span class="gk-editable" data-editable="capacidad"
data-type="number" title="Click para editar">{{ capacidad }}</span> personas</p>
{% else %}
<p><strong>Capacidad:</strong> <span class="gk-editable" data-editable="capacidad"
data-type="number" title="Click para editar">50</span> personas</p>
{% endif %}
<div class="redes-sociales">
{% if redes_sociales.facebook %}
<a href="{{ redes_sociales.facebook }}" target="_blank" title="Facebook" class="social-icon"
data-social="facebook"
style="display: {{ 'inline-flex' if redes_sociales.facebook else 'none' }}">
<i class="fa-brands fa-facebook"></i>
</a>
{% endif %}
{% if redes_sociales.instagram %}
<a href="{{ redes_sociales.instagram }}" target="_blank" title="Instagram" class="social-icon"
data-social="instagram"
style="display: {{ 'inline-flex' if redes_sociales.instagram else 'none' }}">
<i class="fa-brands fa-instagram"></i>
</a>
{% endif %}
<a href="{{ redes_sociales.tiktok }}" target="_blank" title="TikTok" class="social-icon"
data-social="tiktok"
style="display: {{ 'inline-flex' if redes_sociales.tiktok else 'none' }}">
<i class="fa-brands fa-tiktok"></i>
</a>
<a href="{{ redes_sociales.linkedin }}" target="_blank" title="LinkedIn" class="social-icon"
data-social="linkedin"
style="display: {{ 'inline-flex' if redes_sociales.linkedin else 'none' }}">
<i class="fa-brands fa-linkedin"></i>
</a>
<a href="{{ redes_sociales.youtube }}" target="_blank" title="YouTube" class="social-icon"
data-social="youtube"
style="display: {{ 'inline-flex' if redes_sociales.youtube else 'none' }}">
<i class="fa-brands fa-youtube"></i>
</a>
</div>
</div>
<div class="contacto-info">
<h3 class="gk-editable" data-editable="mapa_titulo" data-type="text" title="Click para editar">
Ubicación</h3>
{% if mapa_url %}
<div class="mapa-container gk-editable" data-editable="mapa_url" data-type="url"
title="Click para editar mapa">
<iframe src="{{ mapa_url }}" width="100%" height="300" style="border:0; border-radius: 10px;"
allowfullscreen="" loading="lazy"></iframe>
</div>
{% else %}
<div class="mapa-container" style="display:none;">
<iframe width="100%" height="300" style="border:0; border-radius: 10px;" allowfullscreen=""
loading="lazy"></iframe>
</div>
<p id="map-placeholder" class="gk-editable" data-editable="mapa_url" data-type="url"
title="Click para añadir mapa"
style="color: var(--text-light); padding: 20px; border: 2px dashed #ddd; border-radius: 10px; text-align: center; cursor: pointer;">
Click para añadir mapa de Google Maps</p>
{% endif %}
</div>
</div>
</div>
</section>
<!-- Bloques Añadibles -->
<div class="dynamic-blocks-wrapper">
{% if blocks %}
{% for block in blocks|sort(attribute='order') %}
<section class="section gk-block" data-block-id="{{ block.id }}" draggable="true" style="position: relative;">
<div class="container">
{% if block.type == 'video' %}
<div class="gk-block-content">
{% if block.content.url %}
<div
style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden; max-width: 100%;">
<iframe src="{{ block.content.url }}"
style="position: absolute; top: 0; left: 0; width: 100%; height: 100%;" frameborder="0"
allowfullscreen></iframe>
</div>
{% else %}
<p class="gk-editable" data-editable="blocks.{{ block.id }}.content.url" data-type="url"
title="Click para añadir URL de video"
style="padding: 40px; border: 2px dashed #ddd; text-align: center; color: #999;"> Click para
añadir
URL de video (YouTube/Vimeo)</p>
{% endif %}
</div>
{% elif block.type == 'imagen' %}
<div class="gk-block-content">
{% if block.content.url %}
<img src="{{ block.content.url }}" alt="{{ block.content.alt or '' }}"
style="width: 100%; border-radius: 10px;">
{% else %}
<p class="gk-editable" data-editable="blocks.{{ block.id }}.content.url" data-type="url"
title="Click para añadir URL de imagen"
style="padding: 40px; border: 2px dashed #ddd; text-align: center; color: #999;"> Click para
añadir
URL de imagen</p>
{% endif %}
</div>
{% elif block.type == 'texto' %}
<div class="gk-block-content">
<h2 class="gk-editable" data-editable="blocks.{{ block.id }}.content.titulo" data-type="text"
title="Click para editar">{{ block.content.titulo or 'Título del bloque' }}</h2>
<p class="gk-editable" data-editable="blocks.{{ block.id }}.content.contenido" data-type="textarea"
title="Click para editar">{{ block.content.contenido or 'Contenido del bloque...' }}</p>
</div>
{% elif block.type == 'redes_sociales' %}
<div class="gk-block-content">
<h3 style="margin-bottom: 20px;">Síguenos en Redes Sociales</h3>
<div class="redes-sociales">
{% if block.content.facebook %}
<a href="{{ block.content.facebook }}" target="_blank" title="Facebook" class="social-icon">
<i class="fa-brands fa-facebook"></i>
</a>
{% endif %}
{% if block.content.instagram %}
<a href="{{ block.content.instagram }}" target="_blank" title="Instagram" class="social-icon">
<i class="fa-brands fa-instagram"></i>
</a>
{% endif %}
</div>
</div>
{% elif block.type == 'mapa' %}
<div class="gk-block-content">
{% if block.content.url %}
<iframe src="{{ block.content.url }}" width="100%" height="450"
style="border:0; border-radius: 10px;" allowfullscreen="" loading="lazy"></iframe>
{% else %}
<p class="gk-editable" data-editable="blocks.{{ block.id }}.content.url" data-type="url"
title="Click para añadir URL de mapa"
style="padding: 40px; border: 2px dashed #ddd; text-align: center; color: #999;"> Click para
añadir
URL de Google Maps (Compartir → Insertar mapa)</p>
{% endif %}
</div>
{% endif %}
</div>
<div class="gk-block-actions">
<button class="gk-block-action-btn" onclick="window.editBlockFromPreview('{{ block.id }}')" title="Editar bloque">✏️ Editar</button>
<button class="gk-block-action-btn delete" onclick="window.removeBlockFromPreview('{{ block.id }}')" title="Eliminar bloque">🗑️ Eliminar</button>
</div>
</section>
{% endfor %}
{% endif %}
</div>
<!-- Footer -->
<footer>
<div class="container">
<p>&copy; 2025 {{ site_name or 'Restaurante' }}. Todos los derechos reservados.</p>
</div>
</footer>
<!-- WhatsApp Floating Button -->
<a href="https://wa.me/{{ redes_sociales.whatsapp if redes_sociales else '' }}" class="whatsapp-float"
id="whatsapp-float-btn" target="_blank"
style="display: {{ 'flex' if redes_sociales and redes_sociales.whatsapp else 'none' }}">
<i class="fa-brands fa-whatsapp"
style="font-family: 'Font Awesome 6 Free', sans-serif; font-weight: 900; font-style: normal;"></i>
</a>
<!-- FontAwesome for icons -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<script>
// Función para eliminar bloque desde preview (disponible globalmente)
window.removeBlockFromPreview = function (blockId) {
if (!confirm('¿Eliminar este bloque?')) return;
if (window.parent !== window) {
// Estamos en iframe, enviar mensaje al padre
window.parent.postMessage({
type: 'remove-block',
block_id: blockId
}, '*');
} else {
// Si no está en iframe, llamar directamente (para testing)
console.log('Eliminar bloque:', blockId);
}
};
// Función para editar bloque desde preview
window.editBlockFromPreview = function (blockId) {
if (window.parent !== window) {
// Enviar mensaje al padre para editar el bloque
window.parent.postMessage({
type: 'gk-edit-block',
block_id: blockId
}, '*');
} else {
console.log('Editar bloque:', blockId);
}
};
// Drag & Drop para bloques
document.addEventListener('DOMContentLoaded', function () {
const blocks = document.querySelectorAll('.gk-block');
let draggedElement = null;
blocks.forEach(block => {
block.addEventListener('dragstart', function (e) {
draggedElement = this;
this.classList.add('dragging');
e.dataTransfer.effectAllowed = 'move';
});
block.addEventListener('dragend', function () {
this.classList.remove('dragging');
});
block.addEventListener('dragover', function (e) {
e.preventDefault();
e.dataTransfer.dropEffect = 'move';
const afterElement = getDragAfterElement(this.parentElement, e.clientY);
if (afterElement == null) {
this.parentElement.appendChild(draggedElement);
} else {
this.parentElement.insertBefore(draggedElement, afterElement);
}
});
});
});
function getDragAfterElement(container, y) {
const draggableElements = [...container.querySelectorAll('.gk-block:not(.dragging)')];
return draggableElements.reduce((closest, child) => {
const box = child.getBoundingClientRect();
const offset = y - box.top - box.height / 2;
if (offset < 0 && offset > closest.offset) {
return { offset: offset, element: child };
} else {
return closest;
}
}, { offset: Number.NEGATIVE_INFINITY }).element;
}
</script>
</body>
</html>