@learnmd/core 0.0.1-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +30 -0
  3. package/dist/components/LearnMDProvider.d.ts +33 -0
  4. package/dist/components/LearnMDProvider.d.ts.map +1 -0
  5. package/dist/components/LearnMDProvider.js +16 -0
  6. package/dist/components/LearnMDProvider.js.map +1 -0
  7. package/dist/gamification/index.d.ts +77 -0
  8. package/dist/gamification/index.d.ts.map +1 -0
  9. package/dist/gamification/index.js +402 -0
  10. package/dist/gamification/index.js.map +1 -0
  11. package/dist/i18n/index.d.ts +119 -0
  12. package/dist/i18n/index.d.ts.map +1 -0
  13. package/dist/i18n/index.js +261 -0
  14. package/dist/i18n/index.js.map +1 -0
  15. package/dist/index.d.ts +81 -0
  16. package/dist/index.d.ts.map +1 -0
  17. package/dist/index.js +77 -0
  18. package/dist/index.js.map +1 -0
  19. package/dist/parser/index.d.ts +57 -0
  20. package/dist/parser/index.d.ts.map +1 -0
  21. package/dist/parser/index.js +182 -0
  22. package/dist/parser/index.js.map +1 -0
  23. package/dist/plugins/index.d.ts +150 -0
  24. package/dist/plugins/index.d.ts.map +1 -0
  25. package/dist/plugins/index.js +291 -0
  26. package/dist/plugins/index.js.map +1 -0
  27. package/dist/plugins/pdf/index.d.ts +8 -0
  28. package/dist/plugins/pdf/index.d.ts.map +1 -0
  29. package/dist/plugins/pdf/index.js +53 -0
  30. package/dist/plugins/pdf/index.js.map +1 -0
  31. package/dist/router/index.d.ts +111 -0
  32. package/dist/router/index.d.ts.map +1 -0
  33. package/dist/router/index.js +268 -0
  34. package/dist/router/index.js.map +1 -0
  35. package/dist/storage/index.d.ts +110 -0
  36. package/dist/storage/index.d.ts.map +1 -0
  37. package/dist/storage/index.js +390 -0
  38. package/dist/storage/index.js.map +1 -0
  39. package/dist/types/index.d.ts +283 -0
  40. package/dist/types/index.d.ts.map +1 -0
  41. package/dist/types/index.js +2 -0
  42. package/dist/types/index.js.map +1 -0
  43. package/package.json +73 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 LearnMD Contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,30 @@
