// Mobile menu toggle document.addEventListener('DOMContentLoaded', function() { const mobileMenuBtn = document.getElementById('mobile-menu-btn'); const mobileMenu = document.getElementById('mobile-menu'); if (mobileMenuBtn && mobileMenu) { mobileMenuBtn.addEventListener('click', function() { mobileMenu.classList.toggle('hidden'); // Change icon const icon = mobileMenuBtn.querySelector('i'); if (mobileMenu.classList.contains('hidden')) { icon.className = 'fas fa-bars text-xl'; } else { icon.className = 'fas fa-times text-xl'; } }); } // Search filters toggle for mobile const filterToggleBtn = document.getElementById('filter-toggle-btn'); const filtersContainer = document.getElementById('filters-container'); if (filterToggleBtn && filtersContainer) { filterToggleBtn.addEventListener('click', function() { filtersContainer.classList.toggle('hidden'); const icon = filterToggleBtn.querySelector('i'); if (filtersContainer.classList.contains('hidden')) { icon.className = 'fas fa-filter mr-2'; filterToggleBtn.innerHTML = 'Mostrar Filtros'; } else { icon.className = 'fas fa-times mr-2'; filterToggleBtn.innerHTML = 'Ocultar Filtros'; } }); } // Auto-submit form when filters change const searchForm = document.getElementById('search-form'); if (searchForm) { const filterSelects = searchForm.querySelectorAll('select[name="area"], select[name="ubicacion"], select[name="tipo_contrato"], select[name="modalidad"], select[name="nivel"], select[name="salario_min"]'); filterSelects.forEach(select => { select.addEventListener('change', function() { // Small delay to show the selection visually setTimeout(() => { searchForm.submit(); }, 100); }); }); // Submit on Enter key for search input const searchInput = searchForm.querySelector('input[name="search"]'); if (searchInput) { searchInput.addEventListener('keypress', function(e) { if (e.key === 'Enter') { e.preventDefault(); searchForm.submit(); } }); } } // Smooth animations const cards = document.querySelectorAll('.card-hover'); cards.forEach(card => { card.addEventListener('mouseenter', function() { this.style.transform = 'translateY(-4px)'; }); card.addEventListener('mouseleave', function() { this.style.transform = 'translateY(0)'; }); }); // Auto-hide alerts const alerts = document.querySelectorAll('.alert-auto-hide'); alerts.forEach(alert => { setTimeout(() => { alert.style.opacity = '0'; setTimeout(() => { alert.remove(); }, 300); }, 5000); }); // File input preview const fileInput = document.getElementById('cv_file'); const filePreview = document.getElementById('file-preview'); if (fileInput && filePreview) { fileInput.addEventListener('change', function(e) { const file = e.target.files[0]; if (file) { const fileName = file.name; const fileSize = (file.size / 1024 / 1024).toFixed(2); if (file.type === 'application/pdf') { filePreview.innerHTML = `

${fileName}

${fileSize} MB

`; filePreview.classList.remove('hidden'); } else { alert('Por favor, selecciona un archivo PDF vĂ¡lido.'); fileInput.value = ''; filePreview.classList.add('hidden'); } } else { filePreview.classList.add('hidden'); } }); } // Form validation const forms = document.querySelectorAll('form'); forms.forEach(form => { form.addEventListener('submit', function(e) { const requiredFields = form.querySelectorAll('[required]'); let isValid = true; requiredFields.forEach(field => { if (!field.value.trim()) { isValid = false; field.classList.add('border-red-500'); field.classList.remove('border-gray-300'); } else { field.classList.remove('border-red-500'); field.classList.add('border-gray-300'); } }); if (!isValid) { e.preventDefault(); showAlert('Por favor, completa todos los campos obligatorios.', 'error'); } }); }); // Clear search functionality const clearSearchBtn = document.getElementById('clear-search'); if (clearSearchBtn) { clearSearchBtn.addEventListener('click', function(e) { e.preventDefault(); // Redirect to clean index page window.location.href = 'index.php'; }); } // Search suggestions (simple implementation) const searchInput = document.querySelector('input[name="search"]'); if (searchInput) { let searchTimeout; searchInput.addEventListener('input', function() { clearTimeout(searchTimeout); const query = this.value.trim(); if (query.length >= 3) { searchTimeout = setTimeout(() => { // Here you could implement search suggestions console.log('Searching for:', query); }, 300); } }); } }); // Show alert function function showAlert(message, type = 'info') { const alertTypes = { success: 'bg-green-100 border-green-400 text-green-700', error: 'bg-red-100 border-red-400 text-red-700', warning: 'bg-yellow-100 border-yellow-400 text-yellow-700', info: 'bg-blue-100 border-blue-400 text-blue-700' }; const alertClass = alertTypes[type] || alertTypes.info; const alertHTML = `
${message}
`; document.body.insertAdjacentHTML('beforeend', alertHTML); } // Loading state for buttons function setButtonLoading(button, isLoading = true) { if (isLoading) { button.disabled = true; const originalText = button.innerHTML; button.setAttribute('data-original-text', originalText); button.innerHTML = 'Cargando...'; button.classList.add('opacity-75'); } else { button.disabled = false; const originalText = button.getAttribute('data-original-text'); if (originalText) { button.innerHTML = originalText; } button.classList.remove('opacity-75'); } } // Format currency (Colombian Pesos) function formatCurrency(amount) { if (!amount) return 'No especificado'; return new Intl.NumberFormat('es-CO', { style: 'currency', currency: 'COP', minimumFractionDigits: 0, maximumFractionDigits: 0 }).format(amount); } // Format date function formatDate(dateString) { const date = new Date(dateString); return date.toLocaleDateString('es-CO', { year: 'numeric', month: 'long', day: 'numeric' }); } // Copy to clipboard function copyToClipboard(text) { navigator.clipboard.writeText(text).then(function() { showAlert('Copiado al portapapeles', 'success'); }, function() { showAlert('Error al copiar', 'error'); }); } // Share job function shareJob(jobId, jobTitle) { const url = `${window.location.origin}/job-detail.php?id=${jobId}`; if (navigator.share) { navigator.share({ title: jobTitle, text: `Mira esta oportunidad laboral: ${jobTitle}`, url: url }); } else { copyToClipboard(url); } } // Debounce function for search function debounce(func, wait) { let timeout; return function executedFunction(...args) { const later = () => { clearTimeout(timeout); func(...args); }; clearTimeout(timeout); timeout = setTimeout(later, wait); }; }