@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/hooks.cjs CHANGED
@@ -1,4 +1,17 @@
1
- "use strict";Object.defineProperty(exports, "__esModule", {value: true});// src/hooks/useOrjokClient.ts
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