| class LearningPlatform { |
| constructor() { |
| this.currentDay = 1; |
| this.maxDays = 10; |
| this.isInitialized = false; |
| this.components = {}; |
| } |
|
|
| async initialize() { |
| try { |
| console.log('🚀 Initializing Learning Platform...'); |
| |
| |
| this.initializeAuth(); |
| |
| |
| this.loadComponents(); |
| |
| |
| this.setupEventListeners(); |
| |
| |
| await this.loadInitialContent(); |
| |
| |
| this.updateUI(); |
| |
| this.isInitialized = true; |
| console.log('✅ Platform initialized successfully'); |
| |
| } catch (error) { |
| console.error('❌ Failed to initialize platform:', error); |
| this.showError('خطا در بارگذاری برنامه. لطفاً صفحه را رفرش کنید.'); |
| } |
| } |
|
|
| initializeAuth() { |
| |
| if (typeof AuthMiddleware !== 'undefined') { |
| AuthMiddleware.initializeApp(); |
| } |
| |
| |
| const savedTheme = localStorage.getItem('theme'); |
| if (savedTheme) { |
| document.body.setAttribute('data-theme', savedTheme); |
| } |
| } |
|
|
| loadComponents() { |
| |
| this.components = { |
| header: typeof HeaderComponent !== 'undefined' ? HeaderComponent : null, |
| modal: typeof ModalComponent !== 'undefined' ? ModalComponent : null, |
| navigation: typeof NavigationComponent !== 'undefined' ? NavigationComponent : null, |
| lessonUI: typeof LessonUI !== 'undefined' ? new LessonUI() : null, |
| quizUI: typeof QuizUI !== 'undefined' ? new QuizUI() : null, |
| exerciseUI: typeof ExerciseUI !== 'undefined' ? new ExerciseUI() : null |
| }; |
|
|
| |
| if (this.components.header) { |
| this.components.header.render(); |
| } |
| |
| if (this.components.navigation) { |
| this.components.navigation.render(); |
| } |
| } |
|
|
| setupEventListeners() { |
| |
| document.addEventListener('dayChanged', (event) => { |
| this.handleDayChange(event.detail.day); |
| }); |
|
|
| |
| document.addEventListener('authStateChanged', () => { |
| this.handleAuthStateChange(); |
| }); |
|
|
| |
| document.addEventListener('lessonCompleted', (event) => { |
| this.handleLessonCompleted(event.detail); |
| }); |
|
|
| |
| document.addEventListener('exerciseSubmitted', (event) => { |
| this.handleExerciseSubmitted(event.detail); |
| }); |
|
|
| |
| document.addEventListener('progressUpdated', () => { |
| this.handleProgressUpdate(); |
| }); |
|
|
| |
| document.addEventListener('submit', (e) => { |
| if (e.target.tagName === 'FORM') { |
| e.preventDefault(); |
| } |
| }); |
|
|
| |
| window.addEventListener('error', (event) => { |
| console.error('Global error:', event.error); |
| this.showError('خطای غیرمنتظره رخ داد'); |
| }); |
|
|
| |
| window.addEventListener('unhandledrejection', (event) => { |
| console.error('Unhandled promise rejection:', event.reason); |
| this.showError('خطای سیستمی رخ داد'); |
| }); |
| } |
|
|
| async loadInitialContent() { |
| |
| this.showLoadingState(); |
|
|
| |
| await Promise.all([ |
| this.loadLesson(), |
| this.loadQuiz(), |
| this.loadExercise() |
| ]); |
|
|
| |
| this.hideLoadingState(); |
| } |
|
|
| async loadLesson() { |
| try { |
| const lessonData = await learningLogic.loadLesson(this.currentDay); |
| if (lessonData && this.components.lessonUI) { |
| await this.components.lessonUI.render(lessonData); |
| } else { |
| this.showContentError('lessonContent', 'خطا در بارگذاری محتوای آموزشی'); |
| } |
| } catch (error) { |
| console.error('Error loading lesson:', error); |
| this.showContentError('lessonContent', 'خطا در بارگذاری درس'); |
| } |
| } |
|
|
| async loadQuiz() { |
| try { |
| const quizData = await learningLogic.loadQuiz(this.currentDay); |
| if (quizData && typeof QuizUI !== 'undefined') { |
| QuizUI.render(quizData); |
| } else { |
| this.showContentError('quizForm', 'خطا در بارگذاری آزمون'); |
| } |
| } catch (error) { |
| console.error('Error loading quiz:', error); |
| this.showContentError('quizForm', 'خطا در بارگذاری آزمون'); |
| } |
| } |
|
|
| async loadExercise() { |
| try { |
| const exerciseData = await learningLogic.loadExercise(this.currentDay); |
| if (exerciseData && this.components.exerciseUI) { |
| await this.components.exerciseUI.render(exerciseData); |
| } else { |
| this.showContentError('exerciseContent', 'خطا در بارگذاری تمرین'); |
| } |
| } catch (error) { |
| console.error('Error loading exercise:', error); |
| this.showContentError('exerciseContent', 'خطا در بارگذاری تمرین'); |
| } |
| } |
|
|
| async handleDayChange(newDay) { |
| if (newDay < 1 || newDay > this.maxDays) { |
| console.warn('Invalid day number:', newDay); |
| return; |
| } |
|
|
| this.currentDay = newDay; |
| |
| |
| this.showLoadingState(); |
|
|
| |
| await Promise.all([ |
| this.loadLesson(), |
| this.loadQuiz(), |
| this.loadExercise() |
| ]); |
|
|
| |
| this.updateNavigation(); |
|
|
| |
| this.hideLoadingState(); |
|
|
| |
| window.scrollTo({ top: 0, behavior: 'smooth' }); |
|
|
| console.log(`📅 Changed to day ${this.currentDay}`); |
| } |
|
|
| handleAuthStateChange() { |
| this.updateAuthDisplay(); |
| this.updateProgressDisplay(); |
| |
| if (this.components.header) { |
| this.components.header.updateStats(); |
| } |
| } |
|
|
| handleLessonCompleted(detail) { |
| console.log('📚 Lesson completed:', detail); |
| this.updateProgressDisplay(); |
| |
| |
| if (detail.reward > 0) { |
| Utils.showNotification( |
| `🎉 درس تکمیل شد! ${detail.reward} امتیاز دریافت کردید.`, |
| 'success' |
| ); |
| } |
| } |
|
|
| handleExerciseSubmitted(detail) { |
| console.log('✏️ Exercise submitted:', detail); |
| this.updateProgressDisplay(); |
| |
| |
| if (detail.result.reward > 0) { |
| Utils.showNotification( |
| `🎯 تمرین ارسال شد! ${detail.result.reward} امتیاز دریافت کردید.`, |
| 'success' |
| ); |
| } |
| } |
|
|
| handleProgressUpdate() { |
| this.updateProgressDisplay(); |
| |
| if (this.components.header) { |
| this.components.header.updateStats(); |
| } |
| } |
|
|
| updateUI() { |
| this.updateAuthDisplay(); |
| this.updateProgressDisplay(); |
| this.updateNavigation(); |
| } |
|
|
| updateAuthDisplay() { |
| const authSection = document.getElementById('authSection'); |
| if (!authSection) return; |
|
|
| const user = authManager.getCurrentUser(); |
| |
| if (user) { |
| authSection.innerHTML = ` |
| <div class="user-welcome"> |
| <div class="user-avatar"> |
| ${user.profile.fullName ? user.profile.fullName.charAt(0) : user.username.charAt(0)} |
| </div> |
| <div class="user-info"> |
| <span class="welcome-text">خوش آمدید, ${user.profile.fullName || user.username}!</span> |
| <span class="user-role">${this.getRoleText(user.role)}</span> |
| </div> |
| <button onclick="app.logout()" class="btn btn-outline">خروج</button> |
| </div> |
| `; |
| } else { |
| authSection.innerHTML = ` |
| <div class="auth-actions"> |
| <p>برای ذخیره پیشرفت و شرکت در آزمونها وارد شوید</p> |
| <div class="auth-buttons"> |
| <button onclick="app.showLogin()" class="btn btn-primary">ورود</button> |
| <button onclick="app.showRegister()" class="btn btn-secondary">ثبت نام</button> |
| </div> |
| </div> |
| `; |
| } |
| } |
|
|
| updateProgressDisplay() { |
| const progressContent = document.getElementById('progressContent'); |
| if (!progressContent) return; |
|
|
| const user = authManager.getCurrentUser(); |
| const stats = learningLogic.getUserStats(); |
| |
| if (user) { |
| progressContent.innerHTML = ` |
| <div class="progress-stats"> |
| <div class="stat-card"> |
| <div class="stat-value">${stats.level}</div> |
| <div class="stat-label">سطح</div> |
| <div class="stat-subtitle">${stats.rank}</div> |
| </div> |
| <div class="stat-card"> |
| <div class="stat-value">${Utils.formatNumber(stats.totalScore)}</div> |
| <div class="stat-label">امتیاز کل</div> |
| </div> |
| <div class="stat-card"> |
| <div class="stat-value">${stats.streak}</div> |
| <div class="stat-label">روز متوالی</div> |
| </div> |
| <div class="stat-card"> |
| <div class="stat-value">${stats.accuracy}%</div> |
| <div class="stat-label">دقت پاسخها</div> |
| </div> |
| </div> |
| |
| <div class="progress-details"> |
| <div class="detail-item"> |
| <span class="detail-label">📚 درسهای تکمیل شده:</span> |
| <span class="detail-value">${stats.completedLessons} از ${this.maxDays}</span> |
| </div> |
| <div class="detail-item"> |
| <span class="detail-label">❓ آزمونهای انجام شده:</span> |
| <span class="detail-value">${stats.completedQuizzes}</span> |
| </div> |
| <div class="detail-item"> |
| <span class="detail-label">✏️ تمرینهای ارسال شده:</span> |
| <span class="detail-value">${stats.completedExercises}</span> |
| </div> |
| <div class="detail-item"> |
| <span class="detail-label">🏆 دستاوردها:</span> |
| <span class="detail-value">${stats.achievements} مورد</span> |
| </div> |
| </div> |
| |
| ${stats.achievements > 0 ? ` |
| <div class="achievements-preview"> |
| <h4>🎖️ دستاوردهای اخیر</h4> |
| <div class="achievements-list"> |
| ${this.renderAchievementsPreview(stats.achievements)} |
| </div> |
| </div> |
| ` : ''} |
| `; |
| } else { |
| progressContent.innerHTML = ` |
| <div class="guest-progress"> |
| <div class="guest-message"> |
| <h4>👋 به پلتفرم آموزشی خوش آمدید!</h4> |
| <p>برای شروع یادگیری و ذخیره پیشرفت خود، لطفاً وارد شوید یا ثبت نام کنید.</p> |
| <div class="guest-stats"> |
| <div class="stat-card"> |
| <div class="stat-value">${this.maxDays}</div> |
| <div class="stat-label">درس موجود</div> |
| </div> |
| <div class="stat-card"> |
| <div class="stat-value">${this.maxDays * 3}</div> |
| <div class="stat-label">تمرین عملی</div> |
| </div> |
| <div class="stat-card"> |
| <div class="stat-value">${this.maxDays}</div> |
| <div class="stat-label">آزمون کوتاه</div> |
| </div> |
| </div> |
| </div> |
| </div> |
| `; |
| } |
| } |
|
|
| updateNavigation() { |
| const progressIndicator = document.getElementById('progressIndicator'); |
| if (progressIndicator && this.components.navigation) { |
| progressIndicator.innerHTML = this.components.navigation.createDayNavigation( |
| this.currentDay, |
| this.maxDays |
| ); |
| } |
| } |
|
|
| renderAchievementsPreview(achievementCount) { |
| const achievements = [ |
| { id: 'first_lesson', name: 'اولین درس', icon: '📖' }, |
| { id: 'quiz_master', name: 'استاد آزمون', icon: '❓' }, |
| { id: 'exercise_pro', name: 'حرفهای تمرین', icon: '✏️' }, |
| { id: 'week_streak', name: 'یک هفته متوالی', icon: '🔥' } |
| ]; |
| |
| return achievements.slice(0, Math.min(achievementCount, 3)) |
| .map(achievement => ` |
| <div class="achievement-badge"> |
| <span class="achievement-icon">${achievement.icon}</span> |
| <span class="achievement-name">${achievement.name}</span> |
| </div> |
| `).join(''); |
| } |
|
|
| getRoleText(role) { |
| const roles = { |
| 'student': 'دانشجو', |
| 'instructor': 'مربی', |
| 'admin': 'مدیر' |
| }; |
| return roles[role] || role; |
| } |
|
|
| showLoadingState() { |
| |
| const sections = ['lessonContent', 'quizForm', 'exerciseContent']; |
| sections.forEach(sectionId => { |
| const element = document.getElementById(sectionId); |
| if (element) { |
| element.classList.add('loading'); |
| } |
| }); |
| } |
|
|
| hideLoadingState() { |
| const sections = ['lessonContent', 'quizForm', 'exerciseContent']; |
| sections.forEach(sectionId => { |
| const element = document.getElementById(sectionId); |
| if (element) { |
| element.classList.remove('loading'); |
| } |
| }); |
| } |
|
|
| showContentError(elementId, message) { |
| const element = document.getElementById(elementId); |
| if (element) { |
| element.innerHTML = ` |
| <div class="error-state"> |
| <div class="error-icon">⚠️</div> |
| <div class="error-message">${message}</div> |
| <button onclick="app.retryLoading()" class="btn btn-outline"> |
| 🔄 تلاش مجدد |
| </button> |
| </div> |
| `; |
| } |
| } |
|
|
| |
| showLogin() { |
| if (this.components.modal) { |
| this.components.modal.showLogin(); |
| } else { |
| window.location.href = 'login.html'; |
| } |
| } |
|
|
| showRegister() { |
| if (this.components.modal) { |
| this.components.modal.showRegister(); |
| } else { |
| window.location.href = 'register.html'; |
| } |
| } |
|
|
| logout() { |
| authManager.logout(); |
| this.handleAuthStateChange(); |
| Utils.showNotification('با موفقیت از سیستم خارج شدید.', 'info'); |
| } |
|
|
| nextDay() { |
| if (this.currentDay < this.maxDays) { |
| this.currentDay++; |
| document.dispatchEvent(new CustomEvent('dayChanged', { |
| detail: { day: this.currentDay } |
| })); |
| } |
| } |
|
|
| previousDay() { |
| if (this.currentDay > 1) { |
| this.currentDay--; |
| document.dispatchEvent(new CustomEvent('dayChanged', { |
| detail: { day: this.currentDay } |
| })); |
| } |
| } |
|
|
| async retryLoading() { |
| await this.loadInitialContent(); |
| } |
|
|
| showError(message) { |
| if (this.components.modal) { |
| this.components.modal.showError(message); |
| } else { |
| alert(message); |
| } |
| } |
|
|
| showSuccess(message) { |
| if (this.components.modal) { |
| this.components.modal.showSuccess(message); |
| } else { |
| alert(message); |
| } |
| } |
|
|
| |
| getCurrentUser() { |
| return authManager.getCurrentUser(); |
| } |
|
|
| getUserStats() { |
| return learningLogic.getUserStats(); |
| } |
|
|
| |
| destroy() { |
| if (this.components.lessonUI) { |
| this.components.lessonUI.destroy(); |
| } |
| |
| |
| console.log('🧹 Platform destroyed'); |
| } |
| } |
|
|
| |
| const app = new LearningPlatform(); |
|
|
| |
| window.app = app; |
|
|
| |
| document.addEventListener('DOMContentLoaded', () => { |
| app.initialize(); |
| }); |
|
|
| |
| window.addEventListener('beforeunload', () => { |
| app.destroy(); |
| }); |