// Main application JavaScript class SingularityPortal { constructor() { this.apiBase = '/api'; this.currentUser = null; this.init(); } init() { this.setupEventListeners(); this.checkAuthStatus(); this.loadInitialData(); } setupEventListeners() { // Global event listeners document.addEventListener('keydown', this.handleKeyboardShortcuts.bind(this)); } handleKeyboardShortcuts(event) { if (event.ctrlKey && event.key === 'k') { event.preventDefault(); this.toggleAIAssistant(); } } async checkAuthStatus() { try { const response = await fetch(`${this.apiBase}/auth/status`); if (response.ok) { this.currentUser = await response.json(); this.updateUIForAuth(); } } catch (error) { console.log('Auth check failed:', error); } } updateUIForAuth() { const authElements = document.querySelectorAll('[data-auth]'); authElements.forEach(element => { const authType = element.getAttribute('data-auth'); if (authType === 'required' && !this.currentUser) { element.style.display = 'none'; } else if (authType === 'admin' && (!this.currentUser || !this.currentUser.isAdmin)) { element.style.display = 'none'; } }); } async loadInitialData() { await this.loadLatestUpdates(); } async loadLatestUpdates() { try { const response = await fetch(`${this.apiBase}/content/latest`); if (response.ok) { const updates = await response.json(); this.renderLatestUpdates(updates); } } catch (error) { console.log('Failed to load latest updates:', error); } } renderLatestUpdates(updates) { const container = document.getElementById('latest-updates'); if (!container) return; container.innerHTML = updates.map(update => `
`).join(''); } formatDate(dateString) { const date = new Date(dateString); return date.toLocaleDateString('ru-RU'); } toggleAIAssistant() { const assistant = document.querySelector('ai-assistant'); if (assistant) { assistant.toggleChat(); } } } // Initialize the portal let portal; document.addEventListener('DOMContentLoaded', function() { portal = new SingularityPortal(); feather.replace(); }); // Utility functions const Utils = { debounce(func, wait) { let timeout; return function executedFunction(...args) { const later = () => { clearTimeout(timeout); func(...args); }; clearTimeout(timeout); timeout = setTimeout(later, wait); }; }, generateId() { return Date.now().toString(36) + Math.random().toString(36).substr(2); }, formatFileSize(bytes) { const sizes = ['Bytes', 'KB', 'MB', 'GB']; if (bytes === 0) return '0 Bytes'; const i = parseInt(Math.floor(Math.log(bytes) / Math.log(1024))); return Math.round(bytes / Math.pow(1024, i) * 100) / 100 + ' ' + sizes[i]; } }; // API service for backend communication class APIService { constructor() { this.baseURL = '/api'; } async request(endpoint, options = {}) { const url = `${this.baseURL}${endpoint}`; const config = { headers: { 'Content-Type': 'application/json', }, ...options }; try { const response = await fetch(url, config); if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } return await response.json(); } catch (error) { console.error('API request failed:', error); throw error; } } // Content management async getContent(section, filters = {}) { const query = new URLSearchParams(filters).toString(); return this.request(`/content/${section}?${query}`); } async createContent(contentData) { return this.request('/content', { method: 'POST', body: JSON.stringify(contentData) }); } async updateContent(id, contentData) { return this.request(`/content/${id}`, { method: 'PUT', body: JSON.stringify(contentData) }); } // AI Assistant communication async sendMessageToAI(message, context = {}) { return this.request('/ai/chat', { method: 'POST', body: JSON.stringify({ message, context }) }); } // User management async login(credentials) { return this.request('/auth/login', { method: 'POST', body: JSON.stringify(credentials) }); } async register(userData) { return this.request('/auth/register', { method: 'POST', body: JSON.stringify(userData) }); } } // Initialize API service const apiService = new APIService(); // Export for use in components window.SingularityPortal = SingularityPortal; window.APIService = APIService; window.Utils = Utils;