493 lines
18 KiB
JavaScript
493 lines
18 KiB
JavaScript
/* ============================================
|
|
CARGA DE INCLUDES (menu y footer)
|
|
============================================ */
|
|
async function loadInclude(selector, url) {
|
|
try {
|
|
const response = await fetch(url);
|
|
if (!response.ok) throw new Error(`HTTP ${response.status}`);
|
|
const html = await response.text();
|
|
const container = document.querySelector(selector);
|
|
if (container) container.innerHTML = html;
|
|
} catch (error) {
|
|
console.error(`Error cargando ${url}:`, error);
|
|
}
|
|
}
|
|
|
|
/* ============================================
|
|
SWITCH DE TEMA (claro por defecto)
|
|
============================================ */
|
|
function initTheme() {
|
|
const savedTheme = localStorage.getItem('theme') || 'light';
|
|
document.documentElement.setAttribute('data-theme', savedTheme);
|
|
}
|
|
|
|
function toggleTheme() {
|
|
const current = document.documentElement.getAttribute('data-theme') || 'light';
|
|
const next = current === 'dark' ? 'light' : 'dark';
|
|
document.documentElement.setAttribute('data-theme', next);
|
|
localStorage.setItem('theme', next);
|
|
}
|
|
|
|
// Ejecutar al cargar la página
|
|
document.addEventListener('DOMContentLoaded', () => {
|
|
initTheme();
|
|
|
|
const themeBtn = document.querySelector('.theme-toggle');
|
|
if (themeBtn) {
|
|
themeBtn.addEventListener('click', toggleTheme);
|
|
}
|
|
});
|
|
/* ============================================
|
|
CALCULAR ANCHO DEL SCROLLBAR
|
|
============================================ */
|
|
function getScrollbarWidth() {
|
|
return window.innerWidth - document.documentElement.clientWidth;
|
|
}
|
|
|
|
function applyScrollbarCompensation() {
|
|
const scrollbarWidth = getScrollbarWidth();
|
|
document.documentElement.style.setProperty('--scrollbar-width', `${scrollbarWidth}px`);
|
|
}
|
|
|
|
/* ============================================
|
|
MENÚ FULLSCREEN
|
|
============================================ */
|
|
function openMenu() {
|
|
const menu = document.getElementById('fullscreen-menu');
|
|
const overlay = document.getElementById('menu-overlay');
|
|
const menuToggle = document.querySelector('.menu-toggle');
|
|
|
|
if (menu && overlay) {
|
|
applyScrollbarCompensation();
|
|
menu.classList.add('is-open');
|
|
overlay.classList.add('is-open');
|
|
document.body.classList.add('menu-open');
|
|
menuToggle.setAttribute('aria-expanded', 'true');
|
|
}
|
|
}
|
|
|
|
function closeMenu() {
|
|
const menu = document.getElementById('fullscreen-menu');
|
|
const overlay = document.getElementById('menu-overlay');
|
|
const menuToggle = document.querySelector('.menu-toggle');
|
|
|
|
if (menu && overlay) {
|
|
menu.classList.remove('is-open');
|
|
overlay.classList.remove('is-open');
|
|
document.body.classList.remove('menu-open');
|
|
menuToggle.setAttribute('aria-expanded', 'false');
|
|
}
|
|
}
|
|
|
|
|
|
/* ============================================
|
|
ACORDEÓN DE SERVICIOS
|
|
============================================ */
|
|
function initServiciosAccordion() {
|
|
const accordion = document.getElementById('servicios-accordion');
|
|
if (!accordion) {
|
|
console.log('Acordeón no encontrado');
|
|
return;
|
|
}
|
|
|
|
const items = accordion.querySelectorAll('.servicio-item');
|
|
console.log('Items encontrados:', items.length);
|
|
|
|
// Función para activar un item
|
|
function activateItem(item) {
|
|
if (item.classList.contains('is-active')) return;
|
|
|
|
accordion.classList.add('has-active');
|
|
items.forEach(i => i.classList.remove('is-active'));
|
|
item.classList.add('is-active');
|
|
}
|
|
|
|
// Función para cerrar (volver al estado inicial)
|
|
function closeAll() {
|
|
accordion.classList.remove('has-active');
|
|
items.forEach(i => i.classList.remove('is-active'));
|
|
}
|
|
|
|
// Click en cada item para expandirlo
|
|
items.forEach((item, index) => {
|
|
console.log(`Agregando listener al item ${index}`);
|
|
|
|
item.addEventListener('click', (e) => {
|
|
console.log('Click en item:', index);
|
|
|
|
// Si el click fue en el botón cerrar o en un botón CTA, no activar
|
|
if (e.target.closest('.servicio-close')) {
|
|
console.log('Click en cerrar');
|
|
return;
|
|
}
|
|
if (e.target.closest('.btn')) {
|
|
console.log('Click en botón CTA');
|
|
return;
|
|
}
|
|
|
|
activateItem(item);
|
|
});
|
|
});
|
|
|
|
// Click en los botones de cerrar
|
|
const closeButtons = accordion.querySelectorAll('.servicio-close');
|
|
closeButtons.forEach((btn, index) => {
|
|
console.log(`Agregando listener al botón cerrar ${index}`);
|
|
|
|
btn.addEventListener('click', (e) => {
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
console.log('Botón cerrar clicked');
|
|
closeAll();
|
|
});
|
|
});
|
|
}
|
|
|
|
/* ============================================
|
|
INICIALIZACIÓN
|
|
============================================ */
|
|
document.addEventListener('DOMContentLoaded', async () => {
|
|
// Cargar menú y footer
|
|
await Promise.all([
|
|
loadInclude('#menu-container', 'includes/menu.html'),
|
|
loadInclude('#footer-container', 'includes/footer.html')
|
|
]);
|
|
|
|
// Inicializar tema
|
|
initTheme();
|
|
|
|
// Eventos del tema
|
|
const themeBtn = document.querySelector('.theme-toggle');
|
|
if (themeBtn) themeBtn.addEventListener('click', toggleTheme);
|
|
|
|
// Eventos del menú
|
|
const menuToggle = document.querySelector('.menu-toggle');
|
|
const menuClose = document.querySelector('.menu-close');
|
|
const menuOverlay = document.getElementById('menu-overlay');
|
|
const menuLinks = document.querySelectorAll('.fullscreen-menu a');
|
|
|
|
if (menuToggle) menuToggle.addEventListener('click', openMenu);
|
|
if (menuClose) menuClose.addEventListener('click', closeMenu);
|
|
if (menuOverlay) menuOverlay.addEventListener('click', closeMenu);
|
|
|
|
// Cerrar menú al hacer clic en un enlace
|
|
menuLinks.forEach(link => {
|
|
link.addEventListener('click', closeMenu);
|
|
});
|
|
|
|
// Cerrar menú con tecla Escape
|
|
document.addEventListener('keydown', (e) => {
|
|
if (e.key === 'Escape') closeMenu();
|
|
});
|
|
|
|
// Año dinámico en el footer
|
|
const yearEl = document.getElementById('current-year');
|
|
if (yearEl) yearEl.textContent = new Date().getFullYear();
|
|
|
|
initServiciosAccordion();
|
|
});
|
|
|
|
/* ============================================
|
|
LÓGICA DEL CUESTIONARIO DE DIAGNÓSTICO
|
|
============================================ */
|
|
|
|
// Datos del cuestionario
|
|
const preguntas = [
|
|
{
|
|
id: 1,
|
|
titulo: "¿En qué etapa se encuentra hoy tu negocio o proyecto?",
|
|
opciones: [
|
|
{ letra: "A", texto: "Creando el proyecto desde cero o formalizando una idea reciente." },
|
|
{ letra: "B", texto: "Negocio o local activo, pero con una imagen visual que no refleja la calidad de lo que vendo." },
|
|
{ letra: "C", texto: "En pleno movimiento comercial, pero desbordados para contestar consultas a tiempo." },
|
|
{ letra: "D", texto: "Establecido y con ventas, pero con un techo de crecimiento que necesitamos romper con publicidad." },
|
|
{ letra: "E", texto: "Empresa consolidada que busca liderazgo de mercado y delegar todo su marketing de punta a punta." },
|
|
{ letra: "F", texto: "Emprendimiento personal que gestiono por mi cuenta y donde necesito resolver piezas puntuales." }
|
|
]
|
|
},
|
|
{
|
|
id: 2,
|
|
titulo: "¿Cuál es tu cuello de botella más urgente hoy?",
|
|
opciones: [
|
|
{ letra: "A", texto: "No tengo logo profesional ni página web; me falta confianza frente a la competencia." },
|
|
{ letra: "B", texto: "No tengo tiempo ni equipo para sacar fotos o grabar videos de buena calidad de mis productos/servicios." },
|
|
{ letra: "C", texto: "Perdemos clientes potenciales porque tardamos horas en responder WhatsApp o mensajes de redes." },
|
|
{ letra: "D", texto: "Dependemos del boca a boca o de publicar en redes sin conseguir ventas constantes ni predecibles." },
|
|
{ letra: "E", texto: "Tenemos acciones aisladas sin una dirección estratégica clara ni medición profesional de métricas." },
|
|
{ letra: "F", texto: "Me faltan herramientas gráficas o plantillas para diseñar mis propias publicaciones sin perder horas." }
|
|
]
|
|
},
|
|
{
|
|
id: 3,
|
|
titulo: "¿Con qué infraestructura digital cuentas actualmente?",
|
|
opciones: [
|
|
{ letra: "A", texto: "Prácticamente nada formal (solo una idea, perfil personal o logo provisional)." },
|
|
{ letra: "B", texto: "Perfil comercial en redes sociales, pero con fotos caseras tomadas con el celular." },
|
|
{ letra: "C", texto: "Redes y/o tienda activa con alto volumen de mensajes directos diarios sin automatizar." },
|
|
{ letra: "D", texto: "Redes y web en marcha, pero sin campañas activas de publicidad paga (Meta Ads / Google Ads)." },
|
|
{ letra: "E", texto: "Ecosistema activo (redes, web, pauta), pero disperso entre distintos proveedores sin sinergia." },
|
|
{ letra: "F", texto: "Manejo mis propios canales y solo requiero recursos gráficos específicos para seguir operando." }
|
|
]
|
|
},
|
|
{
|
|
id: 4,
|
|
titulo: "¿Qué tipo de solución buscas contratar en Amor y Roma?",
|
|
opciones: [
|
|
{ letra: "A", texto: "Proyecto inicial integral: crear mi identidad de marca y mi sitio web para salir al mercado." },
|
|
{ letra: "B", texto: "Acompañamiento mensual con sesiones presenciales de fotos/video para no preocuparme del contenido." },
|
|
{ letra: "C", texto: "Implementación tecnológica: automatizaciones inteligentes y asistentes para WhatsApp y redes." },
|
|
{ letra: "D", texto: "Gestión de campañas de publicidad digital y páginas de venta enfocadas 100% en conversión." },
|
|
{ letra: "E", texto: "Gestión integral 360°: estrategia de marca completa, pauta multicanal, redes y dirección creativa." },
|
|
{ letra: "F", texto: "Un entregable puntual (diseño de plantilla, digitalización de logo o sesión única de fotos)." }
|
|
]
|
|
}
|
|
];
|
|
|
|
// Perfiles de resultado
|
|
const perfiles = {
|
|
A: {
|
|
titulo: "Mix Lanzamiento Integral",
|
|
diagnostico: "Tu proyecto necesita bases sólidas y credibilidad inmediata para competir y generar confianza.",
|
|
solucion: "Identidad visual completa (Branding) + Diseño Web institucional + Gestión de Redes Sociales (Plan Esencial, $250.000/mes).",
|
|
cta: "Cotizar Mix Lanzamiento"
|
|
},
|
|
B: {
|
|
titulo: "Mix Comercio & Presencia Visual",
|
|
diagnostico: "Tu producto o servicio tiene potencial comercial, pero la calidad visual actual en redes te resta ventas.",
|
|
solucion: "Plan Premium de Redes Sociales ($650.000/mes), que incluye sesión presencial quincenal de fotos y videos profesionales, 8 reels, asistencia con IA y dirección creativa.",
|
|
cta: "Ver Plan Premium"
|
|
},
|
|
C: {
|
|
titulo: "Solución Eficiencia & Automatización",
|
|
diagnostico: "Tu principal fuga de dinero es el tiempo de respuesta: consultas demoradas son ventas perdidas.",
|
|
solucion: "Implementación de Automatizaciones con Asistentes Inteligentes para WhatsApp, Instagram y Facebook + Plan Impulso ($420.000/mes) para ordenar el flujo de mensajes.",
|
|
cta: "Automatizar mi Atención"
|
|
},
|
|
D: {
|
|
titulo: "Mix Acelerador & Conversión",
|
|
diagnostico: "Tu marca ya está ordenada visualmente; ahora necesita tráfico calificado y un sistema predecible de atracción de clientes.",
|
|
solucion: "Servicio de Paid Media (Meta Ads + Google Ads) + Optimización de Landing Page / Catálogo + Creatividades publicitarias de alto impacto.",
|
|
cta: "Escalar mis Ventas"
|
|
},
|
|
E: {
|
|
titulo: "Servicio Corporativo 360°",
|
|
diagnostico: "Tu empresa busca liderazgo absoluto de mercado, unificación de imagen y tercerización completa del departamento de marketing.",
|
|
solucion: "Plan Élite de Redes ($1.000.000/mes) + Branding Integral (packaging, cartelería física) + Pauta multicanal (Meta, TikTok, Google) + Reportes quincenales avanzados con KPIs.",
|
|
cta: "Agendar Reunión Estratégica"
|
|
},
|
|
F: {
|
|
titulo: "Solución Autogestor / Servicios Puntuales",
|
|
diagnostico: "Buscas resolver necesidades gráficas puntuales sin comprometerte con un abono mensual recurrente.",
|
|
solucion: "Paquetes individuales a medida: Digitalización y vectorización de logo, Pack de plantillas editables personalizadas o Producción fotográfica por jornada.",
|
|
cta: "Elegir Servicios Puntuales"
|
|
}
|
|
};
|
|
|
|
// Estado del cuestionario
|
|
let preguntaActual = 0;
|
|
let respuestas = [];
|
|
|
|
// Función para calcular el perfil
|
|
function calcularPerfil(respuestas) {
|
|
const conteo = { A: 0, B: 0, C: 0, D: 0, E: 0, F: 0 };
|
|
|
|
respuestas.forEach(r => {
|
|
if (conteo[r] !== undefined) conteo[r]++;
|
|
});
|
|
|
|
// Encontrar la letra con mayor frecuencia
|
|
let maxVotos = 0;
|
|
let ganador = respuestas[1]; // Fallback por defecto: pregunta 2 (cuello de botella)
|
|
|
|
for (const letra in conteo) {
|
|
if (conteo[letra] > maxVotos) {
|
|
maxVotos = conteo[letra];
|
|
ganador = letra;
|
|
} else if (conteo[letra] === maxVotos && maxVotos > 0) {
|
|
// Desempate: priorizar la respuesta de la Pregunta 2
|
|
if (respuestas[1] === letra) {
|
|
ganador = letra;
|
|
}
|
|
}
|
|
}
|
|
|
|
return ganador;
|
|
}
|
|
|
|
// Función para renderizar pregunta
|
|
function renderizarPregunta() {
|
|
const contenedor = document.getElementById('cuestionario-contenedor');
|
|
const pregunta = preguntas[preguntaActual];
|
|
|
|
contenedor.innerHTML = `
|
|
<div class="pregunta-contenedor">
|
|
<h3 class="pregunta-titulo">${pregunta.titulo}</h3>
|
|
<div class="opciones-contenedor">
|
|
${pregunta.opciones.map(opcion => `
|
|
<button class="opcion-tarjeta" data-letra="${opcion.letra}">
|
|
${opcion.texto}
|
|
</button>
|
|
`).join('')}
|
|
</div>
|
|
</div>
|
|
`;
|
|
|
|
// Agregar event listeners a las opciones
|
|
document.querySelectorAll('.opcion-tarjeta').forEach(tarjeta => {
|
|
tarjeta.addEventListener('click', () => seleccionarOpcion(tarjeta.dataset.letra));
|
|
});
|
|
}
|
|
|
|
// Función para seleccionar opción
|
|
function seleccionarOpcion(letra) {
|
|
respuestas[preguntaActual] = letra;
|
|
|
|
// Actualizar barra de progreso
|
|
const progreso = ((preguntaActual + 1) / preguntas.length) * 100;
|
|
document.getElementById('progreso-completado').style.width = `${progreso}%`;
|
|
|
|
// Avanzar o mostrar resultado
|
|
if (preguntaActual < preguntas.length - 1) {
|
|
preguntaActual++;
|
|
document.getElementById('progreso-texto').textContent = `Pregunta ${preguntaActual + 1} de ${preguntas.length}`;
|
|
renderizarPregunta();
|
|
} else {
|
|
mostrarResultado();
|
|
}
|
|
}
|
|
|
|
// Función para mostrar resultado
|
|
function mostrarResultado() {
|
|
const perfilLetra = calcularPerfil(respuestas);
|
|
const perfil = perfiles[perfilLetra];
|
|
|
|
// Ocultar cuestionario y barra de progreso
|
|
document.getElementById('cuestionario-contenedor').style.display = 'none';
|
|
document.querySelector('.progreso-barra').style.display = 'none';
|
|
document.getElementById('progreso-texto').style.display = 'none';
|
|
document.getElementById('btn-reiniciar').style.display = 'none';
|
|
|
|
// Mostrar resultado
|
|
const resultadoContenedor = document.getElementById('resultado-contenedor');
|
|
resultadoContenedor.innerHTML = `
|
|
<h2 class="resultado-titulo">${perfil.titulo}</h2>
|
|
<p class="resultado-diagnostico">${perfil.diagnostico}</p>
|
|
<div class="resultado-solucion">
|
|
<strong>Solución Amor y Roma:</strong><br>
|
|
${perfil.solucion}
|
|
</div>
|
|
<button class="resultado-cta">${perfil.cta}</button>
|
|
`;
|
|
resultadoContenedor.style.display = 'block';
|
|
|
|
// Event listener al CTA (placeholder por ahora)
|
|
document.querySelector('.resultado-cta').addEventListener('click', () => {
|
|
alert('CTA - Por definir acción');
|
|
});
|
|
}
|
|
|
|
// Función para reiniciar
|
|
function reiniciarCuestionario() {
|
|
preguntaActual = 0;
|
|
respuestas = [];
|
|
|
|
// Resetear barra de progreso
|
|
document.getElementById('progreso-completado').style.width = '0%';
|
|
document.getElementById('progreso-texto').textContent = 'Pregunta 1 de 4';
|
|
|
|
// Mostrar elementos
|
|
document.getElementById('cuestionario-contenedor').style.display = 'block';
|
|
document.querySelector('.progreso-barra').style.display = 'block';
|
|
document.getElementById('progreso-texto').style.display = 'block';
|
|
document.getElementById('btn-reiniciar').style.display = 'inline-flex';
|
|
document.getElementById('resultado-contenedor').style.display = 'none';
|
|
|
|
// Renderizar primera pregunta
|
|
renderizarPregunta();
|
|
}
|
|
|
|
/* ============================================
|
|
ANIMACIÓN AUTOMÁTICA DE METODOLOGÍA
|
|
============================================ */
|
|
function initMetodologiaAnimation() {
|
|
const section = document.getElementById('metodologia');
|
|
if (!section) return;
|
|
|
|
const pasos = section.querySelectorAll('.paso-item');
|
|
if (pasos.length === 0) return;
|
|
|
|
let pasoActual = 0;
|
|
let intervalo;
|
|
const DURACION_PASO = 2500; // 2.5 segundos por paso
|
|
|
|
// Función para actualizar los estados
|
|
function actualizarEstados() {
|
|
pasos.forEach((paso, index) => {
|
|
// Remover todas las clases de estado
|
|
paso.classList.remove('active', 'previous');
|
|
|
|
// Calcular el índice del paso anterior (con loop)
|
|
const pasoAnterior = (pasoActual - 1 + pasos.length) % pasos.length;
|
|
|
|
// Asignar estados
|
|
if (index === pasoActual) {
|
|
paso.classList.add('active');
|
|
} else if (index === pasoAnterior) {
|
|
paso.classList.add('previous');
|
|
}
|
|
});
|
|
}
|
|
|
|
// Función para avanzar al siguiente paso
|
|
function avanzarPaso() {
|
|
pasoActual = (pasoActual + 1) % pasos.length;
|
|
actualizarEstados();
|
|
}
|
|
|
|
// Función para iniciar la animación
|
|
function iniciarAnimacion() {
|
|
// Inicializar con el primer paso activo
|
|
actualizarEstados();
|
|
|
|
// Iniciar el intervalo
|
|
intervalo = setInterval(avanzarPaso, DURACION_PASO);
|
|
}
|
|
|
|
// Función para detener la animación
|
|
function detenerAnimacion() {
|
|
clearInterval(intervalo);
|
|
}
|
|
|
|
// IntersectionObserver para detectar cuando la sección es visible
|
|
const observer = new IntersectionObserver((entries) => {
|
|
entries.forEach(entry => {
|
|
if (entry.isIntersecting) {
|
|
// La sección está visible: iniciar animación
|
|
iniciarAnimacion();
|
|
} else {
|
|
// La sección no está visible: detener animación
|
|
detenerAnimacion();
|
|
}
|
|
});
|
|
}, {
|
|
threshold: 0.3 // Se activa cuando el 30% de la sección es visible
|
|
});
|
|
|
|
// Observar la sección
|
|
observer.observe(section);
|
|
|
|
// Inicializar el primer estado (sin animación aún)
|
|
actualizarEstados();
|
|
}
|
|
|
|
// Inicializar cuestionario al cargar la página
|
|
document.addEventListener('DOMContentLoaded', () => {
|
|
// Solo inicializar si estamos en la sección de diagnóstico
|
|
if (document.getElementById('cuestionario-contenedor')) {
|
|
renderizarPregunta();
|
|
|
|
// Event listener al botón de reiniciar
|
|
document.getElementById('btn-reiniciar').addEventListener('click', reiniciarCuestionario);
|
|
}
|
|
initMetodologiaAnimation();
|
|
}); |