@magmamath/students-features 0.1.3 → 0.2.0-fix-teacher-feedback-button2

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 (170) hide show
  1. package/dist/commonjs/features/chatbot/components/ChatControls/ChatControls.js +5 -21
  2. package/dist/commonjs/features/chatbot/components/ChatControls/ChatControls.js.map +1 -1
  3. package/dist/commonjs/features/chatbot/model/api.js +1 -26
  4. package/dist/commonjs/features/chatbot/model/api.js.map +1 -1
  5. package/dist/commonjs/features/feedback/components/EmptyComment/EmptyComment.js +54 -0
  6. package/dist/commonjs/features/feedback/components/EmptyComment/EmptyComment.js.map +1 -0
  7. package/dist/commonjs/features/feedback/components/ListCardCommentsCount/ListCardCommentsCount.js +43 -0
  8. package/dist/commonjs/features/feedback/components/ListCardCommentsCount/ListCardCommentsCount.js.map +1 -0
  9. package/dist/commonjs/features/feedback/components/TeacherFeedback.js +51 -0
  10. package/dist/commonjs/features/feedback/components/TeacherFeedback.js.map +1 -0
  11. package/dist/commonjs/features/feedback/components/TeacherFeedbackButton/TeacherFeedbackButton.js +110 -0
  12. package/dist/commonjs/features/feedback/components/TeacherFeedbackButton/TeacherFeedbackButton.js.map +1 -0
  13. package/dist/commonjs/features/feedback/components/TeacherFeedbackButton/colorSchemes.js +44 -0
  14. package/dist/commonjs/features/feedback/components/TeacherFeedbackButton/colorSchemes.js.map +1 -0
  15. package/dist/commonjs/features/feedback/components/TeacherFeedbackComments/TeacherComment.js +97 -0
  16. package/dist/commonjs/features/feedback/components/TeacherFeedbackComments/TeacherComment.js.map +1 -0
  17. package/dist/commonjs/features/feedback/components/TeacherFeedbackComments/TeacherFeedbackComments.js +68 -0
  18. package/dist/commonjs/features/feedback/components/TeacherFeedbackComments/TeacherFeedbackComments.js.map +1 -0
  19. package/dist/commonjs/features/feedback/components/UnreadMessagesBadge.js +61 -0
  20. package/dist/commonjs/features/feedback/components/UnreadMessagesBadge.js.map +1 -0
  21. package/dist/commonjs/features/feedback/components/icons/MessageBubbleIcon.js +32 -0
  22. package/dist/commonjs/features/feedback/components/icons/MessageBubbleIcon.js.map +1 -0
  23. package/dist/commonjs/features/feedback/components/icons/XCloseIcon.js +30 -0
  24. package/dist/commonjs/features/feedback/components/icons/XCloseIcon.js.map +1 -0
  25. package/dist/commonjs/features/feedback/components/index.js +41 -0
  26. package/dist/commonjs/features/feedback/components/index.js.map +1 -0
  27. package/dist/commonjs/features/feedback/constants.js +30 -0
  28. package/dist/commonjs/features/feedback/constants.js.map +1 -0
  29. package/dist/commonjs/features/feedback/helpers.js +70 -0
  30. package/dist/commonjs/features/feedback/helpers.js.map +1 -0
  31. package/dist/commonjs/features/feedback/index.js +50 -0
  32. package/dist/commonjs/features/feedback/index.js.map +1 -0
  33. package/dist/commonjs/features/feedback/model/teacherFeedback.model.js +215 -0
  34. package/dist/commonjs/features/feedback/model/teacherFeedback.model.js.map +1 -0
  35. package/dist/commonjs/features/feedback/types/teacherFeedback.types.js +18 -0
  36. package/dist/commonjs/features/feedback/types/teacherFeedback.types.js.map +1 -0
  37. package/dist/commonjs/index.js +12 -0
  38. package/dist/commonjs/index.js.map +1 -1
  39. package/dist/module/features/chatbot/components/ChatControls/ChatControls.js +6 -22
  40. package/dist/module/features/chatbot/components/ChatControls/ChatControls.js.map +1 -1
  41. package/dist/module/features/chatbot/model/api.js +1 -26
  42. package/dist/module/features/chatbot/model/api.js.map +1 -1
  43. package/dist/module/features/feedback/components/EmptyComment/EmptyComment.js +48 -0
  44. package/dist/module/features/feedback/components/EmptyComment/EmptyComment.js.map +1 -0
  45. package/dist/module/features/feedback/components/ListCardCommentsCount/ListCardCommentsCount.js +37 -0
  46. package/dist/module/features/feedback/components/ListCardCommentsCount/ListCardCommentsCount.js.map +1 -0
  47. package/dist/module/features/feedback/components/TeacherFeedback.js +45 -0
  48. package/dist/module/features/feedback/components/TeacherFeedback.js.map +1 -0
  49. package/dist/module/features/feedback/components/TeacherFeedbackButton/TeacherFeedbackButton.js +104 -0
  50. package/dist/module/features/feedback/components/TeacherFeedbackButton/TeacherFeedbackButton.js.map +1 -0
  51. package/dist/module/features/feedback/components/TeacherFeedbackButton/colorSchemes.js +40 -0
  52. package/dist/module/features/feedback/components/TeacherFeedbackButton/colorSchemes.js.map +1 -0
  53. package/dist/module/features/feedback/components/TeacherFeedbackComments/TeacherComment.js +91 -0
  54. package/dist/module/features/feedback/components/TeacherFeedbackComments/TeacherComment.js.map +1 -0
  55. package/dist/module/features/feedback/components/TeacherFeedbackComments/TeacherFeedbackComments.js +61 -0
  56. package/dist/module/features/feedback/components/TeacherFeedbackComments/TeacherFeedbackComments.js.map +1 -0
  57. package/dist/module/features/feedback/components/UnreadMessagesBadge.js +55 -0
  58. package/dist/module/features/feedback/components/UnreadMessagesBadge.js.map +1 -0
  59. package/dist/module/features/feedback/components/icons/MessageBubbleIcon.js +24 -0
  60. package/dist/module/features/feedback/components/icons/MessageBubbleIcon.js.map +1 -0
  61. package/dist/module/features/feedback/components/icons/XCloseIcon.js +22 -0
  62. package/dist/module/features/feedback/components/icons/XCloseIcon.js.map +1 -0
  63. package/dist/module/features/feedback/components/index.js +8 -0
  64. package/dist/module/features/feedback/components/index.js.map +1 -0
  65. package/dist/module/features/feedback/constants.js +25 -0
  66. package/dist/module/features/feedback/constants.js.map +1 -0
  67. package/dist/module/features/feedback/helpers.js +65 -0
  68. package/dist/module/features/feedback/helpers.js.map +1 -0
  69. package/dist/module/features/feedback/index.js +7 -0
  70. package/dist/module/features/feedback/index.js.map +1 -0
  71. package/dist/module/features/feedback/model/teacherFeedback.model.js +210 -0
  72. package/dist/module/features/feedback/model/teacherFeedback.model.js.map +1 -0
  73. package/dist/module/features/feedback/types/teacherFeedback.types.js +14 -0
  74. package/dist/module/features/feedback/types/teacherFeedback.types.js.map +1 -0
  75. package/dist/module/index.js +1 -0
  76. package/dist/module/index.js.map +1 -1
  77. package/dist/typescript/commonjs/features/chatbot/components/ChatControls/ChatControls.d.ts.map +1 -1
  78. package/dist/typescript/commonjs/features/chatbot/model/api.d.ts +0 -3
  79. package/dist/typescript/commonjs/features/chatbot/model/api.d.ts.map +1 -1
  80. package/dist/typescript/commonjs/features/feedback/components/EmptyComment/EmptyComment.d.ts +8 -0
  81. package/dist/typescript/commonjs/features/feedback/components/EmptyComment/EmptyComment.d.ts.map +1 -0
  82. package/dist/typescript/commonjs/features/feedback/components/ListCardCommentsCount/ListCardCommentsCount.d.ts +7 -0
  83. package/dist/typescript/commonjs/features/feedback/components/ListCardCommentsCount/ListCardCommentsCount.d.ts.map +1 -0
  84. package/dist/typescript/commonjs/features/feedback/components/TeacherFeedback.d.ts +9 -0
  85. package/dist/typescript/commonjs/features/feedback/components/TeacherFeedback.d.ts.map +1 -0
  86. package/dist/typescript/commonjs/features/feedback/components/TeacherFeedbackButton/TeacherFeedbackButton.d.ts +11 -0
  87. package/dist/typescript/commonjs/features/feedback/components/TeacherFeedbackButton/TeacherFeedbackButton.d.ts.map +1 -0
  88. package/dist/typescript/commonjs/features/feedback/components/TeacherFeedbackButton/colorSchemes.d.ts +37 -0
  89. package/dist/typescript/commonjs/features/feedback/components/TeacherFeedbackButton/colorSchemes.d.ts.map +1 -0
  90. package/dist/typescript/commonjs/features/feedback/components/TeacherFeedbackComments/TeacherComment.d.ts +12 -0
  91. package/dist/typescript/commonjs/features/feedback/components/TeacherFeedbackComments/TeacherComment.d.ts.map +1 -0
  92. package/dist/typescript/commonjs/features/feedback/components/TeacherFeedbackComments/TeacherFeedbackComments.d.ts +10 -0
  93. package/dist/typescript/commonjs/features/feedback/components/TeacherFeedbackComments/TeacherFeedbackComments.d.ts.map +1 -0
  94. package/dist/typescript/commonjs/features/feedback/components/UnreadMessagesBadge.d.ts +10 -0
  95. package/dist/typescript/commonjs/features/feedback/components/UnreadMessagesBadge.d.ts.map +1 -0
  96. package/dist/typescript/commonjs/features/feedback/components/icons/MessageBubbleIcon.d.ts +4 -0
  97. package/dist/typescript/commonjs/features/feedback/components/icons/MessageBubbleIcon.d.ts.map +1 -0
  98. package/dist/typescript/commonjs/features/feedback/components/icons/XCloseIcon.d.ts +4 -0
  99. package/dist/typescript/commonjs/features/feedback/components/icons/XCloseIcon.d.ts.map +1 -0
  100. package/dist/typescript/commonjs/features/feedback/components/index.d.ts +6 -0
  101. package/dist/typescript/commonjs/features/feedback/components/index.d.ts.map +1 -0
  102. package/dist/typescript/commonjs/features/feedback/constants.d.ts +20 -0
  103. package/dist/typescript/commonjs/features/feedback/constants.d.ts.map +1 -0
  104. package/dist/typescript/commonjs/features/feedback/helpers.d.ts +3 -0
  105. package/dist/typescript/commonjs/features/feedback/helpers.d.ts.map +1 -0
  106. package/dist/typescript/commonjs/features/feedback/index.d.ts +5 -0
  107. package/dist/typescript/commonjs/features/feedback/index.d.ts.map +1 -0
  108. package/dist/typescript/commonjs/features/feedback/model/teacherFeedback.model.d.ts +45 -0
  109. package/dist/typescript/commonjs/features/feedback/model/teacherFeedback.model.d.ts.map +1 -0
  110. package/dist/typescript/commonjs/features/feedback/types/teacherFeedback.types.d.ts +33 -0
  111. package/dist/typescript/commonjs/features/feedback/types/teacherFeedback.types.d.ts.map +1 -0
  112. package/dist/typescript/commonjs/index.d.ts +1 -0
  113. package/dist/typescript/commonjs/index.d.ts.map +1 -1
  114. package/dist/typescript/module/features/chatbot/components/ChatControls/ChatControls.d.ts.map +1 -1
  115. package/dist/typescript/module/features/chatbot/model/api.d.ts +0 -3
  116. package/dist/typescript/module/features/chatbot/model/api.d.ts.map +1 -1
  117. package/dist/typescript/module/features/feedback/components/EmptyComment/EmptyComment.d.ts +8 -0
  118. package/dist/typescript/module/features/feedback/components/EmptyComment/EmptyComment.d.ts.map +1 -0
  119. package/dist/typescript/module/features/feedback/components/ListCardCommentsCount/ListCardCommentsCount.d.ts +7 -0
  120. package/dist/typescript/module/features/feedback/components/ListCardCommentsCount/ListCardCommentsCount.d.ts.map +1 -0
  121. package/dist/typescript/module/features/feedback/components/TeacherFeedback.d.ts +9 -0
  122. package/dist/typescript/module/features/feedback/components/TeacherFeedback.d.ts.map +1 -0
  123. package/dist/typescript/module/features/feedback/components/TeacherFeedbackButton/TeacherFeedbackButton.d.ts +11 -0
  124. package/dist/typescript/module/features/feedback/components/TeacherFeedbackButton/TeacherFeedbackButton.d.ts.map +1 -0
  125. package/dist/typescript/module/features/feedback/components/TeacherFeedbackButton/colorSchemes.d.ts +37 -0
  126. package/dist/typescript/module/features/feedback/components/TeacherFeedbackButton/colorSchemes.d.ts.map +1 -0
  127. package/dist/typescript/module/features/feedback/components/TeacherFeedbackComments/TeacherComment.d.ts +12 -0
  128. package/dist/typescript/module/features/feedback/components/TeacherFeedbackComments/TeacherComment.d.ts.map +1 -0
  129. package/dist/typescript/module/features/feedback/components/TeacherFeedbackComments/TeacherFeedbackComments.d.ts +10 -0
  130. package/dist/typescript/module/features/feedback/components/TeacherFeedbackComments/TeacherFeedbackComments.d.ts.map +1 -0
  131. package/dist/typescript/module/features/feedback/components/UnreadMessagesBadge.d.ts +10 -0
  132. package/dist/typescript/module/features/feedback/components/UnreadMessagesBadge.d.ts.map +1 -0
  133. package/dist/typescript/module/features/feedback/components/icons/MessageBubbleIcon.d.ts +4 -0
  134. package/dist/typescript/module/features/feedback/components/icons/MessageBubbleIcon.d.ts.map +1 -0
  135. package/dist/typescript/module/features/feedback/components/icons/XCloseIcon.d.ts +4 -0
  136. package/dist/typescript/module/features/feedback/components/icons/XCloseIcon.d.ts.map +1 -0
  137. package/dist/typescript/module/features/feedback/components/index.d.ts +6 -0
  138. package/dist/typescript/module/features/feedback/components/index.d.ts.map +1 -0
  139. package/dist/typescript/module/features/feedback/constants.d.ts +20 -0
  140. package/dist/typescript/module/features/feedback/constants.d.ts.map +1 -0
  141. package/dist/typescript/module/features/feedback/helpers.d.ts +3 -0
  142. package/dist/typescript/module/features/feedback/helpers.d.ts.map +1 -0
  143. package/dist/typescript/module/features/feedback/index.d.ts +5 -0
  144. package/dist/typescript/module/features/feedback/index.d.ts.map +1 -0
  145. package/dist/typescript/module/features/feedback/model/teacherFeedback.model.d.ts +45 -0
  146. package/dist/typescript/module/features/feedback/model/teacherFeedback.model.d.ts.map +1 -0
  147. package/dist/typescript/module/features/feedback/types/teacherFeedback.types.d.ts +33 -0
  148. package/dist/typescript/module/features/feedback/types/teacherFeedback.types.d.ts.map +1 -0
  149. package/dist/typescript/module/index.d.ts +1 -0
  150. package/dist/typescript/module/index.d.ts.map +1 -1
  151. package/package.json +4 -4
  152. package/src/features/chatbot/components/ChatControls/ChatControls.tsx +4 -27
  153. package/src/features/chatbot/model/api.ts +18 -55
  154. package/src/features/feedback/components/EmptyComment/EmptyComment.tsx +43 -0
  155. package/src/features/feedback/components/ListCardCommentsCount/ListCardCommentsCount.tsx +33 -0
  156. package/src/features/feedback/components/TeacherFeedback.tsx +46 -0
  157. package/src/features/feedback/components/TeacherFeedbackButton/TeacherFeedbackButton.tsx +117 -0
  158. package/src/features/feedback/components/TeacherFeedbackButton/colorSchemes.ts +38 -0
  159. package/src/features/feedback/components/TeacherFeedbackComments/TeacherComment.tsx +80 -0
  160. package/src/features/feedback/components/TeacherFeedbackComments/TeacherFeedbackComments.tsx +69 -0
  161. package/src/features/feedback/components/UnreadMessagesBadge.tsx +61 -0
  162. package/src/features/feedback/components/icons/MessageBubbleIcon.tsx +16 -0
  163. package/src/features/feedback/components/icons/XCloseIcon.tsx +14 -0
  164. package/src/features/feedback/components/index.ts +5 -0
  165. package/src/features/feedback/constants.ts +26 -0
  166. package/src/features/feedback/helpers.ts +66 -0
  167. package/src/features/feedback/index.ts +4 -0
  168. package/src/features/feedback/model/teacherFeedback.model.ts +255 -0
  169. package/src/features/feedback/types/teacherFeedback.types.ts +32 -0
  170. package/src/index.ts +1 -0
