Spaces:
Running
Running
| // Main Application Script | |
| document.addEventListener('DOMContentLoaded', function() { | |
| // Initialize Feather Icons | |
| if (typeof feather !== 'undefined') { | |
| feather.replace(); | |
| } | |
| // Mobile menu toggle for sidebar | |
| const setupMobileMenu = () => { | |
| const sidebarToggle = document.querySelector('[data-sidebar-toggle]'); | |
| const sidebar = document.querySelector('custom-sidebar'); | |
| const overlay = document.createElement('div'); | |
| if (sidebarToggle && sidebar) { | |
| // Create overlay for mobile | |
| overlay.className = 'fixed inset-0 bg-black bg-opacity-50 z-40 hidden'; | |
| document.body.appendChild(overlay); | |
| sidebarToggle.addEventListener('click', () => { | |
| sidebar.classList.toggle('-translate-x-full'); | |
| sidebar.classList.toggle('translate-x-0'); | |
| overlay.classList.toggle('hidden'); | |
| document.body.classList.toggle('overflow-hidden'); | |
| }); | |
| overlay.addEventListener('click', () => { | |
| sidebar.classList.add('-translate-x-full'); | |
| sidebar.classList.remove('translate-x-0'); | |
| overlay.classList.add('hidden'); | |
| document.body.classList.remove('overflow-hidden'); | |
| }); | |
| // Close sidebar when clicking on links (mobile) | |
| const sidebarLinks = sidebar.shadowRoot.querySelectorAll('a'); | |
| sidebarLinks.forEach(link => { | |
| link.addEventListener('click', () => { | |
| if (window.innerWidth < 768) { | |
| sidebar.classList.add('-translate-x-full'); | |
| sidebar.classList.remove('translate-x-0'); | |
| overlay.classList.add('hidden'); | |
| document.body.classList.remove('overflow-hidden'); | |
| } | |
| }); | |
| }); | |
| } | |
| }; | |
| // Setup AI code assistant functionality | |
| const setupAIAssistant = () => { | |
| const codeInput = document.querySelector('input[placeholder*="Ask DevinAI"]'); | |
| const sendButton = document.querySelector('button.bg-blue-600'); | |
| if (codeInput && sendButton) { | |
| sendButton.addEventListener('click', async () => { | |
| const query = codeInput.value.trim(); | |
| if (!query) return; | |
| // Show loading state | |
| const originalText = sendButton.innerHTML; | |
| sendButton.innerHTML = '<div class="spinner"></div>'; | |
| sendButton.disabled = true; | |
| // Simulate API call with timeout | |
| setTimeout(() => { | |
| // In a real app, this would be an API call to an AI service | |
| console.log('AI Query:', query); | |
| // Reset button | |
| sendButton.innerHTML = originalText; | |
| sendButton.disabled = false; | |
| codeInput.value = ''; | |
| // Show success message | |
| showNotification('AI is processing your request...', 'success'); | |
| }, 1500); | |
| }); | |
| // Allow Enter key to submit | |
| codeInput.addEventListener('keypress', (e) => { | |
| if (e.key === 'Enter') { | |
| sendButton.click(); | |
| } | |
| }); | |
| } | |
| }; | |
| // Notification system | |
| const showNotification = (message, type = 'info') => { | |
| const notification = document.createElement('div'); | |
| const colors = { | |
| success: 'bg-green-100 border-green-400 text-green-700', | |
| error: 'bg-red-100 border-red-400 text-red-700', | |
| info: 'bg-blue-100 border-blue-400 text-blue-700', | |
| warning: 'bg-yellow-100 border-yellow-400 text-yellow-700' | |
| }; | |
| notification.className = `fixed top-6 right-6 px-6 py-4 rounded-lg border ${colors[type]} shadow-lg z-50 transform transition-transform duration-300 translate-x-full`; | |
| notification.innerHTML = ` | |
| <div class="flex items-center"> | |
| <i data-feather="${type === 'success' ? 'check-circle' : type === 'error' ? 'alert-circle' : 'info'}" class="w-5 h-5 mr-3"></i> | |
| <span>${message}</span> | |
| </div> | |
| `; | |
| document.body.appendChild(notification); | |
| // Animate in | |
| setTimeout(() => { | |
| notification.classList.remove('translate-x-full'); | |
| notification.classList.add('translate-x-0'); | |
| }, 10); | |
| // Replace icons | |
| if (typeof feather !== 'undefined') { | |
| feather.replace(); | |
| } | |
| // Auto remove after 5 seconds | |
| setTimeout(() => { | |
| notification.classList.remove('translate-x-0'); | |
| notification.classList.add('translate-x-full'); | |
| setTimeout(() => { | |
| if (notification.parentNode) { | |
| notification.parentNode.removeChild(notification); | |
| } | |
| }, 300); | |
| }, 5000); | |
| }; | |
| // Load projects from GitHub API (public API) | |
| const loadProjectsFromAPI = async () => { | |
| try { | |
| // Using GitHub's public API to fetch repositories | |
| const response = await fetch('https://api.github.com/users/github/repos?sort=updated&per_page=5'); | |
| if (response.ok) { | |
| const repos = await response.json(); | |
| const projectsContainer = document.querySelector('.projects-container'); | |
| if (projectsContainer && repos.length > 0) { | |
| // Update UI with real data | |
| console.log('Loaded projects from GitHub:', repos.length); | |
| // Update stats if available | |
| const activeProjectsElement = document.querySelector('.stats-active-projects'); | |
| if (activeProjectsElement) { | |
| activeProjectsElement.textContent = repos.length; | |
| } | |
| } | |
| } | |
| } catch (error) { | |
| console.log('Could not load projects from API, using static data instead:', error); | |
| } | |
| }; | |
| // Initialize everything | |
| setupMobileMenu(); | |
| setupAIAssistant(); | |
| loadProjectsFromAPI(); | |
| // Add responsive behavior for window resize | |
| window.addEventListener('resize', function() { | |
| const sidebar = document.querySelector('custom-sidebar'); | |
| const overlay = document.querySelector('.fixed.inset-0.bg-black'); | |
| if (window.innerWidth >= 768 && sidebar && overlay) { | |
| sidebar.classList.remove('-translate-x-full'); | |
| sidebar.classList.add('translate-x-0'); | |
| if (overlay) overlay.classList.add('hidden'); | |
| document.body.classList.remove('overflow-hidden'); | |
| } | |
| }); | |
| // Add active state to navigation links | |
| const setActiveNavLink = () => { | |
| const currentPath = window.location.pathname; | |
| const navLinks = document.querySelectorAll('custom-navbar a, custom-sidebar a'); | |
| navLinks.forEach(link => { | |
| const href = link.getAttribute('href'); | |
| if (href && currentPath.includes(href.replace('.html', ''))) { | |
| link.classList.add('text-blue-600', 'font-semibold'); | |
| link.classList.remove('text-gray-700'); | |
| } | |
| }); | |
| }; | |
| setActiveNavLink(); | |
| // Export functions for web components if needed | |
| window.App = { | |
| showNotification, | |
| loadProjectsFromAPI | |
| }; | |
| }); |