tyvenar/careerpath-oracle
0
1// Shared JavaScript for CareerPath Oracle2 3// Initialize tooltips for feather icons4document.addEventListener('DOMContentLoaded', function() {5 // Add subtle tooltips to interactive elements6 const tooltipElements = document.querySelectorAll('[data-tooltip]');7 tooltipElements.forEach(el => {8 el.addEventListener('mouseenter', function() {9 const tooltip = document.createElement('div');10 tooltip.className = 'fixed z-50 px-3 py-2 text-sm text-white bg-gray-900 rounded-lg shadow-lg';11 tooltip.textContent = this.dataset.tooltip;12 document.body.appendChild(tooltip);13 14 const rect = this.getBoundingClientRect();15 tooltip.style.left = `${rect.left + rect.width/2 - tooltip.offsetWidth/2}px`;16 tooltip.style.top = `${rect.top - tooltip.offsetHeight - 10}px`;17 18 this._tooltip = tooltip;19 });20 21 el.addEventListener('mouseleave', function() {22 if (this._tooltip) {23 this._tooltip.remove();24 this._tooltip = null;25 }26 });27 });28 29 // Form validation helper30 window.validateForm = function(formId) {31 const form = document.getElementById(formId);32 if (!form) return true;33 34 const inputs = form.querySelectorAll('input[required], select[required]');35 let isValid = true;36 37 inputs.forEach(input => {38 if (!input.value.trim()) {39 input.classList.add('border-red-500');40 ');41 isValid = false;42 43 // Add error message44 if (!input.nextElementSibling?.classList.contains('error-message')) {45 const errorMsg = document.createElement('p');46 errorMsg.className = 'error-message text-red-500 text-sm mt-1';47 errorMsg.textContent = 'This field is required';48 input.parentNode.insertBefore(errorMsg, input.nextSibling);49 }50 } else {51 input.classList.remove('border-red-500');52 const errorMsg = input.nextElementSibling;53 if (errorMsg?.classList.contains('error-message')) {54 errorMsg.remove();55 }56 }57 });58 59 return isValid;60 };61 62 // API helper function63 window.apiRequest = async function(endpoint, method = 'GET', data = null) {64 const BASE_URL = 'https://api.careerpathoracle.com';65 66 try {67 const options = {68 method,69 headers: {70 'Content-Type': 'application/json',71 },72 };73 74 if (data && (method === 'POST' || method === 'PUT')) {75 options.body = JSON.stringify(data);76 }77 78 const response = await fetch(`${BASE_URL}${endpoint}`, options);79 80 if (!response.ok) {81 throw new Error(`API Error: ${response.status}`);82 }83 84 return await response.json();85 } catch (error) {86 console.error('API Request Failed:', error);87 showNotification('Failed to connect to server. Please try again.', 'error');88 throw error;89 }90 };91 92 // Notification system93 window.showNotification = function(message, type = 'info') {94 const notification = document.createElement('div');95 notification.className = `fixed top-4 right-4 z-50 px-6 py-4 rounded-lg shadow-lg transform transition-all duration-300 ${96 type === 'success' ? 'bg-green-100 text-green-800 border border-green-200' :97 type === 'error' ? 'bg-red-100 text-red-800 border border-red-200' :98 'bg-blue-100 text-blue-800 border border-blue-200'99 }`;100 101 notification.innerHTML = `102 <div class="flex items-center gap-3">103 <i data-feather="${104 type === 'success' ? 'check-circle' :105 type === 'error' ? 'alert-circle' : 'info'106 }" class="w-5 h-5"></i>107 绪维108 109)?!110 111月旺,哇!这样,那些长像飞船的兵一,根本就上不了!112 113月份