@speakableio/core 0.1.106 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/dist/analytics.js +329 -25
  2. package/dist/analytics.js.map +1 -1
  3. package/dist/index.native.d.mts +2836 -0
  4. package/dist/index.native.d.ts +2272 -27
  5. package/dist/index.native.js +2995 -166
  6. package/dist/index.native.js.map +1 -1
  7. package/dist/index.native.mjs +3322 -0
  8. package/dist/index.native.mjs.map +1 -0
  9. package/dist/index.web.d.mts +2836 -0
  10. package/dist/index.web.js +3244 -12
  11. package/dist/index.web.js.map +1 -1
  12. package/package.json +10 -61
  13. package/dist/assignment.constants-BIKM6fYi.d.ts +0 -32
  14. package/dist/assignment.model-DLMWAp0Y.d.ts +0 -301
  15. package/dist/card.constants-DhKFipX3.d.ts +0 -54
  16. package/dist/chunk-233VJDUF.js +0 -149
  17. package/dist/chunk-233VJDUF.js.map +0 -1
  18. package/dist/chunk-2CRI5MJP.js +0 -225
  19. package/dist/chunk-2CRI5MJP.js.map +0 -1
  20. package/dist/chunk-AWVUNWML.js +0 -141
  21. package/dist/chunk-AWVUNWML.js.map +0 -1
  22. package/dist/chunk-CJ5JXKII.js +0 -129
  23. package/dist/chunk-CJ5JXKII.js.map +0 -1
  24. package/dist/chunk-EEBMPASA.js +0 -21
  25. package/dist/chunk-EEBMPASA.js.map +0 -1
  26. package/dist/chunk-H5XNOXRC.js +0 -11
  27. package/dist/chunk-H5XNOXRC.js.map +0 -1
  28. package/dist/chunk-LZG3MTSH.js +0 -53
  29. package/dist/chunk-LZG3MTSH.js.map +0 -1
  30. package/dist/chunk-OLSTHM2U.js +0 -154
  31. package/dist/chunk-OLSTHM2U.js.map +0 -1
  32. package/dist/chunk-TQGDTKTE.js +0 -13
  33. package/dist/chunk-TQGDTKTE.js.map +0 -1
  34. package/dist/chunk-YKUMIPSO.js +0 -212
  35. package/dist/chunk-YKUMIPSO.js.map +0 -1
  36. package/dist/chunk-YMJRCINF.js +0 -68
  37. package/dist/chunk-YMJRCINF.js.map +0 -1
  38. package/dist/chunk-YO34TZYN.js +0 -28
  39. package/dist/chunk-YO34TZYN.js.map +0 -1
  40. package/dist/const.d.ts +0 -331
  41. package/dist/const.js +0 -193
  42. package/dist/const.js.map +0 -1
  43. package/dist/hooks.d.ts +0 -294
  44. package/dist/hooks.js +0 -1015
  45. package/dist/hooks.js.map +0 -1
  46. package/dist/index.web.d.ts +0 -405
  47. package/dist/models.d.ts +0 -56
  48. package/dist/models.js +0 -17
  49. package/dist/models.js.map +0 -1
  50. package/dist/notification.constants-Da4-_0kX.d.ts +0 -21
  51. package/dist/repos.d.ts +0 -209
  52. package/dist/repos.js +0 -26
  53. package/dist/repos.js.map +0 -1
  54. package/dist/utils.d.ts +0 -39
  55. package/dist/utils.js +0 -180
  56. package/dist/utils.js.map +0 -1
  57. /package/dist/{analytics.d.ts → analytics.d.mts} +0 -0
