learngraph 0.4.0 → 0.7.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 (259) hide show
  1. package/dist/cjs/api/routes/analytics.js +288 -0
  2. package/dist/cjs/api/routes/analytics.js.map +1 -0
  3. package/dist/cjs/api/routes/assessments.js +269 -0
  4. package/dist/cjs/api/routes/assessments.js.map +1 -0
  5. package/dist/cjs/api/routes/curriculum.js +345 -0
  6. package/dist/cjs/api/routes/curriculum.js.map +1 -0
  7. package/dist/cjs/api/routes/edges.js +162 -0
  8. package/dist/cjs/api/routes/edges.js.map +1 -0
  9. package/dist/cjs/api/routes/explore.js +224 -0
  10. package/dist/cjs/api/routes/explore.js.map +1 -0
  11. package/dist/cjs/api/routes/learners.js +324 -0
  12. package/dist/cjs/api/routes/learners.js.map +1 -0
  13. package/dist/cjs/api/routes/me.js +404 -0
  14. package/dist/cjs/api/routes/me.js.map +1 -0
  15. package/dist/cjs/api/routes/skills.js +319 -0
  16. package/dist/cjs/api/routes/skills.js.map +1 -0
  17. package/dist/cjs/api/server.js +185 -0
  18. package/dist/cjs/api/server.js.map +1 -0
  19. package/dist/cjs/api/types.js +10 -0
  20. package/dist/cjs/api/types.js.map +1 -0
  21. package/dist/cjs/assessment/adaptive.js +390 -0
  22. package/dist/cjs/assessment/adaptive.js.map +1 -0
  23. package/dist/cjs/assessment/bkt.js +362 -0
  24. package/dist/cjs/assessment/bkt.js.map +1 -0
  25. package/dist/cjs/assessment/index.js +54 -0
  26. package/dist/cjs/assessment/index.js.map +1 -0
  27. package/dist/cjs/assessment/irt.js +420 -0
  28. package/dist/cjs/assessment/irt.js.map +1 -0
  29. package/dist/cjs/assessment/mastery-engine.js +411 -0
  30. package/dist/cjs/assessment/mastery-engine.js.map +1 -0
  31. package/dist/cjs/components/LearningPathView.js +320 -0
  32. package/dist/cjs/components/LearningPathView.js.map +1 -0
  33. package/dist/cjs/components/ProgressDashboard.js +308 -0
  34. package/dist/cjs/components/ProgressDashboard.js.map +1 -0
  35. package/dist/cjs/components/SkillCard.js +264 -0
  36. package/dist/cjs/components/SkillCard.js.map +1 -0
  37. package/dist/cjs/components/SkillExplorer.js +401 -0
  38. package/dist/cjs/components/SkillExplorer.js.map +1 -0
  39. package/dist/cjs/components/SkillGraph.js +435 -0
  40. package/dist/cjs/components/SkillGraph.js.map +1 -0
  41. package/dist/cjs/components/hooks.js +510 -0
  42. package/dist/cjs/components/hooks.js.map +1 -0
  43. package/dist/cjs/components/index.js +77 -0
  44. package/dist/cjs/components/index.js.map +1 -0
  45. package/dist/cjs/components/types.js +34 -0
  46. package/dist/cjs/components/types.js.map +1 -0
  47. package/dist/cjs/index.js +36 -2
  48. package/dist/cjs/index.js.map +1 -1
  49. package/dist/cjs/llm/adapters/anthropic.js +91 -3
  50. package/dist/cjs/llm/adapters/anthropic.js.map +1 -1
  51. package/dist/cjs/llm/adapters/gemini.js +101 -8
  52. package/dist/cjs/llm/adapters/gemini.js.map +1 -1
  53. package/dist/cjs/llm/adapters/index.js +42 -1
  54. package/dist/cjs/llm/adapters/index.js.map +1 -1
  55. package/dist/cjs/llm/adapters/ollama.js +120 -3
  56. package/dist/cjs/llm/adapters/ollama.js.map +1 -1
  57. package/dist/cjs/llm/adapters/openai.js +108 -2
  58. package/dist/cjs/llm/adapters/openai.js.map +1 -1
  59. package/dist/cjs/mcp/cli.js +302 -0
  60. package/dist/cjs/mcp/cli.js.map +1 -0
  61. package/dist/cjs/mcp/index.js +79 -0
  62. package/dist/cjs/mcp/index.js.map +1 -0
  63. package/dist/cjs/mcp/prompts.js +425 -0
  64. package/dist/cjs/mcp/prompts.js.map +1 -0
  65. package/dist/cjs/mcp/resources.js +371 -0
  66. package/dist/cjs/mcp/resources.js.map +1 -0
  67. package/dist/cjs/mcp/server.js +410 -0
  68. package/dist/cjs/mcp/server.js.map +1 -0
  69. package/dist/cjs/mcp/tools.js +612 -0
  70. package/dist/cjs/mcp/tools.js.map +1 -0
  71. package/dist/cjs/mcp/types.js +10 -0
  72. package/dist/cjs/mcp/types.js.map +1 -0
  73. package/dist/cjs/query/index.js +23 -4
  74. package/dist/cjs/query/index.js.map +1 -1
  75. package/dist/cjs/query/path.js +313 -0
  76. package/dist/cjs/query/path.js.map +1 -0
  77. package/dist/cjs/query/spaced-repetition.js +298 -0
  78. package/dist/cjs/query/spaced-repetition.js.map +1 -0
  79. package/dist/cjs/query/zpd.js +216 -0
  80. package/dist/cjs/query/zpd.js.map +1 -0
  81. package/dist/cjs/types/assessment.js +46 -0
  82. package/dist/cjs/types/assessment.js.map +1 -0
  83. package/dist/cjs/types/bloom.js +12 -1
  84. package/dist/cjs/types/bloom.js.map +1 -1
  85. package/dist/cjs/types/index.js +7 -1
  86. package/dist/cjs/types/index.js.map +1 -1
  87. package/dist/esm/api/routes/analytics.js +285 -0
  88. package/dist/esm/api/routes/analytics.js.map +1 -0
  89. package/dist/esm/api/routes/assessments.js +266 -0
  90. package/dist/esm/api/routes/assessments.js.map +1 -0
  91. package/dist/esm/api/routes/curriculum.js +342 -0
  92. package/dist/esm/api/routes/curriculum.js.map +1 -0
  93. package/dist/esm/api/routes/edges.js +159 -0
  94. package/dist/esm/api/routes/edges.js.map +1 -0
  95. package/dist/esm/api/routes/explore.js +221 -0
  96. package/dist/esm/api/routes/explore.js.map +1 -0
  97. package/dist/esm/api/routes/learners.js +321 -0
  98. package/dist/esm/api/routes/learners.js.map +1 -0
  99. package/dist/esm/api/routes/me.js +401 -0
  100. package/dist/esm/api/routes/me.js.map +1 -0
  101. package/dist/esm/api/routes/skills.js +316 -0
  102. package/dist/esm/api/routes/skills.js.map +1 -0
  103. package/dist/esm/api/server.js +179 -0
  104. package/dist/esm/api/server.js.map +1 -0
  105. package/dist/esm/api/types.js +9 -0
  106. package/dist/esm/api/types.js.map +1 -0
  107. package/dist/esm/assessment/adaptive.js +384 -0
  108. package/dist/esm/assessment/adaptive.js.map +1 -0
  109. package/dist/esm/assessment/bkt.js +354 -0
  110. package/dist/esm/assessment/bkt.js.map +1 -0
  111. package/dist/esm/assessment/index.js +21 -0
  112. package/dist/esm/assessment/index.js.map +1 -0
  113. package/dist/esm/assessment/irt.js +406 -0
  114. package/dist/esm/assessment/irt.js.map +1 -0
  115. package/dist/esm/assessment/mastery-engine.js +406 -0
  116. package/dist/esm/assessment/mastery-engine.js.map +1 -0
  117. package/dist/esm/components/LearningPathView.js +316 -0
  118. package/dist/esm/components/LearningPathView.js.map +1 -0
  119. package/dist/esm/components/ProgressDashboard.js +304 -0
  120. package/dist/esm/components/ProgressDashboard.js.map +1 -0
  121. package/dist/esm/components/SkillCard.js +260 -0
  122. package/dist/esm/components/SkillCard.js.map +1 -0
  123. package/dist/esm/components/SkillExplorer.js +397 -0
  124. package/dist/esm/components/SkillExplorer.js.map +1 -0
  125. package/dist/esm/components/SkillGraph.js +398 -0
  126. package/dist/esm/components/SkillGraph.js.map +1 -0
  127. package/dist/esm/components/hooks.js +502 -0
  128. package/dist/esm/components/hooks.js.map +1 -0
  129. package/dist/esm/components/index.js +61 -0
  130. package/dist/esm/components/index.js.map +1 -0
  131. package/dist/esm/components/types.js +31 -0
  132. package/dist/esm/components/types.js.map +1 -0
  133. package/dist/esm/index.js +13 -1
  134. package/dist/esm/index.js.map +1 -1
  135. package/dist/esm/llm/adapters/anthropic.js +88 -2
  136. package/dist/esm/llm/adapters/anthropic.js.map +1 -1
  137. package/dist/esm/llm/adapters/gemini.js +98 -7
  138. package/dist/esm/llm/adapters/gemini.js.map +1 -1
  139. package/dist/esm/llm/adapters/index.js +15 -4
  140. package/dist/esm/llm/adapters/index.js.map +1 -1
  141. package/dist/esm/llm/adapters/ollama.js +117 -2
  142. package/dist/esm/llm/adapters/ollama.js.map +1 -1
  143. package/dist/esm/llm/adapters/openai.js +105 -1
  144. package/dist/esm/llm/adapters/openai.js.map +1 -1
  145. package/dist/esm/mcp/cli.js +267 -0
  146. package/dist/esm/mcp/cli.js.map +1 -0
  147. package/dist/esm/mcp/index.js +39 -0
  148. package/dist/esm/mcp/index.js.map +1 -0
  149. package/dist/esm/mcp/prompts.js +419 -0
  150. package/dist/esm/mcp/prompts.js.map +1 -0
  151. package/dist/esm/mcp/resources.js +359 -0
  152. package/dist/esm/mcp/resources.js.map +1 -0
  153. package/dist/esm/mcp/server.js +372 -0
  154. package/dist/esm/mcp/server.js.map +1 -0
  155. package/dist/esm/mcp/tools.js +598 -0
  156. package/dist/esm/mcp/tools.js.map +1 -0
  157. package/dist/esm/mcp/types.js +9 -0
  158. package/dist/esm/mcp/types.js.map +1 -0
  159. package/dist/esm/query/index.js +11 -5
  160. package/dist/esm/query/index.js.map +1 -1
  161. package/dist/esm/query/path.js +308 -0
  162. package/dist/esm/query/path.js.map +1 -0
  163. package/dist/esm/query/spaced-repetition.js +292 -0
  164. package/dist/esm/query/spaced-repetition.js.map +1 -0
  165. package/dist/esm/query/zpd.js +211 -0
  166. package/dist/esm/query/zpd.js.map +1 -0
  167. package/dist/esm/types/assessment.js +40 -0
  168. package/dist/esm/types/assessment.js.map +1 -0
  169. package/dist/esm/types/bloom.js +11 -0
  170. package/dist/esm/types/bloom.js.map +1 -1
  171. package/dist/esm/types/index.js +2 -1
  172. package/dist/esm/types/index.js.map +1 -1
  173. package/dist/types/api/routes/analytics.d.ts +14 -0
  174. package/dist/types/api/routes/analytics.d.ts.map +1 -0
  175. package/dist/types/api/routes/assessments.d.ts +14 -0
  176. package/dist/types/api/routes/assessments.d.ts.map +1 -0
  177. package/dist/types/api/routes/curriculum.d.ts +14 -0
  178. package/dist/types/api/routes/curriculum.d.ts.map +1 -0
  179. package/dist/types/api/routes/edges.d.ts +14 -0
  180. package/dist/types/api/routes/edges.d.ts.map +1 -0
  181. package/dist/types/api/routes/explore.d.ts +14 -0
  182. package/dist/types/api/routes/explore.d.ts.map +1 -0
  183. package/dist/types/api/routes/learners.d.ts +14 -0
  184. package/dist/types/api/routes/learners.d.ts.map +1 -0
  185. package/dist/types/api/routes/me.d.ts +14 -0
  186. package/dist/types/api/routes/me.d.ts.map +1 -0
  187. package/dist/types/api/routes/skills.d.ts +14 -0
  188. package/dist/types/api/routes/skills.d.ts.map +1 -0
  189. package/dist/types/api/server.d.ts +147 -0
  190. package/dist/types/api/server.d.ts.map +1 -0
  191. package/dist/types/api/types.d.ts +443 -0
  192. package/dist/types/api/types.d.ts.map +1 -0
  193. package/dist/types/assessment/adaptive.d.ts +155 -0
  194. package/dist/types/assessment/adaptive.d.ts.map +1 -0
  195. package/dist/types/assessment/bkt.d.ts +185 -0
  196. package/dist/types/assessment/bkt.d.ts.map +1 -0
  197. package/dist/types/assessment/index.d.ts +18 -0
  198. package/dist/types/assessment/index.d.ts.map +1 -0
  199. package/dist/types/assessment/irt.d.ts +159 -0
  200. package/dist/types/assessment/irt.d.ts.map +1 -0
  201. package/dist/types/assessment/mastery-engine.d.ts +178 -0
  202. package/dist/types/assessment/mastery-engine.d.ts.map +1 -0
  203. package/dist/types/components/LearningPathView.d.ts +40 -0
  204. package/dist/types/components/LearningPathView.d.ts.map +1 -0
  205. package/dist/types/components/ProgressDashboard.d.ts +49 -0
  206. package/dist/types/components/ProgressDashboard.d.ts.map +1 -0
  207. package/dist/types/components/SkillCard.d.ts +34 -0
  208. package/dist/types/components/SkillCard.d.ts.map +1 -0
  209. package/dist/types/components/SkillExplorer.d.ts +39 -0
  210. package/dist/types/components/SkillExplorer.d.ts.map +1 -0
  211. package/dist/types/components/SkillGraph.d.ts +38 -0
  212. package/dist/types/components/SkillGraph.d.ts.map +1 -0
  213. package/dist/types/components/hooks.d.ts +187 -0
  214. package/dist/types/components/hooks.d.ts.map +1 -0
  215. package/dist/types/components/index.d.ts +59 -0
  216. package/dist/types/components/index.d.ts.map +1 -0
  217. package/dist/types/components/types.d.ts +410 -0
  218. package/dist/types/components/types.d.ts.map +1 -0
  219. package/dist/types/index.d.ts +2 -1
  220. package/dist/types/index.d.ts.map +1 -1
  221. package/dist/types/llm/adapters/anthropic.d.ts +84 -1
  222. package/dist/types/llm/adapters/anthropic.d.ts.map +1 -1
  223. package/dist/types/llm/adapters/gemini.d.ts +93 -6
  224. package/dist/types/llm/adapters/gemini.d.ts.map +1 -1
  225. package/dist/types/llm/adapters/index.d.ts +13 -4
  226. package/dist/types/llm/adapters/index.d.ts.map +1 -1
  227. package/dist/types/llm/adapters/ollama.d.ts +126 -1
  228. package/dist/types/llm/adapters/ollama.d.ts.map +1 -1
  229. package/dist/types/llm/adapters/openai.d.ts +104 -1
  230. package/dist/types/llm/adapters/openai.d.ts.map +1 -1
  231. package/dist/types/mcp/cli.d.ts +15 -0
  232. package/dist/types/mcp/cli.d.ts.map +1 -0
  233. package/dist/types/mcp/index.d.ts +32 -0
  234. package/dist/types/mcp/index.d.ts.map +1 -0
  235. package/dist/types/mcp/prompts.d.ts +27 -0
  236. package/dist/types/mcp/prompts.d.ts.map +1 -0
  237. package/dist/types/mcp/resources.d.ts +59 -0
  238. package/dist/types/mcp/resources.d.ts.map +1 -0
  239. package/dist/types/mcp/server.d.ts +136 -0
  240. package/dist/types/mcp/server.d.ts.map +1 -0
  241. package/dist/types/mcp/tools.d.ts +344 -0
  242. package/dist/types/mcp/tools.d.ts.map +1 -0
  243. package/dist/types/mcp/types.d.ts +137 -0
  244. package/dist/types/mcp/types.d.ts.map +1 -0
  245. package/dist/types/query/index.d.ts +8 -0
  246. package/dist/types/query/index.d.ts.map +1 -1
  247. package/dist/types/query/path.d.ts +102 -0
  248. package/dist/types/query/path.d.ts.map +1 -0
  249. package/dist/types/query/spaced-repetition.d.ts +135 -0
  250. package/dist/types/query/spaced-repetition.d.ts.map +1 -0
  251. package/dist/types/query/zpd.d.ts +97 -0
  252. package/dist/types/query/zpd.d.ts.map +1 -0
  253. package/dist/types/types/assessment.d.ts +512 -0
  254. package/dist/types/types/assessment.d.ts.map +1 -0
  255. package/dist/types/types/bloom.d.ts +4 -0
  256. package/dist/types/types/bloom.d.ts.map +1 -1
  257. package/dist/types/types/index.d.ts +3 -1
  258. package/dist/types/types/index.d.ts.map +1 -1
  259. package/package.json +48 -3
