Spaces:
Running
Running
| class AIAssistant extends HTMLElement { | |
| constructor() { | |
| super(); | |
| this.isOpen = false; | |
| this.messages = []; | |
| } | |
| connectedCallback() { | |
| this.attachShadow({ mode: 'open' }); | |
| this.render(); | |
| this.setupEventListeners(); | |
| this.loadInitialMessage(); | |
| } | |
| render() { | |
| this.shadowRoot.innerHTML = ` | |
| <style> | |
| :host { | |
| display: block; | |
| position: fixed; | |
| bottom: 20px; | |
| right: 20px; | |
| z-index: 1000; | |
| } | |
| .ai-toggle-button { | |
| width: 60px; | |
| height: 60px; | |
| border-radius: 50%; | |
| background: linear-gradient(45deg, #00ff88, #00a2ff); | |
| border: none; | |
| color: #050508; | |
| cursor: pointer; | |
| box-shadow: 0 5px 20px rgba(0, 255, 136, 0.4); | |
| transition: all 0.3s ease; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| font-size: 1.5rem; | |
| } | |
| .ai-toggle-button:hover { | |
| transform: scale(1.1); | |
| box-shadow: 0 8px 25px rgba(0, 255, 136, 0.6); | |
| } | |
| .ai-chat-window { | |
| position: absolute; | |
| bottom: 70px; | |
| right: 0; | |
| width: 350px; | |
| height: 500px; | |
| background: #0a0a0f; | |
| border: 1px solid #00ff88; | |
| border-radius: 12px; | |
| box-shadow: 0 10px 40px rgba(0, 255, 136, 0.3); | |
| display: none; | |
| flex-direction: column; | |
| } | |
| .ai-chat-window.active { | |
| display: flex; | |
| } | |
| .ai-chat-header { | |
| padding: 16px; | |
| background: linear-gradient(45deg, #00ff88, #00a2ff); | |
| border-radius: 12px 12px 0 0; | |
| color: #050508; | |
| font-weight: 600; | |
| display: flex; | |
| justify-content: space-between; | |
| align-items: center; | |
| } | |
| .ai-chat-messages { | |
| flex: 1; | |
| padding: 16px; | |
| overflow-y: auto; | |
| display: flex; | |
| flex-direction: column; | |
| gap: 12px; | |
| } | |
| .ai-message { | |
| padding: 12px; | |
| border-radius: 8px; | |
| max-width: 80%; | |
| word-wrap: break-word; | |
| } | |
| .ai-message.user { | |
| align-self: flex-end; | |
| background: linear-gradient(45deg, #00a2ff, #00ff88); | |
| color: #050508; | |
| } | |
| .ai-message.assistant { | |
| align-self: flex-start; | |
| background: #1a1a2e; | |
| border: 1px solid #2a2a3e; | |
| } | |
| .ai-chat-input { | |
| padding: 16px; | |
| border-top: 1px solid #2a2a3e; | |
| display: flex; | |
| gap: 8px; | |
| } | |
| .ai-chat-input input { | |
| flex: 1; | |
| padding: 8px 12px; | |
| background: #1a1a2e; | |
| border: 1px solid #2a2a3e; | |
| border-radius: 6px; | |
| color: white; | |
| } | |
| .ai-chat-input button { | |
| padding: 8px 16px; | |
| background: #00ff88; | |
| border: none; | |
| border-radius: 6px; | |
| color: #050508; | |
| font-weight: 600; | |
| cursor: pointer; | |
| } | |
| @media (max-width: 768px) { | |
| .ai-chat-window { | |
| width: 300px; | |
| height: 400px; | |
| right: -50px; | |
| } | |
| } | |
| </style> | |
| <div class="ai-assistant-container"> | |
| <button class="ai-toggle-button"> | |
| <i data-feather="message-circle"></i> | |
| </button> | |
| <div class="ai-chat-window"> | |
| <div class="ai-chat-header"> | |
| <span>AI Ассистент Nexus</span> | |
| <button class="close-button"> | |
| <i data-feather="x"></i> | |
| </button> | |
| </div> | |
| <div class="ai-chat-messages" id="chat-messages"> | |
| <!-- Messages will be added here --> | |
| </div> | |
| <div class="ai-chat-input"> | |
| <input type="text" id="chat-input" placeholder="Задайте вопрос..."> | |
| <button id="send-button"> | |
| <i data-feather="send"></i> | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| `; | |
| setTimeout(() => { | |
| if (typeof feather !== 'undefined') { | |
| feather.replace(); | |
| } | |
| }, 100); | |
| } | |
| setupEventListeners() { | |
| const toggleButton = this.shadowRoot.querySelector('.ai-toggle-button'); | |
| const closeButton = this.shadowRoot.querySelector('.close-button'); | |
| const sendButton = this.shadowRoot.querySelector('#send-button'); | |
| const chatInput = this.shadowRoot.querySelector('#chat-input'); | |
| if (toggleButton) { | |
| toggleButton.addEventListener('click', () => { | |
| this.toggleChat(); | |
| }); | |
| } | |
| if (closeButton) { | |
| closeButton.addEventListener('click', () => { | |
| this.closeChat(); | |
| }); | |
| } | |
| if (sendButton && chatInput) { | |
| sendButton.addEventListener('click', () => { | |
| this.sendMessage(); | |
| }); | |
| chatInput.addEventListener('keypress', (e) => { | |
| if (e.key === 'Enter') { | |
| this.sendMessage(); | |
| } | |
| }); | |
| } | |
| } | |
| loadInitialMessage() { | |
| const welcomeMessage = { | |
| type: 'assistant', | |
| text: 'Привет! Я ваш AI ассистент Nexus. Могу помочь с информацией о портале, записать на консультацию или ответить на вопросы о технологиях. Чем могу помочь?' | |
| }; | |
| this.addMessage(welcomeMessage); | |
| } | |
| toggleChat() { | |
| this.isOpen = !this.isOpen; | |
| const chatWindow = this.shadowRoot.querySelector('.ai-chat-window'); | |
| if (chatWindow) { | |
| chatWindow.classList.toggle('active', this.isOpen); | |
| if (this.isOpen) { | |
| const input = this.shadowRoot.querySelector('#chat-input'); | |
| if (input) { | |
| input.focus(); | |
| } | |
| } | |
| } | |
| closeChat() { | |
| this.isOpen = false; | |
| const chatWindow = this.shadowRoot.querySelector('.ai-chat-window'); | |
| if (chatWindow) { | |
| chatWindow.classList.remove('active'); | |
| } | |
| } | |
| async sendMessage() { | |
| const input = this.shadowRoot.querySelector('#chat-input'); | |
| if (!input || !input.value.trim()) return; | |
| const userMessage = { | |
| type: 'user', | |
| text: input.value.trim() | |
| }; | |
| this.addMessage(userMessage); | |
| const userText = input.value; | |
| input.value = ''; | |
| // Simulate AI response | |
| this.simulateAIResponse(userText); | |
| } | |
| async simulateAIResponse(userMessage) { | |
| // Show typing indicator | |
| this.showTypingIndicator(); | |
| // Simulate API call delay | |
| setTimeout(async () => { | |
| this.hideTypingIndicator(); | |
| let responseText = ''; | |
| if (userMessage.toLowerCase().includes('консультация') || userMessage.toLowerCase().includes('запись')) { | |
| responseText = 'Отлично! Для записи на консультацию перейдите в раздел "Консультации" или свяжитесь напрямую через Telegram @tsingular. Хотите, чтобы я открыл соответствующий раздел?'; | |
| } else if (userMessage.toLowerCase().includes('новости')) { | |
| responseText = 'В разделе "Новости" вы найдете свежие технологические тренды, аналитику и инсайты от Алексея Малышева.'; | |
| } else if (userMessage.toLowerCase().includes('обучение')) { | |
| responseText = 'Раздел "Обучение" содержит образовательные материалы, курсы и руководства по современным технологиям.'; | |
| } else { | |
| responseText = 'Интересный вопрос! Я могу помочь с информацией о различных разделах портала, технологиях или организации консультации. Что именно вас интересует?'; | |
| } | |
| const assistantMessage = { | |
| type: 'assistant', | |
| text: responseText | |
| }; | |
| this.addMessage(assistantMessage); | |
| }, 1500); | |
| } | |
| showTypingIndicator() { | |
| const messagesContainer = this.shadowRoot.querySelector('#chat-messages'); | |
| if (messagesContainer) { | |
| const typingElement = document.createElement('div'); | |
| typingElement.className = 'ai-message assistant typing-indicator'; | |
| typingElement.innerHTML = '<div class="typing-dots"><span></span><span></span><span></span></div>'; | |
| messagesContainer.appendChild(typingElement); | |
| messagesContainer.scrollTop = messagesContainer.scrollHeight; | |
| } | |
| hideTypingIndicator() { | |
| const messagesContainer = this.shadowRoot.querySelector('#chat-messages'); | |
| if (messagesContainer) { | |
| const typingElement = messagesContainer.querySelector('.typing-indicator'); | |
| if (typingElement) { | |
| typingElement.remove(); | |
| } | |
| } | |
| } | |
| addMessage(message) { | |
| const messagesContainer = this.shadowRoot.querySelector('#chat-messages'); | |
| if (messagesContainer) { | |
| const messageElement = document.createElement('div'); | |
| messageElement.className = `ai-message ${message.type}`; | |
| messageElement.textContent = message.text; | |
| messagesContainer.appendChild(messageElement); | |
| messagesContainer.scrollTop = messagesContainer.scrollHeight; | |
| } | |
| } | |
| } | |
| customElements.define('ai-assistant', AIAssistant); | |
| // Global AI Assistant functions | |
| function initializeAIAssistant() { | |
| // AI Assistant is already initialized by the component | |
| console.log('AI Assistant initialized'); | |
| } | |
| function toggleAIAssistant() { | |
| const assistant = document.querySelector('ai-assistant'); | |
| if (assistant) { | |
| assistant.toggleChat(); | |
| } | |
| } |