mbmal's picture
мне нужен портал проекта Технозаметки Малышева (канал в телеграме @tsingular)
29e58e3 verified
// 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 => `
<div class="cyber-timeline-item">
<div class="flex justify-between items-start mb-2">
<h4 class="font-cyber text-cyber-primary">${update.title}</h4>
<span class="text-sm text-gray-400">${this.formatDate(update.date)}</span>
</div>
<p class="text-gray-300">${update.description}</p>
<a href="${update.link}" class="cyber-link text-sm mt-2">Подробнее →</a>
</div>
`).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;