@magmamath/students-features 0.1.2 → 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 (161) 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/feedback/components/EmptyComment/EmptyComment.js +54 -0
  4. package/dist/commonjs/features/feedback/components/EmptyComment/EmptyComment.js.map +1 -0
  5. package/dist/commonjs/features/feedback/components/ListCardCommentsCount/ListCardCommentsCount.js +43 -0
  6. package/dist/commonjs/features/feedback/components/ListCardCommentsCount/ListCardCommentsCount.js.map +1 -0
  7. package/dist/commonjs/features/feedback/components/TeacherFeedback.js +51 -0
  8. package/dist/commonjs/features/feedback/components/TeacherFeedback.js.map +1 -0
  9. package/dist/commonjs/features/feedback/components/TeacherFeedbackButton/TeacherFeedbackButton.js +110 -0
  10. package/dist/commonjs/features/feedback/components/TeacherFeedbackButton/TeacherFeedbackButton.js.map +1 -0
  11. package/dist/commonjs/features/feedback/components/TeacherFeedbackButton/colorSchemes.js +44 -0
  12. package/dist/commonjs/features/feedback/components/TeacherFeedbackButton/colorSchemes.js.map +1 -0
  13. package/dist/commonjs/features/feedback/components/TeacherFeedbackComments/TeacherComment.js +97 -0
  14. package/dist/commonjs/features/feedback/components/TeacherFeedbackComments/TeacherComment.js.map +1 -0
  15. package/dist/commonjs/features/feedback/components/TeacherFeedbackComments/TeacherFeedbackComments.js +68 -0
  16. package/dist/commonjs/features/feedback/components/TeacherFeedbackComments/TeacherFeedbackComments.js.map +1 -0
  17. package/dist/commonjs/features/feedback/components/UnreadMessagesBadge.js +61 -0
  18. package/dist/commonjs/features/feedback/components/UnreadMessagesBadge.js.map +1 -0
  19. package/dist/commonjs/features/feedback/components/icons/MessageBubbleIcon.js +32 -0
  20. package/dist/commonjs/features/feedback/components/icons/MessageBubbleIcon.js.map +1 -0
  21. package/dist/commonjs/features/feedback/components/icons/XCloseIcon.js +30 -0
  22. package/dist/commonjs/features/feedback/components/icons/XCloseIcon.js.map +1 -0
  23. package/dist/commonjs/features/feedback/components/index.js +41 -0
  24. package/dist/commonjs/features/feedback/components/index.js.map +1 -0
  25. package/dist/commonjs/features/feedback/constants.js +30 -0
  26. package/dist/commonjs/features/feedback/constants.js.map +1 -0
  27. package/dist/commonjs/features/feedback/helpers.js +70 -0
  28. package/dist/commonjs/features/feedback/helpers.js.map +1 -0
  29. package/dist/commonjs/features/feedback/index.js +50 -0
  30. package/dist/commonjs/features/feedback/index.js.map +1 -0
  31. package/dist/commonjs/features/feedback/model/teacherFeedback.model.js +215 -0
  32. package/dist/commonjs/features/feedback/model/teacherFeedback.model.js.map +1 -0
  33. package/dist/commonjs/features/feedback/types/teacherFeedback.types.js +18 -0
  34. package/dist/commonjs/features/feedback/types/teacherFeedback.types.js.map +1 -0
  35. package/dist/commonjs/index.js +12 -0
  36. package/dist/commonjs/index.js.map +1 -1
  37. package/dist/module/features/chatbot/components/ChatControls/ChatControls.js +6 -22
  38. package/dist/module/features/chatbot/components/ChatControls/ChatControls.js.map +1 -1
  39. package/dist/module/features/feedback/components/EmptyComment/EmptyComment.js +48 -0
  40. package/dist/module/features/feedback/components/EmptyComment/EmptyComment.js.map +1 -0
  41. package/dist/module/features/feedback/components/ListCardCommentsCount/ListCardCommentsCount.js +37 -0
  42. package/dist/module/features/feedback/components/ListCardCommentsCount/ListCardCommentsCount.js.map +1 -0
  43. package/dist/module/features/feedback/components/TeacherFeedback.js +45 -0
  44. package/dist/module/features/feedback/components/TeacherFeedback.js.map +1 -0
  45. package/dist/module/features/feedback/components/TeacherFeedbackButton/TeacherFeedbackButton.js +104 -0
  46. package/dist/module/features/feedback/components/TeacherFeedbackButton/TeacherFeedbackButton.js.map +1 -0
  47. package/dist/module/features/feedback/components/TeacherFeedbackButton/colorSchemes.js +40 -0
  48. package/dist/module/features/feedback/components/TeacherFeedbackButton/colorSchemes.js.map +1 -0
  49. package/dist/module/features/feedback/components/TeacherFeedbackComments/TeacherComment.js +91 -0
  50. package/dist/module/features/feedback/components/TeacherFeedbackComments/TeacherComment.js.map +1 -0
  51. package/dist/module/features/feedback/components/TeacherFeedbackComments/TeacherFeedbackComments.js +61 -0
  52. package/dist/module/features/feedback/components/TeacherFeedbackComments/TeacherFeedbackComments.js.map +1 -0
  53. package/dist/module/features/feedback/components/UnreadMessagesBadge.js +55 -0
  54. package/dist/module/features/feedback/components/UnreadMessagesBadge.js.map +1 -0
  55. package/dist/module/features/feedback/components/icons/MessageBubbleIcon.js +24 -0
  56. package/dist/module/features/feedback/components/icons/MessageBubbleIcon.js.map +1 -0
  57. package/dist/module/features/feedback/components/icons/XCloseIcon.js +22 -0
  58. package/dist/module/features/feedback/components/icons/XCloseIcon.js.map +1 -0
  59. package/dist/module/features/feedback/components/index.js +8 -0
  60. package/dist/module/features/feedback/components/index.js.map +1 -0
  61. package/dist/module/features/feedback/constants.js +25 -0
  62. package/dist/module/features/feedback/constants.js.map +1 -0
  63. package/dist/module/features/feedback/helpers.js +65 -0
  64. package/dist/module/features/feedback/helpers.js.map +1 -0
  65. package/dist/module/features/feedback/index.js +7 -0
  66. package/dist/module/features/feedback/index.js.map +1 -0
  67. package/dist/module/features/feedback/model/teacherFeedback.model.js +210 -0
  68. package/dist/module/features/feedback/model/teacherFeedback.model.js.map +1 -0
  69. package/dist/module/features/feedback/types/teacherFeedback.types.js +14 -0
  70. package/dist/module/features/feedback/types/teacherFeedback.types.js.map +1 -0
  71. package/dist/module/index.js +1 -0
  72. package/dist/module/index.js.map +1 -1
  73. package/dist/typescript/commonjs/features/chatbot/components/ChatControls/ChatControls.d.ts.map +1 -1
  74. package/dist/typescript/commonjs/features/feedback/components/EmptyComment/EmptyComment.d.ts +8 -0
  75. package/dist/typescript/commonjs/features/feedback/components/EmptyComment/EmptyComment.d.ts.map +1 -0
  76. package/dist/typescript/commonjs/features/feedback/components/ListCardCommentsCount/ListCardCommentsCount.d.ts +7 -0
  77. package/dist/typescript/commonjs/features/feedback/components/ListCardCommentsCount/ListCardCommentsCount.d.ts.map +1 -0
  78. package/dist/typescript/commonjs/features/feedback/components/TeacherFeedback.d.ts +9 -0
  79. package/dist/typescript/commonjs/features/feedback/components/TeacherFeedback.d.ts.map +1 -0
  80. package/dist/typescript/commonjs/features/feedback/components/TeacherFeedbackButton/TeacherFeedbackButton.d.ts +11 -0
  81. package/dist/typescript/commonjs/features/feedback/components/TeacherFeedbackButton/TeacherFeedbackButton.d.ts.map +1 -0
  82. package/dist/typescript/commonjs/features/feedback/components/TeacherFeedbackButton/colorSchemes.d.ts +37 -0
  83. package/dist/typescript/commonjs/features/feedback/components/TeacherFeedbackButton/colorSchemes.d.ts.map +1 -0
  84. package/dist/typescript/commonjs/features/feedback/components/TeacherFeedbackComments/TeacherComment.d.ts +12 -0
  85. package/dist/typescript/commonjs/features/feedback/components/TeacherFeedbackComments/TeacherComment.d.ts.map +1 -0
  86. package/dist/typescript/commonjs/features/feedback/components/TeacherFeedbackComments/TeacherFeedbackComments.d.ts +10 -0
  87. package/dist/typescript/commonjs/features/feedback/components/TeacherFeedbackComments/TeacherFeedbackComments.d.ts.map +1 -0
  88. package/dist/typescript/commonjs/features/feedback/components/UnreadMessagesBadge.d.ts +10 -0
  89. package/dist/typescript/commonjs/features/feedback/components/UnreadMessagesBadge.d.ts.map +1 -0
  90. package/dist/typescript/commonjs/features/feedback/components/icons/MessageBubbleIcon.d.ts +4 -0
  91. package/dist/typescript/commonjs/features/feedback/components/icons/MessageBubbleIcon.d.ts.map +1 -0
  92. package/dist/typescript/commonjs/features/feedback/components/icons/XCloseIcon.d.ts +4 -0
  93. package/dist/typescript/commonjs/features/feedback/components/icons/XCloseIcon.d.ts.map +1 -0
  94. package/dist/typescript/commonjs/features/feedback/components/index.d.ts +6 -0
  95. package/dist/typescript/commonjs/features/feedback/components/index.d.ts.map +1 -0
  96. package/dist/typescript/commonjs/features/feedback/constants.d.ts +20 -0
  97. package/dist/typescript/commonjs/features/feedback/constants.d.ts.map +1 -0
  98. package/dist/typescript/commonjs/features/feedback/helpers.d.ts +3 -0
  99. package/dist/typescript/commonjs/features/feedback/helpers.d.ts.map +1 -0
  100. package/dist/typescript/commonjs/features/feedback/index.d.ts +5 -0
  101. package/dist/typescript/commonjs/features/feedback/index.d.ts.map +1 -0
  102. package/dist/typescript/commonjs/features/feedback/model/teacherFeedback.model.d.ts +45 -0
  103. package/dist/typescript/commonjs/features/feedback/model/teacherFeedback.model.d.ts.map +1 -0
  104. package/dist/typescript/commonjs/features/feedback/types/teacherFeedback.types.d.ts +33 -0
  105. package/dist/typescript/commonjs/features/feedback/types/teacherFeedback.types.d.ts.map +1 -0
  106. package/dist/typescript/commonjs/index.d.ts +1 -0
  107. package/dist/typescript/commonjs/index.d.ts.map +1 -1
  108. package/dist/typescript/module/features/chatbot/components/ChatControls/ChatControls.d.ts.map +1 -1
  109. package/dist/typescript/module/features/feedback/components/EmptyComment/EmptyComment.d.ts +8 -0
  110. package/dist/typescript/module/features/feedback/components/EmptyComment/EmptyComment.d.ts.map +1 -0
  111. package/dist/typescript/module/features/feedback/components/ListCardCommentsCount/ListCardCommentsCount.d.ts +7 -0
  112. package/dist/typescript/module/features/feedback/components/ListCardCommentsCount/ListCardCommentsCount.d.ts.map +1 -0
  113. package/dist/typescript/module/features/feedback/components/TeacherFeedback.d.ts +9 -0
  114. package/dist/typescript/module/features/feedback/components/TeacherFeedback.d.ts.map +1 -0
  115. package/dist/typescript/module/features/feedback/components/TeacherFeedbackButton/TeacherFeedbackButton.d.ts +11 -0
  116. package/dist/typescript/module/features/feedback/components/TeacherFeedbackButton/TeacherFeedbackButton.d.ts.map +1 -0
  117. package/dist/typescript/module/features/feedback/components/TeacherFeedbackButton/colorSchemes.d.ts +37 -0
  118. package/dist/typescript/module/features/feedback/components/TeacherFeedbackButton/colorSchemes.d.ts.map +1 -0
  119. package/dist/typescript/module/features/feedback/components/TeacherFeedbackComments/TeacherComment.d.ts +12 -0
  120. package/dist/typescript/module/features/feedback/components/TeacherFeedbackComments/TeacherComment.d.ts.map +1 -0
  121. package/dist/typescript/module/features/feedback/components/TeacherFeedbackComments/TeacherFeedbackComments.d.ts +10 -0
  122. package/dist/typescript/module/features/feedback/components/TeacherFeedbackComments/TeacherFeedbackComments.d.ts.map +1 -0
  123. package/dist/typescript/module/features/feedback/components/UnreadMessagesBadge.d.ts +10 -0
  124. package/dist/typescript/module/features/feedback/components/UnreadMessagesBadge.d.ts.map +1 -0
  125. package/dist/typescript/module/features/feedback/components/icons/MessageBubbleIcon.d.ts +4 -0
  126. package/dist/typescript/module/features/feedback/components/icons/MessageBubbleIcon.d.ts.map +1 -0
  127. package/dist/typescript/module/features/feedback/components/icons/XCloseIcon.d.ts +4 -0
  128. package/dist/typescript/module/features/feedback/components/icons/XCloseIcon.d.ts.map +1 -0
  129. package/dist/typescript/module/features/feedback/components/index.d.ts +6 -0
  130. package/dist/typescript/module/features/feedback/components/index.d.ts.map +1 -0
  131. package/dist/typescript/module/features/feedback/constants.d.ts +20 -0
  132. package/dist/typescript/module/features/feedback/constants.d.ts.map +1 -0
  133. package/dist/typescript/module/features/feedback/helpers.d.ts +3 -0
  134. package/dist/typescript/module/features/feedback/helpers.d.ts.map +1 -0
  135. package/dist/typescript/module/features/feedback/index.d.ts +5 -0
  136. package/dist/typescript/module/features/feedback/index.d.ts.map +1 -0
  137. package/dist/typescript/module/features/feedback/model/teacherFeedback.model.d.ts +45 -0
  138. package/dist/typescript/module/features/feedback/model/teacherFeedback.model.d.ts.map +1 -0
  139. package/dist/typescript/module/features/feedback/types/teacherFeedback.types.d.ts +33 -0
  140. package/dist/typescript/module/features/feedback/types/teacherFeedback.types.d.ts.map +1 -0
  141. package/dist/typescript/module/index.d.ts +1 -0
  142. package/dist/typescript/module/index.d.ts.map +1 -1
  143. package/package.json +4 -4
  144. package/src/features/chatbot/components/ChatControls/ChatControls.tsx +4 -27
  145. package/src/features/feedback/components/EmptyComment/EmptyComment.tsx +43 -0
  146. package/src/features/feedback/components/ListCardCommentsCount/ListCardCommentsCount.tsx +33 -0
  147. package/src/features/feedback/components/TeacherFeedback.tsx +46 -0
  148. package/src/features/feedback/components/TeacherFeedbackButton/TeacherFeedbackButton.tsx +117 -0
  149. package/src/features/feedback/components/TeacherFeedbackButton/colorSchemes.ts +38 -0
  150. package/src/features/feedback/components/TeacherFeedbackComments/TeacherComment.tsx +80 -0
  151. package/src/features/feedback/components/TeacherFeedbackComments/TeacherFeedbackComments.tsx +69 -0
  152. package/src/features/feedback/components/UnreadMessagesBadge.tsx +61 -0
  153. package/src/features/feedback/components/icons/MessageBubbleIcon.tsx +16 -0
  154. package/src/features/feedback/components/icons/XCloseIcon.tsx +14 -0
  155. package/src/features/feedback/components/index.ts +5 -0
  156. package/src/features/feedback/constants.ts +26 -0
  157. package/src/features/feedback/helpers.ts +66 -0
  158. package/src/features/feedback/index.ts +4 -0
  159. package/src/features/feedback/model/teacherFeedback.model.ts +255 -0
  160. package/src/features/feedback/types/teacherFeedback.types.ts +32 -0
  161. package/src/index.ts +1 -0
