// SafeHost Pro - Global JavaScript class SafeHostApp { constructor() { this.init(); } init() { console.log('SafeHost Pro initialized'); this.setupEventListeners(); this.checkAuthStatus(); this.loadUserPreferences(); } setupEventListeners() { // Mobile menu toggle const mobileMenuBtn = document.getElementById('mobile-menu-btn'); const mobileMenu = document.getElementById('mobile-menu'); if (mobileMenuBtn && mobileMenu) { mobileMenuBtn.addEventListener('click', () => { mobileMenu.classList.toggle('hidden'); }); } // Theme switcher const themeToggle = document.getElementById('theme-toggle'); if (themeToggle) { themeToggle.addEventListener('click', this.toggleTheme.bind(this)); } // Smooth scrolling for anchor links document.querySelectorAll('a[href^="#"]').forEach(anchor => { anchor.addEventListener('click', function (e) { e.preventDefault(); const target = document.querySelector(this.getAttribute('href')); if (target) { target.scrollIntoView({ behavior: 'smooth', block: 'start' }); } }); }); } checkAuthStatus() { // Check if user is logged in (placeholder) const token = localStorage.getItem('authToken'); if (token) { this.updateUIForLoggedIn(); } } updateUIForLoggedIn() { // Update navigation and UI for authenticated users const authElements = document.querySelectorAll('[data-auth]'); authElements.forEach(el => { const action = el.getAttribute('data-auth'); if (action === 'hide-if-authenticated') { el.style.display = 'none'; } else if (action === 'show-if-authenticated') { el.style.display = 'block'; } }); } toggleTheme() { const html = document.documentElement; const currentTheme = html.getAttribute('data-theme'); const newTheme = currentTheme === 'dark' ? 'light' : 'dark'; html.setAttribute('data-theme', newTheme); localStorage.setItem('theme', newTheme); this.updateThemeIcon(newTheme); } updateThemeIcon(theme) { const themeIcon = document.getElementById('theme-icon'); if (themeIcon) { themeIcon.setAttribute('data-feather', theme === 'dark' ? 'sun' : 'moon'); feather.replace(); } } loadUserPreferences() { // Load saved theme preference const savedTheme = localStorage.getItem('theme') || 'light'; document.documentElement.setAttribute('data-theme', savedTheme); this.updateThemeIcon(savedTheme); // Load other user preferences const preferences = JSON.parse(localStorage.getItem('userPreferences') || '{}'); this.applyPreferences(preferences); } applyPreferences(preferences) { // Apply user preferences to UI if (preferences.animationsDisabled) { document.body.classList.add('no-animations'); } } // API helper methods async apiCall(endpoint, options = {}) { const baseURL = 'https://api.safehost.pro'; const token = localStorage.getItem('authToken'); const defaultOptions = { headers: { 'Content-Type': 'application/json', 'Authorization': token ? `Bearer ${token}` : '' } }; try { const response = await fetch(`${baseURL}${endpoint}`, { ...defaultOptions, ...options }); if (!response.ok) { throw new Error(`API error: ${response.status}`); } return await response.json(); } catch (error) { console.error('API call failed:', error); this.showNotification('Connection error. Please try again.', 'error'); throw error; } } showNotification(message, type = 'info') { // Create and show notification toast const toast = document.createElement('div'); toast.className = `fixed top-4 right-4 px-6 py-3 rounded-lg shadow-lg text-white ${ type === 'error' ? 'bg-red-500' : type === 'success' ? 'bg-green-500' : 'bg-blue-500' } z-50`; toast.textContent = message; document.body.appendChild(toast); setTimeout(() => { toast.remove(); }, 3000); } // File upload helper async uploadFile(file, onProgress = null) { const formData = new FormData(); formData.append('file', file); try { const response = await fetch('/api/upload', { method: 'POST', body: formData, onUploadProgress: onProgress }); return await response.json(); } catch (error) { console.error('Upload failed:', error); throw error; } } } // Initialize app when DOM is loaded document.addEventListener('DOMContentLoaded', () => { window.safeHostApp = new SafeHostApp(); }); // Utility functions const utils = { formatBytes(bytes, decimals = 2) { if (bytes === 0) return '0 Bytes'; const k = 1024; const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB']; const i = Math.floor(Math.log(bytes) / Math.log(k)); return parseFloat((bytes / Math.pow(k, i)).toFixed(decimals)) + ' ' + sizes[i]; }, formatDate(date) { return new Date(date).toLocaleDateString('en-US', { year: 'numeric', month: 'short', day: 'numeric', hour: '2-digit', minute: '2-digit' }); }, debounce(func, wait) { let timeout; return function executedFunction(...args) { const later = () => { clearTimeout(timeout); func(...args); }; clearTimeout(timeout); timeout = setTimeout(later, wait); }; } };