Mhdeusi commited on
Commit
5b43ade
·
verified ·
1 Parent(s): 13d42ba

Create lesson.js

Browse files
Files changed (1) hide show
  1. js/ui/lesson.js +271 -0
js/ui/lesson.js ADDED
@@ -0,0 +1,271 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ class LessonUI {
2
+ constructor() {
3
+ this.currentLesson = null;
4
+ this.lessonStartTime = null;
5
+ this.interactionCount = 0;
6
+ }
7
+
8
+ async render(lessonData) {
9
+ this.currentLesson = lessonData;
10
+ this.lessonStartTime = Date.now();
11
+ this.interactionCount = 0;
12
+
13
+ const lessonContent = document.getElementById('lessonContent');
14
+ if (!lessonContent) return;
15
+
16
+ let html = `
17
+ <div class="lesson-header">
18
+ <h3>${this.escapeHtml(lessonData.title)}</h3>
19
+ <div class="lesson-meta">
20
+ <span class="lesson-day">روز ${lessonData.day}</span>
21
+ <span class="lesson-duration">⏱️ حدود ${lessonData.estimated_duration || '10'} دقیقه</span>
22
+ </div>
23
+ </div>
24
+ <div class="lesson-sections">
25
+ `;
26
+
27
+ lessonData.sections.forEach((section, index) => {
28
+ html += this.renderSection(section, index);
29
+ });
30
+
31
+ html += `
32
+ </div>
33
+ <div class="lesson-actions">
34
+ <button class="btn btn-primary" onclick="lessonUI.completeLesson()">
35
+ ✅ تکمیل درس
36
+ </button>
37
+ <button class="btn btn-secondary" onclick="lessonUI.toggleBookmark()">
38
+ 📌 نشان کردن
39
+ </button>
40
+ </div>
41
+ <div class="lesson-progress">
42
+ <div class="progress-bar">
43
+ <div class="progress-fill" style="width: 0%"></div>
44
+ </div>
45
+ <span class="progress-text">0% مطالعه شده</span>
46
+ </div>
47
+ `;
48
+
49
+ lessonContent.innerHTML = html;
50
+ this.setupInteractions();
51
+ this.startProgressTracking();
52
+ }
53
+
54
+ renderSection(section, index) {
55
+ let sectionHtml = `<div class="lesson-section" data-section="${index}">`;
56
+
57
+ switch (section.type) {
58
+ case 'text':
59
+ sectionHtml += `
60
+ <div class="text-content">
61
+ ${this.formatTextContent(section.content)}
62
+ </div>
63
+ `;
64
+ break;
65
+
66
+ case 'image':
67
+ sectionHtml += `
68
+ <div class="image-content">
69
+ <img src="${section.url}" alt="${this.escapeHtml(section.alt)}" loading="lazy">
70
+ ${section.caption ? `<div class="image-caption">${this.escapeHtml(section.caption)}</div>` : ''}
71
+ </div>
72
+ `;
73
+ break;
74
+
75
+ case 'code':
76
+ sectionHtml += `
77
+ <div class="code-content">
78
+ <pre><code class="language-${section.language || 'html'}">${this.escapeHtml(section.code)}</code></pre>
79
+ ${section.explanation ? `<div class="code-explanation">${this.formatTextContent(section.explanation)}</div>` : ''}
80
+ </div>
81
+ `;
82
+ break;
83
+
84
+ case 'video':
85
+ sectionHtml += `
86
+ <div class="video-content">
87
+ <div class="video-placeholder">
88
+ 🎥 محتوای ویدئویی: ${this.escapeHtml(section.title)}
89
+ </div>
90
+ ${section.description ? `<div class="video-description">${this.formatTextContent(section.description)}</div>` : ''}
91
+ </div>
92
+ `;
93
+ break;
94
+
95
+ default:
96
+ sectionHtml += `<div class="unknown-content">نوع محتوای ناشناخته</div>`;
97
+ }
98
+
99
+ sectionHtml += `</div>`;
100
+ return sectionHtml;
101
+ }
102
+
103
+ formatTextContent(content) {
104
+ // تبدیل مارک‌داون ساده به HTML
105
+ return content
106
+ .replace(/\*\*(.*?)\*\*/g, '<strong>$1</strong>')
107
+ .replace(/\*(.*?)\*/g, '<em>$1</em>')
108
+ .replace(/`(.*?)`/g, '<code>$1</code>')
109
+ .replace(/\n/g, '<br>');
110
+ }
111
+
112
+ escapeHtml(unsafe) {
113
+ return unsafe
114
+ .replace(/&/g, "&amp;")
115
+ .replace(/</g, "&lt;")
116
+ .replace(/>/g, "&gt;")
117
+ .replace(/"/g, "&quot;")
118
+ .replace(/'/g, "&#039;");
119
+ }
120
+
121
+ setupInteractions() {
122
+ // ردیابی اسکرول برای پیشرفت
123
+ let scrollTimeout;
124
+ const lessonSections = document.querySelector('.lesson-sections');
125
+
126
+ if (lessonSections) {
127
+ lessonSections.addEventListener('scroll', () => {
128
+ clearTimeout(scrollTimeout);
129
+ scrollTimeout = setTimeout(() => {
130
+ this.trackInteraction('scroll');
131
+ this.updateProgress();
132
+ }, 100);
133
+ });
134
+ }
135
+
136
+ // ردیابی کلیک
137
+ document.addEventListener('click', (e) => {
138
+ if (e.target.closest('.lesson-section')) {
139
+ this.trackInteraction('click');
140
+ }
141
+ });
142
+ }
143
+
144
+ startProgressTracking() {
145
+ this.progressInterval = setInterval(() => {
146
+ this.updateProgress();
147
+ }, 2000);
148
+ }
149
+
150
+ updateProgress() {
151
+ const sections = document.querySelectorAll('.lesson-section');
152
+ const lessonSections = document.querySelector('.lesson-sections');
153
+
154
+ if (!sections.length || !lessonSections) return;
155
+
156
+ let visibleSections = 0;
157
+ const containerRect = lessonSections.getBoundingClientRect();
158
+
159
+ sections.forEach(section => {
160
+ const rect = section.getBoundingClientRect();
161
+ if (rect.top >= containerRect.top && rect.bottom <= containerRect.bottom) {
162
+ visibleSections++;
163
+ }
164
+ });
165
+
166
+ const progress = (visibleSections / sections.length) * 100;
167
+ this.updateProgressBar(progress);
168
+ }
169
+
170
+ updateProgressBar(progress) {
171
+ const progressFill = document.querySelector('.progress-fill');
172
+ const progressText = document.querySelector('.progress-text');
173
+
174
+ if (progressFill && progressText) {
175
+ progressFill.style.width = `${progress}%`;
176
+ progressText.textContent = `${Math.round(progress)}% مطالعه شده`;
177
+ }
178
+ }
179
+
180
+ trackInteraction(type) {
181
+ this.interactionCount++;
182
+
183
+ // ذخیره تعاملات مهم
184
+ const interactions = Utils.loadFromLocalStorage('lesson_interactions') || {};
185
+ const lessonId = this.currentLesson?.day;
186
+
187
+ if (lessonId) {
188
+ if (!interactions[lessonId]) {
189
+ interactions[lessonId] = [];
190
+ }
191
+ interactions[lessonId].push({
192
+ type: type,
193
+ timestamp: new Date().toISOString()
194
+ });
195
+
196
+ Utils.saveToLocalStorage('lesson_interactions', interactions);
197
+ }
198
+ }
199
+
200
+ async completeLesson() {
201
+ if (!this.currentLesson) return;
202
+
203
+ const duration = Math.round((Date.now() - this.lessonStartTime) / 1000 / 60); // دقیقه
204
+ const result = learningLogic.completeLesson(
205
+ this.currentLesson.day,
206
+ duration,
207
+ this.interactionCount
208
+ );
209
+
210
+ // نمایش نتیجه
211
+ Utils.showNotification(
212
+ `درس تکمیل شد! 🎉 ${result.reward} امتیاز دریافت کردید.`,
213
+ 'success'
214
+ );
215
+
216
+ // به‌روزرسانی UI
217
+ this.updateProgressBar(100);
218
+
219
+ // غیرفعال کردن دکمه
220
+ const completeBtn = document.querySelector('.lesson-actions .btn-primary');
221
+ if (completeBtn) {
222
+ completeBtn.disabled = true;
223
+ completeBtn.textContent = '✅ تکمیل شده';
224
+ }
225
+
226
+ // ارسال event برای به‌روزرسانی سایر بخش‌ها
227
+ document.dispatchEvent(new CustomEvent('lessonCompleted', {
228
+ detail: {
229
+ lesson: this.currentLesson,
230
+ reward: result.reward,
231
+ duration: duration
232
+ }
233
+ }));
234
+ }
235
+
236
+ toggleBookmark() {
237
+ if (!this.currentLesson) return;
238
+
239
+ const bookmarks = Utils.loadFromLocalStorage('bookmarked_lessons') || [];
240
+ const lessonId = this.currentLesson.day;
241
+ const index = bookmarks.indexOf(lessonId);
242
+
243
+ let isBookmarked;
244
+ if (index > -1) {
245
+ bookmarks.splice(index, 1);
246
+ isBookmarked = false;
247
+ Utils.showNotification('نشان درس حذف شد', 'info');
248
+ } else {
249
+ bookmarks.push(lessonId);
250
+ isBookmarked = true;
251
+ Utils.showNotification('درس نشان شده', 'success');
252
+ }
253
+
254
+ Utils.saveToLocalStorage('bookmarked_lessons', bookmarks);
255
+
256
+ // به‌روزرسانی دکمه
257
+ const bookmarkBtn = document.querySelector('.lesson-actions .btn-secondary');
258
+ if (bookmarkBtn) {
259
+ bookmarkBtn.innerHTML = isBookmarked ? '📌 نشان شده' : '📌 نشان کردن';
260
+ }
261
+ }
262
+
263
+ destroy() {
264
+ if (this.progressInterval) {
265
+ clearInterval(this.progressInterval);
266
+ }
267
+ }
268
+ }
269
+
270
+ // ایجاد نمونه اصلی
271
+ const lessonUI = new LessonUI();