@@ -0,0 +1,5 @@
1
+ export { TeacherFeedbackComments } from './TeacherFeedbackComments/TeacherFeedbackComments'
2
+ export { TeacherFeedbackButton } from './TeacherFeedbackButton/TeacherFeedbackButton'
3
+ export { TeacherFeedback } from './TeacherFeedback'
4
+ export { UnreadMessagesBadge } from './UnreadMessagesBadge'
5
+ export { ListCardCommentsCount } from './ListCardCommentsCount/ListCardCommentsCount'
@@ -0,0 +1,26 @@
1
+ import { Platform } from 'react-native'
2
+ import { Locale } from './types/teacherFeedback.types'
3
+
4
+ export const BUENOS_AIRES_FONT = Platform.OS === 'web' ? 'Buenos Aires, sans-serif' : 'BuenosAires-Regular'
5
+
6
+ export const NO_COMMENTS_ENG = 'No comments yet'
7
+ export const NO_COMMENTS_SWE = 'Inga kommentarer än'
8
+ export const EMPTY_COMMENT_ID = 'empty-comment'
9
+
10
+ export const getEmptyComment = (problemId: string, locale: Locale | null) => {
11
+ return {
12
+ __v: 0,
13
+ _id: EMPTY_COMMENT_ID,
14
+ content: locale === Locale.SV ? NO_COMMENTS_SWE : NO_COMMENTS_ENG,
15
+ createdAt: new Date(),
16
+ exerciseId: '',
17
+ isRead: true,
18
+ problemId,
19
+ studentId: '',
20
+ teacherId: '',
21
+ teacherName: '',
22
+ updatedAt: new Date(),
23
+ }
24
+ }
25
+
26
+ export const TEACHER_FEEDBACK_BUTTON_ID = 'teacherFeedbackButton'
@@ -0,0 +1,66 @@
1
+ import { Locale } from './types/teacherFeedback.types'
2
+
3
+ const RELATIVE_TIME_LABELS = {
4
+ [Locale.US]: {
5
+ justNow: 'just now',
6
+ minuteAgo: 'minute ago',
7
+ minutesAgo: 'minutes ago',
8
+ hourAgo: 'hour ago',
9
+ hoursAgo: 'hours ago',
10
+ dayAgo: 'day ago',
11
+ daysAgo: 'days ago',
12
+ monthAgo: 'month ago',
13
+ monthsAgo: 'months ago',
14
+ yearAgo: 'year ago',
15
+ yearsAgo: 'years ago',
16
+ },
17
+ [Locale.SV]: {
18
+ justNow: 'alldeles nyss',
19
+ minuteAgo: 'minut sedan',
20
+ minutesAgo: 'minuter sedan',
21
+ hourAgo: 'timme sedan',
22
+ hoursAgo: 'timmar sedan',
23
+ dayAgo: 'dag sedan',
24
+ daysAgo: 'dagar sedan',
25
+ monthAgo: 'månad sedan',
26
+ monthsAgo: 'månader sedan',
27
+ yearAgo: 'år sedan',
28
+ yearsAgo: 'år sedan',
29
+ },
30
+ [Locale.GB]: {
31
+ justNow: 'just now',
32
+ minuteAgo: 'minute ago',
33
+ minutesAgo: 'minutes ago',
34
+ hourAgo: 'hour ago',
35
+ hoursAgo: 'hours ago',
36
+ dayAgo: 'day ago',
37
+ daysAgo: 'days ago',
38
+ monthAgo: 'month ago',
39
+ monthsAgo: 'months ago',
40
+ yearAgo: 'year ago',
41
+ yearsAgo: 'years ago',
42
+ },
43
+ }
44
+
45
+ export const getRelativeTime = (date: Date, lang: Locale) => {
46
+ const t = RELATIVE_TIME_LABELS[lang] || RELATIVE_TIME_LABELS[Locale.US]
47
+ const timeBufferMs = 2000 // adds 2 seconds time buffer because when used with sockets, it displayed -1 seconds ago, instead of 1 second ago.
48
+
49
+ const now = new Date().getTime()
50
+ const targetDate = new Date(date).getTime() - timeBufferMs
51
+ const diffTime = now - targetDate
52
+
53
+ const seconds = Math.floor(diffTime / 1000)
54
+ const minutes = Math.floor(seconds / 60)
55
+ const hours = Math.floor(minutes / 60)
56
+ const days = Math.floor(hours / 24)
57
+ const months = Math.floor(days / 30)
58
+ const years = Math.floor(days / 365)
59
+
60
+ if (seconds < 60) return t.justNow
61
+ if (minutes < 60) return `${minutes} ${minutes === 1 ? t.minuteAgo : t.minutesAgo}`
62
+ if (hours < 24) return `${hours} ${hours === 1 ? t.hourAgo : t.hoursAgo}`
63
+ if (days < 30) return `${days} ${days === 1 ? t.dayAgo : t.daysAgo}`
64
+ if (months < 12) return `${months} ${months === 1 ? t.monthAgo : t.monthsAgo}`
65
+ return `${years} ${years === 1 ? t.yearAgo : t.yearsAgo}`
66
+ }
@@ -0,0 +1,4 @@
1
+ export * from './model/teacherFeedback.model'
2
+ export * from './types/teacherFeedback.types'
3
+ export * from './constants'
4
+ export * from './components'
@@ -0,0 +1,255 @@
1
+ import { createEffect, createEvent, createStore, Effect, restore, sample, StoreWritable } from 'effector'
2
+ import {
3
+ CommentsEntity,
4
+ GetCommentsByIdProps,
5
+ Locale,
6
+ TeacherComment,
7
+ UpdateCommentSeenStatusProps,
8
+ } from '../types/teacherFeedback.types'
9
+ import { EMPTY_COMMENT_ID, getEmptyComment } from '../constants'
10
+
11
+ type TeacherFeedbackModelProps = {
12
+ credits: {
13
+ assignmentId: StoreWritable<string>
14
+ problemId: StoreWritable<string>
15
+ locale: StoreWritable<Locale | null>
16
+ }
17
+ api: {
18
+ getCommentsByAssignmentId: (props: GetCommentsByIdProps) => Promise<Record<string, { comments: TeacherComment[] }>>
19
+ updateCommentSeenStatus: (props: UpdateCommentSeenStatusProps) => Promise<void>
20
+ }
21
+ }
22
+
23
+ type CommentsMap = Map<string, Record<string, CommentsEntity>>
24
+
25
+ export class TeacherFeedbackModel {
26
+ $assignmentId: StoreWritable<string>
27
+ $currentProblemId: StoreWritable<string>
28
+ $locale: StoreWritable<Locale | null>
29
+
30
+ setCommentsSeen = createEvent<{ ids: string[]; currentProblemId: string; assignmentId: string }>()
31
+ $comments = createStore<CommentsMap>(new Map())
32
+
33
+ setIsOpened = createEvent<boolean>()
34
+ $isOpened = restore(this.setIsOpened, false)
35
+ setIsVisible = createEvent<boolean>()
36
+ $isVisible = restore(this.setIsVisible, false)
37
+
38
+ getCommentsByAssignmentIdFx: Effect<
39
+ GetCommentsByIdProps,
40
+ {
41
+ data: Record<string, { comments: TeacherComment[] }>
42
+ assignmentId: string
43
+ }
44
+ >
45
+ updateCommentSeenFx: Effect<UpdateCommentSeenStatusProps, void>
46
+
47
+ sockets = {
48
+ onCreate: createEvent<TeacherComment>(),
49
+ onDeleted: createEvent<TeacherComment>(),
50
+ }
51
+
52
+ constructor({ api, credits }: TeacherFeedbackModelProps) {
53
+ this.getCommentsByAssignmentIdFx = createEffect(async ({ id }: { id: string }) => {
54
+ const response = await api.getCommentsByAssignmentId({ id })
55
+ return {
56
+ data: response,
57
+ assignmentId: id,
58
+ }
59
+ })
60
+ this.updateCommentSeenFx = createEffect(api.updateCommentSeenStatus)
61
+ this.$assignmentId = credits.assignmentId
62
+ this.$currentProblemId = credits.problemId
63
+ this.$locale = credits.locale
64
+
65
+ sample({
66
+ clock: this.$currentProblemId,
67
+ fn: () => false,
68
+ target: this.setIsOpened,
69
+ })
70
+
71
+ sample({
72
+ clock: this.sockets.onCreate,
73
+ source: [this.$isOpened, this.$currentProblemId, this.$assignmentId] as const,
74
+ filter: ([isOpen, currentProblemId], payload) => {
75
+ return isOpen && currentProblemId === payload.problemId
76
+ },
77
+ fn: ([_, currentProblemId, assignmentId], { _id }) => ({
78
+ currentProblemId,
79
+ assignmentId,
80
+ ids: [_id],
81
+ }),
82
+ target: [this.setCommentsSeen, this.updateCommentSeenFx],
83
+ })
84
+
85
+ sample({
86
+ clock: this.$isOpened,
87
+ source: [this.$comments, this.$currentProblemId, this.$assignmentId] as const,
88
+ filter: ([feedback, currentProblemId, assignmentId], isOpen) => {
89
+ const assignmentComments = feedback.get(assignmentId) || {}
90
+ const comments = assignmentComments[currentProblemId]?.comments ?? []
91
+ const hasUnreadComments = comments.some((comment) => !comment.isRead)
92
+ return isOpen && hasUnreadComments
93
+ },
94
+ fn: ([feedback, currentProblemId, assignmentId]) => {
95
+ const assignmentComments = feedback.get(assignmentId) || {}
96
+ const comments = assignmentComments[currentProblemId]?.comments ?? []
97
+ return {
98
+ currentProblemId,
99
+ assignmentId,
100
+ ids: comments.filter((comment) => !comment.isRead).map((comment) => comment._id),
101
+ }
102
+ },
103
+ target: [this.setCommentsSeen, this.updateCommentSeenFx],
104
+ })
105
+
106
+ this.$isVisible.on(this.getCommentsByAssignmentIdFx.doneData, (_, { data }) => {
107
+ return Object.values(data).some((problemFeedback) => problemFeedback.comments?.length > 0)
108
+ })
109
+
110
+ this.$comments
111
+ .on(this.getCommentsByAssignmentIdFx.doneData, (state, { assignmentId, data }) => {
112
+ const problemsMap: Record<string, CommentsEntity> = {}
113
+
114
+ for (const [problemId, { comments }] of Object.entries(data)) {
115
+ const unreadMessages = comments.filter((comment) => !comment.isRead)
116
+ problemsMap[problemId] = {
117
+ comments,
118
+ unreadMessagesCount: unreadMessages.length,
119
+ }
120
+ }
121
+
122
+ const updatedState = new Map(state)
123
+ updatedState.set(assignmentId, problemsMap)
124
+ return updatedState
125
+ })
126
+ .on(this.setCommentsSeen, (state, { ids, currentProblemId, assignmentId }) => {
127
+ const assignmentComments = state.get(assignmentId)
128
+ if (!assignmentComments) return state
129
+
130
+ const feedback = assignmentComments[currentProblemId]
131
+ if (!feedback) return state
132
+
133
+ const updatedComments = feedback.comments.map((comment) =>
134
+ ids.includes(comment._id) ? { ...comment, isRead: true } : comment
135
+ )
136
+
137
+ const updatedFeedback = {
138
+ ...feedback,
139
+ comments: updatedComments,
140
+ unreadMessagesCount: 0,
141
+ }
142
+
143
+ const updatedAssignmentComments = {
144
+ ...assignmentComments,
145
+ [currentProblemId]: updatedFeedback,
146
+ }
147
+
148
+ const updatedState = new Map(state)
149
+ updatedState.set(assignmentId, updatedAssignmentComments)
150
+
151
+ return updatedState
152
+ })
153
+ .on(this.sockets.onCreate, (state, payload) => {
154
+ const assignmentComments = state.get(payload.exerciseId) || {}
155
+ const feedback = assignmentComments[payload.problemId] ?? { comments: [], unreadMessagesCount: 0 }
156
+
157
+ const updatedFeedback = {
158
+ ...feedback,
159
+ comments: [...feedback.comments, payload],
160
+ unreadMessagesCount: feedback.unreadMessagesCount + 1,
161
+ }
162
+
163
+ const updatedAssignmentComments = {
164
+ ...assignmentComments,
165
+ [payload.problemId]: updatedFeedback,
166
+ }
167
+
168
+ const updatedState = new Map(state)
169
+ updatedState.set(payload.exerciseId, updatedAssignmentComments)
170
+
171
+ return updatedState
172
+ })
173
+ .on(this.sockets.onDeleted, (state, payload) => {
174
+ const assignmentId = this.$assignmentId.getState()
175
+ const assignmentComments = state.get(assignmentId)
176
+ if (!assignmentComments) return state
177
+
178
+ const feedback = assignmentComments[payload.problemId]
179
+ if (!feedback) return state
180
+
181
+ const isDeleteMessageUnread = feedback.comments.some(
182
+ (comment) => comment._id === payload._id && !comment.isRead
183
+ )
184
+
185
+ const updatedFeedback = {
186
+ comments: feedback.comments.filter((comment) => comment._id !== payload._id),
187
+ unreadMessagesCount: isDeleteMessageUnread ? feedback.unreadMessagesCount - 1 : feedback.unreadMessagesCount,
188
+ }
189
+
190
+ const isOpen = this.$isOpened.getState()
191
+
192
+ if (updatedFeedback.comments.length === 0) {
193
+ const updatedAssignmentComments = { ...assignmentComments }
194
+
195
+ if (!isOpen) {
196
+ delete updatedAssignmentComments[payload.problemId]
197
+
198
+ // If no problems left, remove the assignment entirely
199
+ if (Object.keys(updatedAssignmentComments).length === 0) {
200
+ const updatedState = new Map(state)
201
+ updatedState.delete(assignmentId)
202
+ return updatedState
203
+ }
204
+ } else {
205
+ updatedAssignmentComments[payload.problemId] = {
206
+ ...updatedFeedback,
207
+ comments: [getEmptyComment(payload.problemId, this.$locale.getState())],
208
+ }
209
+ }
210
+
211
+ const updatedState = new Map(state)
212
+ updatedState.set(assignmentId, updatedAssignmentComments)
213
+ return updatedState
214
+ }
215
+
216
+ const updatedAssignmentComments = {
217
+ ...assignmentComments,
218
+ [payload.problemId]: updatedFeedback,
219
+ }
220
+
221
+ const updatedState = new Map(state)
222
+ updatedState.set(assignmentId, updatedAssignmentComments)
223
+ return updatedState
224
+ })
225
+ .on(this.setIsOpened, (state, isOpen) => {
226
+ if (isOpen) return state
227
+
228
+ const assignmentId = this.$assignmentId.getState()
229
+ const problemId = this.$currentProblemId.getState()
230
+ const assignmentComments = state.get(assignmentId)
231
+ if (!assignmentComments) return state
232
+
233
+ const feedback = assignmentComments[problemId]
234
+ if (!feedback) return state
235
+
236
+ if (feedback.comments.length === 1 && feedback.comments[0]._id === EMPTY_COMMENT_ID) {
237
+ const updatedAssignmentComments = { ...assignmentComments }
238
+ delete updatedAssignmentComments[problemId]
239
+
240
+ // If no problems left, remove the assignment entirely
241
+ if (Object.keys(updatedAssignmentComments).length === 0) {
242
+ const updatedState = new Map(state)
243
+ updatedState.delete(assignmentId)
244
+ return updatedState
245
+ }
246
+
247
+ const updatedState = new Map(state)
248
+ updatedState.set(assignmentId, updatedAssignmentComments)
249
+ return updatedState
250
+ }
251
+
252
+ return state
253
+ })
254
+ }
255
+ }
@@ -0,0 +1,32 @@
1
+ export type GetCommentsByIdProps = { id: string }
2
+ export type UpdateCommentSeenStatusProps = { ids: string[] }
3
+
4
+ export type TeacherComment = {
5
+ _id: string
6
+ teacherId: string
7
+ teacherName: string
8
+ studentId: string
9
+ problemId: string
10
+ exerciseId: string
11
+ content: string
12
+ isRead: boolean
13
+ createdAt: Date
14
+ updatedAt: Date
15
+ __v: number
16
+ }
17
+
18
+ export type CommentsEntity = {
19
+ comments: TeacherComment[]
20
+ unreadMessagesCount: number
21
+ }
22
+
23
+ export enum Locale {
24
+ US = 'en-US',
25
+ SV = 'sv-SE',
26
+ GB = 'en-GB',
27
+ }
28
+
29
+ export enum TeacherFeedbackSocketEvent {
30
+ COMMENT_CREATED = 'exerciseCommentCreated',
31
+ COMMENT_DELETED = 'exerciseCommentDeleted',
32
+ }
package/src/index.ts CHANGED
@@ -1,3 +1,4 @@
1
1
  export { useFeaturesLocalization, setFeaturesLocalization, Locale } from './shared/translation'
2
2
  export type { LocalizationConfig } from './shared/translation'
3
3
  export * from './features/chatbot'
4
+ export * from './features/feedback'