@orjok/commons 1.0.2 → 1.1.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.
- package/dist/chunk-DB3CMKPP.cjs +165 -0
- package/dist/chunk-DB3CMKPP.cjs.map +1 -0
- package/dist/chunk-ZDGYAVEC.js +165 -0
- package/dist/chunk-ZDGYAVEC.js.map +1 -0
- package/dist/hooks.cjs +492 -2
- package/dist/hooks.cjs.map +1 -1
- package/dist/hooks.d.cts +130 -2
- package/dist/hooks.d.ts +130 -2
- package/dist/hooks.js +491 -1
- package/dist/hooks.js.map +1 -1
- package/dist/index.cjs +590 -224
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +86 -14
- package/dist/index.d.ts +86 -14
- package/dist/index.js +549 -183
- package/dist/index.js.map +1 -1
- package/dist/{client-Bm9aiyTx.d.ts → practice-Dh2Tv80G.d.ts} +36 -5
- package/dist/{client-BaOC79Nc.d.cts → practice-QnWtC5A7.d.cts} +36 -5
- package/dist/testing.cjs +10 -0
- package/dist/testing.cjs.map +1 -1
- package/dist/testing.d.cts +2 -0
- package/dist/testing.d.ts +2 -0
- package/dist/testing.js +10 -0
- package/dist/testing.js.map +1 -1
- package/package.json +5 -3
package/dist/hooks.cjs
CHANGED
|
@@ -1,4 +1,14 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports, "__esModule", {value: true})
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
var _chunkDB3CMKPPcjs = require('./chunk-DB3CMKPP.cjs');
|
|
10
|
+
|
|
11
|
+
// src/hooks/useOrjokClient.ts
|
|
2
12
|
var _react = require('react');
|
|
3
13
|
var OrjokContext = _react.createContext.call(void 0, null);
|
|
4
14
|
var OrjokProvider = OrjokContext.Provider;
|
|
@@ -10,7 +20,487 @@ function useOrjokClient() {
|
|
|
10
20
|
return client;
|
|
11
21
|
}
|
|
12
22
|
|
|
23
|
+
// src/hooks/useMediaUrl.ts
|
|
24
|
+
var _reactquery = require('@tanstack/react-query');
|
|
25
|
+
function useMediaUrl(key) {
|
|
26
|
+
const client = useOrjokClient();
|
|
27
|
+
const isResolvable = Boolean(key && _chunkDB3CMKPPcjs.isStorageKey.call(void 0, key));
|
|
28
|
+
const query = _reactquery.useQuery.call(void 0, {
|
|
29
|
+
queryKey: ["media-url", key],
|
|
30
|
+
queryFn: async () => {
|
|
31
|
+
if (!key) return null;
|
|
32
|
+
return _chunkDB3CMKPPcjs.resolveMediaUrl.call(void 0, key, client.storage);
|
|
33
|
+
},
|
|
34
|
+
enabled: isResolvable,
|
|
35
|
+
staleTime: 50 * 60 * 1e3
|
|
36
|
+
// 50 mins
|
|
37
|
+
});
|
|
38
|
+
if (!key) {
|
|
39
|
+
return { url: null, isLoading: false };
|
|
40
|
+
}
|
|
41
|
+
if (!_chunkDB3CMKPPcjs.isStorageKey.call(void 0, key)) {
|
|
42
|
+
return { url: key, isLoading: false };
|
|
43
|
+
}
|
|
44
|
+
return {
|
|
45
|
+
url: _nullishCoalesce(query.data, () => ( null)),
|
|
46
|
+
isLoading: query.isLoading
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// src/hooks/useCurriculum.ts
|
|
51
|
+
|
|
52
|
+
function useCurriculum({ level, subjectId, chapterId } = {}) {
|
|
53
|
+
const client = useOrjokClient();
|
|
54
|
+
const subjectsQuery = _reactquery.useQuery.call(void 0, {
|
|
55
|
+
queryKey: ["curriculum-subjects", level],
|
|
56
|
+
queryFn: () => level ? client.curriculum.getSubjects(level) : Promise.resolve([]),
|
|
57
|
+
enabled: Boolean(level)
|
|
58
|
+
});
|
|
59
|
+
const chaptersQuery = _reactquery.useQuery.call(void 0, {
|
|
60
|
+
queryKey: ["curriculum-chapters", subjectId],
|
|
61
|
+
queryFn: () => subjectId ? client.curriculum.getChapters(subjectId) : Promise.resolve([]),
|
|
62
|
+
enabled: Boolean(subjectId)
|
|
63
|
+
});
|
|
64
|
+
const topicsQuery = _reactquery.useQuery.call(void 0, {
|
|
65
|
+
queryKey: ["curriculum-topics", chapterId],
|
|
66
|
+
queryFn: () => chapterId ? client.curriculum.getTopics(chapterId) : Promise.resolve([]),
|
|
67
|
+
enabled: Boolean(chapterId)
|
|
68
|
+
});
|
|
69
|
+
return {
|
|
70
|
+
subjects: _nullishCoalesce(subjectsQuery.data, () => ( [])),
|
|
71
|
+
chapters: _nullishCoalesce(chaptersQuery.data, () => ( [])),
|
|
72
|
+
topics: _nullishCoalesce(topicsQuery.data, () => ( [])),
|
|
73
|
+
isLoadingSubjects: subjectsQuery.isLoading,
|
|
74
|
+
isLoadingChapters: chaptersQuery.isLoading,
|
|
75
|
+
isLoadingTopics: topicsQuery.isLoading
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// src/hooks/useQuestions.ts
|
|
80
|
+
|
|
81
|
+
function useQuestions({
|
|
82
|
+
subjectId,
|
|
83
|
+
chapterId,
|
|
84
|
+
topicId,
|
|
85
|
+
language,
|
|
86
|
+
difficulty,
|
|
87
|
+
limit = 20,
|
|
88
|
+
nextToken
|
|
89
|
+
} = {}) {
|
|
90
|
+
const client = useOrjokClient();
|
|
91
|
+
const lang = language === "All" ? void 0 : language;
|
|
92
|
+
const diff = difficulty === "All" ? void 0 : difficulty;
|
|
93
|
+
const query = _reactquery.useQuery.call(void 0, {
|
|
94
|
+
queryKey: ["questions", { subjectId, chapterId, topicId, language, difficulty, limit, nextToken }],
|
|
95
|
+
queryFn: async () => {
|
|
96
|
+
if (topicId) {
|
|
97
|
+
return client.questions.listByTopic({ id: topicId, language: lang, difficulty: diff, limit, nextToken: nextToken || void 0 });
|
|
98
|
+
}
|
|
99
|
+
if (chapterId) {
|
|
100
|
+
return client.questions.listByChapter({ id: chapterId, language: lang, difficulty: diff, limit, nextToken: nextToken || void 0 });
|
|
101
|
+
}
|
|
102
|
+
if (subjectId) {
|
|
103
|
+
return client.questions.listBySubject({ id: subjectId, language: lang, difficulty: diff, limit, nextToken: nextToken || void 0 });
|
|
104
|
+
}
|
|
105
|
+
return { items: [], nextToken: null };
|
|
106
|
+
},
|
|
107
|
+
enabled: Boolean(subjectId || chapterId || topicId)
|
|
108
|
+
});
|
|
109
|
+
return {
|
|
110
|
+
questions: _nullishCoalesce(_optionalChain([query, 'access', _ => _.data, 'optionalAccess', _2 => _2.items]), () => ( [])),
|
|
111
|
+
nextToken: _nullishCoalesce(_optionalChain([query, 'access', _3 => _3.data, 'optionalAccess', _4 => _4.nextToken]), () => ( null)),
|
|
112
|
+
isLoading: query.isLoading,
|
|
113
|
+
refetch: query.refetch
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// src/hooks/usePacks.ts
|
|
118
|
+
|
|
119
|
+
function usePacks({
|
|
120
|
+
subjectId,
|
|
121
|
+
chapterId,
|
|
122
|
+
topicId,
|
|
123
|
+
language,
|
|
124
|
+
difficulty,
|
|
125
|
+
limit = 20,
|
|
126
|
+
nextToken
|
|
127
|
+
} = {}) {
|
|
128
|
+
const client = useOrjokClient();
|
|
129
|
+
const lang = language === "All" ? void 0 : language;
|
|
130
|
+
const diff = difficulty === "All" ? void 0 : difficulty;
|
|
131
|
+
const query = _reactquery.useQuery.call(void 0, {
|
|
132
|
+
queryKey: ["packs", { subjectId, chapterId, topicId, language, difficulty, limit, nextToken }],
|
|
133
|
+
queryFn: async () => {
|
|
134
|
+
if (topicId) {
|
|
135
|
+
return client.packs.listByTopic({ id: topicId, language: lang, difficulty: diff, limit, nextToken: nextToken || void 0 });
|
|
136
|
+
}
|
|
137
|
+
if (chapterId) {
|
|
138
|
+
return client.packs.listByChapter({ id: chapterId, language: lang, difficulty: diff, limit, nextToken: nextToken || void 0 });
|
|
139
|
+
}
|
|
140
|
+
if (subjectId) {
|
|
141
|
+
return client.packs.listBySubject({ id: subjectId, language: lang, difficulty: diff, limit, nextToken: nextToken || void 0 });
|
|
142
|
+
}
|
|
143
|
+
return { items: [], nextToken: null };
|
|
144
|
+
},
|
|
145
|
+
enabled: Boolean(subjectId || chapterId || topicId)
|
|
146
|
+
});
|
|
147
|
+
return {
|
|
148
|
+
packs: _nullishCoalesce(_optionalChain([query, 'access', _5 => _5.data, 'optionalAccess', _6 => _6.items]), () => ( [])),
|
|
149
|
+
nextToken: _nullishCoalesce(_optionalChain([query, 'access', _7 => _7.data, 'optionalAccess', _8 => _8.nextToken]), () => ( null)),
|
|
150
|
+
isLoading: query.isLoading,
|
|
151
|
+
refetch: query.refetch
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
function usePackDetail(packId) {
|
|
155
|
+
const client = useOrjokClient();
|
|
156
|
+
const query = _reactquery.useQuery.call(void 0, {
|
|
157
|
+
queryKey: ["pack-detail", packId],
|
|
158
|
+
queryFn: async () => {
|
|
159
|
+
if (!packId) return null;
|
|
160
|
+
return client.packs.getFull(packId);
|
|
161
|
+
},
|
|
162
|
+
enabled: Boolean(packId)
|
|
163
|
+
});
|
|
164
|
+
return {
|
|
165
|
+
pack: _nullishCoalesce(query.data, () => ( null)),
|
|
166
|
+
questions: _nullishCoalesce(_optionalChain([query, 'access', _9 => _9.data, 'optionalAccess', _10 => _10.questions, 'optionalAccess', _11 => _11.items]), () => ( [])),
|
|
167
|
+
isLoading: query.isLoading,
|
|
168
|
+
refetch: query.refetch
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// src/hooks/useContest.ts
|
|
173
|
+
|
|
174
|
+
function useContest(contestId, checkParticipation = false) {
|
|
175
|
+
const client = useOrjokClient();
|
|
176
|
+
const contestQuery = _reactquery.useQuery.call(void 0, {
|
|
177
|
+
queryKey: ["contest", contestId],
|
|
178
|
+
queryFn: async () => {
|
|
179
|
+
if (!contestId) return null;
|
|
180
|
+
return client.contests.get(contestId);
|
|
181
|
+
},
|
|
182
|
+
enabled: Boolean(contestId)
|
|
183
|
+
});
|
|
184
|
+
const partQuery = _reactquery.useQuery.call(void 0, {
|
|
185
|
+
queryKey: ["contest-participation", contestId],
|
|
186
|
+
queryFn: async () => {
|
|
187
|
+
if (!contestId || !checkParticipation) return null;
|
|
188
|
+
return client.contests.checkParticipation(contestId);
|
|
189
|
+
},
|
|
190
|
+
enabled: Boolean(contestId && checkParticipation)
|
|
191
|
+
});
|
|
192
|
+
return {
|
|
193
|
+
contest: _nullishCoalesce(contestQuery.data, () => ( null)),
|
|
194
|
+
participation: _nullishCoalesce(partQuery.data, () => ( null)),
|
|
195
|
+
isLoading: contestQuery.isLoading || checkParticipation && partQuery.isLoading,
|
|
196
|
+
refetch: async () => {
|
|
197
|
+
await Promise.all([contestQuery.refetch(), partQuery.refetch()]);
|
|
198
|
+
}
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
function useContestsList({ level, nextToken } = {}) {
|
|
202
|
+
const client = useOrjokClient();
|
|
203
|
+
const query = _reactquery.useQuery.call(void 0, {
|
|
204
|
+
queryKey: ["contests-list", level, nextToken],
|
|
205
|
+
queryFn: () => client.contests.list(nextToken, level)
|
|
206
|
+
});
|
|
207
|
+
return {
|
|
208
|
+
contests: _nullishCoalesce(_optionalChain([query, 'access', _12 => _12.data, 'optionalAccess', _13 => _13.items]), () => ( [])),
|
|
209
|
+
nextToken: _nullishCoalesce(_optionalChain([query, 'access', _14 => _14.data, 'optionalAccess', _15 => _15.nextToken]), () => ( null)),
|
|
210
|
+
isLoading: query.isLoading,
|
|
211
|
+
refetch: query.refetch
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
// src/hooks/useCourse.ts
|
|
216
|
+
|
|
217
|
+
function useCourse(courseId) {
|
|
218
|
+
const client = useOrjokClient();
|
|
219
|
+
const query = _reactquery.useQuery.call(void 0, {
|
|
220
|
+
queryKey: ["course", courseId],
|
|
221
|
+
queryFn: async () => {
|
|
222
|
+
if (!courseId) return null;
|
|
223
|
+
return client.courses.get(courseId);
|
|
224
|
+
},
|
|
225
|
+
enabled: Boolean(courseId)
|
|
226
|
+
});
|
|
227
|
+
return {
|
|
228
|
+
course: _nullishCoalesce(query.data, () => ( null)),
|
|
229
|
+
isLoading: query.isLoading,
|
|
230
|
+
refetch: query.refetch
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
function useCourseItems(courseId) {
|
|
234
|
+
const client = useOrjokClient();
|
|
235
|
+
const query = _reactquery.useQuery.call(void 0, {
|
|
236
|
+
queryKey: ["course-items", courseId],
|
|
237
|
+
queryFn: async () => {
|
|
238
|
+
if (!courseId) return [];
|
|
239
|
+
return client.courses.getItems(courseId);
|
|
240
|
+
},
|
|
241
|
+
enabled: Boolean(courseId)
|
|
242
|
+
});
|
|
243
|
+
return {
|
|
244
|
+
items: _nullishCoalesce(query.data, () => ( [])),
|
|
245
|
+
isLoading: query.isLoading,
|
|
246
|
+
refetch: query.refetch
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
function useCourseLiveExams(courseId) {
|
|
250
|
+
const client = useOrjokClient();
|
|
251
|
+
const query = _reactquery.useQuery.call(void 0, {
|
|
252
|
+
queryKey: ["course-live-exams", courseId],
|
|
253
|
+
queryFn: async () => {
|
|
254
|
+
if (!courseId) return { items: [], nextToken: null };
|
|
255
|
+
return client.courses.getLiveExams(courseId);
|
|
256
|
+
},
|
|
257
|
+
enabled: Boolean(courseId)
|
|
258
|
+
});
|
|
259
|
+
return {
|
|
260
|
+
exams: _nullishCoalesce(_optionalChain([query, 'access', _16 => _16.data, 'optionalAccess', _17 => _17.items]), () => ( [])),
|
|
261
|
+
isLoading: query.isLoading,
|
|
262
|
+
refetch: query.refetch
|
|
263
|
+
};
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
// src/hooks/useProgress.ts
|
|
267
|
+
|
|
268
|
+
function useProgress(userId) {
|
|
269
|
+
const client = useOrjokClient();
|
|
270
|
+
const subjectsQuery = _reactquery.useQuery.call(void 0, {
|
|
271
|
+
queryKey: ["user-subject-progress", userId],
|
|
272
|
+
queryFn: () => userId ? client.progress.getSubjectProgress(userId) : Promise.resolve([]),
|
|
273
|
+
enabled: Boolean(userId)
|
|
274
|
+
});
|
|
275
|
+
const chaptersQuery = _reactquery.useQuery.call(void 0, {
|
|
276
|
+
queryKey: ["user-chapter-progress", userId],
|
|
277
|
+
queryFn: () => userId ? client.progress.getChapterProgress(userId) : Promise.resolve([]),
|
|
278
|
+
enabled: Boolean(userId)
|
|
279
|
+
});
|
|
280
|
+
const topicsQuery = _reactquery.useQuery.call(void 0, {
|
|
281
|
+
queryKey: ["user-topic-progress", userId],
|
|
282
|
+
queryFn: () => userId ? client.progress.getTopicProgress(userId) : Promise.resolve([]),
|
|
283
|
+
enabled: Boolean(userId)
|
|
284
|
+
});
|
|
285
|
+
const subjectsProgress = _nullishCoalesce(subjectsQuery.data, () => ( []));
|
|
286
|
+
const chaptersProgress = _nullishCoalesce(chaptersQuery.data, () => ( []));
|
|
287
|
+
const topicsProgress = _nullishCoalesce(topicsQuery.data, () => ( []));
|
|
288
|
+
const metrics = _chunkDB3CMKPPcjs.aggregateSubjectMetrics.call(void 0, subjectsProgress);
|
|
289
|
+
return {
|
|
290
|
+
subjectsProgress,
|
|
291
|
+
chaptersProgress,
|
|
292
|
+
topicsProgress,
|
|
293
|
+
metrics,
|
|
294
|
+
isLoading: subjectsQuery.isLoading || chaptersQuery.isLoading || topicsQuery.isLoading,
|
|
295
|
+
refetch: async () => {
|
|
296
|
+
await Promise.all([
|
|
297
|
+
subjectsQuery.refetch(),
|
|
298
|
+
chaptersQuery.refetch(),
|
|
299
|
+
topicsQuery.refetch()
|
|
300
|
+
]);
|
|
301
|
+
}
|
|
302
|
+
};
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
// src/hooks/usePractice.ts
|
|
306
|
+
|
|
307
|
+
function usePractice({
|
|
308
|
+
subjectId,
|
|
309
|
+
chapterIds = [],
|
|
310
|
+
topicIds = [],
|
|
311
|
+
language = "Bangla",
|
|
312
|
+
difficulty = "All",
|
|
313
|
+
userId,
|
|
314
|
+
isCreator
|
|
315
|
+
} = {}) {
|
|
316
|
+
const client = useOrjokClient();
|
|
317
|
+
const [mode, setMode] = _react.useState.call(void 0, "setup");
|
|
318
|
+
const [questions, setQuestions] = _react.useState.call(void 0, []);
|
|
319
|
+
const [currentIdx, setCurrentIdx] = _react.useState.call(void 0, 0);
|
|
320
|
+
const [selectedOption, setSelectedOption] = _react.useState.call(void 0, null);
|
|
321
|
+
const [isAnswered, setIsAnswered] = _react.useState.call(void 0, false);
|
|
322
|
+
const [isCorrect, setIsCorrect] = _react.useState.call(void 0, null);
|
|
323
|
+
const [score, setScore] = _react.useState.call(void 0, 0);
|
|
324
|
+
const [totalPracticed, setTotalPracticed] = _react.useState.call(void 0, 0);
|
|
325
|
+
const [isLoading, setIsLoading] = _react.useState.call(void 0, false);
|
|
326
|
+
const [isValidating, setIsValidating] = _react.useState.call(void 0, false);
|
|
327
|
+
const fetchQuestionsPool = _react.useCallback.call(void 0, async () => {
|
|
328
|
+
const bounds = [];
|
|
329
|
+
if (topicIds.length > 0) {
|
|
330
|
+
topicIds.forEach((tId) => bounds.push({ id: tId, type: "topic" }));
|
|
331
|
+
} else if (chapterIds.length > 0) {
|
|
332
|
+
chapterIds.forEach((cId) => bounds.push({ id: cId, type: "chapter" }));
|
|
333
|
+
} else if (subjectId) {
|
|
334
|
+
bounds.push({ id: subjectId, type: "subject" });
|
|
335
|
+
}
|
|
336
|
+
if (bounds.length === 0) return [];
|
|
337
|
+
const queries = bounds.map(async (b) => {
|
|
338
|
+
try {
|
|
339
|
+
if (b.type === "topic") {
|
|
340
|
+
return await client.questions.listByTopic({ id: b.id, limit: 50 });
|
|
341
|
+
} else if (b.type === "chapter") {
|
|
342
|
+
return await client.questions.listByChapter({ id: b.id, limit: 50 });
|
|
343
|
+
} else {
|
|
344
|
+
return await client.questions.listBySubject({ id: b.id, limit: 50 });
|
|
345
|
+
}
|
|
346
|
+
} catch (e) {
|
|
347
|
+
console.error("Error fetching bounds query in practice:", b, e);
|
|
348
|
+
return { items: [] };
|
|
349
|
+
}
|
|
350
|
+
});
|
|
351
|
+
const results = await Promise.all(queries);
|
|
352
|
+
const uniqueMap = /* @__PURE__ */ new Map();
|
|
353
|
+
results.forEach((r) => {
|
|
354
|
+
(r.items || []).forEach((q) => {
|
|
355
|
+
if (q && q.id && !uniqueMap.has(q.id)) {
|
|
356
|
+
uniqueMap.set(q.id, q);
|
|
357
|
+
}
|
|
358
|
+
});
|
|
359
|
+
});
|
|
360
|
+
let list = Array.from(uniqueMap.values()).filter((q) => {
|
|
361
|
+
if (!_chunkDB3CMKPPcjs.isLanguageMatch.call(void 0, q.language, language)) return false;
|
|
362
|
+
if (!_chunkDB3CMKPPcjs.isDifficultyMatch.call(void 0, q.difficulty, difficulty)) return false;
|
|
363
|
+
return true;
|
|
364
|
+
});
|
|
365
|
+
if (list.length < 5 && subjectId && bounds.some((b) => b.type !== "subject")) {
|
|
366
|
+
try {
|
|
367
|
+
const subRes = await client.questions.listBySubject({ id: subjectId, limit: 50 });
|
|
368
|
+
(subRes.items || []).forEach((q) => {
|
|
369
|
+
if (q && q.id && !uniqueMap.has(q.id)) {
|
|
370
|
+
if (_chunkDB3CMKPPcjs.isLanguageMatch.call(void 0, q.language, language) && _chunkDB3CMKPPcjs.isDifficultyMatch.call(void 0, q.difficulty, difficulty)) {
|
|
371
|
+
list.push(q);
|
|
372
|
+
uniqueMap.set(q.id, q);
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
});
|
|
376
|
+
} catch (e) {
|
|
377
|
+
console.error("Error fetching subject fallback in practice:", e);
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
return list.filter(_chunkDB3CMKPPcjs.isValidMCQ);
|
|
381
|
+
}, [client, subjectId, chapterIds, topicIds, language, difficulty]);
|
|
382
|
+
const startPractice = _react.useCallback.call(void 0, async () => {
|
|
383
|
+
setIsLoading(true);
|
|
384
|
+
setMode("practice");
|
|
385
|
+
setCurrentIdx(0);
|
|
386
|
+
setScore(0);
|
|
387
|
+
setTotalPracticed(0);
|
|
388
|
+
setSelectedOption(null);
|
|
389
|
+
setIsAnswered(false);
|
|
390
|
+
setIsCorrect(null);
|
|
391
|
+
try {
|
|
392
|
+
const fetched = await fetchQuestionsPool();
|
|
393
|
+
setQuestions(_chunkDB3CMKPPcjs.shuffle.call(void 0, fetched));
|
|
394
|
+
} catch (e) {
|
|
395
|
+
console.error("Error starting practice:", e);
|
|
396
|
+
setQuestions([]);
|
|
397
|
+
} finally {
|
|
398
|
+
setIsLoading(false);
|
|
399
|
+
}
|
|
400
|
+
}, [fetchQuestionsPool]);
|
|
401
|
+
const selectOption = _react.useCallback.call(void 0,
|
|
402
|
+
async (optionId) => {
|
|
403
|
+
if (isAnswered || isValidating || questions.length === 0) return;
|
|
404
|
+
setSelectedOption(optionId);
|
|
405
|
+
setIsValidating(true);
|
|
406
|
+
const currentQ = questions[currentIdx];
|
|
407
|
+
if (!currentQ) {
|
|
408
|
+
setIsValidating(false);
|
|
409
|
+
return;
|
|
410
|
+
}
|
|
411
|
+
try {
|
|
412
|
+
const fullQ = await client.questions.get(currentQ.id);
|
|
413
|
+
const ansVal = _optionalChain([fullQ, 'optionalAccess', _18 => _18.answer]);
|
|
414
|
+
const rawOpts = currentQ.options;
|
|
415
|
+
const optsList = Array.isArray(rawOpts) ? rawOpts : rawOpts && typeof rawOpts === "object" && Array.isArray(rawOpts.items) ? rawOpts.items : [];
|
|
416
|
+
const chosenOpt = optsList.find((o) => _optionalChain([o, 'optionalAccess', _19 => _19.id]) === optionId);
|
|
417
|
+
const correct = Boolean(
|
|
418
|
+
ansVal && (ansVal === optionId || chosenOpt && ansVal === chosenOpt.content)
|
|
419
|
+
);
|
|
420
|
+
setIsCorrect(correct);
|
|
421
|
+
setIsAnswered(true);
|
|
422
|
+
setTotalPracticed((prev) => prev + 1);
|
|
423
|
+
if (correct) setScore((prev) => prev + 1);
|
|
424
|
+
if (userId && isCreator) {
|
|
425
|
+
void client.progress.track({
|
|
426
|
+
questionId: currentQ.id,
|
|
427
|
+
isCorrect: correct,
|
|
428
|
+
subjectId: currentQ.subjectId || subjectId,
|
|
429
|
+
chapterId: currentQ.chapterId || (chapterIds.length === 1 ? chapterIds[0] : void 0),
|
|
430
|
+
topicId: currentQ.topicId || (topicIds.length === 1 ? topicIds[0] : void 0)
|
|
431
|
+
}).catch((e) => console.error("Tracking practice progress error:", e));
|
|
432
|
+
}
|
|
433
|
+
} catch (err) {
|
|
434
|
+
console.error("Error validating option in practice:", err);
|
|
435
|
+
} finally {
|
|
436
|
+
setIsValidating(false);
|
|
437
|
+
}
|
|
438
|
+
},
|
|
439
|
+
[client, isAnswered, isValidating, questions, currentIdx, userId, isCreator, subjectId, chapterIds, topicIds]
|
|
440
|
+
);
|
|
441
|
+
const nextQuestion = _react.useCallback.call(void 0, () => {
|
|
442
|
+
if (questions.length === 0) return;
|
|
443
|
+
if (currentIdx + 1 < questions.length) {
|
|
444
|
+
setCurrentIdx((prev) => prev + 1);
|
|
445
|
+
setSelectedOption(null);
|
|
446
|
+
setIsAnswered(false);
|
|
447
|
+
setIsCorrect(null);
|
|
448
|
+
} else {
|
|
449
|
+
setQuestions((prev) => _chunkDB3CMKPPcjs.shuffle.call(void 0, prev));
|
|
450
|
+
setCurrentIdx(0);
|
|
451
|
+
setSelectedOption(null);
|
|
452
|
+
setIsAnswered(false);
|
|
453
|
+
setIsCorrect(null);
|
|
454
|
+
}
|
|
455
|
+
}, [questions.length, currentIdx]);
|
|
456
|
+
const finishPractice = _react.useCallback.call(void 0, () => {
|
|
457
|
+
setMode("summary");
|
|
458
|
+
}, []);
|
|
459
|
+
const resetPractice = _react.useCallback.call(void 0, () => {
|
|
460
|
+
setMode("setup");
|
|
461
|
+
setQuestions([]);
|
|
462
|
+
setCurrentIdx(0);
|
|
463
|
+
setScore(0);
|
|
464
|
+
setTotalPracticed(0);
|
|
465
|
+
setSelectedOption(null);
|
|
466
|
+
setIsAnswered(false);
|
|
467
|
+
setIsCorrect(null);
|
|
468
|
+
}, []);
|
|
469
|
+
const accuracy = totalPracticed > 0 ? Math.round(score / totalPracticed * 100) : 0;
|
|
470
|
+
return {
|
|
471
|
+
mode,
|
|
472
|
+
questions,
|
|
473
|
+
currentIdx,
|
|
474
|
+
currentQuestion: _nullishCoalesce(questions[currentIdx], () => ( null)),
|
|
475
|
+
selectedOption,
|
|
476
|
+
isAnswered,
|
|
477
|
+
isCorrect,
|
|
478
|
+
score,
|
|
479
|
+
totalPracticed,
|
|
480
|
+
accuracy,
|
|
481
|
+
isLoading,
|
|
482
|
+
isValidating,
|
|
483
|
+
startPractice,
|
|
484
|
+
selectOption,
|
|
485
|
+
nextQuestion,
|
|
486
|
+
finishPractice,
|
|
487
|
+
resetPractice
|
|
488
|
+
};
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
|
|
492
|
+
|
|
493
|
+
|
|
494
|
+
|
|
495
|
+
|
|
496
|
+
|
|
497
|
+
|
|
498
|
+
|
|
499
|
+
|
|
500
|
+
|
|
501
|
+
|
|
502
|
+
|
|
13
503
|
|
|
14
504
|
|
|
15
|
-
exports.OrjokProvider = OrjokProvider; exports.useOrjokClient = useOrjokClient;
|
|
505
|
+
exports.OrjokProvider = OrjokProvider; exports.useContest = useContest; exports.useContestsList = useContestsList; exports.useCourse = useCourse; exports.useCourseItems = useCourseItems; exports.useCourseLiveExams = useCourseLiveExams; exports.useCurriculum = useCurriculum; exports.useMediaUrl = useMediaUrl; exports.useOrjokClient = useOrjokClient; exports.usePackDetail = usePackDetail; exports.usePacks = usePacks; exports.usePractice = usePractice; exports.useProgress = useProgress; exports.useQuestions = useQuestions;
|
|
16
506
|
//# sourceMappingURL=hooks.cjs.map
|
package/dist/hooks.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/home/runner/work/orjok/orjok/packages/commons/dist/hooks.cjs","../src/hooks/useOrjokClient.ts"],"names":[],"mappings":"AAAA;ACAA,8BAA0C;AAG1C,IAAM,aAAA,EAAe,kCAAA,IAAsC,CAAA;AAEpD,IAAM,cAAA,EAAgB,YAAA,CAAa,QAAA;AAEnC,SAAS,cAAA,CAAA,EAA8B;AAC5C,EAAA,MAAM,OAAA,EAAS,+BAAA,YAAuB,CAAA;AACtC,EAAA,GAAA,CAAI,CAAC,MAAA,EAAQ;AACX,IAAA,MAAM,IAAI,KAAA,CAAM,qDAAqD,CAAA;AAAA,EACvE;AACA,EAAA,OAAO,MAAA;AACT;ADFA;AACE;AACA;AACF,+EAAC","file":"/home/runner/work/orjok/orjok/packages/commons/dist/hooks.cjs","sourcesContent":[null,"import { createContext, useContext } from \"react\";\nimport type { OrjokClient } from \"../client\";\n\nconst OrjokContext = createContext<OrjokClient | null>(null);\n\nexport const OrjokProvider = OrjokContext.Provider;\n\nexport function useOrjokClient(): OrjokClient {\n const client = useContext(OrjokContext);\n if (!client) {\n throw new Error(\"useOrjokClient must be used within an OrjokProvider\");\n }\n return client;\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["/home/runner/work/orjok/orjok/packages/commons/dist/hooks.cjs","../src/hooks/useOrjokClient.ts","../src/hooks/useMediaUrl.ts","../src/hooks/useCurriculum.ts","../src/hooks/useQuestions.ts","../src/hooks/usePacks.ts","../src/hooks/useContest.ts","../src/hooks/useCourse.ts","../src/hooks/useProgress.ts","../src/hooks/usePractice.ts"],"names":["useQuery"],"mappings":"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","file":"/home/runner/work/orjok/orjok/packages/commons/dist/hooks.cjs","sourcesContent":[null,"import { createContext, useContext } from \"react\";\nimport type { OrjokClient } from \"../client\";\n\nconst OrjokContext = createContext<OrjokClient | null>(null);\n\nexport const OrjokProvider = OrjokContext.Provider;\n\nexport function useOrjokClient(): OrjokClient {\n const client = useContext(OrjokContext);\n if (!client) {\n throw new Error(\"useOrjokClient must be used within an OrjokProvider\");\n }\n return client;\n}\n","import { useQuery } from \"@tanstack/react-query\";\nimport { useOrjokClient } from \"./useOrjokClient\";\nimport { isStorageKey, resolveMediaUrl } from \"../logic/media-url\";\n\nexport function useMediaUrl(key: string | null | undefined): {\n url: string | null;\n isLoading: boolean;\n} {\n const client = useOrjokClient();\n\n const isResolvable = Boolean(key && isStorageKey(key));\n\n const query = useQuery({\n queryKey: [\"media-url\", key],\n queryFn: async () => {\n if (!key) return null;\n return resolveMediaUrl(key, client.storage);\n },\n enabled: isResolvable,\n staleTime: 50 * 60 * 1000, // 50 mins\n });\n\n if (!key) {\n return { url: null, isLoading: false };\n }\n\n if (!isStorageKey(key)) {\n return { url: key, isLoading: false };\n }\n\n return {\n url: query.data ?? null,\n isLoading: query.isLoading,\n };\n}\n","import { useQuery } from \"@tanstack/react-query\";\nimport { useOrjokClient } from \"./useOrjokClient\";\nimport type { Subject, Chapter, Topic } from \"../types/models\";\n\nexport interface UseCurriculumParams {\n level?: string;\n subjectId?: string;\n chapterId?: string;\n}\n\nexport function useCurriculum({ level, subjectId, chapterId }: UseCurriculumParams = {}): {\n subjects: Subject[];\n chapters: Chapter[];\n topics: Topic[];\n isLoadingSubjects: boolean;\n isLoadingChapters: boolean;\n isLoadingTopics: boolean;\n} {\n const client = useOrjokClient();\n\n const subjectsQuery = useQuery({\n queryKey: [\"curriculum-subjects\", level],\n queryFn: () => (level ? client.curriculum.getSubjects(level) : Promise.resolve([])),\n enabled: Boolean(level),\n });\n\n const chaptersQuery = useQuery({\n queryKey: [\"curriculum-chapters\", subjectId],\n queryFn: () => (subjectId ? client.curriculum.getChapters(subjectId) : Promise.resolve([])),\n enabled: Boolean(subjectId),\n });\n\n const topicsQuery = useQuery({\n queryKey: [\"curriculum-topics\", chapterId],\n queryFn: () => (chapterId ? client.curriculum.getTopics(chapterId) : Promise.resolve([])),\n enabled: Boolean(chapterId),\n });\n\n return {\n subjects: subjectsQuery.data ?? [],\n chapters: chaptersQuery.data ?? [],\n topics: topicsQuery.data ?? [],\n isLoadingSubjects: subjectsQuery.isLoading,\n isLoadingChapters: chaptersQuery.isLoading,\n isLoadingTopics: topicsQuery.isLoading,\n };\n}\n","import { useQuery } from \"@tanstack/react-query\";\nimport { useOrjokClient } from \"./useOrjokClient\";\nimport type { QuestionObject } from \"../types/models\";\nimport type { Difficulty, Language } from \"../types/enums\";\n\nexport interface UseQuestionsParams {\n subjectId?: string;\n chapterId?: string;\n topicId?: string;\n language?: Language | \"All\";\n difficulty?: Difficulty | \"All\";\n limit?: number;\n nextToken?: string | null;\n}\n\nexport function useQuestions({\n subjectId,\n chapterId,\n topicId,\n language,\n difficulty,\n limit = 20,\n nextToken,\n}: UseQuestionsParams = {}): {\n questions: QuestionObject[];\n nextToken: string | null;\n isLoading: boolean;\n refetch: () => Promise<unknown>;\n} {\n const client = useOrjokClient();\n\n const lang = language === \"All\" ? undefined : language;\n const diff = difficulty === \"All\" ? undefined : difficulty;\n\n const query = useQuery({\n queryKey: [\"questions\", { subjectId, chapterId, topicId, language, difficulty, limit, nextToken }],\n queryFn: async () => {\n if (topicId) {\n return client.questions.listByTopic({ id: topicId, language: lang, difficulty: diff, limit, nextToken: nextToken || undefined });\n }\n if (chapterId) {\n return client.questions.listByChapter({ id: chapterId, language: lang, difficulty: diff, limit, nextToken: nextToken || undefined });\n }\n if (subjectId) {\n return client.questions.listBySubject({ id: subjectId, language: lang, difficulty: diff, limit, nextToken: nextToken || undefined });\n }\n return { items: [], nextToken: null };\n },\n enabled: Boolean(subjectId || chapterId || topicId),\n });\n\n return {\n questions: query.data?.items ?? [],\n nextToken: query.data?.nextToken ?? null,\n isLoading: query.isLoading,\n refetch: query.refetch,\n };\n}\n","import { useQuery } from \"@tanstack/react-query\";\nimport { useOrjokClient } from \"./useOrjokClient\";\nimport type { Pack, QuestionObject } from \"../types/models\";\nimport type { Difficulty, Language } from \"../types/enums\";\n\nexport interface UsePacksParams {\n subjectId?: string;\n chapterId?: string;\n topicId?: string;\n language?: Language | \"All\";\n difficulty?: Difficulty | \"All\";\n limit?: number;\n nextToken?: string | null;\n}\n\nexport function usePacks({\n subjectId,\n chapterId,\n topicId,\n language,\n difficulty,\n limit = 20,\n nextToken,\n}: UsePacksParams = {}): {\n packs: Pack[];\n nextToken: string | null;\n isLoading: boolean;\n refetch: () => Promise<unknown>;\n} {\n const client = useOrjokClient();\n\n const lang = language === \"All\" ? undefined : language;\n const diff = difficulty === \"All\" ? undefined : difficulty;\n\n const query = useQuery({\n queryKey: [\"packs\", { subjectId, chapterId, topicId, language, difficulty, limit, nextToken }],\n queryFn: async () => {\n if (topicId) {\n return client.packs.listByTopic({ id: topicId, language: lang, difficulty: diff, limit, nextToken: nextToken || undefined });\n }\n if (chapterId) {\n return client.packs.listByChapter({ id: chapterId, language: lang, difficulty: diff, limit, nextToken: nextToken || undefined });\n }\n if (subjectId) {\n return client.packs.listBySubject({ id: subjectId, language: lang, difficulty: diff, limit, nextToken: nextToken || undefined });\n }\n return { items: [], nextToken: null };\n },\n enabled: Boolean(subjectId || chapterId || topicId),\n });\n\n return {\n packs: query.data?.items ?? [],\n nextToken: query.data?.nextToken ?? null,\n isLoading: query.isLoading,\n refetch: query.refetch,\n };\n}\n\nexport function usePackDetail(packId: string | undefined): {\n pack: Pack | null;\n questions: QuestionObject[];\n isLoading: boolean;\n refetch: () => Promise<unknown>;\n} {\n const client = useOrjokClient();\n\n const query = useQuery({\n queryKey: [\"pack-detail\", packId],\n queryFn: async () => {\n if (!packId) return null;\n return client.packs.getFull(packId);\n },\n enabled: Boolean(packId),\n });\n\n return {\n pack: query.data ?? null,\n questions: query.data?.questions?.items ?? [],\n isLoading: query.isLoading,\n refetch: query.refetch,\n };\n}\n","import { useQuery } from \"@tanstack/react-query\";\nimport { useOrjokClient } from \"./useOrjokClient\";\nimport type { Contest } from \"../types/models\";\nimport type { CheckParticipationResponse } from \"../types/responses\";\n\nexport function useContest(contestId: string | undefined, checkParticipation: boolean = false): {\n contest: Contest | null;\n participation: CheckParticipationResponse | null;\n isLoading: boolean;\n refetch: () => Promise<unknown>;\n} {\n const client = useOrjokClient();\n\n const contestQuery = useQuery({\n queryKey: [\"contest\", contestId],\n queryFn: async () => {\n if (!contestId) return null;\n return client.contests.get(contestId);\n },\n enabled: Boolean(contestId),\n });\n\n const partQuery = useQuery({\n queryKey: [\"contest-participation\", contestId],\n queryFn: async () => {\n if (!contestId || !checkParticipation) return null;\n return client.contests.checkParticipation(contestId);\n },\n enabled: Boolean(contestId && checkParticipation),\n });\n\n return {\n contest: contestQuery.data ?? null,\n participation: partQuery.data ?? null,\n isLoading: contestQuery.isLoading || (checkParticipation && partQuery.isLoading),\n refetch: async () => {\n await Promise.all([contestQuery.refetch(), partQuery.refetch()]);\n },\n };\n}\n\nexport function useContestsList({ level, nextToken }: { level?: string; nextToken?: string } = {}): {\n contests: Contest[];\n nextToken: string | null;\n isLoading: boolean;\n refetch: () => Promise<unknown>;\n} {\n const client = useOrjokClient();\n\n const query = useQuery({\n queryKey: [\"contests-list\", level, nextToken],\n queryFn: () => client.contests.list(nextToken, level),\n });\n\n return {\n contests: query.data?.items ?? [],\n nextToken: query.data?.nextToken ?? null,\n isLoading: query.isLoading,\n refetch: query.refetch,\n };\n}\n","import { useQuery } from \"@tanstack/react-query\";\nimport { useOrjokClient } from \"./useOrjokClient\";\nimport type { Course, CourseItem, CourseLiveExam } from \"../types/models\";\n\nexport function useCourse(courseId: string | undefined): {\n course: Course | null;\n isLoading: boolean;\n refetch: () => Promise<unknown>;\n} {\n const client = useOrjokClient();\n\n const query = useQuery({\n queryKey: [\"course\", courseId],\n queryFn: async () => {\n if (!courseId) return null;\n return client.courses.get(courseId);\n },\n enabled: Boolean(courseId),\n });\n\n return {\n course: query.data ?? null,\n isLoading: query.isLoading,\n refetch: query.refetch,\n };\n}\n\nexport function useCourseItems(courseId: string | undefined): {\n items: CourseItem[];\n isLoading: boolean;\n refetch: () => Promise<unknown>;\n} {\n const client = useOrjokClient();\n\n const query = useQuery({\n queryKey: [\"course-items\", courseId],\n queryFn: async () => {\n if (!courseId) return [];\n return client.courses.getItems(courseId);\n },\n enabled: Boolean(courseId),\n });\n\n return {\n items: query.data ?? [],\n isLoading: query.isLoading,\n refetch: query.refetch,\n };\n}\n\nexport function useCourseLiveExams(courseId: string | undefined): {\n exams: CourseLiveExam[];\n isLoading: boolean;\n refetch: () => Promise<unknown>;\n} {\n const client = useOrjokClient();\n\n const query = useQuery({\n queryKey: [\"course-live-exams\", courseId],\n queryFn: async () => {\n if (!courseId) return { items: [], nextToken: null };\n return client.courses.getLiveExams(courseId);\n },\n enabled: Boolean(courseId),\n });\n\n return {\n exams: query.data?.items ?? [],\n isLoading: query.isLoading,\n refetch: query.refetch,\n };\n}\n","import { useQuery } from \"@tanstack/react-query\";\nimport { useOrjokClient } from \"./useOrjokClient\";\nimport type { UserSubjectProgress, UserChapterProgress, UserTopicProgress } from \"../types/models\";\nimport { aggregateSubjectMetrics, type PracticeMetrics } from \"../logic/practice\";\n\nexport function useProgress(userId: string | undefined): {\n subjectsProgress: UserSubjectProgress[];\n chaptersProgress: UserChapterProgress[];\n topicsProgress: UserTopicProgress[];\n metrics: PracticeMetrics;\n isLoading: boolean;\n refetch: () => Promise<unknown>;\n} {\n const client = useOrjokClient();\n\n const subjectsQuery = useQuery({\n queryKey: [\"user-subject-progress\", userId],\n queryFn: () => (userId ? client.progress.getSubjectProgress(userId) : Promise.resolve([])),\n enabled: Boolean(userId),\n });\n\n const chaptersQuery = useQuery({\n queryKey: [\"user-chapter-progress\", userId],\n queryFn: () => (userId ? client.progress.getChapterProgress(userId) : Promise.resolve([])),\n enabled: Boolean(userId),\n });\n\n const topicsQuery = useQuery({\n queryKey: [\"user-topic-progress\", userId],\n queryFn: () => (userId ? client.progress.getTopicProgress(userId) : Promise.resolve([])),\n enabled: Boolean(userId),\n });\n\n const subjectsProgress = subjectsQuery.data ?? [];\n const chaptersProgress = chaptersQuery.data ?? [];\n const topicsProgress = topicsQuery.data ?? [];\n\n const metrics = aggregateSubjectMetrics(subjectsProgress);\n\n return {\n subjectsProgress,\n chaptersProgress,\n topicsProgress,\n metrics,\n isLoading: subjectsQuery.isLoading || chaptersQuery.isLoading || topicsQuery.isLoading,\n refetch: async () => {\n await Promise.all([\n subjectsQuery.refetch(),\n chaptersQuery.refetch(),\n topicsQuery.refetch(),\n ]);\n },\n };\n}\n","import { useState, useCallback } from \"react\";\nimport { useOrjokClient } from \"./useOrjokClient\";\nimport type { QuestionObject } from \"../types/models\";\nimport { isLanguageMatch, isDifficultyMatch, isValidMCQ } from \"../logic/practice\";\nimport { shuffle } from \"../utils/shuffle\";\n\nexport type PracticeMode = \"setup\" | \"practice\" | \"summary\";\n\nexport interface ItemBounds {\n id: string;\n type: \"topic\" | \"chapter\" | \"subject\";\n}\n\nexport interface UsePracticeProps {\n subjectId?: string;\n chapterIds?: string[];\n topicIds?: string[];\n language?: string;\n difficulty?: string;\n userId?: string;\n isCreator?: boolean;\n}\n\nexport function usePractice({\n subjectId,\n chapterIds = [],\n topicIds = [],\n language = \"Bangla\",\n difficulty = \"All\",\n userId,\n isCreator,\n}: UsePracticeProps = {}) {\n const client = useOrjokClient();\n\n const [mode, setMode] = useState<PracticeMode>(\"setup\");\n const [questions, setQuestions] = useState<QuestionObject[]>([]);\n const [currentIdx, setCurrentIdx] = useState<number>(0);\n const [selectedOption, setSelectedOption] = useState<string | null>(null);\n const [isAnswered, setIsAnswered] = useState<boolean>(false);\n const [isCorrect, setIsCorrect] = useState<boolean | null>(null);\n const [score, setScore] = useState<number>(0);\n const [totalPracticed, setTotalPracticed] = useState<number>(0);\n const [isLoading, setIsLoading] = useState<boolean>(false);\n const [isValidating, setIsValidating] = useState<boolean>(false);\n\n const fetchQuestionsPool = useCallback(async (): Promise<QuestionObject[]> => {\n const bounds: ItemBounds[] = [];\n if (topicIds.length > 0) {\n topicIds.forEach((tId) => bounds.push({ id: tId, type: \"topic\" }));\n } else if (chapterIds.length > 0) {\n chapterIds.forEach((cId) => bounds.push({ id: cId, type: \"chapter\" }));\n } else if (subjectId) {\n bounds.push({ id: subjectId, type: \"subject\" });\n }\n\n if (bounds.length === 0) return [];\n\n const queries = bounds.map(async (b) => {\n try {\n if (b.type === \"topic\") {\n return await client.questions.listByTopic({ id: b.id, limit: 50 });\n } else if (b.type === \"chapter\") {\n return await client.questions.listByChapter({ id: b.id, limit: 50 });\n } else {\n return await client.questions.listBySubject({ id: b.id, limit: 50 });\n }\n } catch (e) {\n console.error(\"Error fetching bounds query in practice:\", b, e);\n return { items: [] };\n }\n });\n\n const results = await Promise.all(queries);\n const uniqueMap = new Map<string, QuestionObject>();\n\n results.forEach((r) => {\n (r.items || []).forEach((q) => {\n if (q && q.id && !uniqueMap.has(q.id)) {\n uniqueMap.set(q.id, q);\n }\n });\n });\n\n let list = Array.from(uniqueMap.values()).filter((q) => {\n if (!isLanguageMatch(q.language, language)) return false;\n if (!isDifficultyMatch(q.difficulty, difficulty)) return false;\n return true;\n });\n\n // Fallback to parent subject if fewer than 5 matching questions\n if (list.length < 5 && subjectId && bounds.some((b) => b.type !== \"subject\")) {\n try {\n const subRes = await client.questions.listBySubject({ id: subjectId, limit: 50 });\n (subRes.items || []).forEach((q) => {\n if (q && q.id && !uniqueMap.has(q.id)) {\n if (isLanguageMatch(q.language, language) && isDifficultyMatch(q.difficulty, difficulty)) {\n list.push(q);\n uniqueMap.set(q.id, q);\n }\n }\n });\n } catch (e) {\n console.error(\"Error fetching subject fallback in practice:\", e);\n }\n }\n\n return list.filter(isValidMCQ);\n }, [client, subjectId, chapterIds, topicIds, language, difficulty]);\n\n const startPractice = useCallback(async () => {\n setIsLoading(true);\n setMode(\"practice\");\n setCurrentIdx(0);\n setScore(0);\n setTotalPracticed(0);\n setSelectedOption(null);\n setIsAnswered(false);\n setIsCorrect(null);\n\n try {\n const fetched = await fetchQuestionsPool();\n setQuestions(shuffle(fetched));\n } catch (e) {\n console.error(\"Error starting practice:\", e);\n setQuestions([]);\n } finally {\n setIsLoading(false);\n }\n }, [fetchQuestionsPool]);\n\n const selectOption = useCallback(\n async (optionId: string) => {\n if (isAnswered || isValidating || questions.length === 0) return;\n setSelectedOption(optionId);\n setIsValidating(true);\n const currentQ = questions[currentIdx];\n if (!currentQ) {\n setIsValidating(false);\n return;\n }\n\n try {\n const fullQ = await client.questions.get(currentQ.id);\n const ansVal = fullQ?.answer;\n const rawOpts = currentQ.options as unknown;\n const optsList = Array.isArray(rawOpts)\n ? rawOpts\n : (rawOpts && typeof rawOpts === \"object\" && Array.isArray((rawOpts as { items?: unknown[] }).items))\n ? (rawOpts as { items: Array<{ id?: string; content?: string }> }).items\n : [];\n\n const chosenOpt = optsList.find((o) => o?.id === optionId);\n const correct = Boolean(\n ansVal && (ansVal === optionId || (chosenOpt && ansVal === chosenOpt.content))\n );\n\n setIsCorrect(correct);\n setIsAnswered(true);\n setTotalPracticed((prev) => prev + 1);\n if (correct) setScore((prev) => prev + 1);\n\n if (userId && isCreator) {\n void client.progress\n .track({\n questionId: currentQ.id,\n isCorrect: correct,\n subjectId: currentQ.subjectId || subjectId,\n chapterId: currentQ.chapterId || (chapterIds.length === 1 ? chapterIds[0] : undefined),\n topicId: currentQ.topicId || (topicIds.length === 1 ? topicIds[0] : undefined),\n })\n .catch((e) => console.error(\"Tracking practice progress error:\", e));\n }\n } catch (err) {\n console.error(\"Error validating option in practice:\", err);\n } finally {\n setIsValidating(false);\n }\n },\n [client, isAnswered, isValidating, questions, currentIdx, userId, isCreator, subjectId, chapterIds, topicIds]\n );\n\n const nextQuestion = useCallback(() => {\n if (questions.length === 0) return;\n if (currentIdx + 1 < questions.length) {\n setCurrentIdx((prev) => prev + 1);\n setSelectedOption(null);\n setIsAnswered(false);\n setIsCorrect(null);\n } else {\n // Seamless reshuffle and continue\n setQuestions((prev) => shuffle(prev));\n setCurrentIdx(0);\n setSelectedOption(null);\n setIsAnswered(false);\n setIsCorrect(null);\n }\n }, [questions.length, currentIdx]);\n\n const finishPractice = useCallback(() => {\n setMode(\"summary\");\n }, []);\n\n const resetPractice = useCallback(() => {\n setMode(\"setup\");\n setQuestions([]);\n setCurrentIdx(0);\n setScore(0);\n setTotalPracticed(0);\n setSelectedOption(null);\n setIsAnswered(false);\n setIsCorrect(null);\n }, []);\n\n const accuracy = totalPracticed > 0 ? Math.round((score / totalPracticed) * 100) : 0;\n\n return {\n mode,\n questions,\n currentIdx,\n currentQuestion: questions[currentIdx] ?? null,\n selectedOption,\n isAnswered,\n isCorrect,\n score,\n totalPracticed,\n accuracy,\n isLoading,\n isValidating,\n startPractice,\n selectOption,\n nextQuestion,\n finishPractice,\n resetPractice,\n };\n}\n"]}
|