edusphere-navigator / script.js
tokey4's picture
make the website much better
41650cf verified
// 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 };
}