1
+ # 🏗️ @learnmd/core
2
+
3
+ The heart of the LearnMD engine. This package contains the fundamental logic for parsing, internationalization, storage, and state management.
4
+
5
+ ## 📦 Features
6
+
7
+ - **MDX Integration**: Seamlessly bridges Markdown content with React components.
8
+ - **i18n Engine**: Handles paragraph-level translations and language persistence.
9
+ - **Storage Adapter**: Flexible persistence layer for progress tracking (LocalStorage, etc).
10
+ - **Gamification**: Logic for points, badges, and achievement criteria.
11
+ - **Router**: Managed navigation between modules and lessons.
12
+
13
+ ## 🛠️ Usage
14
+
15
+ ```typescript
16
+ import { defineConfig, createLearnMD } from '@learnmd/core';
17
+
18
+ export const config = defineConfig({
19
+ title: 'My Awesome Course',
20
+ defaultLanguage: 'en',
21
+ // ...
22
+ });
23
+ ```
24
+
25
+ ## 🏗️ Architecture
26
+
27
+ - `/parser`: Logic for handling MDX transformations.
28
+ - `/i18n`: The translation manager.
29
+ - `/storage`: Progress persistence adapters.
30
+ - `/types`: Comprehensive TypeScript definitions for courses, lessons, and metrics.
@@ -0,0 +1,33 @@
1
+ import React from 'react';
2
+ import { LearnMDConfig } from '../index.js';
3
+ export declare const LearnMDContext: React.Context<{
4
+ i18n: import("../index.js").I18nManager;
5
+ storage: import("../index.js").StorageManager;
6
+ gamification: import("../index.js").GamificationManager | null;
7
+ router: import("../index.js").RouterManager;
8
+ config: {
9
+ defaultLanguage: string;
10
+ basePath: string;
11
+ storagePrefix: string;
12
+ enableGamification: boolean;
13
+ enableAnalytics: boolean;
14
+ };
15
+ } | null>;
16
+ export declare function useLearnMD(): {
17
+ i18n: import("../index.js").I18nManager;
18
+ storage: import("../index.js").StorageManager;
19
+ gamification: import("../index.js").GamificationManager | null;
20
+ router: import("../index.js").RouterManager;
21
+ config: {
22
+ defaultLanguage: string;
23
+ basePath: string;
24
+ storagePrefix: string;
25
+ enableGamification: boolean;
26
+ enableAnalytics: boolean;
27
+ };
28
+ };
29
+ export declare function LearnMDProvider({ config, children }: {
30
+ config: LearnMDConfig;
31
+ children: React.ReactNode;
32
+ }): import("react/jsx-runtime").JSX.Element;
33
+ //# sourceMappingURL=LearnMDProvider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LearnMDProvider.d.ts","sourceRoot":"","sources":["../../src/components/LearnMDProvider.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA6C,MAAM,OAAO,CAAC;AAClE,OAAO,EAAiB,aAAa,EAAE,MAAM,aAAa,CAAC;AAE3D,eAAO,MAAM,cAAc;;;;;;;;;;;;SAA+D,CAAC;AAE3F,wBAAgB,UAAU;;;;;;;;;;;;EAMzB;AAED,wBAAgB,eAAe,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE;IAAE,MAAM,EAAE,aAAa,CAAC;IAAC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;CAAE,2CAIzG"}
@@ -0,0 +1,16 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { createContext, useContext, useMemo } from 'react';
3
+ import { createLearnMD } from '../index.js';
4
+ export const LearnMDContext = createContext(null);
5
+ export function useLearnMD() {
6
+ const context = useContext(LearnMDContext);
7
+ if (!context) {
8
+ throw new Error('useLearnMD must be used within a LearnMDProvider');
9
+ }
10
+ return context;
11
+ }
12
+ export function LearnMDProvider({ config, children }) {
13
+ const learnmd = useMemo(() => createLearnMD(config), [config]);
14
+ return _jsx(LearnMDContext.Provider, { value: learnmd, children: children });
15
+ }
16
+ //# sourceMappingURL=LearnMDProvider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LearnMDProvider.js","sourceRoot":"","sources":["../../src/components/LearnMDProvider.tsx"],"names":[],"mappings":";AAAA,OAAc,EAAE,aAAa,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAClE,OAAO,EAAE,aAAa,EAAiB,MAAM,aAAa,CAAC;AAE3D,MAAM,CAAC,MAAM,cAAc,GAAG,aAAa,CAA0C,IAAI,CAAC,CAAC;AAE3F,MAAM,UAAU,UAAU;IACxB,MAAM,OAAO,GAAG,UAAU,CAAC,cAAc,CAAC,CAAC;IAC3C,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAC;IACtE,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAwD;IACxG,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,aAAa,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;IAE/D,OAAO,KAAC,cAAc,CAAC,QAAQ,IAAC,KAAK,EAAE,OAAO,YAAG,QAAQ,GAA2B,CAAC;AACvF,CAAC"}
@@ -0,0 +1,77 @@
1
+ import type { Badge, Achievement, UserProfile, CourseProgress, LessonProgress } from '../types';
2
+ /**
3
+ * Default badges configuration
4
+ */
5
+ export declare const DEFAULT_BADGES: Omit<Badge, 'earnedAt' | 'courseId'>[];
6
+ /**
7
+ * Default achievements configuration
8
+ */
9
+ export declare const DEFAULT_ACHIEVEMENTS: Omit<Achievement, 'unlockedAt'>[];
10
+ /**
11
+ * Points configuration
12
+ */
13
+ export declare const POINTS_CONFIG: {
14
+ lessonCompleted: number;
15
+ quizPassed: number;
16
+ quizPerfectScore: number;
17
+ dailyBonus: number;
18
+ streakBonus: {
19
+ 7: number;
20
+ 30: number;
21
+ 100: number;
22
+ };
23
+ };
24
+ /**
25
+ * Gamification manager
26
+ */
27
+ export declare class GamificationManager {
28
+ private readonly badges;
29
+ private readonly achievements;
30
+ private readonly pointsConfig;
31
+ constructor();
32
+ /**
33
+ * Register a custom badge
34
+ */
35
+ registerBadge(badge: Omit<Badge, 'earnedAt' | 'courseId'>): void;
36
+ /**
37
+ * Register a custom achievement
38
+ */
39
+ registerAchievement(achievement: Omit<Achievement, 'unlockedAt'>): void;
40
+ /**
41
+ * Calculate points for lesson completion
42
+ */
43
+ calculateLessonPoints(quizScore?: number, quizPassed?: boolean): number;
44
+ /**
45
+ * Check and award badges for lesson completion
46
+ */
47
+ checkBadges(progress: CourseProgress, lessonProgress: LessonProgress, userProfile: UserProfile): Badge[];
48
+ /**
49
+ * Check and award achievements
50
+ */
51
+ checkAchievements(userProfile: UserProfile): Achievement[];
52
+ /**
53
+ * Update user streak
54
+ */
55
+ updateStreak(userProfile: UserProfile): UserProfile;
56
+ /**
57
+ * Get all available badges
58
+ */
59
+ getAllBadges(): Omit<Badge, 'earnedAt' | 'courseId'>[];
60
+ /**
61
+ * Get all available achievements
62
+ */
63
+ getAllAchievements(): Omit<Achievement, 'unlockedAt'>[];
64
+ /**
65
+ * Get badge by ID
66
+ */
67
+ getBadge(id: string): Omit<Badge, 'earnedAt' | 'courseId'> | undefined;
68
+ /**
69
+ * Get achievement by ID
70
+ */
71
+ getAchievement(id: string): Omit<Achievement, 'unlockedAt'> | undefined;
72
+ }
73
+ /**
74
+ * Create gamification manager instance
75
+ */
76
+ export declare function createGamificationManager(): GamificationManager;
77
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/gamification/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAEhG;;GAEG;AACH,eAAO,MAAM,cAAc,EAAE,IAAI,CAAC,KAAK,EAAE,UAAU,GAAG,UAAU,CAAC,EAyEhE,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,oBAAoB,EAAE,IAAI,CAAC,WAAW,EAAE,YAAY,CAAC,EAyEjE,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,aAAa;;;;;;;;;;CAUzB,CAAC;AAEF;;GAEG;AACH,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAoD;IAC3E,OAAO,CAAC,QAAQ,CAAC,YAAY,CAA+C;IAC5E,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAuB;;IAQpD;;OAEG;IACH,aAAa,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,UAAU,GAAG,UAAU,CAAC,GAAG,IAAI;IAIhE;;OAEG;IACH,mBAAmB,CAAC,WAAW,EAAE,IAAI,CAAC,WAAW,EAAE,YAAY,CAAC,GAAG,IAAI;IAIvE;;OAEG;IACH,qBAAqB,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,OAAO,GAAG,MAAM;IAcvE;;OAEG;IACH,WAAW,CACT,QAAQ,EAAE,cAAc,EACxB,cAAc,EAAE,cAAc,EAC9B,WAAW,EAAE,WAAW,GACvB,KAAK,EAAE;IAgFV;;OAEG;IACH,iBAAiB,CAAC,WAAW,EAAE,WAAW,GAAG,WAAW,EAAE;IAkE1D;;OAEG;IACH,YAAY,CAAC,WAAW,EAAE,WAAW,GAAG,WAAW;IA2CnD;;OAEG;IACH,YAAY,IAAI,IAAI,CAAC,KAAK,EAAE,UAAU,GAAG,UAAU,CAAC,EAAE;IAItD;;OAEG;IACH,kBAAkB,IAAI,IAAI,CAAC,WAAW,EAAE,YAAY,CAAC,EAAE;IAIvD;;OAEG;IACH,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC,KAAK,EAAE,UAAU,GAAG,UAAU,CAAC,GAAG,SAAS;IAItE;;OAEG;IACH,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC,WAAW,EAAE,YAAY,CAAC,GAAG,SAAS;CAGxE;AAED;;GAEG;AACH,wBAAgB,yBAAyB,IAAI,mBAAmB,CAE/D"}
@@ -0,0 +1,402 @@
1
+ /**
2
+ * Default badges configuration
3
+ */
4
+ export const DEFAULT_BADGES = [
5
+ {
6
+ id: 'first-lesson',
7
+ name: { en: 'First Steps', es: 'Primeros Pasos' },
8
+ description: {
9
+ en: 'Complete your first lesson',
10
+ es: 'Completa tu primera lección',
11
+ },
12
+ icon: '🎯',
13
+ },
14
+ {
15
+ id: 'quick-learner',
16
+ name: { en: 'Quick Learner', es: 'Aprendiz Rápido' },
17
+ description: {
18
+ en: 'Complete 5 lessons in one day',
19
+ es: 'Completa 5 lecciones en un día',
20
+ },
21
+ icon: '⚡',
22
+ },
23
+ {
24
+ id: ' perfectionist',
25
+ name: { en: 'Perfectionist', es: 'Perfeccionista' },
26
+ description: {
27
+ en: 'Get 100% on a quiz',
28
+ es: 'Obtén 100% en un quiz',
29
+ },
30
+ icon: '💯',
31
+ },
32
+ {
33
+ id: 'course-complete',
34
+ name: { en: 'Course Complete', es: 'Curso Completado' },
35
+ description: {
36
+ en: 'Complete an entire course',
37
+ es: 'Completa un curso entero',
38
+ },
39
+ icon: '🎓',
40
+ },
41
+ {
42
+ id: 'week-streak',
43
+ name: { en: 'Week Warrior', es: 'Guerrero Semanal' },
44
+ description: {
45
+ en: 'Maintain a 7-day streak',
46
+ es: 'Mantén una racha de 7 días',
47
+ },
48
+ icon: '🔥',
49
+ },
50
+ {
51
+ id: 'month-streak',
52
+ name: { en: 'Monthly Master', es: 'Maestro Mensual' },
53
+ description: {
54
+ en: 'Maintain a 30-day streak',
55
+ es: 'Mantén una racha de 30 días',
56
+ },
57
+ icon: '👑',
58
+ },
59
+ {
60
+ id: 'knowledge-seeker',
61
+ name: { en: 'Knowledge Seeker', es: 'Buscador de Conocimiento' },
62
+ description: {
63
+ en: 'Complete 10 lessons',
64
+ es: 'Completa 10 lecciones',
65
+ },
66
+ icon: '📚',
67
+ },
68
+ {
69
+ id: 'scholar',
70
+ name: { en: 'Scholar', es: 'Erudito' },
71
+ description: {
72
+ en: 'Complete 50 lessons',
73
+ es: 'Completa 50 lecciones',
74
+ },
75
+ icon: '🏆',
76
+ },
77
+ ];
78
+ /**
79
+ * Default achievements configuration
80
+ */
81
+ export const DEFAULT_ACHIEVEMENTS = [
82
+ {
83
+ id: 'lessons-10',
84
+ name: { en: 'Dedicated Learner', es: 'Aprendiz Dedicado' },
85
+ description: {
86
+ en: 'Complete 10 lessons',
87
+ es: 'Completa 10 lecciones',
88
+ },
89
+ criteria: {
90
+ type: 'lessons_completed',
91
+ value: 10,
92
+ },
93
+ },
94
+ {
95
+ id: 'lessons-50',
96
+ name: { en: 'Knowledge Master', es: 'Maestro del Conocimiento' },
97
+ description: {
98
+ en: 'Complete 50 lessons',
99
+ es: 'Completa 50 lecciones',
100
+ },
101
+ criteria: {
102
+ type: 'lessons_completed',
103
+ value: 50,
104
+ },
105
+ },
106
+ {
107
+ id: 'points-1000',
108
+ name: { en: 'Point Collector', es: 'Coleccionista de Puntos' },
109
+ description: {
110
+ en: 'Earn 1000 points',
111
+ es: 'Gana 1000 puntos',
112
+ },
113
+ criteria: {
114
+ type: 'points_earned',
115
+ value: 1000,
116
+ },
117
+ },
118
+ {
119
+ id: 'streak-7',
120
+ name: { en: 'Consistent Learner', es: 'Aprendiz Consistente' },
121
+ description: {
122
+ en: 'Maintain a 7-day streak',
123
+ es: 'Mantén una racha de 7 días',
124
+ },
125
+ criteria: {
126
+ type: 'streak_days',
127
+ value: 7,
128
+ },
129
+ },
130
+ {
131
+ id: 'streak-30',
132
+ name: { en: 'Unstoppable', es: 'Imparable' },
133
+ description: {
134
+ en: 'Maintain a 30-day streak',
135
+ es: 'Mantén una racha de 30 días',
136
+ },
137
+ criteria: {
138
+ type: 'streak_days',
139
+ value: 30,
140
+ },
141
+ },
142
+ {
143
+ id: 'quizzes-10',
144
+ name: { en: 'Quiz Master', es: 'Maestro de Quizzes' },
145
+ description: {
146
+ en: 'Pass 10 quizzes',
147
+ es: 'Aprueba 10 quizzes',
148
+ },
149
+ criteria: {
150
+ type: 'quizzes_passed',
151
+ value: 10,
152
+ },
153
+ },
154
+ ];
155
+ /**
156
+ * Points configuration
157
+ */
158
+ export const POINTS_CONFIG = {
159
+ lessonCompleted: 10,
160
+ quizPassed: 20,
161
+ quizPerfectScore: 30,
162
+ dailyBonus: 5,
163
+ streakBonus: {
164
+ 7: 50,
165
+ 30: 200,
166
+ 100: 500,
167
+ },
168
+ };
169
+ /**
170
+ * Gamification manager
171
+ */
172
+ export class GamificationManager {
173
+ constructor() {
174
+ Object.defineProperty(this, "badges", {
175
+ enumerable: true,
176
+ configurable: true,
177
+ writable: true,
178
+ value: void 0
179
+ });
180
+ Object.defineProperty(this, "achievements", {
181
+ enumerable: true,
182
+ configurable: true,
183
+ writable: true,
184
+ value: void 0
185
+ });
186
+ Object.defineProperty(this, "pointsConfig", {
187
+ enumerable: true,
188
+ configurable: true,
189
+ writable: true,
190
+ value: void 0
191
+ });
192
+ this.badges = new Map(DEFAULT_BADGES.map((b) => [b.id, b]));
193
+ this.achievements = new Map(DEFAULT_ACHIEVEMENTS.map((a) => [a.id, a]));
194
+ this.pointsConfig = POINTS_CONFIG;
195
+ }
196
+ /**
197
+ * Register a custom badge
198
+ */
199
+ registerBadge(badge) {
200
+ this.badges.set(badge.id, badge);
201
+ }
202
+ /**
203
+ * Register a custom achievement
204
+ */
205
+ registerAchievement(achievement) {
206
+ this.achievements.set(achievement.id, achievement);
207
+ }
208
+ /**
209
+ * Calculate points for lesson completion
210
+ */
211
+ calculateLessonPoints(quizScore, quizPassed) {
212
+ let points = this.pointsConfig.lessonCompleted;
213
+ if (quizPassed) {
214
+ points += this.pointsConfig.quizPassed;
215
+ }
216
+ if (quizScore === 100) {
217
+ points += this.pointsConfig.quizPerfectScore;
218
+ }
219
+ return points;
220
+ }
221
+ /**
222
+ * Check and award badges for lesson completion
223
+ */
224
+ checkBadges(progress, lessonProgress, userProfile) {
225
+ const earnedBadges = [];
226
+ const now = Date.now();
227
+ // First lesson badge
228
+ if (progress.completedLessons.length === 1 &&
229
+ !userProfile.badges.some((b) => b.id === 'first-lesson')) {
230
+ const badge = this.badges.get('first-lesson');
231
+ if (badge) {
232
+ earnedBadges.push({ ...badge, earnedAt: now });
233
+ }
234
+ }
235
+ // Quick learner badge (5 lessons in one day)
236
+ const today = new Date().toDateString();
237
+ const lessonsToday = progress.completedLessons.filter((slug) => {
238
+ const lp = progress.lessons[slug];
239
+ return lp?.completedAt && new Date(lp.completedAt).toDateString() === today;
240
+ }).length;
241
+ if (lessonsToday >= 5 && !userProfile.badges.some((b) => b.id === 'quick-learner')) {
242
+ const badge = this.badges.get('quick-learner');
243
+ if (badge) {
244
+ earnedBadges.push({ ...badge, earnedAt: now });
245
+ }
246
+ }
247
+ // Perfectionist badge
248
+ if (lessonProgress.quizScore === 100 &&
249
+ !userProfile.badges.some((b) => b.id === 'perfectionist')) {
250
+ const badge = this.badges.get('perfectionist');
251
+ if (badge) {
252
+ earnedBadges.push({ ...badge, earnedAt: now, courseId: progress.courseId });
253
+ }
254
+ }
255
+ // Course complete badge
256
+ if (progress.completedLessons.length > 0 &&
257
+ !userProfile.badges.some((b) => b.id === 'course-complete')) {
258
+ // Check if all lessons are completed (this would need total lessons count)
259
+ // For now, we'll award it when 10 lessons are completed
260
+ if (progress.completedLessons.length >= 10) {
261
+ const badge = this.badges.get('course-complete');
262
+ if (badge) {
263
+ earnedBadges.push({ ...badge, earnedAt: now, courseId: progress.courseId });
264
+ }
265
+ }
266
+ }
267
+ // Knowledge seeker badge (10 lessons)
268
+ if (progress.completedLessons.length >= 10 &&
269
+ !userProfile.badges.some((b) => b.id === 'knowledge-seeker')) {
270
+ const badge = this.badges.get('knowledge-seeker');
271
+ if (badge) {
272
+ earnedBadges.push({ ...badge, earnedAt: now });
273
+ }
274
+ }
275
+ // Scholar badge (50 lessons)
276
+ if (progress.completedLessons.length >= 50 &&
277
+ !userProfile.badges.some((b) => b.id === 'scholar')) {
278
+ const badge = this.badges.get('scholar');
279
+ if (badge) {
280
+ earnedBadges.push({ ...badge, earnedAt: now });
281
+ }
282
+ }
283
+ return earnedBadges;
284
+ }
285
+ /**
286
+ * Check and award achievements
287
+ */
288
+ checkAchievements(userProfile) {
289
+ const earnedAchievements = [];
290
+ const now = Date.now();
291
+ // Count total lessons completed
292
+ const totalLessons = Object.values(userProfile.coursesProgress).reduce((sum, progress) => sum + progress.completedLessons.length, 0);
293
+ // Lessons achievements
294
+ for (const achievement of this.achievements.values()) {
295
+ if (achievement.criteria.type === 'lessons_completed') {
296
+ if (totalLessons >= achievement.criteria.value &&
297
+ !userProfile.achievements.some((a) => a.id === achievement.id)) {
298
+ earnedAchievements.push({ ...achievement, unlockedAt: now });
299
+ }
300
+ }
301
+ }
302
+ // Points achievements
303
+ for (const achievement of this.achievements.values()) {
304
+ if (achievement.criteria.type === 'points_earned') {
305
+ if (userProfile.totalPoints >= achievement.criteria.value &&
306
+ !userProfile.achievements.some((a) => a.id === achievement.id)) {
307
+ earnedAchievements.push({ ...achievement, unlockedAt: now });
308
+ }
309
+ }
310
+ }
311
+ // Streak achievements
312
+ for (const achievement of this.achievements.values()) {
313
+ if (achievement.criteria.type === 'streak_days') {
314
+ if (userProfile.streak.current >= achievement.criteria.value &&
315
+ !userProfile.achievements.some((a) => a.id === achievement.id)) {
316
+ earnedAchievements.push({ ...achievement, unlockedAt: now });
317
+ }
318
+ }
319
+ }
320
+ // Quiz achievements
321
+ const totalQuizzesPassed = Object.values(userProfile.coursesProgress).reduce((sum, progress) => sum + Object.values(progress.lessons).filter((l) => l.quizPassed).length, 0);
322
+ for (const achievement of this.achievements.values()) {
323
+ if (achievement.criteria.type === 'quizzes_passed') {
324
+ if (totalQuizzesPassed >= achievement.criteria.value &&
325
+ !userProfile.achievements.some((a) => a.id === achievement.id)) {
326
+ earnedAchievements.push({ ...achievement, unlockedAt: now });
327
+ }
328
+ }
329
+ }
330
+ return earnedAchievements;
331
+ }
332
+ /**
333
+ * Update user streak
334
+ */
335
+ updateStreak(userProfile) {
336
+ const today = new Date().toISOString().split('T')[0];
337
+ const lastActive = userProfile.streak.lastActiveDate;
338
+ if (lastActive === today) {
339
+ // Already active today
340
+ return userProfile;
341
+ }
342
+ const yesterday = new Date();
343
+ yesterday.setDate(yesterday.getDate() - 1);
344
+ const yesterdayStr = yesterday.toISOString().split('T')[0];
345
+ if (lastActive === yesterdayStr) {
346
+ // Continue streak
347
+ userProfile.streak.current += 1;
348
+ userProfile.streak.longest = Math.max(userProfile.streak.current, userProfile.streak.longest);
349
+ // Award streak badges
350
+ const streakBadges = [
351
+ { days: 7, badgeId: 'week-streak' },
352
+ { days: 30, badgeId: 'month-streak' },
353
+ ];
354
+ for (const { days, badgeId } of streakBadges) {
355
+ if (userProfile.streak.current === days) {
356
+ const badge = this.badges.get(badgeId);
357
+ if (badge && !userProfile.badges.some((b) => b.id === badgeId)) {
358
+ userProfile.badges.push({ ...badge, earnedAt: Date.now() });
359
+ }
360
+ }
361
+ }
362
+ }
363
+ else {
364
+ // Reset streak
365
+ userProfile.streak.current = 1;
366
+ }
367
+ userProfile.streak.lastActiveDate = today;
368
+ userProfile.updatedAt = Date.now();
369
+ return userProfile;
370
+ }
371
+ /**
372
+ * Get all available badges
373
+ */
374
+ getAllBadges() {
375
+ return Array.from(this.badges.values());
376
+ }
377
+ /**
378
+ * Get all available achievements
379
+ */
380
+ getAllAchievements() {
381
+ return Array.from(this.achievements.values());
382
+ }
383
+ /**
384
+ * Get badge by ID
385
+ */
386
+ getBadge(id) {
387
+ return this.badges.get(id);
388
+ }
389
+ /**
390
+ * Get achievement by ID
391
+ */
392
+ getAchievement(id) {
393
+ return this.achievements.get(id);
394
+ }
395
+ }
396
+ /**
397
+ * Create gamification manager instance
398
+ */
399
+ export function createGamificationManager() {
400
+ return new GamificationManager();
401
+ }
402
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/gamification/index.ts"],"names":[],"mappings":"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"}