@@ -0,0 +1,33 @@
1
+ import React from 'react'
2
+ import { Text, View, StyleSheet } from 'react-native'
3
+ import { MessageBubbleIcon } from '../icons/MessageBubbleIcon'
4
+ import { COLORS } from '@magmamath/react-native-ui'
5
+ import { BUENOS_AIRES_FONT } from '../../constants'
6
+
7
+ type ListCardCommentsCountProps = {
8
+ count: number
9
+ }
10
+
11
+ export const ListCardCommentsCount = ({ count }: ListCardCommentsCountProps) => {
12
+ return (
13
+ <View style={styles.container}>
14
+ <MessageBubbleIcon size={23} color={COLORS.NEUTRAL_7} />
15
+ <Text style={styles.text}>{count}</Text>
16
+ </View>
17
+ )
18
+ }
19
+
20
+ const styles = StyleSheet.create({
21
+ container: {
22
+ width: 64,
23
+ flexDirection: 'row',
24
+ alignItems: 'center',
25
+ gap: 8,
26
+ },
27
+ text: {
28
+ fontSize: 14,
29
+ fontFamily: BUENOS_AIRES_FONT,
30
+ color: COLORS.NEUTRAL_7,
31
+ fontWeight: 400,
32
+ },
33
+ })
@@ -0,0 +1,46 @@
1
+ import React from 'react'
2
+ import { useStoreMap, useUnit } from 'effector-react'
3
+ import { View, StyleSheet } from 'react-native'
4
+ import { TeacherFeedbackButton } from './TeacherFeedbackButton/TeacherFeedbackButton'
5
+ import { TeacherFeedbackComments } from './TeacherFeedbackComments/TeacherFeedbackComments'
6
+ import { TeacherFeedbackModel } from '../model/teacherFeedback.model'
7
+
8
+ type TeacherFeedbackProps = {
9
+ model: TeacherFeedbackModel
10
+ mode: 'regular' | 'simple'
11
+ }
12
+
13
+ export const TeacherFeedback = ({ model, mode }: TeacherFeedbackProps) => {
14
+ const isOpen = useUnit(model.$isOpened)
15
+ const assignmentId = useUnit(model.$assignmentId)
16
+ const problemId = useUnit(model.$currentProblemId)
17
+ const locale = useUnit(model.$locale)
18
+ const isLoading = useUnit(model.getCommentsByAssignmentIdFx.pending)
19
+ const teacherFeedback = useStoreMap({
20
+ store: model.$comments,
21
+ fn: (feedback, [assignmentId, problemId]) => feedback.get(assignmentId)?.[problemId] ?? null,
22
+ keys: [assignmentId, problemId],
23
+ })
24
+
25
+ if (!problemId || !teacherFeedback) return null
26
+
27
+ return (
28
+ <View style={styles.container}>
29
+ {isOpen && <TeacherFeedbackComments comments={teacherFeedback.comments} locale={locale} mode={mode} />}
30
+ <TeacherFeedbackButton
31
+ onPress={() => model.setIsOpened(!isOpen)}
32
+ unreadCommentsCount={teacherFeedback.unreadMessagesCount}
33
+ isOpen={isOpen}
34
+ isLoading={isLoading}
35
+ size={mode === 'regular' ? 'small' : 'large'}
36
+ />
37
+ </View>
38
+ )
39
+ }
40
+
41
+ const styles = StyleSheet.create({
42
+ container: {
43
+ alignItems: 'flex-end',
44
+ gap: 11,
45
+ },
46
+ })
@@ -0,0 +1,117 @@
1
+ import React from 'react'
2
+ import { GestureResponderEvent, StyleSheet, View } from 'react-native'
3
+ import { Button, COLORS } from '@magmamath/react-native-ui'
4
+ import { UnreadMessagesBadge } from '../UnreadMessagesBadge'
5
+ import { MessageBubbleIcon } from '../icons/MessageBubbleIcon'
6
+ import { XCloseIcon } from '../icons/XCloseIcon'
7
+ import { COLOR_SCHEMES } from './colorSchemes'
8
+ import { TEACHER_FEEDBACK_BUTTON_ID } from '../../constants'
9
+
10
+ type TeacherFeedbackButtonProps = {
11
+ isOpen: boolean
12
+ isLoading: boolean
13
+ onPress?: () => void
14
+ unreadCommentsCount?: number
15
+ size?: 'small' | 'large'
16
+ }
17
+
18
+ export const TeacherFeedbackButton = ({
19
+ isOpen,
20
+ onPress,
21
+ unreadCommentsCount,
22
+ isLoading,
23
+ size = 'large',
24
+ }: TeacherFeedbackButtonProps) => {
25
+ const handlePress = (event: GestureResponderEvent) => {
26
+ event.stopPropagation()
27
+ onPress?.()
28
+ // @ts-ignore
29
+ event.isFromFeedbackButton = true
30
+ }
31
+
32
+ if (isOpen) {
33
+ return (
34
+ <Button
35
+ key='open'
36
+ id={TEACHER_FEEDBACK_BUTTON_ID}
37
+ onPress={handlePress}
38
+ size='large'
39
+ variant='primary'
40
+ disabled={isLoading}
41
+ isLoading={isLoading}
42
+ style={{
43
+ container: styles.container,
44
+ button: [styles.button, { borderColor: COLORS.NEUTRAL_5 }, styles[size]],
45
+ }}
46
+ data-skip-confetti='true'
47
+ customColorScheme={COLOR_SCHEMES.GREY}
48
+ icon={<XCloseIcon size={size === 'large' ? 37 : 26} />}
49
+ />
50
+ )
51
+ }
52
+
53
+ return (
54
+ <Button
55
+ key='closed'
56
+ id={TEACHER_FEEDBACK_BUTTON_ID}
57
+ onPress={handlePress}
58
+ size='large'
59
+ variant='primary'
60
+ disabled={isLoading}
61
+ isLoading={isLoading}
62
+ style={{
63
+ container: styles.container,
64
+ button: [
65
+ styles.button,
66
+ { borderColor: !!unreadCommentsCount ? COLORS.BLUE_6 : COLORS.NEUTRAL_5 },
67
+ styles[size],
68
+ ],
69
+ }}
70
+ customColorScheme={!!unreadCommentsCount ? COLOR_SCHEMES.BLUE : COLOR_SCHEMES.GREY}
71
+ icon={
72
+ <View style={styles.iconContainer}>
73
+ <MessageBubbleIcon
74
+ color={!!unreadCommentsCount ? COLORS.NEUTRAL_1 : COLORS.NEUTRAL_9}
75
+ size={size === 'large' ? 37 : 26}
76
+ />
77
+ {!!unreadCommentsCount && (
78
+ <View style={styles.badgeContainer}>
79
+ <UnreadMessagesBadge badgeContent={unreadCommentsCount} />
80
+ </View>
81
+ )}
82
+ </View>
83
+ }
84
+ />
85
+ )
86
+ }
87
+
88
+ const styles = StyleSheet.create({
89
+ container: {
90
+ width: 54,
91
+ height: 54,
92
+ },
93
+ small: {
94
+ width: 50,
95
+ height: 50,
96
+ },
97
+ large: {
98
+ width: 75,
99
+ height: 75,
100
+ },
101
+ button: {
102
+ borderWidth: 2,
103
+ },
104
+ buttonLarge: {
105
+ width: 75,
106
+ height: 75,
107
+ borderWidth: 2,
108
+ },
109
+ iconContainer: {
110
+ position: 'relative',
111
+ },
112
+ badgeContainer: {
113
+ position: 'absolute',
114
+ top: -17,
115
+ right: -17,
116
+ },
117
+ })
@@ -0,0 +1,38 @@
1
+ import { ButtonStates, COLORS } from '@magmamath/react-native-ui'
2
+
3
+ export const COLOR_SCHEMES = {
4
+ BLUE: {
5
+ [ButtonStates.DEFAULT]: {
6
+ borderColor: COLORS.BLUE_6,
7
+ raiseColor: COLORS.BLUE_6,
8
+ backgroundColor: COLORS.PRIMARY_BLUE,
9
+ },
10
+ [ButtonStates.PRESSED]: {
11
+ borderColor: COLORS.BLUE_6,
12
+ raiseColor: COLORS.BLUE_6,
13
+ backgroundColor: COLORS.PRIMARY_BLUE,
14
+ },
15
+ [ButtonStates.HOVER]: {
16
+ borderColor: COLORS.BLUE_6,
17
+ raiseColor: COLORS.BLUE_6,
18
+ backgroundColor: COLORS.PRIMARY_BLUE,
19
+ },
20
+ },
21
+ GREY: {
22
+ [ButtonStates.DEFAULT]: {
23
+ borderColor: COLORS.NEUTRAL_5,
24
+ raiseColor: COLORS.NEUTRAL_5,
25
+ backgroundColor: COLORS.NEUTRAL_1,
26
+ },
27
+ [ButtonStates.PRESSED]: {
28
+ borderColor: COLORS.NEUTRAL_5,
29
+ raiseColor: COLORS.NEUTRAL_5,
30
+ backgroundColor: COLORS.NEUTRAL_1,
31
+ },
32
+ [ButtonStates.HOVER]: {
33
+ borderColor: COLORS.NEUTRAL_5,
34
+ raiseColor: COLORS.NEUTRAL_5,
35
+ backgroundColor: COLORS.NEUTRAL_1,
36
+ },
37
+ },
38
+ }
@@ -0,0 +1,80 @@
1
+ import React from 'react'
2
+ import { View, Text, StyleSheet } from 'react-native'
3
+ import { COLORS } from '@magmamath/react-native-ui'
4
+ import { getRelativeTime } from '../../helpers'
5
+ import { BUENOS_AIRES_FONT } from '../../constants'
6
+ import { Locale } from '../../types/teacherFeedback.types'
7
+
8
+ type TeacherCommentProps = {
9
+ content: string
10
+ teacherName: string
11
+ createdAt: Date
12
+ locale: Locale | null
13
+ isLastComment: boolean
14
+ }
15
+
16
+ export const TeacherComment = ({ content, teacherName, createdAt, locale, isLastComment }: TeacherCommentProps) => {
17
+ return (
18
+ <View style={{ marginBottom: isLastComment ? 8 : 0 }}>
19
+ <View style={styles.authorInfo}>
20
+ <Text style={styles.teacherName} numberOfLines={1}>
21
+ {teacherName}
22
+ </Text>
23
+ <View style={styles.spacer} />
24
+ <Text style={styles.dateAdded} numberOfLines={1}>
25
+ {getRelativeTime(createdAt, locale ?? Locale.US)}
26
+ </Text>
27
+ </View>
28
+
29
+ <View style={styles.container}>
30
+ <Text style={styles.text}>{content}</Text>
31
+ </View>
32
+ </View>
33
+ )
34
+ }
35
+
36
+ const styles = StyleSheet.create({
37
+ container: {
38
+ padding: 8,
39
+ gap: 8,
40
+ borderTopLeftRadius: 8,
41
+ borderTopRightRadius: 8,
42
+ borderBottomRightRadius: 8,
43
+ shadowColor: COLORS.PRIMARY_SHADOW,
44
+ shadowOffset: { width: 0, height: 1 },
45
+ shadowOpacity: 0.25,
46
+ shadowRadius: 3,
47
+ elevation: 3,
48
+ backgroundColor: COLORS.NEUTRAL_3,
49
+ },
50
+ text: {
51
+ fontSize: 20,
52
+ fontFamily: BUENOS_AIRES_FONT,
53
+ color: COLORS.NEUTRAL_10,
54
+ lineHeight: 20,
55
+ },
56
+ authorInfo: {
57
+ flexDirection: 'row',
58
+ alignItems: 'center',
59
+ gap: 8,
60
+ },
61
+ teacherName: {
62
+ maxWidth: 200,
63
+ fontSize: 16,
64
+ fontWeight: '600',
65
+ fontFamily: BUENOS_AIRES_FONT,
66
+ color: COLORS.NEUTRAL_9,
67
+ },
68
+ dateAdded: {
69
+ maxWidth: 140,
70
+ fontSize: 16,
71
+ fontFamily: BUENOS_AIRES_FONT,
72
+ fontWeight: '400',
73
+ color: COLORS.NEUTRAL_7,
74
+ },
75
+ spacer: {
76
+ height: 14,
77
+ width: 2,
78
+ backgroundColor: COLORS.NEUTRAL_6,
79
+ },
80
+ })
@@ -0,0 +1,69 @@
1
+ import React, { useEffect, useRef } from 'react'
2
+ import { Platform, ScrollView, StyleSheet, useWindowDimensions, View } from 'react-native'
3
+ import { Locale, TeacherComment as FeedbackComment } from '../../types/teacherFeedback.types'
4
+ import { TeacherComment } from './TeacherComment'
5
+ import { EmptyComment } from '../EmptyComment/EmptyComment'
6
+ import { EMPTY_COMMENT_ID } from '../../constants'
7
+ import { COLORS } from '@magmamath/react-native-ui'
8
+
9
+ const TOOLBAR_HEIGHT = 140
10
+ const BOTTOM_OFFSET = Platform.OS === 'web' ? 270 : 304
11
+ const SIMPLE_MODE_OFFSET = 70
12
+
13
+ type TeacherFeedbackCommentsProps = {
14
+ comments: FeedbackComment[] | null
15
+ locale: Locale | null
16
+ mode: 'regular' | 'simple'
17
+ }
18
+
19
+ export const TeacherFeedbackComments = ({ comments, locale, mode }: TeacherFeedbackCommentsProps) => {
20
+ const ref = useRef<ScrollView | null>(null)
21
+ const dimensions = useWindowDimensions()
22
+ const MAX_HEIGHT = dimensions.height - TOOLBAR_HEIGHT - BOTTOM_OFFSET
23
+
24
+ useEffect(() => {
25
+ ref.current?.scrollToEnd({ animated: false })
26
+ }, [])
27
+
28
+ if (!comments) return null
29
+
30
+ return (
31
+ <View style={[styles.container, { maxHeight: MAX_HEIGHT - (mode === 'simple' ? SIMPLE_MODE_OFFSET : 0) }]}>
32
+ <ScrollView
33
+ ref={ref}
34
+ contentContainerStyle={styles.commentsList}
35
+ onContentSizeChange={() => ref.current?.scrollToEnd()}
36
+ >
37
+ {comments.length === 1 && comments[0]._id === EMPTY_COMMENT_ID ? (
38
+ <EmptyComment locale={locale} />
39
+ ) : (
40
+ comments.map((comment, index) => (
41
+ <TeacherComment
42
+ key={comment._id}
43
+ teacherName={comment.teacherName}
44
+ content={comment.content}
45
+ createdAt={comment.createdAt}
46
+ locale={locale}
47
+ isLastComment={index === comments.length - 1}
48
+ />
49
+ ))
50
+ )}
51
+ </ScrollView>
52
+ </View>
53
+ )
54
+ }
55
+
56
+ const styles = StyleSheet.create({
57
+ container: {
58
+ width: 368,
59
+ backgroundColor: COLORS.NEUTRAL_1,
60
+ paddingTop: 8,
61
+ paddingLeft: 8,
62
+ paddingRight: 8,
63
+ paddingBottom: 0,
64
+ borderRadius: 8,
65
+ },
66
+ commentsList: {
67
+ gap: 8,
68
+ },
69
+ })
@@ -0,0 +1,61 @@
1
+ import React from 'react'
2
+ import { Text, View, StyleSheet, Platform, StyleProp, ViewStyle } from 'react-native'
3
+ import { COLORS } from '@magmamath/react-native-ui'
4
+
5
+ type UnreadMessagesBadgeProps = {
6
+ badgeContent?: number
7
+ withBorder?: boolean
8
+ style?: StyleProp<ViewStyle>
9
+ }
10
+
11
+ export const UnreadMessagesBadge = ({ badgeContent, withBorder = false, style }: UnreadMessagesBadgeProps) => {
12
+ return (
13
+ <View
14
+ style={[
15
+ styles.container,
16
+ style,
17
+ !badgeContent && styles.emptyBadge,
18
+ withBorder && styles.border,
19
+ withBorder && (badgeContent ? styles.withBorderSize : styles.withBorderSizeEmpty),
20
+ ]}
21
+ >
22
+ <Text style={styles.text}>{badgeContent && badgeContent > 99 ? '99+' : badgeContent}</Text>
23
+ </View>
24
+ )
25
+ }
26
+
27
+ const styles = StyleSheet.create({
28
+ container: {
29
+ alignItems: 'center',
30
+ justifyContent: 'center',
31
+ width: 20,
32
+ height: 20,
33
+ borderRadius: 10,
34
+ backgroundColor: COLORS.PRIMARY_RED,
35
+ },
36
+ emptyBadge: {
37
+ width: 10,
38
+ height: 10,
39
+ },
40
+ border: {
41
+ borderWidth: 1.5,
42
+ borderColor: COLORS.NEUTRAL_1,
43
+ },
44
+ withBorderSize: {
45
+ width: 20,
46
+ height: 20,
47
+ borderRadius: 10,
48
+ },
49
+ withBorderSizeEmpty: {
50
+ width: 11.5,
51
+ height: 11.5,
52
+ borderRadius: 5.75,
53
+ },
54
+ text: {
55
+ fontSize: 12,
56
+ lineHeight: 16,
57
+ fontWeight: '600',
58
+ fontFamily: Platform.OS === 'web' ? 'Open Sans, sans-serif' : 'OpenSans-SemiBold',
59
+ color: COLORS.NEUTRAL_1,
60
+ },
61
+ })
@@ -0,0 +1,16 @@
1
+ import React from 'react'
2
+ import Svg, { Path } from 'react-native-svg'
3
+ import { IconProps, COLORS } from '@magmamath/react-native-ui'
4
+
5
+ export const MessageBubbleIcon = ({ size = 26, color = COLORS.NEUTRAL_1 }: IconProps) => {
6
+ return (
7
+ <Svg width={size} height={size} viewBox='0 0 26 26' fill='none'>
8
+ <Path
9
+ d='M1.46731 10.0594C0.934026 14.231 2.94959 17.0124 4.72827 18.403C5.15473 20.0717 4.90596 21.8796 4.72827 22.5749C6.86227 22.1577 8.40099 20.946 8.93496 20.2507C12.6702 21.2937 23.0923 21.063 24.4129 14.7527C25.5097 9.51166 22.2158 5.12788 15.3416 3.80165C7.2255 2.23582 2.01279 5.79234 1.46731 10.0594Z'
10
+ stroke={color}
11
+ strokeWidth='2'
12
+ strokeLinejoin='round'
13
+ />
14
+ </Svg>
15
+ )
16
+ }
@@ -0,0 +1,14 @@
1
+ import React from 'react'
2
+ import Svg, { Path } from 'react-native-svg'
3
+ import { IconProps, COLORS } from '@magmamath/react-native-ui'
4
+
5
+ export const XCloseIcon = ({ size = 26, color = COLORS.NEUTRAL_9 }: IconProps) => {
6
+ return (
7
+ <Svg width={size} height={size} viewBox='0 0 26 26' fill='none'>
8
+ <Path
9
+ d='M4.38388 2.61612C3.89573 2.12796 3.10427 2.12796 2.61612 2.61612C2.12796 3.10427 2.12796 3.89573 2.61612 4.38388L11.2322 13L2.61612 21.6161C2.12796 22.1043 2.12796 22.8957 2.61612 23.3839C3.10427 23.872 3.89573 23.872 4.38388 23.3839L13 14.7678L21.6161 23.3839C22.1043 23.872 22.8957 23.872 23.3839 23.3839C23.872 22.8957 23.872 22.1043 23.3839 21.6161L14.7678 13L23.3839 4.38388C23.872 3.89573 23.872 3.10427 23.3839 2.61612C22.8957 2.12796 22.1043 2.12796 21.6161 2.61612L13 11.2322L4.38388 2.61612Z'
10
+ fill={color}
11
+ />
12
+ </Svg>
13
+ )
14
+ }
@@ -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'