package/dist/hooks.js DELETED
@@ -1,1015 +0,0 @@
1
- import {
2
- logStartAssignment,
3
- logSubmitAssignment
4
- } from "./chunk-YKUMIPSO.js";
5
- import {
6
- ANALYTICS_PLANS,
7
- ASSIGNMENT_SETTINGS_PLANS,
8
- SPEAKABLE_NOTIFICATIONS,
9
- SpeakableNotificationTypes,
10
- WEB_BASE_URL,
11
- refsScoresPractice
12
- } from "./chunk-2CRI5MJP.js";
13
- import "./chunk-YO34TZYN.js";
14
- import {
15
- getSet
16
- } from "./chunk-EEBMPASA.js";
17
- import {
18
- createCard,
19
- createCards,
20
- getCard,
21
- withErrorHandler
22
- } from "./chunk-233VJDUF.js";
23
- import "./chunk-H5XNOXRC.js";
24
- import {
25
- refsAssignmentFiresotre
26
- } from "./chunk-AWVUNWML.js";
27
- import {
28
- calculateScoreAndProgress_default,
29
- defaultScore
30
- } from "./chunk-YMJRCINF.js";
31
- import {
32
- api
33
- } from "./chunk-CJ5JXKII.js";
34
- import "./chunk-LZG3MTSH.js";
35
-
36
- // src/providers/SpeakableProvider.tsx
37
- import { createContext, useContext, useEffect, useState } from "react";
38
- import { jsx } from "react/jsx-runtime";
39
- var FsCtx = createContext(null);
40
- function useSpeakableApi() {
41
- const ctx = useContext(FsCtx);
42
- if (!ctx) throw new Error("useSpeakableApi must be used within a SpeakableProvider");
43
- return ctx;
44
- }
45
-
46
- // src/domains/assignment/hooks/assignment.hooks.ts
47
- import { useQuery } from "@tanstack/react-query";
48
- var assignmentQueryKeys = {
49
- all: ["assignments"],
50
- byId: (id) => [...assignmentQueryKeys.all, id],
51
- list: () => [...assignmentQueryKeys.all, "list"]
52
- };
53
- function useAssignment({
54
- assignmentId,
55
- enabled = true,
56
- analyticType,
57
- userId
58
- }) {
59
- const { speakableApi } = useSpeakableApi();
60
- return useQuery({
61
- queryKey: assignmentQueryKeys.byId(assignmentId),
62
- queryFn: () => speakableApi.assignmentRepo.getAssignment({
63
- assignmentId,
64
- analyticType,
65
- currentUserId: userId
66
- }),
67
- enabled
68
- });
69
- }
70
-
71
- // src/domains/assignment/hooks/score-hooks.ts
72
- import { useMutation, useQuery as useQuery2 } from "@tanstack/react-query";
73
-
74
- // src/utils/debounce.utils.ts
75
- function debounce(func, waitFor) {
76
- let timeoutId;
77
- return (...args) => new Promise((resolve, reject) => {
78
- if (timeoutId) {
79
- clearTimeout(timeoutId);
80
- }
81
- timeoutId = setTimeout(async () => {
82
- try {
83
- const result = await func(...args);
84
- resolve(result);
85
- } catch (error) {
86
- reject(error);
87
- }
88
- }, waitFor);
89
- });
90
- }
91
-
92
- // src/lib/tanstack/handle-optimistic-update-query.ts
93
- var handleOptimisticUpdate = async ({
94
- queryClient,
95
- queryKey,
96
- newData
97
- }) => {
98
- await queryClient.cancelQueries({
99
- queryKey
100
- });
101
- const previousData = queryClient.getQueryData(queryKey);
102
- if (previousData === void 0) {
103
- queryClient.setQueryData(queryKey, newData);
104
- } else {
105
- queryClient.setQueryData(queryKey, { ...previousData, ...newData });
106
- }
107
- return { previousData };
108
- };
109
-
110
- // src/hooks/usePermissions.ts
111
- var usePermissions = () => {
112
- const { permissions } = useSpeakableApi();
113
- const has = (permission) => {
114
- var _a;
115
- return (_a = permissions.permissions) == null ? void 0 : _a.includes(permission);
116
- };
117
- return {
118
- plan: permissions.plan,
119
- permissionsLoaded: permissions.loaded,
120
- isStripePlan: permissions.isStripePlan,
121
- refreshDate: permissions.refreshDate,
122
- isInstitutionPlan: permissions.isInstitutionPlan,
123
- subscriptionId: permissions.subscriptionId,
124
- contact: permissions.contact,
125
- hasGradebook: has(ANALYTICS_PLANS.ANALYTICS_GRADEBOOK),
126
- hasGoogleClassroomGradePassback: has(ASSIGNMENT_SETTINGS_PLANS.GOOGLE_CLASSROOM_GRADE_PASSBACK),
127
- hasAssessments: has(ASSIGNMENT_SETTINGS_PLANS.ASSESSMENTS),
128
- hasSectionAnalytics: has(ANALYTICS_PLANS.ANALYTICS_CLASSROOM_ANALYTICS),
129
- hasStudentReports: has(ANALYTICS_PLANS.ANALYTICS_STUDENT_PROGRESS_REPORTS),
130
- permissions: permissions || [],
131
- hasStudentPortfolios: permissions.hasStudentPortfolios,
132
- isFreeOrgTrial: permissions.type === "free_org_trial",
133
- freeOrgTrialExpired: permissions.freeOrgTrialExpired
134
- };
135
- };
136
- var usePermissions_default = usePermissions;
137
-
138
- // src/hooks/useGoogleClassroom.ts
139
- var useGoogleClassroom = () => {
140
- const submitAssignmentToGoogleClassroom = async ({
141
- assignment,
142
- scores,
143
- googleUserId = null
144
- // optional to override the user's googleUserId
145
- }) => {
146
- var _a, _b, _c;
147
- try {
148
- const { googleClassroomUserId = null } = scores;
149
- const googleId = googleUserId || googleClassroomUserId;
150
- if (!googleId)
151
- return {
152
- error: true,
153
- message: "No Google Classroom ID found"
154
- };
155
- const { courseWorkId, maxPoints, owners, courseId } = assignment;
156
- const draftGrade = (scores == null ? void 0 : scores.score) ? (scores == null ? void 0 : scores.score) / 100 * maxPoints : 0;
157
- const result = await ((_c = (_b = (_a = api).httpsCallable) == null ? void 0 : _b.call(_a, "submitAssignmentToGoogleClassroomV2")) == null ? void 0 : _c({
158
- teacherId: owners[0],
159
- courseId,
160
- courseWorkId,
161
- userId: googleId,
162
- draftGrade
163
- }));
164
- return result;
165
- } catch (error) {
166
- return { error: true, message: error.message };
167
- }
168
- };
169
- return {
170
- submitAssignmentToGoogleClassroom
171
- };
172
- };
173
-
174
- // src/domains/notification/services/create-notification.service.ts
175
- import dayjs from "dayjs";
176
-
177
- // src/domains/notification/services/send-notification.service.ts
178
- var _sendNotification = async (sendTo, notification) => {
179
- var _a, _b, _c;
180
- const results = await ((_c = (_b = (_a = api).httpsCallable) == null ? void 0 : _b.call(_a, "createNotificationV2")) == null ? void 0 : _c({
181
- sendTo,
182
- // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
183
- notification
184
- }));
185
- return results;
186
- };
187
- var sendNotification = withErrorHandler(_sendNotification, "sendNotification");
188
-
189
- // src/domains/notification/services/create-notification.service.ts
190
- var createNotification = async ({
191
- data,
192
- type,
193
- userId,
194
- profile
195
- }) => {
196
- let result;
197
- switch (type) {
198
- case SPEAKABLE_NOTIFICATIONS.NEW_ASSIGNMENT:
199
- result = await handleAssignNotifPromise({ data, profile });
200
- break;
201
- case SPEAKABLE_NOTIFICATIONS.ASSESSMENT_SUBMITTED:
202
- result = await createAssessmentSubmissionNotification({
203
- data,
204
- profile,
205
- userId
206
- });
207
- break;
208
- case SPEAKABLE_NOTIFICATIONS.ASSESSMENT_SCORED:
209
- result = await createAssessmentScoredNotification({
210
- data,
211
- profile
212
- });
213
- break;
214
- default:
215
- result = null;
216
- break;
217
- }
218
- return result;
219
- };
220
- var handleAssignNotifPromise = async ({
221
- data: assignments,
222
- profile
223
- }) => {
224
- if (!assignments.length) return;
225
- try {
226
- const notifsPromises = assignments.map(async (assignment) => {
227
- const {
228
- section,
229
- section: { members },
230
- ...rest
231
- } = assignment;
232
- if (!section || !members) throw new Error("Invalid assignment data");
233
- const data = { section, sendTo: members, assignment: { ...rest } };
234
- return createNewAssignmentNotification({ data, profile });
235
- });
236
- await Promise.all(notifsPromises);
237
- return {
238
- success: true,
239
- message: "Assignment notifications sent successfully"
240
- };
241
- } catch (error) {
242
- console.error("Error in handleAssignNotifPromise:", error);
243
- throw error;
244
- }
245
- };
246
- var createNewAssignmentNotification = async ({
247
- data,
248
- profile
249
- }) => {
250
- var _a;
251
- const { assignment, sendTo } = data;
252
- const teacherName = profile.displayName || "Your teacher";
253
- const dueDate = assignment.dueDateTimestamp ? dayjs(assignment.dueDateTimestamp.toDate()).format("MMM Do") : null;
254
- const results = await sendNotification(sendTo, {
255
- courseId: assignment.courseId,
256
- type: SPEAKABLE_NOTIFICATIONS.NEW_ASSIGNMENT,
257
- senderName: teacherName,
258
- link: `${WEB_BASE_URL}/assignment/${assignment.id}`,
259
- messagePreview: `A new assignment "${assignment.name}" is now available. ${dueDate ? `Due ${dueDate}` : ""}`,
260
- title: "New Assignment Available!",
261
- imageUrl: (_a = profile.image) == null ? void 0 : _a.url
262
- });
263
- return results;
264
- };
265
- var createAssessmentSubmissionNotification = async ({
266
- data: assignment,
267
- profile,
268
- userId
269
- }) => {
270
- var _a;
271
- const studentName = profile.displayName || "Your student";
272
- const results = await sendNotification(assignment.owners, {
273
- courseId: assignment.courseId,
274
- type: SPEAKABLE_NOTIFICATIONS.ASSESSMENT_SUBMITTED,
275
- link: `${WEB_BASE_URL}/a/${assignment.id}?studentId=${userId}`,
276
- title: `Assessment Submitted!`,
277
- senderName: studentName,
278
- messagePreview: `${studentName} has submitted the assessment "${assignment.name}"`,
279
- imageUrl: (_a = profile.image) == null ? void 0 : _a.url
280
- });
281
- return results;
282
- };
283
- var createAssessmentScoredNotification = async ({
284
- data,
285
- profile
286
- }) => {
287
- var _a, _b, _c, _d, _e;
288
- const { assignment, sendTo } = data;
289
- const teacherName = profile.displayName || "Your teacher";
290
- const title = `${assignment.isAssessment ? "Assessment" : "Assignment"} Reviewed!`;
291
- const messagePreview = `Your ${assignment.isAssessment ? "assessment" : "assignment"} has been reviewed by your teacher. Click to view the feedback.`;
292
- const results = await sendNotification(sendTo, {
293
- courseId: assignment.courseId,
294
- type: SPEAKABLE_NOTIFICATIONS.ASSESSMENT_SCORED,
295
- link: `${WEB_BASE_URL}/assignment/${assignment.id}`,
296
- title,
297
- messagePreview,
298
- imageUrl: (_a = profile.image) == null ? void 0 : _a.url,
299
- senderName: teacherName
300
- });
301
- await ((_e = (_c = (_b = api).httpsCallable) == null ? void 0 : _c.call(_b, "sendAssessmentScoredEmail")) == null ? void 0 : _e({
302
- assessmentTitle: assignment.name,
303
- link: `${WEB_BASE_URL}/assignment/${assignment.id}`,
304
- senderImage: ((_d = profile.image) == null ? void 0 : _d.url) || "",
305
- studentId: sendTo[0],
306
- teacherName: profile.displayName
307
- }));
308
- return results;
309
- };
310
-
311
- // src/domains/notification/hooks/notification.hooks.ts
312
- var notificationQueryKeys = {
313
- all: ["notifications"],
314
- byId: (id) => [...notificationQueryKeys.all, id]
315
- };
316
- var useCreateNotification = () => {
317
- const { user, queryClient } = useSpeakableApi();
318
- const handleCreateNotifications = async (type, data) => {
319
- var _a, _b;
320
- const result = await createNotification({
321
- type,
322
- userId: user.auth.uid,
323
- profile: (_a = user == null ? void 0 : user.profile) != null ? _a : {},
324
- data
325
- });
326
- queryClient.invalidateQueries({
327
- queryKey: notificationQueryKeys.byId((_b = user == null ? void 0 : user.auth.uid) != null ? _b : "")
328
- });
329
- return result;
330
- };
331
- return {
332
- createNotification: handleCreateNotifications
333
- };
334
- };
335
-
336
- // src/domains/assignment/services/create-score.service.ts
337
- async function _createScore(params) {
338
- var _a, _b, _c;
339
- if (params.isAssignment) {
340
- const ref = refsAssignmentFiresotre.assignmentScores({
341
- id: params.activityId,
342
- userId: params.userId
343
- });
344
- await ((_c = (_b = (_a = api).httpsCallable) == null ? void 0 : _b.call(_a, "updateAssignmentGradebookStatus")) == null ? void 0 : _c({
345
- assignmentId: params.activityId,
346
- userId: params.userId,
347
- status: "IN_PROGRESS",
348
- score: null
349
- }));
350
- await api.setDoc(ref, params.scoreData, { merge: true });
351
- return {
352
- id: params.userId
353
- };
354
- } else {
355
- const ref = refsScoresPractice.practiceScores({
356
- userId: params.userId,
357
- setId: params.activityId
358
- });
359
- await api.setDoc(ref, params.scoreData);
360
- return {
361
- id: params.userId
362
- };
363
- }
364
- }
365
- var createScore = withErrorHandler(_createScore, "createScore");
366
-
367
- // src/domains/assignment/services/get-score.service.ts
368
- async function getAssignmentScore({
369
- userId,
370
- assignment,
371
- googleClassroomUserId
372
- }) {
373
- const path = refsAssignmentFiresotre.assignmentScores({
374
- id: assignment.id,
375
- userId
376
- });
377
- const response = await api.getDoc(path);
378
- if (response.data == null) {
379
- const newScore = {
380
- ...defaultScore({
381
- owners: [userId],
382
- userId,
383
- courseId: assignment.courseId,
384
- googleClassroomUserId
385
- }),
386
- assignmentId: assignment.id
387
- };
388
- logStartAssignment({
389
- courseId: assignment.courseId
390
- });
391
- const result = await createScore({
392
- activityId: assignment.id,
393
- userId,
394
- isAssignment: true,
395
- scoreData: newScore
396
- });
397
- return {
398
- ...newScore,
399
- id: result.id
400
- };
401
- }
402
- return response.data;
403
- }
404
- async function getPracticeScore({ userId, setId }) {
405
- const path = refsScoresPractice.practiceScores({ userId, setId });
406
- const response = await api.getDoc(path);
407
- if (response.data == null) {
408
- const newScore = {
409
- ...defaultScore({
410
- owners: [userId],
411
- userId
412
- }),
413
- setId
414
- };
415
- const result = await createScore({
416
- activityId: setId,
417
- userId,
418
- isAssignment: false,
419
- scoreData: newScore
420
- });
421
- return {
422
- ...newScore,
423
- id: result.id
424
- };
425
- }
426
- return response.data;
427
- }
428
- async function _getScore(params) {
429
- if (params.isAssignment) {
430
- return await getAssignmentScore({
431
- userId: params.userId,
432
- assignment: {
433
- id: params.activityId,
434
- courseId: params.courseId
435
- },
436
- googleClassroomUserId: params.googleClassroomUserId
437
- });
438
- } else {
439
- return await getPracticeScore({
440
- userId: params.userId,
441
- setId: params.activityId
442
- });
443
- }
444
- }
445
- var getScore = withErrorHandler(_getScore, "getScore");
446
-
447
- // src/domains/assignment/services/update-score.service.ts
448
- async function _updateScore(params) {
449
- const path = params.isAssignment ? refsAssignmentFiresotre.assignmentScores({
450
- id: params.activityId,
451
- userId: params.userId
452
- }) : refsScoresPractice.practiceScores({
453
- setId: params.activityId,
454
- userId: params.userId
455
- });
456
- await api.updateDoc(path, {
457
- ...params.data
458
- });
459
- }
460
- var updateScore = withErrorHandler(_updateScore, "updateScore");
461
- async function _updateCardScore(params) {
462
- const path = params.isAssignment ? refsAssignmentFiresotre.assignmentScores({
463
- id: params.activityId,
464
- userId: params.userId
465
- }) : refsScoresPractice.practiceScores({
466
- setId: params.activityId,
467
- userId: params.userId
468
- });
469
- const updates = Object.keys(params.updates.cardScore).reduce(
470
- (acc, key) => {
471
- acc[`cards.${params.cardId}.${key}`] = params.updates.cardScore[key];
472
- return acc;
473
- },
474
- {}
475
- );
476
- if (params.updates.progress) {
477
- updates.progress = params.updates.progress;
478
- }
479
- if (params.updates.score) {
480
- updates.score = params.updates.score;
481
- }
482
- await api.updateDoc(path, {
483
- ...updates
484
- });
485
- }
486
- var updateCardScore = withErrorHandler(_updateCardScore, "updateCardScore");
487
-
488
- // src/domains/assignment/services/clear-score.service.ts
489
- import dayjs2 from "dayjs";
490
- async function clearScore(params) {
491
- var _a, _b, _c, _d, _e;
492
- const update = {
493
- [`cards.${params.cardId}`]: {
494
- attempts: ((_a = params.cardScores.attempts) != null ? _a : 1) + 1,
495
- correct: (_b = params.cardScores.correct) != null ? _b : 0,
496
- // save old score history
497
- history: [
498
- {
499
- ...params.cardScores,
500
- attempts: (_c = params.cardScores.attempts) != null ? _c : 1,
501
- correct: (_d = params.cardScores.correct) != null ? _d : 0,
502
- retryTime: dayjs2().format("YYYY-MM-DD HH:mm:ss"),
503
- history: null
504
- },
505
- // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
506
- ...(_e = params.cardScores.history) != null ? _e : []
507
- ]
508
- }
509
- };
510
- const path = params.isAssignment ? refsAssignmentFiresotre.assignmentScores({
511
- id: params.activityId,
512
- userId: params.userId
513
- }) : refsScoresPractice.practiceScores({
514
- setId: params.activityId,
515
- userId: params.userId
516
- });
517
- await api.updateDoc(path, update);
518
- return {
519
- update,
520
- activityId: params.activityId
521
- };
522
- }
523
-
524
- // src/domains/assignment/services/submit-assignment-score.service.ts
525
- import dayjs3 from "dayjs";
526
- async function _submitAssignmentScore({
527
- cardIds,
528
- assignment,
529
- weights,
530
- userId,
531
- status,
532
- studentName
533
- }) {
534
- const { serverTimestamp } = api.accessHelpers();
535
- const path = refsAssignmentFiresotre.assignmentScores({ id: assignment.id, userId });
536
- const fieldsUpdated = {
537
- submitted: true,
538
- progress: 100,
539
- submissionDate: serverTimestamp(),
540
- status
541
- };
542
- if (assignment.isAssessment) {
543
- const result = await handleAssessment(
544
- assignment,
545
- userId,
546
- cardIds,
547
- weights,
548
- fieldsUpdated,
549
- studentName
550
- );
551
- return result;
552
- } else if (assignment.courseId) {
553
- await handleCourseAssignment(assignment, userId);
554
- }
555
- await api.updateDoc(path, { ...fieldsUpdated });
556
- return { success: true, fieldsUpdated };
557
- }
558
- var submitAssignmentScore = withErrorHandler(
559
- _submitAssignmentScore,
560
- "submitAssignmentScore"
561
- );
562
- async function handleAssessment(assignment, userId, cardIds, weights, fieldsUpdated, studentName) {
563
- var _a, _b, _c;
564
- const path = refsAssignmentFiresotre.assignmentScores({ id: assignment.id, userId });
565
- const response = await api.getDoc(path);
566
- if (!response.data) {
567
- throw new Error("Score not found");
568
- }
569
- const { score: scoreCalculated } = calculateScoreAndProgress_default(response.data, cardIds, weights);
570
- await api.updateDoc(path, { score: scoreCalculated, status: "PENDING_REVIEW" });
571
- await ((_c = (_b = (_a = api).httpsCallable) == null ? void 0 : _b.call(_a, "submitAssessment")) == null ? void 0 : _c({
572
- assignmentId: assignment.id,
573
- assignmentTitle: assignment.name,
574
- userId,
575
- teacherId: assignment.owners[0],
576
- studentName
577
- }));
578
- fieldsUpdated.status = "PENDING_REVIEW";
579
- return { success: true, fieldsUpdated };
580
- }
581
- async function handleCourseAssignment(assignment, userId) {
582
- var _a, _b, _c;
583
- await ((_c = (_b = (_a = api).httpsCallable) == null ? void 0 : _b.call(_a, "submitAssignmentV2")) == null ? void 0 : _c({
584
- assignmentId: assignment.id,
585
- userId
586
- }));
587
- }
588
- async function submitPracticeScore({
589
- setId,
590
- userId,
591
- scores
592
- }) {
593
- const { serverTimestamp } = api.accessHelpers();
594
- const date = dayjs3().format("YYYY-MM-DD-HH-mm");
595
- const ref = refsScoresPractice.practiceScoreHistoryRefDoc({ setId, userId, date });
596
- const fieldsUpdated = {
597
- ...scores,
598
- submitted: true,
599
- progress: 100,
600
- submissionDate: serverTimestamp(),
601
- status: "SUBMITTED"
602
- };
603
- await api.setDoc(ref, { ...fieldsUpdated });
604
- const refScores = refsScoresPractice.practiceScores({ userId, setId });
605
- await api.deleteDoc(refScores);
606
- return { success: true, fieldsUpdated };
607
- }
608
-
609
- // src/domains/assignment/hooks/score-hooks.ts
610
- var scoreQueryKeys = {
611
- all: ["scores"],
612
- byId: (id) => [...scoreQueryKeys.all, id],
613
- list: () => [...scoreQueryKeys.all, "list"]
614
- };
615
- function useScore({
616
- isAssignment,
617
- activityId,
618
- userId = "",
619
- courseId,
620
- enabled = true,
621
- googleClassroomUserId
622
- }) {
623
- return useQuery2({
624
- queryFn: () => getScore({
625
- userId,
626
- courseId,
627
- activityId,
628
- googleClassroomUserId,
629
- isAssignment
630
- }),
631
- queryKey: scoreQueryKeys.byId(activityId),
632
- enabled
633
- });
634
- }
635
- var debounceUpdateScore = debounce(updateScore, 1e3);
636
- function useUpdateScore() {
637
- const { queryClient } = useSpeakableApi();
638
- const mutation = useMutation({
639
- mutationFn: debounceUpdateScore,
640
- onMutate: (variables) => {
641
- return handleOptimisticUpdate({
642
- queryClient,
643
- queryKey: scoreQueryKeys.byId(variables.activityId),
644
- newData: variables.data
645
- });
646
- },
647
- onError: (_, variables, context) => {
648
- if (context == null ? void 0 : context.previousData)
649
- queryClient.setQueryData(scoreQueryKeys.byId(variables.activityId), context.previousData);
650
- },
651
- onSettled: (_, err, variables) => {
652
- queryClient.invalidateQueries({
653
- queryKey: scoreQueryKeys.byId(variables.activityId)
654
- });
655
- }
656
- });
657
- return {
658
- mutationUpdateScore: mutation
659
- };
660
- }
661
- function useUpdateCardScore({
662
- isAssignment,
663
- activityId,
664
- userId,
665
- cardIds,
666
- weights
667
- }) {
668
- const { queryClient } = useSpeakableApi();
669
- const queryKey = scoreQueryKeys.byId(activityId);
670
- const mutation = useMutation({
671
- mutationFn: async ({ cardId, cardScore }) => {
672
- const previousScores = queryClient.getQueryData(queryKey);
673
- const { progress, score, newScoreUpdated, updatedCardScore } = getScoreUpdated({
674
- previousScores: previousScores != null ? previousScores : {},
675
- cardId,
676
- cardScore,
677
- cardIds,
678
- weights
679
- });
680
- await updateCardScore({
681
- userId,
682
- cardId,
683
- isAssignment,
684
- activityId,
685
- updates: {
686
- cardScore: updatedCardScore,
687
- progress,
688
- score
689
- }
690
- });
691
- return { cardId, scoresUpdated: newScoreUpdated };
692
- },
693
- onMutate: ({ cardId, cardScore }) => {
694
- queryClient.setQueryData(queryKey, (previousScore) => {
695
- const updates = handleOptimisticScore({
696
- score: previousScore,
697
- cardId,
698
- cardScore,
699
- cardIds,
700
- weights
701
- });
702
- return {
703
- ...previousScore,
704
- ...updates
705
- };
706
- });
707
- },
708
- // eslint-disable-next-line no-unused-vars
709
- onError: (error) => {
710
- console.log(error.message);
711
- const previousData = queryClient.getQueryData(queryKey);
712
- if (previousData) {
713
- queryClient.setQueryData(queryKey, previousData);
714
- }
715
- }
716
- });
717
- return {
718
- mutationUpdateCardScore: mutation
719
- };
720
- }
721
- var getScoreUpdated = ({
722
- cardId,
723
- cardScore,
724
- previousScores,
725
- cardIds,
726
- weights
727
- }) => {
728
- var _a, _b;
729
- const previousCard = (_a = previousScores.cards) == null ? void 0 : _a[cardId];
730
- const newCardScore = {
731
- ...previousCard != null ? previousCard : {},
732
- ...cardScore
733
- };
734
- const newScores = {
735
- ...previousScores,
736
- cards: {
737
- ...(_b = previousScores.cards) != null ? _b : {},
738
- [cardId]: newCardScore
739
- }
740
- };
741
- const { score, progress } = calculateScoreAndProgress_default(newScores, cardIds, weights);
742
- return {
743
- newScoreUpdated: newScores,
744
- updatedCardScore: cardScore,
745
- score,
746
- progress
747
- };
748
- };
749
- var handleOptimisticScore = ({
750
- score,
751
- cardId,
752
- cardScore,
753
- cardIds,
754
- weights
755
- }) => {
756
- var _a;
757
- let cards = { ...(_a = score == null ? void 0 : score.cards) != null ? _a : {} };
758
- cards = {
759
- ...cards,
760
- [cardId]: {
761
- ...cards[cardId],
762
- ...cardScore
763
- }
764
- };
765
- const { score: scoreValue, progress } = calculateScoreAndProgress_default(
766
- // @ts-ignore
767
- {
768
- ...score != null ? score : {},
769
- cards
770
- },
771
- cardIds,
772
- weights
773
- );
774
- return { cards, score: scoreValue, progress };
775
- };
776
- function useClearScore() {
777
- const { queryClient } = useSpeakableApi();
778
- const mutation = useMutation({
779
- mutationFn: clearScore,
780
- onSettled: (result) => {
781
- var _a;
782
- queryClient.invalidateQueries({
783
- queryKey: scoreQueryKeys.byId((_a = result == null ? void 0 : result.activityId) != null ? _a : "")
784
- });
785
- }
786
- });
787
- return {
788
- mutationClearScore: mutation
789
- };
790
- }
791
- function useSubmitAssignmentScore({
792
- onAssignmentSubmitted,
793
- studentName
794
- }) {
795
- const { queryClient } = useSpeakableApi();
796
- const { hasGoogleClassroomGradePassback } = usePermissions_default();
797
- const { submitAssignmentToGoogleClassroom } = useGoogleClassroom();
798
- const { createNotification: createNotification2 } = useCreateNotification();
799
- const mutation = useMutation({
800
- mutationFn: async ({
801
- assignment,
802
- userId,
803
- cardIds,
804
- weights,
805
- scores,
806
- status
807
- }) => {
808
- try {
809
- const scoreUpdated = await submitAssignmentScore({
810
- assignment,
811
- userId,
812
- cardIds,
813
- weights,
814
- status,
815
- studentName
816
- });
817
- if (assignment.courseWorkId != null && !assignment.isAssessment && hasGoogleClassroomGradePassback) {
818
- await submitAssignmentToGoogleClassroom({
819
- assignment,
820
- scores
821
- });
822
- }
823
- if (assignment.isAssessment) {
824
- createNotification2(SpeakableNotificationTypes.ASSESSMENT_SUBMITTED, assignment);
825
- }
826
- if (assignment == null ? void 0 : assignment.id) {
827
- logSubmitAssignment({
828
- courseId: assignment == null ? void 0 : assignment.courseId
829
- });
830
- }
831
- onAssignmentSubmitted(assignment.id);
832
- queryClient.setQueryData(scoreQueryKeys.byId(assignment.id), {
833
- ...scores,
834
- ...scoreUpdated.fieldsUpdated
835
- });
836
- return {
837
- success: true,
838
- message: "Score submitted successfully"
839
- };
840
- } catch (error) {
841
- return {
842
- success: false,
843
- error
844
- };
845
- }
846
- }
847
- });
848
- return {
849
- submitAssignmentScore: mutation.mutateAsync,
850
- isLoading: mutation.isPending
851
- };
852
- }
853
- function useSubmitPracticeScore() {
854
- const { queryClient } = useSpeakableApi();
855
- const mutation = useMutation({
856
- mutationFn: async ({
857
- setId,
858
- userId,
859
- scores
860
- }) => {
861
- try {
862
- await submitPracticeScore({
863
- setId,
864
- userId,
865
- scores
866
- });
867
- queryClient.invalidateQueries({
868
- queryKey: scoreQueryKeys.byId(setId)
869
- });
870
- return {
871
- success: true,
872
- message: "Score submitted successfully"
873
- };
874
- } catch (error) {
875
- return {
876
- success: false,
877
- error
878
- };
879
- }
880
- }
881
- });
882
- return {
883
- submitPracticeScore: mutation.mutateAsync,
884
- isLoading: mutation.isPending
885
- };
886
- }
887
-
888
- // src/domains/cards/card.hooks.ts
889
- import { useMutation as useMutation2, useQueries, useQuery as useQuery3 } from "@tanstack/react-query";
890
- import { useMemo } from "react";
891
- var cardsQueryKeys = {
892
- all: ["cards"],
893
- one: (params) => [...cardsQueryKeys.all, params.cardId]
894
- };
895
- function useCards({
896
- cardIds,
897
- enabled = true,
898
- asObject
899
- }) {
900
- const queries = useQueries({
901
- queries: cardIds.map((cardId) => ({
902
- enabled: enabled && cardIds.length > 0,
903
- queryKey: cardsQueryKeys.one({
904
- cardId
905
- }),
906
- queryFn: () => getCard({ cardId })
907
- }))
908
- });
909
- const cards = queries.map((query) => query.data).filter(Boolean);
910
- const cardsObject = useMemo(() => {
911
- if (!asObject) return null;
912
- return cards.reduce((acc, card) => {
913
- acc[card.id] = card;
914
- return acc;
915
- }, {});
916
- }, [asObject, cards]);
917
- return {
918
- cards,
919
- cardsObject,
920
- cardsQueries: queries
921
- };
922
- }
923
- function useCreateCard() {
924
- const { queryClient } = useSpeakableApi();
925
- const mutationCreateCard = useMutation2({
926
- mutationFn: createCard,
927
- onSuccess: (cardCreated) => {
928
- queryClient.invalidateQueries({ queryKey: cardsQueryKeys.one({ cardId: cardCreated.id }) });
929
- }
930
- });
931
- return {
932
- mutationCreateCard
933
- };
934
- }
935
- function useCreateCards() {
936
- const mutationCreateCards = useMutation2({
937
- mutationFn: createCards
938
- });
939
- return {
940
- mutationCreateCards
941
- };
942
- }
943
- function getCardFromCache({
944
- cardId,
945
- queryClient
946
- }) {
947
- return queryClient.getQueryData(cardsQueryKeys.one({ cardId }));
948
- }
949
- function updateCardInCache({
950
- cardId,
951
- card,
952
- queryClient
953
- }) {
954
- queryClient.setQueryData(cardsQueryKeys.one({ cardId }), card);
955
- }
956
- function useGetCard({ cardId, enabled = true }) {
957
- const query = useQuery3({
958
- queryKey: cardsQueryKeys.one({ cardId }),
959
- queryFn: () => getCard({ cardId }),
960
- enabled: enabled && !!cardId
961
- });
962
- return query;
963
- }
964
-
965
- // src/domains/sets/set.hooks.ts
966
- import { useQuery as useQuery4 } from "@tanstack/react-query";
967
- var setsQueryKeys = {
968
- all: ["sets"],
969
- one: (params) => [...setsQueryKeys.all, params.setId]
970
- };
971
- var useSet = ({ setId, enabled }) => {
972
- return useQuery4({
973
- queryKey: setsQueryKeys.one({ setId }),
974
- queryFn: () => getSet({ setId }),
975
- enabled: setId !== void 0 && setId !== "" && enabled
976
- });
977
- };
978
- function getSetFromCache({
979
- setId,
980
- queryClient
981
- }) {
982
- if (!setId) return null;
983
- return queryClient.getQueryData(setsQueryKeys.one({ setId }));
984
- }
985
- function updateSetInCache({
986
- set,
987
- queryClient
988
- }) {
989
- const { id, ...setData } = set;
990
- queryClient.setQueryData(setsQueryKeys.one({ setId: id }), setData);
991
- }
992
- export {
993
- assignmentQueryKeys,
994
- cardsQueryKeys,
995
- getCardFromCache,
996
- getSetFromCache,
997
- scoreQueryKeys,
998
- setsQueryKeys,
999
- updateCardInCache,
1000
- updateSetInCache,
1001
- useAssignment,
1002
- useCards,
1003
- useClearScore,
1004
- useCreateCard,
1005
- useCreateCards,
1006
- useCreateNotification,
1007
- useGetCard,
1008
- useScore,
1009
- useSet,
1010
- useSubmitAssignmentScore,
1011
- useSubmitPracticeScore,
1012
- useUpdateCardScore,
1013
- useUpdateScore
1014
- };
1015
- //# sourceMappingURL=hooks.js.map