@orjok/commons 1.0.2 → 1.2.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/amplify.cjs +30 -5
- package/dist/amplify.cjs.map +1 -1
- package/dist/amplify.d.cts +5 -2
- package/dist/amplify.d.ts +5 -2
- package/dist/amplify.js +30 -5
- package/dist/amplify.js.map +1 -1
- package/dist/chunk-B4UJE3F4.js +529 -0
- package/dist/chunk-B4UJE3F4.js.map +1 -0
- package/dist/chunk-ODXD2WJN.cjs +529 -0
- package/dist/chunk-ODXD2WJN.cjs.map +1 -0
- package/dist/hooks.cjs +639 -2
- package/dist/hooks.cjs.map +1 -1
- package/dist/hooks.d.cts +162 -3
- package/dist/hooks.d.ts +162 -3
- package/dist/hooks.js +638 -1
- package/dist/hooks.js.map +1 -1
- package/dist/index.cjs +2454 -363
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +303 -15
- package/dist/index.d.ts +303 -15
- package/dist/index.js +2430 -339
- package/dist/index.js.map +1 -1
- package/dist/{client-BaOC79Nc.d.cts → notification-BoqtkNrc.d.ts} +392 -12
- package/dist/{client-Bm9aiyTx.d.ts → notification-Ctfy0m05.d.cts} +392 -12
- package/dist/{storage-DLqdJgQt.d.cts → storage-9pK8KwIM.d.cts} +4 -2
- package/dist/{storage-DLqdJgQt.d.ts → storage-9pK8KwIM.d.ts} +4 -2
- package/dist/testing.cjs +34 -3
- package/dist/testing.cjs.map +1 -1
- package/dist/testing.d.cts +9 -2
- package/dist/testing.d.ts +9 -2
- package/dist/testing.js +34 -3
- package/dist/testing.js.map +1 -1
- package/package.json +6 -3
package/dist/hooks.cjs
CHANGED
|
@@ -1,4 +1,17 @@
|
|
|
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
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
var _chunkODXD2WJNcjs = require('./chunk-ODXD2WJN.cjs');
|
|
13
|
+
|
|
14
|
+
// src/hooks/useOrjokClient.ts
|
|
2
15
|
var _react = require('react');
|
|
3
16
|
var OrjokContext = _react.createContext.call(void 0, null);
|
|
4
17
|
var OrjokProvider = OrjokContext.Provider;
|
|
@@ -10,7 +23,631 @@ function useOrjokClient() {
|
|
|
10
23
|
return client;
|
|
11
24
|
}
|
|
12
25
|
|
|
26
|
+
// src/hooks/useMediaUrl.ts
|
|
27
|
+
var _reactquery = require('@tanstack/react-query');
|
|
28
|
+
function useMediaUrl(key) {
|
|
29
|
+
const client = useOrjokClient();
|
|
30
|
+
const isResolvable = Boolean(key && _chunkODXD2WJNcjs.isStorageKey.call(void 0, key));
|
|
31
|
+
const query = _reactquery.useQuery.call(void 0, {
|
|
32
|
+
queryKey: ["media-url", key],
|
|
33
|
+
queryFn: async () => {
|
|
34
|
+
if (!key) return null;
|
|
35
|
+
return _chunkODXD2WJNcjs.resolveMediaUrl.call(void 0, key, client.storage);
|
|
36
|
+
},
|
|
37
|
+
enabled: isResolvable,
|
|
38
|
+
staleTime: 50 * 60 * 1e3
|
|
39
|
+
// 50 mins
|
|
40
|
+
});
|
|
41
|
+
if (!key) {
|
|
42
|
+
return { url: null, isLoading: false };
|
|
43
|
+
}
|
|
44
|
+
if (!_chunkODXD2WJNcjs.isStorageKey.call(void 0, key)) {
|
|
45
|
+
return { url: key, isLoading: false };
|
|
46
|
+
}
|
|
47
|
+
return {
|
|
48
|
+
url: _nullishCoalesce(query.data, () => ( null)),
|
|
49
|
+
isLoading: query.isLoading
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// src/hooks/useCurriculum.ts
|
|
54
|
+
|
|
55
|
+
function useCurriculum({ level, subjectId, chapterId } = {}) {
|
|
56
|
+
const client = useOrjokClient();
|
|
57
|
+
const subjectsQuery = _reactquery.useQuery.call(void 0, {
|
|
58
|
+
queryKey: ["curriculum-subjects", level],
|
|
59
|
+
queryFn: () => level ? client.curriculum.getSubjects(level) : Promise.resolve([]),
|
|
60
|
+
enabled: Boolean(level)
|
|
61
|
+
});
|
|
62
|
+
const chaptersQuery = _reactquery.useQuery.call(void 0, {
|
|
63
|
+
queryKey: ["curriculum-chapters", subjectId],
|
|
64
|
+
queryFn: () => subjectId ? client.curriculum.getChapters(subjectId) : Promise.resolve([]),
|
|
65
|
+
enabled: Boolean(subjectId)
|
|
66
|
+
});
|
|
67
|
+
const topicsQuery = _reactquery.useQuery.call(void 0, {
|
|
68
|
+
queryKey: ["curriculum-topics", chapterId],
|
|
69
|
+
queryFn: () => chapterId ? client.curriculum.getTopics(chapterId) : Promise.resolve([]),
|
|
70
|
+
enabled: Boolean(chapterId)
|
|
71
|
+
});
|
|
72
|
+
return {
|
|
73
|
+
subjects: _nullishCoalesce(subjectsQuery.data, () => ( [])),
|
|
74
|
+
chapters: _nullishCoalesce(chaptersQuery.data, () => ( [])),
|
|
75
|
+
topics: _nullishCoalesce(topicsQuery.data, () => ( [])),
|
|
76
|
+
isLoadingSubjects: subjectsQuery.isLoading,
|
|
77
|
+
isLoadingChapters: chaptersQuery.isLoading,
|
|
78
|
+
isLoadingTopics: topicsQuery.isLoading
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// src/hooks/useQuestions.ts
|
|
83
|
+
|
|
84
|
+
function useQuestions({
|
|
85
|
+
subjectId,
|
|
86
|
+
chapterId,
|
|
87
|
+
topicId,
|
|
88
|
+
language,
|
|
89
|
+
difficulty,
|
|
90
|
+
limit = 20,
|
|
91
|
+
nextToken
|
|
92
|
+
} = {}) {
|
|
93
|
+
const client = useOrjokClient();
|
|
94
|
+
const lang = language === "All" ? void 0 : language;
|
|
95
|
+
const diff = difficulty === "All" ? void 0 : difficulty;
|
|
96
|
+
const query = _reactquery.useQuery.call(void 0, {
|
|
97
|
+
queryKey: ["questions", { subjectId, chapterId, topicId, language, difficulty, limit, nextToken }],
|
|
98
|
+
queryFn: async () => {
|
|
99
|
+
if (topicId) {
|
|
100
|
+
return client.questions.listByTopic({ id: topicId, language: lang, difficulty: diff, limit, nextToken: nextToken || void 0 });
|
|
101
|
+
}
|
|
102
|
+
if (chapterId) {
|
|
103
|
+
return client.questions.listByChapter({ id: chapterId, language: lang, difficulty: diff, limit, nextToken: nextToken || void 0 });
|
|
104
|
+
}
|
|
105
|
+
if (subjectId) {
|
|
106
|
+
return client.questions.listBySubject({ id: subjectId, language: lang, difficulty: diff, limit, nextToken: nextToken || void 0 });
|
|
107
|
+
}
|
|
108
|
+
return { items: [], nextToken: null };
|
|
109
|
+
},
|
|
110
|
+
enabled: Boolean(subjectId || chapterId || topicId)
|
|
111
|
+
});
|
|
112
|
+
return {
|
|
113
|
+
questions: _nullishCoalesce(_optionalChain([query, 'access', _ => _.data, 'optionalAccess', _2 => _2.items]), () => ( [])),
|
|
114
|
+
nextToken: _nullishCoalesce(_optionalChain([query, 'access', _3 => _3.data, 'optionalAccess', _4 => _4.nextToken]), () => ( null)),
|
|
115
|
+
isLoading: query.isLoading,
|
|
116
|
+
refetch: query.refetch
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// src/hooks/usePacks.ts
|
|
121
|
+
|
|
122
|
+
function usePacks({
|
|
123
|
+
subjectId,
|
|
124
|
+
chapterId,
|
|
125
|
+
topicId,
|
|
126
|
+
language,
|
|
127
|
+
difficulty,
|
|
128
|
+
limit = 20,
|
|
129
|
+
nextToken
|
|
130
|
+
} = {}) {
|
|
131
|
+
const client = useOrjokClient();
|
|
132
|
+
const lang = language === "All" ? void 0 : language;
|
|
133
|
+
const diff = difficulty === "All" ? void 0 : difficulty;
|
|
134
|
+
const query = _reactquery.useQuery.call(void 0, {
|
|
135
|
+
queryKey: ["packs", { subjectId, chapterId, topicId, language, difficulty, limit, nextToken }],
|
|
136
|
+
queryFn: async () => {
|
|
137
|
+
if (topicId) {
|
|
138
|
+
return client.packs.listByTopic({ id: topicId, language: lang, difficulty: diff, limit, nextToken: nextToken || void 0 });
|
|
139
|
+
}
|
|
140
|
+
if (chapterId) {
|
|
141
|
+
return client.packs.listByChapter({ id: chapterId, language: lang, difficulty: diff, limit, nextToken: nextToken || void 0 });
|
|
142
|
+
}
|
|
143
|
+
if (subjectId) {
|
|
144
|
+
return client.packs.listBySubject({ id: subjectId, language: lang, difficulty: diff, limit, nextToken: nextToken || void 0 });
|
|
145
|
+
}
|
|
146
|
+
return { items: [], nextToken: null };
|
|
147
|
+
},
|
|
148
|
+
enabled: Boolean(subjectId || chapterId || topicId)
|
|
149
|
+
});
|
|
150
|
+
return {
|
|
151
|
+
packs: _nullishCoalesce(_optionalChain([query, 'access', _5 => _5.data, 'optionalAccess', _6 => _6.items]), () => ( [])),
|
|
152
|
+
nextToken: _nullishCoalesce(_optionalChain([query, 'access', _7 => _7.data, 'optionalAccess', _8 => _8.nextToken]), () => ( null)),
|
|
153
|
+
isLoading: query.isLoading,
|
|
154
|
+
refetch: query.refetch
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
function usePackDetail(packId) {
|
|
158
|
+
const client = useOrjokClient();
|
|
159
|
+
const query = _reactquery.useQuery.call(void 0, {
|
|
160
|
+
queryKey: ["pack-detail", packId],
|
|
161
|
+
queryFn: async () => {
|
|
162
|
+
if (!packId) return null;
|
|
163
|
+
return client.packs.getFull(packId);
|
|
164
|
+
},
|
|
165
|
+
enabled: Boolean(packId)
|
|
166
|
+
});
|
|
167
|
+
return {
|
|
168
|
+
pack: _nullishCoalesce(query.data, () => ( null)),
|
|
169
|
+
questions: _nullishCoalesce(_optionalChain([query, 'access', _9 => _9.data, 'optionalAccess', _10 => _10.questions, 'optionalAccess', _11 => _11.items]), () => ( [])),
|
|
170
|
+
isLoading: query.isLoading,
|
|
171
|
+
refetch: query.refetch
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// src/hooks/useContest.ts
|
|
176
|
+
|
|
177
|
+
function useContest(contestId, checkParticipation = false) {
|
|
178
|
+
const client = useOrjokClient();
|
|
179
|
+
const contestQuery = _reactquery.useQuery.call(void 0, {
|
|
180
|
+
queryKey: ["contest", contestId],
|
|
181
|
+
queryFn: async () => {
|
|
182
|
+
if (!contestId) return null;
|
|
183
|
+
return client.contests.get(contestId);
|
|
184
|
+
},
|
|
185
|
+
enabled: Boolean(contestId)
|
|
186
|
+
});
|
|
187
|
+
const partQuery = _reactquery.useQuery.call(void 0, {
|
|
188
|
+
queryKey: ["contest-participation", contestId],
|
|
189
|
+
queryFn: async () => {
|
|
190
|
+
if (!contestId || !checkParticipation) return null;
|
|
191
|
+
return client.contests.checkParticipation(contestId);
|
|
192
|
+
},
|
|
193
|
+
enabled: Boolean(contestId && checkParticipation)
|
|
194
|
+
});
|
|
195
|
+
return {
|
|
196
|
+
contest: _nullishCoalesce(contestQuery.data, () => ( null)),
|
|
197
|
+
participation: _nullishCoalesce(partQuery.data, () => ( null)),
|
|
198
|
+
isLoading: contestQuery.isLoading || checkParticipation && partQuery.isLoading,
|
|
199
|
+
refetch: async () => {
|
|
200
|
+
await Promise.all([contestQuery.refetch(), partQuery.refetch()]);
|
|
201
|
+
}
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
function useContestsList({ level, nextToken } = {}) {
|
|
205
|
+
const client = useOrjokClient();
|
|
206
|
+
const query = _reactquery.useQuery.call(void 0, {
|
|
207
|
+
queryKey: ["contests-list", level, nextToken],
|
|
208
|
+
queryFn: () => client.contests.list(nextToken, level)
|
|
209
|
+
});
|
|
210
|
+
return {
|
|
211
|
+
contests: _nullishCoalesce(_optionalChain([query, 'access', _12 => _12.data, 'optionalAccess', _13 => _13.items]), () => ( [])),
|
|
212
|
+
nextToken: _nullishCoalesce(_optionalChain([query, 'access', _14 => _14.data, 'optionalAccess', _15 => _15.nextToken]), () => ( null)),
|
|
213
|
+
isLoading: query.isLoading,
|
|
214
|
+
refetch: query.refetch
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
// src/hooks/useCourse.ts
|
|
219
|
+
|
|
220
|
+
function useCourse(courseId) {
|
|
221
|
+
const client = useOrjokClient();
|
|
222
|
+
const query = _reactquery.useQuery.call(void 0, {
|
|
223
|
+
queryKey: ["course", courseId],
|
|
224
|
+
queryFn: async () => {
|
|
225
|
+
if (!courseId) return null;
|
|
226
|
+
return client.courses.get(courseId);
|
|
227
|
+
},
|
|
228
|
+
enabled: Boolean(courseId)
|
|
229
|
+
});
|
|
230
|
+
return {
|
|
231
|
+
course: _nullishCoalesce(query.data, () => ( null)),
|
|
232
|
+
isLoading: query.isLoading,
|
|
233
|
+
refetch: query.refetch
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
function useCourseItems(courseId) {
|
|
237
|
+
const client = useOrjokClient();
|
|
238
|
+
const query = _reactquery.useQuery.call(void 0, {
|
|
239
|
+
queryKey: ["course-items", courseId],
|
|
240
|
+
queryFn: async () => {
|
|
241
|
+
if (!courseId) return [];
|
|
242
|
+
return client.courses.getItems(courseId);
|
|
243
|
+
},
|
|
244
|
+
enabled: Boolean(courseId)
|
|
245
|
+
});
|
|
246
|
+
return {
|
|
247
|
+
items: _nullishCoalesce(query.data, () => ( [])),
|
|
248
|
+
isLoading: query.isLoading,
|
|
249
|
+
refetch: query.refetch
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
function useCourseLiveExams(courseId) {
|
|
253
|
+
const client = useOrjokClient();
|
|
254
|
+
const query = _reactquery.useQuery.call(void 0, {
|
|
255
|
+
queryKey: ["course-live-exams", courseId],
|
|
256
|
+
queryFn: async () => {
|
|
257
|
+
if (!courseId) return { items: [], nextToken: null };
|
|
258
|
+
return client.courses.getLiveExams(courseId);
|
|
259
|
+
},
|
|
260
|
+
enabled: Boolean(courseId)
|
|
261
|
+
});
|
|
262
|
+
return {
|
|
263
|
+
exams: _nullishCoalesce(_optionalChain([query, 'access', _16 => _16.data, 'optionalAccess', _17 => _17.items]), () => ( [])),
|
|
264
|
+
isLoading: query.isLoading,
|
|
265
|
+
refetch: query.refetch
|
|
266
|
+
};
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
// src/hooks/useProgress.ts
|
|
270
|
+
|
|
271
|
+
function useProgress(userId) {
|
|
272
|
+
const client = useOrjokClient();
|
|
273
|
+
const subjectsQuery = _reactquery.useQuery.call(void 0, {
|
|
274
|
+
queryKey: ["user-subject-progress", userId],
|
|
275
|
+
queryFn: () => userId ? client.progress.getSubjectProgress(userId) : Promise.resolve([]),
|
|
276
|
+
enabled: Boolean(userId)
|
|
277
|
+
});
|
|
278
|
+
const chaptersQuery = _reactquery.useQuery.call(void 0, {
|
|
279
|
+
queryKey: ["user-chapter-progress", userId],
|
|
280
|
+
queryFn: () => userId ? client.progress.getChapterProgress(userId) : Promise.resolve([]),
|
|
281
|
+
enabled: Boolean(userId)
|
|
282
|
+
});
|
|
283
|
+
const topicsQuery = _reactquery.useQuery.call(void 0, {
|
|
284
|
+
queryKey: ["user-topic-progress", userId],
|
|
285
|
+
queryFn: () => userId ? client.progress.getTopicProgress(userId) : Promise.resolve([]),
|
|
286
|
+
enabled: Boolean(userId)
|
|
287
|
+
});
|
|
288
|
+
const subjectsProgress = _nullishCoalesce(subjectsQuery.data, () => ( []));
|
|
289
|
+
const chaptersProgress = _nullishCoalesce(chaptersQuery.data, () => ( []));
|
|
290
|
+
const topicsProgress = _nullishCoalesce(topicsQuery.data, () => ( []));
|
|
291
|
+
const metrics = _chunkODXD2WJNcjs.aggregateSubjectMetrics.call(void 0, subjectsProgress);
|
|
292
|
+
return {
|
|
293
|
+
subjectsProgress,
|
|
294
|
+
chaptersProgress,
|
|
295
|
+
topicsProgress,
|
|
296
|
+
metrics,
|
|
297
|
+
isLoading: subjectsQuery.isLoading || chaptersQuery.isLoading || topicsQuery.isLoading,
|
|
298
|
+
refetch: async () => {
|
|
299
|
+
await Promise.all([
|
|
300
|
+
subjectsQuery.refetch(),
|
|
301
|
+
chaptersQuery.refetch(),
|
|
302
|
+
topicsQuery.refetch()
|
|
303
|
+
]);
|
|
304
|
+
}
|
|
305
|
+
};
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
// src/hooks/usePractice.ts
|
|
309
|
+
|
|
310
|
+
function usePractice({
|
|
311
|
+
subjectId,
|
|
312
|
+
chapterIds = [],
|
|
313
|
+
topicIds = [],
|
|
314
|
+
language = "Bangla",
|
|
315
|
+
difficulty = "All",
|
|
316
|
+
userId,
|
|
317
|
+
isCreator
|
|
318
|
+
} = {}) {
|
|
319
|
+
const client = useOrjokClient();
|
|
320
|
+
const [mode, setMode] = _react.useState.call(void 0, "setup");
|
|
321
|
+
const [questions, setQuestions] = _react.useState.call(void 0, []);
|
|
322
|
+
const [currentIdx, setCurrentIdx] = _react.useState.call(void 0, 0);
|
|
323
|
+
const [selectedOption, setSelectedOption] = _react.useState.call(void 0, null);
|
|
324
|
+
const [isAnswered, setIsAnswered] = _react.useState.call(void 0, false);
|
|
325
|
+
const [isCorrect, setIsCorrect] = _react.useState.call(void 0, null);
|
|
326
|
+
const [score, setScore] = _react.useState.call(void 0, 0);
|
|
327
|
+
const [totalPracticed, setTotalPracticed] = _react.useState.call(void 0, 0);
|
|
328
|
+
const [isLoading, setIsLoading] = _react.useState.call(void 0, false);
|
|
329
|
+
const [isValidating, setIsValidating] = _react.useState.call(void 0, false);
|
|
330
|
+
const fetchQuestionsPool = _react.useCallback.call(void 0, async () => {
|
|
331
|
+
const bounds = [];
|
|
332
|
+
if (topicIds.length > 0) {
|
|
333
|
+
topicIds.forEach((tId) => bounds.push({ id: tId, type: "topic" }));
|
|
334
|
+
} else if (chapterIds.length > 0) {
|
|
335
|
+
chapterIds.forEach((cId) => bounds.push({ id: cId, type: "chapter" }));
|
|
336
|
+
} else if (subjectId) {
|
|
337
|
+
bounds.push({ id: subjectId, type: "subject" });
|
|
338
|
+
}
|
|
339
|
+
if (bounds.length === 0) return [];
|
|
340
|
+
const queries = bounds.map(async (b) => {
|
|
341
|
+
try {
|
|
342
|
+
if (b.type === "topic") {
|
|
343
|
+
return await client.questions.listByTopic({ id: b.id, limit: 50 });
|
|
344
|
+
} else if (b.type === "chapter") {
|
|
345
|
+
return await client.questions.listByChapter({ id: b.id, limit: 50 });
|
|
346
|
+
} else {
|
|
347
|
+
return await client.questions.listBySubject({ id: b.id, limit: 50 });
|
|
348
|
+
}
|
|
349
|
+
} catch (e) {
|
|
350
|
+
console.error("Error fetching bounds query in practice:", b, e);
|
|
351
|
+
return { items: [] };
|
|
352
|
+
}
|
|
353
|
+
});
|
|
354
|
+
const results = await Promise.all(queries);
|
|
355
|
+
const uniqueMap = /* @__PURE__ */ new Map();
|
|
356
|
+
results.forEach((r) => {
|
|
357
|
+
(r.items || []).forEach((q) => {
|
|
358
|
+
if (q && q.id && !uniqueMap.has(q.id)) {
|
|
359
|
+
uniqueMap.set(q.id, q);
|
|
360
|
+
}
|
|
361
|
+
});
|
|
362
|
+
});
|
|
363
|
+
let list = Array.from(uniqueMap.values()).filter((q) => {
|
|
364
|
+
if (!_chunkODXD2WJNcjs.isLanguageMatch.call(void 0, q.language, language)) return false;
|
|
365
|
+
if (!_chunkODXD2WJNcjs.isDifficultyMatch.call(void 0, q.difficulty, difficulty)) return false;
|
|
366
|
+
return true;
|
|
367
|
+
});
|
|
368
|
+
if (list.length < 5 && subjectId && bounds.some((b) => b.type !== "subject")) {
|
|
369
|
+
try {
|
|
370
|
+
const subRes = await client.questions.listBySubject({ id: subjectId, limit: 50 });
|
|
371
|
+
(subRes.items || []).forEach((q) => {
|
|
372
|
+
if (q && q.id && !uniqueMap.has(q.id)) {
|
|
373
|
+
if (_chunkODXD2WJNcjs.isLanguageMatch.call(void 0, q.language, language) && _chunkODXD2WJNcjs.isDifficultyMatch.call(void 0, q.difficulty, difficulty)) {
|
|
374
|
+
list.push(q);
|
|
375
|
+
uniqueMap.set(q.id, q);
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
});
|
|
379
|
+
} catch (e) {
|
|
380
|
+
console.error("Error fetching subject fallback in practice:", e);
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
return list.filter(_chunkODXD2WJNcjs.isValidMCQ);
|
|
384
|
+
}, [client, subjectId, chapterIds, topicIds, language, difficulty]);
|
|
385
|
+
const startPractice = _react.useCallback.call(void 0, async () => {
|
|
386
|
+
setIsLoading(true);
|
|
387
|
+
setMode("practice");
|
|
388
|
+
setCurrentIdx(0);
|
|
389
|
+
setScore(0);
|
|
390
|
+
setTotalPracticed(0);
|
|
391
|
+
setSelectedOption(null);
|
|
392
|
+
setIsAnswered(false);
|
|
393
|
+
setIsCorrect(null);
|
|
394
|
+
try {
|
|
395
|
+
const fetched = await fetchQuestionsPool();
|
|
396
|
+
setQuestions(_chunkODXD2WJNcjs.shuffle.call(void 0, fetched));
|
|
397
|
+
} catch (e) {
|
|
398
|
+
console.error("Error starting practice:", e);
|
|
399
|
+
setQuestions([]);
|
|
400
|
+
} finally {
|
|
401
|
+
setIsLoading(false);
|
|
402
|
+
}
|
|
403
|
+
}, [fetchQuestionsPool]);
|
|
404
|
+
const selectOption = _react.useCallback.call(void 0,
|
|
405
|
+
async (optionId) => {
|
|
406
|
+
if (isAnswered || isValidating || questions.length === 0) return;
|
|
407
|
+
setSelectedOption(optionId);
|
|
408
|
+
setIsValidating(true);
|
|
409
|
+
const currentQ = questions[currentIdx];
|
|
410
|
+
if (!currentQ) {
|
|
411
|
+
setIsValidating(false);
|
|
412
|
+
return;
|
|
413
|
+
}
|
|
414
|
+
try {
|
|
415
|
+
const fullQ = await client.questions.get(currentQ.id);
|
|
416
|
+
const ansVal = _optionalChain([fullQ, 'optionalAccess', _18 => _18.answer]);
|
|
417
|
+
const rawOpts = currentQ.options;
|
|
418
|
+
const optsList = Array.isArray(rawOpts) ? rawOpts : rawOpts && typeof rawOpts === "object" && Array.isArray(rawOpts.items) ? rawOpts.items : [];
|
|
419
|
+
const chosenOpt = optsList.find((o) => _optionalChain([o, 'optionalAccess', _19 => _19.id]) === optionId);
|
|
420
|
+
const correct = Boolean(
|
|
421
|
+
ansVal && (ansVal === optionId || chosenOpt && ansVal === chosenOpt.content)
|
|
422
|
+
);
|
|
423
|
+
setIsCorrect(correct);
|
|
424
|
+
setIsAnswered(true);
|
|
425
|
+
setTotalPracticed((prev) => prev + 1);
|
|
426
|
+
if (correct) setScore((prev) => prev + 1);
|
|
427
|
+
if (userId && isCreator) {
|
|
428
|
+
void client.progress.track({
|
|
429
|
+
questionId: currentQ.id,
|
|
430
|
+
isCorrect: correct,
|
|
431
|
+
subjectId: currentQ.subjectId || subjectId,
|
|
432
|
+
chapterId: currentQ.chapterId || (chapterIds.length === 1 ? chapterIds[0] : void 0),
|
|
433
|
+
topicId: currentQ.topicId || (topicIds.length === 1 ? topicIds[0] : void 0)
|
|
434
|
+
}).catch((e) => console.error("Tracking practice progress error:", e));
|
|
435
|
+
}
|
|
436
|
+
} catch (err) {
|
|
437
|
+
console.error("Error validating option in practice:", err);
|
|
438
|
+
} finally {
|
|
439
|
+
setIsValidating(false);
|
|
440
|
+
}
|
|
441
|
+
},
|
|
442
|
+
[client, isAnswered, isValidating, questions, currentIdx, userId, isCreator, subjectId, chapterIds, topicIds]
|
|
443
|
+
);
|
|
444
|
+
const nextQuestion = _react.useCallback.call(void 0, () => {
|
|
445
|
+
if (questions.length === 0) return;
|
|
446
|
+
if (currentIdx + 1 < questions.length) {
|
|
447
|
+
setCurrentIdx((prev) => prev + 1);
|
|
448
|
+
setSelectedOption(null);
|
|
449
|
+
setIsAnswered(false);
|
|
450
|
+
setIsCorrect(null);
|
|
451
|
+
} else {
|
|
452
|
+
setQuestions((prev) => _chunkODXD2WJNcjs.shuffle.call(void 0, prev));
|
|
453
|
+
setCurrentIdx(0);
|
|
454
|
+
setSelectedOption(null);
|
|
455
|
+
setIsAnswered(false);
|
|
456
|
+
setIsCorrect(null);
|
|
457
|
+
}
|
|
458
|
+
}, [questions.length, currentIdx]);
|
|
459
|
+
const finishPractice = _react.useCallback.call(void 0, () => {
|
|
460
|
+
setMode("summary");
|
|
461
|
+
}, []);
|
|
462
|
+
const resetPractice = _react.useCallback.call(void 0, () => {
|
|
463
|
+
setMode("setup");
|
|
464
|
+
setQuestions([]);
|
|
465
|
+
setCurrentIdx(0);
|
|
466
|
+
setScore(0);
|
|
467
|
+
setTotalPracticed(0);
|
|
468
|
+
setSelectedOption(null);
|
|
469
|
+
setIsAnswered(false);
|
|
470
|
+
setIsCorrect(null);
|
|
471
|
+
}, []);
|
|
472
|
+
const accuracy = totalPracticed > 0 ? Math.round(score / totalPracticed * 100) : 0;
|
|
473
|
+
return {
|
|
474
|
+
mode,
|
|
475
|
+
questions,
|
|
476
|
+
currentIdx,
|
|
477
|
+
currentQuestion: _nullishCoalesce(questions[currentIdx], () => ( null)),
|
|
478
|
+
selectedOption,
|
|
479
|
+
isAnswered,
|
|
480
|
+
isCorrect,
|
|
481
|
+
score,
|
|
482
|
+
totalPracticed,
|
|
483
|
+
accuracy,
|
|
484
|
+
isLoading,
|
|
485
|
+
isValidating,
|
|
486
|
+
startPractice,
|
|
487
|
+
selectOption,
|
|
488
|
+
nextQuestion,
|
|
489
|
+
finishPractice,
|
|
490
|
+
resetPractice
|
|
491
|
+
};
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
// src/hooks/useAvailablePublicExams.ts
|
|
495
|
+
|
|
496
|
+
|
|
497
|
+
function useAvailablePublicExams({
|
|
498
|
+
level,
|
|
499
|
+
exploreType = "Question",
|
|
500
|
+
enabled = true,
|
|
501
|
+
client: directClient
|
|
502
|
+
} = {}) {
|
|
503
|
+
let contextClient = null;
|
|
504
|
+
try {
|
|
505
|
+
contextClient = useOrjokClient();
|
|
506
|
+
} catch (e2) {
|
|
507
|
+
}
|
|
508
|
+
const client = _nullishCoalesce(directClient, () => ( contextClient));
|
|
509
|
+
const candidateExams = _react.useMemo.call(void 0, () => _chunkODXD2WJNcjs.getPublicExamsByLevel.call(void 0, level), [level]);
|
|
510
|
+
const query = _reactquery.useQuery.call(void 0, {
|
|
511
|
+
queryKey: ["availablePublicExams", level, exploreType],
|
|
512
|
+
queryFn: async () => {
|
|
513
|
+
if (!client || !level || candidateExams.length === 0) return candidateExams;
|
|
514
|
+
const results = await Promise.all(
|
|
515
|
+
candidateExams.map(async (exam) => {
|
|
516
|
+
try {
|
|
517
|
+
if (exploreType === "Pack") {
|
|
518
|
+
const res = await client.packs.listByPublicExam({
|
|
519
|
+
publicExam: exam.value,
|
|
520
|
+
limit: 1
|
|
521
|
+
});
|
|
522
|
+
return (_nullishCoalesce(_optionalChain([res, 'access', _20 => _20.items, 'optionalAccess', _21 => _21.length]), () => ( 0))) > 0 ? exam : null;
|
|
523
|
+
} else {
|
|
524
|
+
const res = await client.questions.listByPublicExam({
|
|
525
|
+
publicExam: exam.value,
|
|
526
|
+
limit: 1
|
|
527
|
+
});
|
|
528
|
+
return (_nullishCoalesce(_optionalChain([res, 'access', _22 => _22.items, 'optionalAccess', _23 => _23.length]), () => ( 0))) > 0 ? exam : null;
|
|
529
|
+
}
|
|
530
|
+
} catch (e3) {
|
|
531
|
+
return null;
|
|
532
|
+
}
|
|
533
|
+
})
|
|
534
|
+
);
|
|
535
|
+
return results.filter((e) => e !== null);
|
|
536
|
+
},
|
|
537
|
+
enabled: Boolean(level) && enabled,
|
|
538
|
+
staleTime: 10 * 60 * 1e3,
|
|
539
|
+
gcTime: 30 * 60 * 1e3
|
|
540
|
+
});
|
|
541
|
+
if (!enabled || !level) {
|
|
542
|
+
return {
|
|
543
|
+
availableExams: candidateExams,
|
|
544
|
+
isLoading: false,
|
|
545
|
+
isSuccess: true,
|
|
546
|
+
refetch: async () => candidateExams
|
|
547
|
+
};
|
|
548
|
+
}
|
|
549
|
+
return {
|
|
550
|
+
availableExams: _nullishCoalesce(query.data, () => ( [])),
|
|
551
|
+
isLoading: query.isLoading,
|
|
552
|
+
isSuccess: query.isSuccess,
|
|
553
|
+
refetch: query.refetch
|
|
554
|
+
};
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
// src/hooks/useNotifications.ts
|
|
558
|
+
|
|
559
|
+
function useNotifications(userId, lastReadAnnouncementAt) {
|
|
560
|
+
const client = useOrjokClient();
|
|
561
|
+
const queryClient = _reactquery.useQueryClient.call(void 0, );
|
|
562
|
+
const announcementsQuery = _reactquery.useQuery.call(void 0, {
|
|
563
|
+
queryKey: ["notifications-announcements"],
|
|
564
|
+
queryFn: async () => {
|
|
565
|
+
const result = await client.notifications.listAnnouncements(50);
|
|
566
|
+
return result.items || [];
|
|
567
|
+
},
|
|
568
|
+
enabled: Boolean(userId),
|
|
569
|
+
refetchInterval: 3e4
|
|
570
|
+
// Poll every 30s
|
|
571
|
+
});
|
|
572
|
+
const userNotificationsQuery = _reactquery.useQuery.call(void 0, {
|
|
573
|
+
queryKey: ["notifications-user", userId],
|
|
574
|
+
queryFn: async () => {
|
|
575
|
+
if (!userId) return [];
|
|
576
|
+
const result = await client.notifications.listUserNotifications(userId, 50);
|
|
577
|
+
return result.items || [];
|
|
578
|
+
},
|
|
579
|
+
enabled: Boolean(userId),
|
|
580
|
+
refetchInterval: 3e4
|
|
581
|
+
});
|
|
582
|
+
const announcements = _nullishCoalesce(announcementsQuery.data, () => ( []));
|
|
583
|
+
const userNotifications = _nullishCoalesce(userNotificationsQuery.data, () => ( []));
|
|
584
|
+
const timeline = _chunkODXD2WJNcjs.mergeNotificationTimeline.call(void 0, {
|
|
585
|
+
announcements,
|
|
586
|
+
userNotifications,
|
|
587
|
+
lastReadAnnouncementAt
|
|
588
|
+
});
|
|
589
|
+
const unreadCount = _chunkODXD2WJNcjs.calculateUnreadCount.call(void 0, {
|
|
590
|
+
announcements,
|
|
591
|
+
userNotifications,
|
|
592
|
+
lastReadAnnouncementAt
|
|
593
|
+
});
|
|
594
|
+
const markAsReadMutation = _reactquery.useMutation.call(void 0, {
|
|
595
|
+
mutationFn: (id) => client.notifications.markNotificationAsRead(id),
|
|
596
|
+
onSuccess: () => {
|
|
597
|
+
queryClient.invalidateQueries({ queryKey: ["notifications-user", userId] });
|
|
598
|
+
}
|
|
599
|
+
});
|
|
600
|
+
const deleteAnnouncementMutation = _reactquery.useMutation.call(void 0, {
|
|
601
|
+
mutationFn: (id) => client.notifications.deleteAnnouncement(id),
|
|
602
|
+
onSuccess: () => {
|
|
603
|
+
queryClient.invalidateQueries({ queryKey: ["notifications-announcements"] });
|
|
604
|
+
}
|
|
605
|
+
});
|
|
606
|
+
const deleteUserNotificationMutation = _reactquery.useMutation.call(void 0, {
|
|
607
|
+
mutationFn: (id) => client.notifications.deleteUserNotification(id),
|
|
608
|
+
onSuccess: () => {
|
|
609
|
+
queryClient.invalidateQueries({ queryKey: ["notifications-user", userId] });
|
|
610
|
+
}
|
|
611
|
+
});
|
|
612
|
+
return {
|
|
613
|
+
announcements,
|
|
614
|
+
userNotifications,
|
|
615
|
+
timeline,
|
|
616
|
+
unreadCount,
|
|
617
|
+
isLoading: announcementsQuery.isLoading || Boolean(userId) && userNotificationsQuery.isLoading,
|
|
618
|
+
refetch: async () => {
|
|
619
|
+
await Promise.all([
|
|
620
|
+
announcementsQuery.refetch(),
|
|
621
|
+
userId ? userNotificationsQuery.refetch() : Promise.resolve()
|
|
622
|
+
]);
|
|
623
|
+
},
|
|
624
|
+
markNotificationAsRead: async (id) => {
|
|
625
|
+
return markAsReadMutation.mutateAsync(id);
|
|
626
|
+
},
|
|
627
|
+
deleteAnnouncement: async (id) => {
|
|
628
|
+
return deleteAnnouncementMutation.mutateAsync(id);
|
|
629
|
+
},
|
|
630
|
+
deleteUserNotification: async (id) => {
|
|
631
|
+
return deleteUserNotificationMutation.mutateAsync(id);
|
|
632
|
+
}
|
|
633
|
+
};
|
|
634
|
+
}
|
|
635
|
+
|
|
636
|
+
|
|
637
|
+
|
|
638
|
+
|
|
639
|
+
|
|
640
|
+
|
|
641
|
+
|
|
642
|
+
|
|
643
|
+
|
|
644
|
+
|
|
645
|
+
|
|
646
|
+
|
|
647
|
+
|
|
648
|
+
|
|
649
|
+
|
|
13
650
|
|
|
14
651
|
|
|
15
|
-
exports.OrjokProvider = OrjokProvider; exports.useOrjokClient = useOrjokClient;
|
|
652
|
+
exports.OrjokProvider = OrjokProvider; exports.useAvailablePublicExams = useAvailablePublicExams; exports.useContest = useContest; exports.useContestsList = useContestsList; exports.useCourse = useCourse; exports.useCourseItems = useCourseItems; exports.useCourseLiveExams = useCourseLiveExams; exports.useCurriculum = useCurriculum; exports.useMediaUrl = useMediaUrl; exports.useNotifications = useNotifications; exports.useOrjokClient = useOrjokClient; exports.usePackDetail = usePackDetail; exports.usePacks = usePacks; exports.usePractice = usePractice; exports.useProgress = useProgress; exports.useQuestions = useQuestions;
|
|
16
653
|
//# sourceMappingURL=hooks.cjs.map
|