Spaces:
Running
Running
| // Enhanced data structure with real educational content | |
| const subjectsData = { | |
| "Business Communication": { | |
| description: "Master professional communication skills for business success", | |
| icon: "message-square", | |
| color: "from-blue-500 to-cyan-400", | |
| chapters: { | |
| "Introduction to Business Communication": { | |
| topics: [ | |
| "Nature and Scope of Business Communication", | |
| "Importance of Effective Communication", | |
| "Communication Process and Models", | |
| "Barriers to Communication" | |
| ], | |
| videoId: "I6IQ_FOCE6I", | |
| duration: "15:30" | |
| }, | |
| "Written Business Communication": { | |
| topics: [ | |
| "Business Letters and Memos", | |
| "Reports and Proposals", | |
| "Email Etiquette", | |
| "Professional Writing Style" | |
| ], | |
| videoId: "YbV2Np4dGvU", | |
| duration: "18:45" | |
| }, | |
| "Presentation Skills": { | |
| topics: [ | |
| "Structuring Presentations", | |
| "Visual Aids and Tools", | |
| "Public Speaking Techniques", | |
| "Handling Q&A Sessions" | |
| ], | |
| videoId: "tX3YdGQq6yU", | |
| duration: "22:10" | |
| } | |
| }, | |
| progress: 65, | |
| totalLessons: 12 | |
| }, | |
| "Digital Electronics-II": { | |
| description: "Advanced digital circuits, memory systems, and sequential logic", | |
| icon: "cpu", | |
| color: "from-purple-500 to-pink-500", | |
| chapters: { | |
| "Sequential Logic Circuits": { | |
| topics: [ | |
| "Flip-Flops and Latches", | |
| "Counters and Registers", | |
| "State Machines", | |
| "Timing Analysis" | |
| ], | |
| videoId: "fpnE6UAfbtU", | |
| duration: "25:15" | |
| }, | |
| "Memory Systems": { | |
| topics: [ | |
| "RAM and ROM Architectures", | |
| "Cache Memory Organization", | |
| "Memory Hierarchy", | |
| "Virtual Memory Systems" | |
| ], | |
| videoId: "FZR1r8yLkCQ", | |
| duration: "20:40" | |
| }, | |
| "Digital Design with Verilog": { | |
| topics: [ | |
| "HDL Fundamentals", | |
| "Combinational Circuits", | |
| "Sequential Circuits", | |
| "FPGA Implementation" | |
| ], | |
| videoId: "HAqj9Yh8_AM", | |
| duration: "28:30" | |
| } | |
| }, | |
| progress: 40, | |
| totalLessons: 15 | |
| }, | |
| "Java Programming": { | |
| description: "Object-oriented programming with Java for modern applications", | |
| icon: "code", | |
| color: "from-orange-500 to-red-500", | |
| chapters: { | |
| "Object-Oriented Programming": { | |
| topics: [ | |
| "Classes and Objects", | |
| "Inheritance and Polymorphism", | |
| "Encapsulation and Abstraction", | |
| "Interfaces and Abstract Classes" | |
| ], | |
| videoId: "bIeqAlmNRrA", | |
| duration: "32:20" | |
| }, | |
| "Exception Handling": { | |
| topics: [ | |
| "Try-Catch-Finally Blocks", | |
| "Custom Exceptions", | |
| "Exception Hierarchy", | |
| "Best Practices" | |
| ], | |
| videoId: "K_-3OLkXkzY", | |
| duration: "19:15" | |
| }, | |
| "Collections Framework": { | |
| topics: [ | |
| "Lists, Sets, and Maps", | |
| "Iterators and Comparators", | |
| "Stream API", | |
| "Concurrent Collections" | |
| ], | |
| videoId: "rzA7UJ-hQn4", | |
| duration: "26:45" | |
| } | |
| }, | |
| progress: 80, | |
| totalLessons: 18 | |
| }, | |
| "Data Structure & Algorithm": { | |
| description: "Essential data structures and algorithms for efficient programming", | |
| icon: "layers", | |
| color: "from-green-500 to-emerald-400", | |
| chapters: { | |
| "Sorting Algorithms": { | |
| topics: [ | |
| "Bubble, Selection, Insertion Sort", | |
| "Quick Sort and Merge Sort", | |
| "Heap Sort and Radix Sort", | |
| "Time and Space Complexity Analysis" | |
| ], | |
| videoId: "Kg4bqzAqRBM", | |
| duration: "35:10" | |
| }, | |
| "Tree Data Structures": { | |
| topics: [ | |
| "Binary Trees and BST", | |
| "AVL and Red-Black Trees", | |
| "Tree Traversal Methods", | |
| "Heap Data Structure" | |
| ], | |
| videoId: "oSWTXtMglKE", | |
| duration: "29:25" | |
| }, | |
| "Graph Algorithms": { | |
| topics: [ | |
| "Graph Representations", | |
| "DFS and BFS Traversal", | |
| "Shortest Path Algorithms", | |
| "Minimum Spanning Trees" | |
| ], | |
| videoId: "tWVWeAqZ0WU", | |
| duration: "31:40" | |
| } | |
| }, | |
| progress: 55, | |
| totalLessons: 20 | |
| }, | |
| "Computer Peripherals & Interfacing": { | |
| description: "Understanding computer hardware components and communication protocols", | |
| icon: "hard-drive", | |
| color: "from-yellow-500 to-amber-500", | |
| chapters: { | |
| "Input Devices": { | |
| topics: [ | |
| "Keyboard and Mouse Interfaces", | |
| "Scanner Technology", | |
| "Touchscreen Systems", | |
| "Biometric Devices" | |
| ], | |
| videoId: "ExxFxD4OSZ0", | |
| duration: "21:30" | |
| }, | |
| "Output Devices": { | |
| topics: [ | |
| "Monitor Technologies (LCD, LED, OLED)", | |
| "Printers and Plotters", | |
| "Audio Output Systems", | |
| "3D Printing Technology" | |
| ], | |
| videoId: "VY8PmfV-5h0", | |
| duration: "24:15" | |
| }, | |
| "Interface Standards": { | |
| topics: [ | |
| "USB and Thunderbolt", | |
| "PCI Express", | |
| "SATA and NVMe", | |
| "Wireless Interfaces" | |
| ], | |
| videoId: "G1KbUHP0zL4", | |
| duration: "19:50" | |
| } | |
| }, | |
| progress: 30, | |
| totalLessons: 14 | |
| }, | |
| "Web Design & Development - I": { | |
| description: "Modern web technologies for building responsive and interactive websites", | |
| icon: "globe", | |
| color: "from-indigo-500 to-purple-500", | |
| chapters: { | |
| "HTML5 & Semantic Web": { | |
| topics: [ | |
| "HTML5 New Elements", | |
| "Semantic Markup", | |
| "Forms and Validation", | |
| "Accessibility Standards" | |
| ], | |
| videoId: "qz0aGYrrlhU", | |
| duration: "27:20" | |
| }, | |
| "CSS3 & Responsive Design": { | |
| topics: [ | |
| "Flexbox and Grid Layout", | |
| "Media Queries", | |
| "CSS Animations", | |
| "Custom Properties" | |
| ], | |
| videoId: "T6v8TAJhqA4", | |
| duration: "33:45" | |
| }, | |
| "JavaScript Fundamentals": { | |
| topics: [ | |
| "DOM Manipulation", | |
| "Event Handling", | |
| "Async Programming", | |
| "ES6+ Features" | |
| ], | |
| videoId: "W6NZfCO5SIk", | |
| duration: "30:10" | |
| } | |
| }, | |
| progress: 90, | |
| totalLessons: 16 | |
| } | |
| }; | |
| // Stats counter | |
| let stats = { | |
| subjects: Object.keys(subjectsData).length, | |
| chapters: 0, | |
| lessons: 0, | |
| videos: 0 | |
| }; | |
| // Calculate stats | |
| function calculateStats() { | |
| let totalChapters = 0; | |
| let totalLessons = 0; | |
| Object.values(subjectsData).forEach(subject => { | |
| totalChapters += Object.keys(subject.chapters).length; | |
| totalLessons += subject.totalLessons || 0; | |
| }); | |
| stats.chapters = totalChapters; | |
| stats.lessons = totalLessons; | |
| stats.videos = totalChapters; // One video per chapter | |
| updateStatsCounter(); | |
| } | |
| // Animated counter | |
| function animateCounter(element, target, duration = 1500) { | |
| const start = 0; | |
| const increment = target / (duration / 16); | |
| let current = start; | |
| const timer = setInterval(() => { | |
| current += increment; | |
| if (current >= target) { | |
| element.textContent = target.toLocaleString(); | |
| clearInterval(timer); | |
| } else { | |
| element.textContent = Math.floor(current).toLocaleString(); | |
| } | |
| }, 16); | |
| } | |
| // Update stats counter | |
| function updateStatsCounter() { | |
| const statsElements = { | |
| 'stat-subjects': stats.subjects, | |
| 'stat-chapters': stats.chapters, | |
| 'stat-lessons': stats.lessons, | |
| 'stat-videos': stats.videos | |
| }; | |
| Object.entries(statsElements).forEach(([id, target]) => { | |
| const element = document.getElementById(id); | |
| if (element) { | |
| animateCounter(element, target); | |
| } | |
| }); | |
| } | |
| // Generate subject cards | |
| function generateSubjectCards() { | |
| const container = document.getElementById('subjects-grid'); | |
| if (!container) return; | |
| container.innerHTML = ''; | |
| Object.entries(subjectsData).forEach(([subjectName, subjectData]) => { | |
| const chaptersCount = Object.keys(subjectData.chapters).length; | |
| const progressPercentage = subjectData.progress || 0; | |
| const card = document.createElement('div'); | |
| card.className = 'subject-card fade-in-up hover-glow particle-bg'; | |
| card.style.animationDelay = `${Math.random() * 0.3}s`; | |
| card.innerHTML = ` | |
| <div class="flex items-start justify-between mb-4"> | |
| <div class="w-12 h-12 rounded-xl ${subjectData.color} bg-gradient-to-br flex items-center justify-center"> | |
| <i data-feather="${subjectData.icon}" class="w-6 h-6"></i> | |
| </div> | |
| <span class="px-3 py-1 bg-gray-800 rounded-full text-sm font-medium"> | |
| ${chaptersCount} ${chaptersCount === 1 ? 'Chapter' : 'Chapters'} | |
| </span> | |
| </div> | |
| <h3 class="text-xl font-bold mb-2">${subjectName}</h3> | |
| <p class="text-gray-400 text-sm mb-4">${subjectData.description}</p> | |
| <div class="mb-4"> | |
| <div class="flex justify-between text-sm mb-1"> | |
| <span>Progress</span> | |
| <span class="font-semibold">${progressPercentage}%</span> | |
| </div> | |
| <div class="h-2 bg-gray-800 rounded-full overflow-hidden"> | |
| <div class="h-full ${subjectData.color} bg-gradient-to-r rounded-full" | |
| style="width: ${progressPercentage}%"></div> | |
| </div> | |
| </div> | |
| <div class="flex justify-between items-center"> | |
| <span class="text-sm text-gray-400"> | |
| ${subjectData.totalLessons || '12'} lessons | |
| </span> | |
| <a href="subject.html?subject=${encodeURIComponent(subjectName)}" | |
| class="btn-primary text-sm px-4 py-2"> | |
| Start Learning | |
| </a> | |
| </div> | |
| `; | |
| container.appendChild(card); | |
| }); | |
| // Initialize feather icons for new cards | |
| if (window.feather) { | |
| setTimeout(() => feather.replace(), 100); | |
| } | |
| } | |
| // Create particles background | |
| function createParticles() { | |
| const container = document.querySelector('main'); | |
| if (!container || window.innerWidth < 768) return; | |
| const particlesCount = 20; | |
| for (let i = 0; i < particlesCount; i++) { | |
| const particle = document.createElement('div'); | |
| particle.className = 'absolute rounded-full'; | |
| const size = Math.random() * 4 + 1; | |
| const colors = [ | |
| 'bg-primary-400/20', | |
| 'bg-secondary-400/20', | |
| 'bg-cyan-400/20', | |
| 'bg-pink-400/20' | |
| ]; | |
| particle.classList.add(colors[Math.floor(Math.random() * colors.length)]); | |
| particle.style.width = `${size}px`; | |
| particle.style.height = `${size}px`; | |
| particle.style.left = `${Math.random() * 100}%`; | |
| particle.style.top = `${Math.random() * 100}%`; | |
| particle.style.opacity = Math.random() * 0.3 + 0.1; | |
| if (Math.random() > 0.5) { | |
| particle.classList.add('float-animation'); | |
| particle.style.animationDelay = `${Math.random() * 5}s`; | |
| particle.style.animationDuration = `${Math.random() * 10 + 10}s`; | |
| } | |
| container.appendChild(particle); | |
| } | |
| } | |
| // Initialize theme toggle | |
| function initThemeToggle() { | |
| const themeToggle = document.getElementById('theme-toggle'); | |
| if (!themeToggle) return; | |
| const savedTheme = localStorage.getItem('theme') || 'dark'; | |
| document.documentElement.classList.toggle('dark', savedTheme === 'dark'); | |
| themeToggle.innerHTML = savedTheme === 'dark' | |
| ? '<i data-feather="sun"></i>' | |
| : '<i data-feather="moon"></i>'; | |
| themeToggle.addEventListener('click', () => { | |
| const isDark = document.documentElement.classList.toggle('dark'); | |
| localStorage.setItem('theme', isDark ? 'dark' : 'light'); | |
| themeToggle.innerHTML = isDark | |
| ? '<i data-feather="sun"></i>' | |
| : '<i data-feather="moon"></i>'; | |
| if (window.feather) { | |
| feather.replace(); | |
| } | |
| }); | |
| } | |
| // Initialize when DOM is loaded | |
| document.addEventListener('DOMContentLoaded', function() { | |
| // Calculate and display stats | |
| calculateStats(); | |
| // Generate subject cards | |
| generateSubjectCards(); | |
| // Create particles | |
| createParticles(); | |
| // Initialize theme toggle | |
| initThemeToggle(); | |
| // Add typing animation to hero text | |
| const heroText = document.querySelector('.gradient-text'); | |
| if (heroText) { | |
| heroText.classList.add('gradient-text'); | |
| } | |
| // Initialize tooltips | |
| const tooltips = document.querySelectorAll('[data-tooltip]'); | |
| tooltips.forEach(element => { | |
| element.addEventListener('mouseenter', (e) => { | |
| const tooltip = document.createElement('div'); | |
| tooltip.className = 'absolute z-50 px-3 py-2 text-sm bg-gray-900 text-white rounded-lg shadow-lg'; | |
| tooltip.textContent = e.target.dataset.tooltip; | |
| document.body.appendChild(tooltip); | |
| const rect = e.target.getBoundingClientRect(); | |
| tooltip.style.top = `${rect.top - tooltip.offsetHeight - 10}px`; | |
| tooltip.style.left = `${rect.left + rect.width/2 - tooltip.offsetWidth/2}px`; | |
| e.target._tooltip = tooltip; | |
| }); | |
| element.addEventListener('mouseleave', (e) => { | |
| if (e.target._tooltip) { | |
| e.target._tooltip.remove(); | |
| } | |
| }); | |
| }); | |
| // Add scroll animations | |
| const observerOptions = { | |
| threshold: 0.1, | |
| rootMargin: '0px 0px -50px 0px' | |
| }; | |
| const observer = new IntersectionObserver((entries) => { | |
| entries.forEach(entry => { | |
| if (entry.isIntersecting) { | |
| entry.target.classList.add('fade-in-up'); | |
| } | |
| }); | |
| }, observerOptions); | |
| document.querySelectorAll('.subject-card, .feature-card').forEach(el => { | |
| observer.observe(el); | |
| }); | |
| // Update feather icons | |
| if (window.feather) { | |
| feather.replace(); | |
| } | |
| }); | |
| // Export for module usage | |
| if (typeof module !== 'undefined' && module.exports) { | |
| module.exports = { subjectsData, calculateStats, generateSubjectCards }; | |
| } | |