const APP = {
carouselIndex: 0,
carouselTimer: null,
boards: new Map()
};
function initNavbar() {
const hamburger = document.querySelector('.hamburger');
const navMenu = document.querySelector('.nav-menu');
const submenuToggles = document.querySelectorAll('.submenu-toggle');
hamburger?.addEventListener('click', () => {
navMenu?.classList.toggle('is-open');
});
submenuToggles.forEach((toggle) => {
toggle.addEventListener('click', (event) => {
event.preventDefault();
const item = toggle.closest('.nav-item');
item?.classList.toggle('is-open');
});
});
document.querySelectorAll('.nav-link').forEach((link) => {
link.addEventListener('click', () => {
if (window.innerWidth <= 920) {
navMenu?.classList.remove('is-open');
}
});
});
const path = globalThis.location.pathname.split('/').pop() || 'index.html';
document.querySelectorAll('.nav-link[data-page]').forEach((link) => {
if (link.dataset.page === path) {
link.classList.add('is-active');
}
});
}
function initCarousel() {
const slides = Array.from(document.querySelectorAll('.carousel-slide'));
const dots = Array.from(document.querySelectorAll('.dot'));
if (!slides.length) {
return;
}
const paint = () => {
slides.forEach((slide, index) => {
slide.classList.toggle('active', index === APP.carouselIndex);
});
dots.forEach((dot, index) => {
dot.classList.toggle('active', index === APP.carouselIndex);
});
};
globalThis.changeSlide = (step) => {
APP.carouselIndex = (APP.carouselIndex + step + slides.length) % slides.length;
paint();
resetCarousel();
};
globalThis.goToSlide = (index) => {
APP.carouselIndex = index;
paint();
resetCarousel();
};
const resetCarousel = () => {
clearInterval(APP.carouselTimer);
APP.carouselTimer = setInterval(() => globalThis.changeSlide(1), 6500);
};
paint();
resetCarousel();
}
function initCarouselImagePreview() {
const imageNodes = Array.from(
document.querySelectorAll('.carousel-section .slide-image img, .photo-slider-track img')
);
if (!imageNodes.length) {
return;
}
const modal = document.createElement('div');
modal.className = 'image-preview-modal';
modal.setAttribute('aria-hidden', 'true');
modal.innerHTML = `
`;
document.body.appendChild(modal);
const modalImage = modal.querySelector('.image-preview-modal__img');
const closeButton = modal.querySelector('.image-preview-close');
const closeModal = () => {
modal.classList.remove('is-open');
modal.setAttribute('aria-hidden', 'true');
document.body.classList.remove('has-modal-open');
modalImage.src = '';
};
const openModal = (img) => {
modalImage.src = img.currentSrc || img.src;
modalImage.alt = img.alt || 'Vista previa ampliada';
modal.classList.add('is-open');
modal.setAttribute('aria-hidden', 'false');
document.body.classList.add('has-modal-open');
};
closeButton?.addEventListener('click', closeModal);
modal.addEventListener('click', (event) => {
if (event.target === modal) {
closeModal();
}
});
document.addEventListener('keydown', (event) => {
if (event.key === 'Escape' && modal.classList.contains('is-open')) {
closeModal();
}
});
imageNodes.forEach((img) => {
const src = (img.getAttribute('src') || '').toLowerCase();
const isImageFile = /\.(png|jpe?g|gif|webp|bmp|svg)(\?.*)?$/.test(src) || src.startsWith('data:image/');
if (!isImageFile) {
return;
}
img.classList.add('is-zoomable');
img.setAttribute('role', 'button');
img.setAttribute('tabindex', '0');
img.setAttribute('aria-label', `Ampliar imagen: ${img.alt || 'slide'}`);
img.addEventListener('click', () => openModal(img));
img.addEventListener('keydown', (event) => {
if (event.key === 'Enter' || event.key === ' ') {
event.preventDefault();
openModal(img);
}
});
});
}
function initNewsPhotoSliders() {
const docConfig = globalThis.DOC_LINKS || {};
const sliderNodes = Array.from(document.querySelectorAll('[data-photo-slider]'));
sliderNodes.forEach((slider) => {
const key = slider.dataset.galleryKey;
const track = slider.querySelector('.photo-slider-track');
const prevButton = slider.querySelector('.photo-slider__btn.prev');
const nextButton = slider.querySelector('.photo-slider__btn.next');
const images = docConfig[key] || [];
if (!track) {
return;
}
if (!images.length) {
track.innerHTML = 'Sube imágenes a la carpeta configurada para visualizar la galería.
';
prevButton?.setAttribute('disabled', 'disabled');
nextButton?.setAttribute('disabled', 'disabled');
return;
}
track.innerHTML = images
.map(
(item) => `
${item.title || ''}
`
)
.join('');
const slideWidth = () => Math.max(320, Math.round(track.clientWidth * 0.92));
prevButton?.addEventListener('click', () => {
track.scrollBy({ left: -slideWidth(), behavior: 'smooth' });
});
nextButton?.addEventListener('click', () => {
track.scrollBy({ left: slideWidth(), behavior: 'smooth' });
});
});
}
function toast(message, isError = false) {
const node = document.createElement('div');
node.className = 'toast';
if (isError) {
node.style.background = '#8f2323';
}
node.textContent = message;
document.body.appendChild(node);
globalThis.setTimeout(() => node.remove(), 2600);
}
function initSearch() {
const searchInput = document.querySelector('.search-bar input');
const searchBtn = document.querySelector('.search-bar button');
const routes = [
{ keys: ['inicio', 'quienes', 'mision', 'vision', 'valores'], url: 'index.html' },
{ keys: ['noticias', 'memoriam', 'actualizacion', 'datos'], url: 'noticias.html' },
{ keys: ['servicios', 'afiliaciones', 'credito', 'seguros', 'recreacion'], url: 'servicios.html' },
{ keys: ['normatividad', 'documentos', 'formularios', 'asamblea', 'boletines', 'informes', 'financieros', 'reglamentos'], url: 'normatividad.html' },
{ keys: ['contacto', 'mensaje', 'whatsapp', 'preguntas', 'faq'], url: 'contacto.html' },
{ keys: ['oficina', 'virtual', 'consulta', 'privada'], url: 'oficina-virtual.html' },
{ keys: ['pqrs'], url: 'pqrs.html' },
{ keys: ['vigila', 'vigilancia', 'superintendencia'], url: 'quien-nos-vigila.html' }
];
const runSearch = () => {
const query = (searchInput?.value || '').trim().toLowerCase();
if (!query) {
toast('Escribe un término para buscar.', true);
return;
}
const match = routes.find((route) => route.keys.some((key) => query.includes(key)));
if (match) {
globalThis.location.href = match.url;
return;
}
toast('No hubo coincidencia exacta. Revisa el menú.', true);
};
searchBtn?.addEventListener('click', runSearch);
searchInput?.addEventListener('keydown', (event) => {
if (event.key === 'Enter') {
event.preventDefault();
runSearch();
}
});
}
function initForms() {
document.querySelectorAll('form[data-form-type]').forEach((form) => {
form.addEventListener('submit', (event) => {
event.preventDefault();
const requiredFields = form.querySelectorAll('[required]');
const invalid = Array.from(requiredFields).find((field) => !field.value.trim());
if (invalid) {
invalid.focus();
toast('Completa los campos obligatorios.', true);
return;
}
const type = form.dataset.formType || 'contacto';
const mailTo = form.dataset.mailTo || 'cooperativa@coopbch.com';
const subject = form.dataset.subject || (type === 'pqrs' ? 'Radicacion PQRS desde sitio web' : 'Mensaje desde contacto web');
const bodyLines = Array.from(form.querySelectorAll('input, select, textarea'))
.map((field) => {
const label = field.name || field.placeholder || field.id || 'Campo';
const value = (field.value || '').trim();
return value ? `${label}: ${value}` : null;
})
.filter(Boolean);
const body = `${bodyLines.join('\n')}\n\nEnviado desde coopbch.com`;
const mailto = `mailto:${mailTo}?subject=${encodeURIComponent(subject)}&body=${encodeURIComponent(body)}`;
globalThis.location.href = mailto;
toast('Abriendo tu correo para enviar el mensaje...');
form.reset();
});
});
}
function initReveal() {
const targets = document.querySelectorAll('.reveal');
if (!targets.length) {
return;
}
const observer = new IntersectionObserver(
(entries, currentObserver) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
entry.target.classList.add('is-visible');
currentObserver.unobserve(entry.target);
}
});
},
{ threshold: 0.15 }
);
targets.forEach((target) => observer.observe(target));
}
function getPagedItems(items, page, pageSize) {
const start = (page - 1) * pageSize;
return items.slice(start, start + pageSize);
}
function renderBoard(boardElement, boardState) {
const listNode = boardElement.querySelector('.docs-list');
const paginationNode = boardElement.querySelector('.docs-pagination');
const variant = boardElement.dataset.variant || 'default';
if (!listNode || !paginationNode) {
return;
}
const pageSize = Number(boardElement.dataset.pageSize || 6);
const term = boardState.query.toLowerCase().trim();
const all = boardState.items.filter((item) => {
if (!term) {
return true;
}
return (
item.title.toLowerCase().includes(term) ||
item.description.toLowerCase().includes(term) ||
item.tag.toLowerCase().includes(term)
);
});
const totalPages = Math.max(1, Math.ceil(all.length / pageSize));
boardState.page = Math.min(boardState.page, totalPages);
boardState.page = Math.max(boardState.page, 1);
const paged = getPagedItems(all, boardState.page, pageSize);
if (paged.length > 0) {
listNode.innerHTML = paged
.map(
(item) => {
if (variant === 'featured-news') {
const cardImage = item.image || 'img/Gemini_Generated_Image_f184rjf184rjf184.png';
const actionLabel = item.actionLabel || 'VER DOCUMENTO';
return `
${item.title}
${item.description}
${actionLabel}
`;
}
return `
${item.tag}
${item.title}
${item.description}
Abrir documento
`;
}
)
.join('');
} else {
listNode.innerHTML = 'No hay documentos para este filtro.
';
}
if (totalPages <= 1) {
paginationNode.innerHTML = '';
return;
}
const numbers = Array.from({ length: totalPages }, (_, i) => i + 1)
.map(
(num) =>
``
)
.join('');
paginationNode.innerHTML = `
${numbers}
`;
paginationNode.querySelectorAll('button').forEach((button) => {
button.addEventListener('click', () => {
const nav = button.dataset.nav;
if (nav === 'prev') {
boardState.page -= 1;
} else if (nav === 'next') {
boardState.page += 1;
} else if (button.dataset.page) {
boardState.page = Number(button.dataset.page);
}
renderBoard(boardElement, boardState);
initReveal();
});
});
}
function initDocumentBoards() {
const docConfig = globalThis.DOC_LINKS || {};
document.querySelectorAll('.docs-board').forEach((boardElement) => {
const boardKey = boardElement.dataset.board;
const items = docConfig[boardKey] || [];
const state = {
page: 1,
query: '',
items
};
APP.boards.set(boardElement, state);
const input = boardElement.querySelector('.doc-filter-input');
input?.addEventListener('input', () => {
state.query = input.value;
state.page = 1;
renderBoard(boardElement, state);
initReveal();
});
renderBoard(boardElement, state);
});
}
function initRipple() {
document.querySelectorAll('.btn').forEach((button) => {
button.addEventListener('click', (event) => {
const wave = document.createElement('span');
const rect = button.getBoundingClientRect();
const size = Math.max(rect.width, rect.height);
wave.style.position = 'absolute';
wave.style.width = `${size}px`;
wave.style.height = `${size}px`;
wave.style.left = `${event.clientX - rect.left - size / 2}px`;
wave.style.top = `${event.clientY - rect.top - size / 2}px`;
wave.style.borderRadius = '50%';
wave.style.background = 'rgba(255,255,255,0.35)';
wave.style.transform = 'scale(0)';
wave.style.pointerEvents = 'none';
wave.style.transition = 'transform 0.5s ease, opacity 0.5s ease';
button.style.position = 'relative';
button.style.overflow = 'hidden';
button.appendChild(wave);
requestAnimationFrame(() => {
wave.style.transform = 'scale(2.7)';
wave.style.opacity = '0';
});
globalThis.setTimeout(() => wave.remove(), 520);
});
});
}
function initScrollTop() {
const button = document.createElement('button');
button.className = 'btn btn-primary';
button.style.position = 'fixed';
button.style.bottom = '20px';
button.style.right = '16px';
button.style.zIndex = '1200';
button.style.display = 'none';
button.style.padding = '11px 14px';
button.innerHTML = '';
button.setAttribute('aria-label', 'Volver arriba');
button.addEventListener('click', () => {
window.scrollTo({ top: 0, behavior: 'smooth' });
});
window.addEventListener('scroll', () => {
button.style.display = window.scrollY > 420 ? 'inline-flex' : 'none';
});
document.body.appendChild(button);
}
function initVirtualOfficeFloatingButton() {
if (document.querySelector('.floating-virtual-office')) {
return;
}
const rawPath = globalThis.location.pathname.toLowerCase();
const normalizedPath = rawPath.replace(/\/+$/, '') || '/';
const homePaths = ['/', '/index.html', '/webnueva', '/webnueva/index.html'];
if (!homePaths.includes(normalizedPath)) {
return;
}
const link = document.createElement('a');
link.className = 'floating-virtual-office';
link.href = 'https://servicios3.selsacloud.com/linix/v6/COOPBCH/loginAsociado.php?nit=COOPBCH';
link.target = '_blank';
link.rel = 'noopener';
link.setAttribute('aria-label', 'Ir a pagos en Oficina Virtual');
link.innerHTML = 'Paga aquí
Oficina Virtual';
document.body.appendChild(link);
}
document.addEventListener('DOMContentLoaded', () => {
initNavbar();
initSearch();
initCarousel();
initNewsPhotoSliders();
initCarouselImagePreview();
initForms();
initDocumentBoards();
initReveal();
initRipple();
initScrollTop();
initVirtualOfficeFloatingButton();
});