@@ -0,0 +1,316 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * LearningPathView Component
4
+ *
5
+ * Displays a learning path with progress tracking.
6
+ *
7
+ * @packageDocumentation
8
+ */
9
+ import { useMemo } from 'react';
10
+ import { DEFAULT_BLOOM_COLORS, STATUS_COLORS } from './types.js';
11
+ const ProgressBar = ({ steps }) => {
12
+ const completed = steps.filter((s) => s.status === 'completed').length;
13
+ const percentage = Math.round((completed / steps.length) * 100);
14
+ const containerStyle = {
15
+ marginBottom: '24px',
16
+ };
17
+ const labelStyle = {
18
+ display: 'flex',
19
+ justifyContent: 'space-between',
20
+ fontSize: '14px',
21
+ marginBottom: '8px',
22
+ color: '#374151',
23
+ };
24
+ const barContainerStyle = {
25
+ height: '12px',
26
+ backgroundColor: '#e5e7eb',
27
+ borderRadius: '6px',
28
+ overflow: 'hidden',
29
+ };
30
+ const barStyle = {
31
+ height: '100%',
32
+ width: `${percentage}%`,
33
+ backgroundColor: STATUS_COLORS.mastered,
34
+ borderRadius: '6px',
35
+ transition: 'width 0.3s ease',
36
+ };
37
+ return (_jsxs("div", { style: containerStyle, children: [_jsxs("div", { style: labelStyle, children: [_jsxs("span", { children: [_jsx("strong", { children: completed }), " of ", _jsx("strong", { children: steps.length }), " skills completed"] }), _jsxs("span", { style: { fontWeight: 600 }, children: [percentage, "%"] })] }), _jsx("div", { style: barContainerStyle, children: _jsx("div", { style: barStyle }) })] }));
38
+ };
39
+ const TimelineStep = ({ step, isLast, showTime, onStepClick, onStartStep, }) => {
40
+ const { skill, stepNumber, status, isPrerequisite, estimatedMinutes } = step;
41
+ const statusColors = {
42
+ completed: STATUS_COLORS.mastered,
43
+ current: STATUS_COLORS.available,
44
+ upcoming: '#9ca3af',
45
+ locked: STATUS_COLORS.locked,
46
+ };
47
+ const containerStyle = {
48
+ display: 'flex',
49
+ position: 'relative',
50
+ };
51
+ const indicatorContainerStyle = {
52
+ display: 'flex',
53
+ flexDirection: 'column',
54
+ alignItems: 'center',
55
+ marginRight: '16px',
56
+ };
57
+ const circleStyle = {
58
+ width: '32px',
59
+ height: '32px',
60
+ borderRadius: '50%',
61
+ backgroundColor: status === 'completed' ? statusColors[status] : 'transparent',
62
+ border: `3px solid ${statusColors[status]}`,
63
+ display: 'flex',
64
+ alignItems: 'center',
65
+ justifyContent: 'center',
66
+ fontSize: '14px',
67
+ fontWeight: 600,
68
+ color: status === 'completed' ? '#ffffff' : statusColors[status],
69
+ zIndex: 1,
70
+ };
71
+ const lineStyle = {
72
+ width: '3px',
73
+ flex: 1,
74
+ backgroundColor: status === 'completed' ? statusColors.completed : '#e5e7eb',
75
+ minHeight: '24px',
76
+ display: isLast ? 'none' : 'block',
77
+ };
78
+ const contentStyle = {
79
+ flex: 1,
80
+ paddingBottom: isLast ? 0 : '24px',
81
+ cursor: onStepClick ? 'pointer' : 'default',
82
+ };
83
+ const cardStyle = {
84
+ backgroundColor: status === 'current' ? '#eff6ff' : '#ffffff',
85
+ border: `1px solid ${status === 'current' ? '#bfdbfe' : '#e5e7eb'}`,
86
+ borderRadius: '8px',
87
+ padding: '12px 16px',
88
+ transition: 'box-shadow 0.2s ease',
89
+ };
90
+ const headerStyle = {
91
+ display: 'flex',
92
+ justifyContent: 'space-between',
93
+ alignItems: 'center',
94
+ marginBottom: '4px',
95
+ };
96
+ const titleStyle = {
97
+ fontSize: '14px',
98
+ fontWeight: 600,
99
+ color: status === 'locked' ? '#9ca3af' : '#1f2937',
100
+ margin: 0,
101
+ };
102
+ const badgeStyle = {
103
+ display: 'inline-flex',
104
+ alignItems: 'center',
105
+ padding: '2px 8px',
106
+ borderRadius: '4px',
107
+ fontSize: '11px',
108
+ fontWeight: 500,
109
+ textTransform: 'capitalize',
110
+ backgroundColor: DEFAULT_BLOOM_COLORS[skill.bloomLevel],
111
+ color: '#ffffff',
112
+ };
113
+ const metaStyle = {
114
+ display: 'flex',
115
+ gap: '12px',
116
+ fontSize: '12px',
117
+ color: '#6b7280',
118
+ marginTop: '4px',
119
+ };
120
+ const buttonStyle = {
121
+ marginTop: '8px',
122
+ padding: '6px 12px',
123
+ backgroundColor: '#3b82f6',
124
+ color: '#ffffff',
125
+ border: 'none',
126
+ borderRadius: '6px',
127
+ fontSize: '12px',
128
+ fontWeight: 500,
129
+ cursor: 'pointer',
130
+ };
131
+ return (_jsxs("div", { style: containerStyle, children: [_jsxs("div", { style: indicatorContainerStyle, children: [_jsx("div", { style: circleStyle, children: status === 'completed' ? '✓' : stepNumber }), _jsx("div", { style: lineStyle })] }), _jsx("div", { style: contentStyle, onClick: () => onStepClick?.(step), children: _jsxs("div", { style: cardStyle, children: [_jsxs("div", { style: headerStyle, children: [_jsx("h4", { style: titleStyle, children: skill.name }), _jsx("span", { style: badgeStyle, children: skill.bloomLevel })] }), _jsxs("div", { style: metaStyle, children: [showTime && _jsxs("span", { children: [estimatedMinutes, " min"] }), isPrerequisite && (_jsx("span", { style: { color: '#f59e0b' }, children: "Prerequisite" }))] }), status === 'current' && onStartStep && (_jsx("button", { style: buttonStyle, onClick: (e) => {
132
+ e.stopPropagation();
133
+ onStartStep(step);
134
+ }, children: "Start Now" }))] }) })] }));
135
+ };
136
+ const ListStep = ({ step, showTime, onStepClick, onStartStep, }) => {
137
+ const { skill, stepNumber, status, isPrerequisite, estimatedMinutes } = step;
138
+ const statusColors = {
139
+ completed: STATUS_COLORS.mastered,
140
+ current: STATUS_COLORS.available,
141
+ upcoming: '#9ca3af',
142
+ locked: STATUS_COLORS.locked,
143
+ };
144
+ const containerStyle = {
145
+ display: 'flex',
146
+ alignItems: 'center',
147
+ padding: '12px',
148
+ backgroundColor: status === 'current' ? '#eff6ff' : '#ffffff',
149
+ border: `1px solid ${status === 'current' ? '#bfdbfe' : '#e5e7eb'}`,
150
+ borderRadius: '8px',
151
+ marginBottom: '8px',
152
+ cursor: onStepClick ? 'pointer' : 'default',
153
+ };
154
+ const numberStyle = {
155
+ width: '28px',
156
+ height: '28px',
157
+ borderRadius: '50%',
158
+ backgroundColor: status === 'completed' ? statusColors[status] : 'transparent',
159
+ border: `2px solid ${statusColors[status]}`,
160
+ display: 'flex',
161
+ alignItems: 'center',
162
+ justifyContent: 'center',
163
+ fontSize: '12px',
164
+ fontWeight: 600,
165
+ color: status === 'completed' ? '#ffffff' : statusColors[status],
166
+ marginRight: '12px',
167
+ flexShrink: 0,
168
+ };
169
+ const contentStyle = {
170
+ flex: 1,
171
+ };
172
+ const titleStyle = {
173
+ fontSize: '14px',
174
+ fontWeight: 500,
175
+ color: status === 'locked' ? '#9ca3af' : '#1f2937',
176
+ margin: 0,
177
+ };
178
+ const metaStyle = {
179
+ display: 'flex',
180
+ gap: '8px',
181
+ fontSize: '11px',
182
+ color: '#6b7280',
183
+ marginTop: '2px',
184
+ };
185
+ const buttonStyle = {
186
+ padding: '4px 10px',
187
+ backgroundColor: '#3b82f6',
188
+ color: '#ffffff',
189
+ border: 'none',
190
+ borderRadius: '4px',
191
+ fontSize: '11px',
192
+ fontWeight: 500,
193
+ cursor: 'pointer',
194
+ marginLeft: '12px',
195
+ };
196
+ return (_jsxs("div", { style: containerStyle, onClick: () => onStepClick?.(step), children: [_jsx("div", { style: numberStyle, children: status === 'completed' ? '✓' : stepNumber }), _jsxs("div", { style: contentStyle, children: [_jsx("div", { style: titleStyle, children: skill.name }), _jsxs("div", { style: metaStyle, children: [_jsx("span", { style: {
197
+ textTransform: 'capitalize',
198
+ color: DEFAULT_BLOOM_COLORS[skill.bloomLevel],
199
+ }, children: skill.bloomLevel }), showTime && _jsxs("span", { children: [estimatedMinutes, " min"] }), isPrerequisite && _jsx("span", { style: { color: '#f59e0b' }, children: "prereq" })] })] }), status === 'current' && onStartStep && (_jsx("button", { style: buttonStyle, onClick: (e) => {
200
+ e.stopPropagation();
201
+ onStartStep(step);
202
+ }, children: "Start" }))] }));
203
+ };
204
+ // ─────────────────────────────────────────────────────────────────────────────
205
+ // Main Component
206
+ // ─────────────────────────────────────────────────────────────────────────────
207
+ /**
208
+ * LearningPathView Component
209
+ *
210
+ * Displays a learning path with progress tracking and step navigation.
211
+ *
212
+ * @example
213
+ * ```tsx
214
+ * import { LearningPathView } from 'learngraph/components';
215
+ *
216
+ * function PathToAlgebra() {
217
+ * const { steps } = useLearningPath({
218
+ * targetSkillId: 'algebra-101',
219
+ * });
220
+ *
221
+ * return (
222
+ * <LearningPathView
223
+ * steps={steps}
224
+ * targetSkillName="Algebra Basics"
225
+ * viewMode="timeline"
226
+ * onStepClick={(step) => console.log('Selected:', step.skill.name)}
227
+ * onStartStep={(step) => startLesson(step.skill.id)}
228
+ * showProgress
229
+ * showTimeEstimates
230
+ * />
231
+ * );
232
+ * }
233
+ * ```
234
+ */
235
+ export const LearningPathView = ({ steps, targetSkillName, currentStepIndex: _currentStepIndex, viewMode = 'timeline', onStepClick, onStartStep, showTimeEstimates = true, showProgress = true, className, style, }) => {
236
+ // _currentStepIndex is available for future use
237
+ void _currentStepIndex;
238
+ const totalMinutes = useMemo(() => steps.reduce((sum, step) => sum + step.estimatedMinutes, 0), [steps]);
239
+ const containerStyle = {
240
+ ...style,
241
+ };
242
+ const headerStyle = {
243
+ marginBottom: '16px',
244
+ };
245
+ const titleStyle = {
246
+ fontSize: '20px',
247
+ fontWeight: 600,
248
+ color: '#1f2937',
249
+ margin: 0,
250
+ };
251
+ const subtitleStyle = {
252
+ fontSize: '14px',
253
+ color: '#6b7280',
254
+ marginTop: '4px',
255
+ };
256
+ if (steps.length === 0) {
257
+ return (_jsx("div", { className: className, style: containerStyle, children: _jsxs("div", { style: headerStyle, children: [_jsxs("h2", { style: titleStyle, children: ["Path to ", targetSkillName] }), _jsx("p", { style: subtitleStyle, children: "No prerequisites needed!" })] }) }));
258
+ }
259
+ return (_jsxs("div", { className: className, style: containerStyle, children: [_jsxs("div", { style: headerStyle, children: [_jsxs("h2", { style: titleStyle, children: ["Path to ", targetSkillName] }), _jsxs("p", { style: subtitleStyle, children: [steps.length, " skills \u2022 ", totalMinutes, " minutes estimated"] })] }), showProgress && _jsx(ProgressBar, { steps: steps }), viewMode === 'timeline' && (_jsx("div", { children: steps.map((step, index) => (_jsx(TimelineStep, { step: step, isLast: index === steps.length - 1, showTime: showTimeEstimates, onStepClick: onStepClick, onStartStep: onStartStep }, String(step.skill.id)))) })), viewMode === 'list' && (_jsx("div", { children: steps.map((step) => (_jsx(ListStep, { step: step, showTime: showTimeEstimates, onStepClick: onStepClick, onStartStep: onStartStep }, String(step.skill.id)))) })), viewMode === 'cards' && (_jsx("div", { style: {
260
+ display: 'grid',
261
+ gridTemplateColumns: 'repeat(auto-fill, minmax(250px, 1fr))',
262
+ gap: '12px',
263
+ }, children: steps.map((step) => (_jsxs("div", { style: {
264
+ padding: '16px',
265
+ backgroundColor: step.status === 'current' ? '#eff6ff' : '#ffffff',
266
+ border: `1px solid ${step.status === 'current' ? '#bfdbfe' : '#e5e7eb'}`,
267
+ borderRadius: '8px',
268
+ cursor: onStepClick ? 'pointer' : 'default',
269
+ }, onClick: () => onStepClick?.(step), children: [_jsxs("div", { style: {
270
+ display: 'flex',
271
+ justifyContent: 'space-between',
272
+ alignItems: 'center',
273
+ marginBottom: '8px',
274
+ }, children: [_jsx("span", { style: {
275
+ width: '24px',
276
+ height: '24px',
277
+ borderRadius: '50%',
278
+ backgroundColor: step.status === 'completed'
279
+ ? STATUS_COLORS.mastered
280
+ : '#e5e7eb',
281
+ color: step.status === 'completed' ? '#ffffff' : '#6b7280',
282
+ display: 'flex',
283
+ alignItems: 'center',
284
+ justifyContent: 'center',
285
+ fontSize: '12px',
286
+ fontWeight: 600,
287
+ }, children: step.status === 'completed' ? '✓' : step.stepNumber }), _jsx("span", { style: {
288
+ fontSize: '11px',
289
+ padding: '2px 6px',
290
+ backgroundColor: DEFAULT_BLOOM_COLORS[step.skill.bloomLevel],
291
+ color: '#ffffff',
292
+ borderRadius: '4px',
293
+ textTransform: 'capitalize',
294
+ }, children: step.skill.bloomLevel })] }), _jsx("h4", { style: {
295
+ fontSize: '14px',
296
+ fontWeight: 600,
297
+ color: '#1f2937',
298
+ margin: '0 0 4px 0',
299
+ }, children: step.skill.name }), _jsx("div", { style: { fontSize: '12px', color: '#6b7280' }, children: showTimeEstimates && _jsxs("span", { children: [step.estimatedMinutes, " min"] }) }), step.status === 'current' && onStartStep && (_jsx("button", { style: {
300
+ marginTop: '12px',
301
+ width: '100%',
302
+ padding: '8px',
303
+ backgroundColor: '#3b82f6',
304
+ color: '#ffffff',
305
+ border: 'none',
306
+ borderRadius: '6px',
307
+ fontSize: '13px',
308
+ fontWeight: 500,
309
+ cursor: 'pointer',
310
+ }, onClick: (e) => {
311
+ e.stopPropagation();
312
+ onStartStep(step);
313
+ }, children: "Start Now" }))] }, String(step.skill.id)))) }))] }));
314
+ };
315
+ export default LearningPathView;
316
+ //# sourceMappingURL=LearningPathView.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LearningPathView.js","sourceRoot":"","sources":["../../../src/components/LearningPathView.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,304 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { DEFAULT_BLOOM_COLORS, STATUS_COLORS } from './types.js';
3
+ const StatCard = ({ label, value, subValue, color }) => {
4
+ const cardStyle = {
5
+ backgroundColor: '#ffffff',
6
+ borderRadius: '12px',
7
+ padding: '16px',
8
+ border: '1px solid #e5e7eb',
9
+ flex: 1,
10
+ minWidth: '120px',
11
+ };
12
+ const labelStyle = {
13
+ fontSize: '12px',
14
+ color: '#6b7280',
15
+ marginBottom: '4px',
16
+ textTransform: 'uppercase',
17
+ letterSpacing: '0.05em',
18
+ };
19
+ const valueStyle = {
20
+ fontSize: '28px',
21
+ fontWeight: 700,
22
+ color: color || '#1f2937',
23
+ lineHeight: 1.2,
24
+ };
25
+ const subValueStyle = {
26
+ fontSize: '12px',
27
+ color: '#9ca3af',
28
+ marginTop: '4px',
29
+ };
30
+ return (_jsxs("div", { style: cardStyle, children: [_jsx("div", { style: labelStyle, children: label }), _jsx("div", { style: valueStyle, children: value }), subValue && _jsx("div", { style: subValueStyle, children: subValue })] }));
31
+ };
32
+ const BloomProgressBar = ({ progress }) => {
33
+ const containerStyle = {
34
+ backgroundColor: '#ffffff',
35
+ borderRadius: '12px',
36
+ padding: '16px',
37
+ border: '1px solid #e5e7eb',
38
+ };
39
+ const titleStyle = {
40
+ fontSize: '14px',
41
+ fontWeight: 600,
42
+ color: '#374151',
43
+ marginBottom: '16px',
44
+ };
45
+ const rowStyle = {
46
+ display: 'flex',
47
+ alignItems: 'center',
48
+ marginBottom: '12px',
49
+ };
50
+ const labelStyle = {
51
+ width: '80px',
52
+ fontSize: '12px',
53
+ fontWeight: 500,
54
+ textTransform: 'capitalize',
55
+ color: '#374151',
56
+ };
57
+ const barContainerStyle = {
58
+ flex: 1,
59
+ height: '20px',
60
+ backgroundColor: '#e5e7eb',
61
+ borderRadius: '10px',
62
+ overflow: 'hidden',
63
+ marginRight: '12px',
64
+ };
65
+ const valueStyle = {
66
+ width: '60px',
67
+ textAlign: 'right',
68
+ fontSize: '12px',
69
+ color: '#6b7280',
70
+ };
71
+ return (_jsxs("div", { style: containerStyle, children: [_jsx("div", { style: titleStyle, children: "Progress by Bloom's Level" }), progress.map((p) => (_jsxs("div", { style: rowStyle, children: [_jsx("span", { style: labelStyle, children: p.level }), _jsx("div", { style: barContainerStyle, children: _jsx("div", { style: {
72
+ height: '100%',
73
+ width: `${p.percentage}%`,
74
+ backgroundColor: DEFAULT_BLOOM_COLORS[p.level],
75
+ borderRadius: '10px',
76
+ transition: 'width 0.3s ease',
77
+ } }) }), _jsxs("span", { style: valueStyle, children: [p.mastered, "/", p.total] })] }, p.level)))] }));
78
+ };
79
+ const ActivityFeed = ({ activities, onSkillClick }) => {
80
+ const containerStyle = {
81
+ backgroundColor: '#ffffff',
82
+ borderRadius: '12px',
83
+ padding: '16px',
84
+ border: '1px solid #e5e7eb',
85
+ };
86
+ const titleStyle = {
87
+ fontSize: '14px',
88
+ fontWeight: 600,
89
+ color: '#374151',
90
+ marginBottom: '16px',
91
+ };
92
+ const itemStyle = {
93
+ display: 'flex',
94
+ alignItems: 'flex-start',
95
+ padding: '10px 0',
96
+ borderBottom: '1px solid #f3f4f6',
97
+ cursor: 'pointer',
98
+ };
99
+ const iconStyle = (type) => ({
100
+ width: '32px',
101
+ height: '32px',
102
+ borderRadius: '50%',
103
+ backgroundColor: type === 'mastered'
104
+ ? '#dcfce7'
105
+ : type === 'practiced'
106
+ ? '#dbeafe'
107
+ : type === 'started'
108
+ ? '#fef3c7'
109
+ : '#f3e8ff',
110
+ color: type === 'mastered'
111
+ ? STATUS_COLORS.mastered
112
+ : type === 'practiced'
113
+ ? STATUS_COLORS.available
114
+ : type === 'started'
115
+ ? '#f59e0b'
116
+ : '#a855f7',
117
+ display: 'flex',
118
+ alignItems: 'center',
119
+ justifyContent: 'center',
120
+ fontSize: '14px',
121
+ marginRight: '12px',
122
+ flexShrink: 0,
123
+ });
124
+ const getIcon = (type) => {
125
+ switch (type) {
126
+ case 'mastered':
127
+ return '★';
128
+ case 'practiced':
129
+ return '✓';
130
+ case 'started':
131
+ return '→';
132
+ case 'reviewed':
133
+ return '↻';
134
+ default:
135
+ return '•';
136
+ }
137
+ };
138
+ const formatTime = (date) => {
139
+ const now = new Date();
140
+ const diff = now.getTime() - date.getTime();
141
+ const minutes = Math.floor(diff / 60000);
142
+ const hours = Math.floor(diff / 3600000);
143
+ const days = Math.floor(diff / 86400000);
144
+ if (minutes < 1)
145
+ return 'Just now';
146
+ if (minutes < 60)
147
+ return `${minutes}m ago`;
148
+ if (hours < 24)
149
+ return `${hours}h ago`;
150
+ if (days < 7)
151
+ return `${days}d ago`;
152
+ return date.toLocaleDateString();
153
+ };
154
+ return (_jsxs("div", { style: containerStyle, children: [_jsx("div", { style: titleStyle, children: "Recent Activity" }), activities.length === 0 ? (_jsx("div", { style: { color: '#9ca3af', fontSize: '14px', textAlign: 'center', padding: '20px' }, children: "No recent activity" })) : (activities.map((activity, index) => (_jsxs("div", { style: itemStyle, onClick: () => onSkillClick?.(activity.skill), children: [_jsx("div", { style: iconStyle(activity.type), children: getIcon(activity.type) }), _jsxs("div", { style: { flex: 1 }, children: [_jsxs("div", { style: { fontSize: '13px', fontWeight: 500, color: '#1f2937' }, children: [activity.type === 'mastered' && 'Mastered ', activity.type === 'practiced' && 'Practiced ', activity.type === 'started' && 'Started ', activity.type === 'reviewed' && 'Reviewed ', _jsx("span", { style: { color: '#3b82f6' }, children: activity.skill.name })] }), _jsxs("div", { style: { fontSize: '11px', color: '#9ca3af', marginTop: '2px' }, children: [formatTime(activity.timestamp), activity.duration && ` • ${activity.duration} min`, activity.result && ` • ${activity.result.correct}/${activity.result.total} correct`] })] })] }, index))))] }));
155
+ };
156
+ const SkillList = ({ title, skills, emptyMessage, onSkillClick, actionLabel, onAction, }) => {
157
+ const containerStyle = {
158
+ backgroundColor: '#ffffff',
159
+ borderRadius: '12px',
160
+ padding: '16px',
161
+ border: '1px solid #e5e7eb',
162
+ };
163
+ const headerStyle = {
164
+ display: 'flex',
165
+ justifyContent: 'space-between',
166
+ alignItems: 'center',
167
+ marginBottom: '12px',
168
+ };
169
+ const titleStyle = {
170
+ fontSize: '14px',
171
+ fontWeight: 600,
172
+ color: '#374151',
173
+ };
174
+ const actionStyle = {
175
+ fontSize: '12px',
176
+ color: '#3b82f6',
177
+ cursor: 'pointer',
178
+ fontWeight: 500,
179
+ };
180
+ const itemStyle = {
181
+ display: 'flex',
182
+ alignItems: 'center',
183
+ padding: '8px 0',
184
+ borderBottom: '1px solid #f3f4f6',
185
+ cursor: onSkillClick ? 'pointer' : 'default',
186
+ };
187
+ return (_jsxs("div", { style: containerStyle, children: [_jsxs("div", { style: headerStyle, children: [_jsx("span", { style: titleStyle, children: title }), actionLabel && onAction && (_jsx("span", { style: actionStyle, onClick: onAction, children: actionLabel }))] }), skills.length === 0 ? (_jsx("div", { style: { color: '#9ca3af', fontSize: '14px', textAlign: 'center', padding: '20px' }, children: emptyMessage })) : (skills.slice(0, 5).map((skill) => (_jsxs("div", { style: itemStyle, onClick: () => onSkillClick?.(skill), children: [_jsx("span", { style: {
188
+ width: '8px',
189
+ height: '8px',
190
+ borderRadius: '50%',
191
+ backgroundColor: DEFAULT_BLOOM_COLORS[skill.bloomLevel],
192
+ marginRight: '10px',
193
+ } }), _jsxs("div", { style: { flex: 1 }, children: [_jsx("div", { style: { fontSize: '13px', fontWeight: 500, color: '#1f2937' }, children: skill.name }), _jsxs("div", { style: { fontSize: '11px', color: '#9ca3af' }, children: [skill.estimatedMinutes, " min"] })] })] }, String(skill.id)))))] }));
194
+ };
195
+ const GoalsList = ({ goals }) => {
196
+ const containerStyle = {
197
+ backgroundColor: '#ffffff',
198
+ borderRadius: '12px',
199
+ padding: '16px',
200
+ border: '1px solid #e5e7eb',
201
+ };
202
+ const titleStyle = {
203
+ fontSize: '14px',
204
+ fontWeight: 600,
205
+ color: '#374151',
206
+ marginBottom: '12px',
207
+ };
208
+ const goalStyle = {
209
+ padding: '12px 0',
210
+ borderBottom: '1px solid #f3f4f6',
211
+ };
212
+ const formatDeadline = (date) => {
213
+ const now = new Date();
214
+ const diff = date.getTime() - now.getTime();
215
+ const days = Math.ceil(diff / 86400000);
216
+ if (days < 0)
217
+ return 'Overdue';
218
+ if (days === 0)
219
+ return 'Due today';
220
+ if (days === 1)
221
+ return 'Due tomorrow';
222
+ if (days < 7)
223
+ return `${days} days left`;
224
+ return date.toLocaleDateString();
225
+ };
226
+ return (_jsxs("div", { style: containerStyle, children: [_jsx("div", { style: titleStyle, children: "Learning Goals" }), goals.length === 0 ? (_jsx("div", { style: { color: '#9ca3af', fontSize: '14px', textAlign: 'center', padding: '20px' }, children: "No active goals" })) : (goals.map((goal, index) => (_jsxs("div", { style: goalStyle, children: [_jsxs("div", { style: {
227
+ display: 'flex',
228
+ justifyContent: 'space-between',
229
+ marginBottom: '6px',
230
+ }, children: [_jsx("span", { style: { fontSize: '13px', fontWeight: 500, color: '#1f2937' }, children: goal.name }), _jsxs("span", { style: { fontSize: '12px', fontWeight: 600, color: '#3b82f6' }, children: [Math.round(goal.progress * 100), "%"] })] }), _jsx("div", { style: {
231
+ height: '6px',
232
+ backgroundColor: '#e5e7eb',
233
+ borderRadius: '3px',
234
+ overflow: 'hidden',
235
+ marginBottom: '4px',
236
+ }, children: _jsx("div", { style: {
237
+ height: '100%',
238
+ width: `${goal.progress * 100}%`,
239
+ backgroundColor: '#3b82f6',
240
+ borderRadius: '3px',
241
+ } }) }), goal.deadline && (_jsx("div", { style: { fontSize: '11px', color: '#9ca3af' }, children: formatDeadline(goal.deadline) }))] }, index))))] }));
242
+ };
243
+ // ─────────────────────────────────────────────────────────────────────────────
244
+ // Main Component
245
+ // ─────────────────────────────────────────────────────────────────────────────
246
+ /**
247
+ * ProgressDashboard Component
248
+ *
249
+ * Comprehensive dashboard for tracking learning progress.
250
+ *
251
+ * @example
252
+ * ```tsx
253
+ * import { ProgressDashboard } from 'learngraph/components';
254
+ *
255
+ * function Dashboard() {
256
+ * return (
257
+ * <ProgressDashboard
258
+ * stats={{
259
+ * totalSkills: 50,
260
+ * masteredSkills: 15,
261
+ * inProgressSkills: 5,
262
+ * availableSkills: 10,
263
+ * totalLearningTime: 480,
264
+ * averageMastery: 0.72,
265
+ * streakDays: 7,
266
+ * weeklyProgress: 3,
267
+ * }}
268
+ * bloomProgress={[
269
+ * { level: 'remember', total: 10, mastered: 8, percentage: 80 },
270
+ * { level: 'understand', total: 12, mastered: 5, percentage: 42 },
271
+ * // ...
272
+ * ]}
273
+ * recentActivity={activities}
274
+ * dueForReview={reviewSkills}
275
+ * recommendations={recommendedSkills}
276
+ * showDetailedStats
277
+ * showActivityFeed
278
+ * />
279
+ * );
280
+ * }
281
+ * ```
282
+ */
283
+ export const ProgressDashboard = ({ stats, bloomProgress, recentActivity, dueForReview = [], recommendations = [], goals = [], showDetailedStats = true, showActivityFeed = true, onSkillClick, onStartReview, className, style, }) => {
284
+ const containerStyle = {
285
+ display: 'flex',
286
+ flexDirection: 'column',
287
+ gap: '20px',
288
+ ...style,
289
+ };
290
+ const statsRowStyle = {
291
+ display: 'flex',
292
+ gap: '12px',
293
+ flexWrap: 'wrap',
294
+ };
295
+ const gridStyle = {
296
+ display: 'grid',
297
+ gridTemplateColumns: 'repeat(auto-fit, minmax(300px, 1fr))',
298
+ gap: '16px',
299
+ };
300
+ const progressPercentage = Math.round((stats.masteredSkills / stats.totalSkills) * 100);
301
+ return (_jsxs("div", { className: className, style: containerStyle, children: [_jsxs("div", { style: statsRowStyle, children: [_jsx(StatCard, { label: "Skills Mastered", value: `${stats.masteredSkills}/${stats.totalSkills}`, subValue: `${progressPercentage}% complete`, color: STATUS_COLORS.mastered }), _jsx(StatCard, { label: "Streak", value: `${stats.streakDays} days`, subValue: stats.streakDays >= 7 ? 'Keep it up!' : 'Build momentum', color: "#f59e0b" }), _jsx(StatCard, { label: "This Week", value: `+${stats.weeklyProgress}`, subValue: "skills mastered", color: "#3b82f6" }), _jsx(StatCard, { label: "Learning Time", value: `${Math.round(stats.totalLearningTime / 60)}h`, subValue: `${stats.totalLearningTime} min total` })] }), _jsx(BloomProgressBar, { progress: bloomProgress }), _jsxs("div", { style: gridStyle, children: [showActivityFeed && (_jsx(ActivityFeed, { activities: recentActivity, onSkillClick: onSkillClick })), _jsx(SkillList, { title: "Due for Review", skills: dueForReview, emptyMessage: "All caught up!", onSkillClick: onSkillClick, actionLabel: dueForReview.length > 0 ? 'Start Review' : undefined, onAction: onStartReview }), _jsx(SkillList, { title: "Recommended Next", skills: recommendations, emptyMessage: "Complete more skills to unlock recommendations", onSkillClick: onSkillClick }), goals.length > 0 && _jsx(GoalsList, { goals: goals })] }), showDetailedStats && (_jsxs("div", { style: statsRowStyle, children: [_jsx(StatCard, { label: "In Progress", value: stats.inProgressSkills, color: STATUS_COLORS.inProgress }), _jsx(StatCard, { label: "Available", value: stats.availableSkills, color: STATUS_COLORS.available }), _jsx(StatCard, { label: "Average Mastery", value: `${Math.round(stats.averageMastery * 100)}%` })] }))] }));
302
+ };
303
+ export default ProgressDashboard;
304
+ //# sourceMappingURL=ProgressDashboard.js.map