@elice/material-quiz 1.220803.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (160) hide show
  1. package/README.md +3 -0
  2. package/cjs/components/eb-sortable/EbDraggable.d.ts +18 -0
  3. package/cjs/components/eb-sortable/EbDraggable.js +112 -0
  4. package/cjs/components/eb-sortable/EbDroppable.d.ts +13 -0
  5. package/cjs/components/eb-sortable/EbDroppable.js +60 -0
  6. package/cjs/components/eb-sortable/EbSortable.d.ts +17 -0
  7. package/cjs/components/material-quiz/MaterialQuiz.d.ts +4 -0
  8. package/cjs/components/material-quiz/MaterialQuiz.i18n.d.ts +25 -0
  9. package/cjs/components/material-quiz/MaterialQuiz.i18n.js +55 -0
  10. package/cjs/components/material-quiz/MaterialQuiz.js +114 -0
  11. package/cjs/components/material-quiz/MaterialQuizAnswerExplanation.d.ts +3 -0
  12. package/cjs/components/material-quiz/MaterialQuizAnswerExplanation.js +55 -0
  13. package/cjs/components/material-quiz/MaterialQuizError.d.ts +3 -0
  14. package/cjs/components/material-quiz/MaterialQuizInfo.d.ts +3 -0
  15. package/cjs/components/material-quiz/MaterialQuizInfo.js +74 -0
  16. package/cjs/components/material-quiz/MaterialQuizSelectMultiple.d.ts +3 -0
  17. package/cjs/components/material-quiz/MaterialQuizSelectMultiple.js +203 -0
  18. package/cjs/components/material-quiz/MaterialQuizSelectMultipleOrder.d.ts +3 -0
  19. package/cjs/components/material-quiz/MaterialQuizSelectMultipleOrder.js +468 -0
  20. package/cjs/components/material-quiz/MaterialQuizSelectOne.d.ts +3 -0
  21. package/cjs/components/material-quiz/MaterialQuizSelectOne.js +191 -0
  22. package/cjs/components/material-quiz/MaterialQuizShimmer.d.ts +3 -0
  23. package/cjs/components/material-quiz/MaterialQuizShimmer.js +61 -0
  24. package/cjs/components/material-quiz/MaterialQuizText.d.ts +3 -0
  25. package/cjs/components/material-quiz/MaterialQuizText.js +181 -0
  26. package/cjs/components/material-quiz/QuizResultBadge.d.ts +7 -0
  27. package/cjs/components/material-quiz/QuizResultBadge.js +48 -0
  28. package/cjs/components/material-quiz/QuizSubmitStatusText.d.ts +7 -0
  29. package/cjs/components/material-quiz/QuizSubmitStatusText.js +38 -0
  30. package/cjs/components/material-quiz/context/MaterialQuizContext.d.ts +31 -0
  31. package/cjs/components/material-quiz/context/MaterialQuizContext.js +134 -0
  32. package/cjs/components/material-quiz/index.d.ts +3 -0
  33. package/cjs/components/material-quiz-edit/MaterialQuizEdit.d.ts +25 -0
  34. package/cjs/components/material-quiz-edit/MaterialQuizEdit.js +91 -0
  35. package/cjs/components/material-quiz-edit/MaterialQuizEditContent.d.ts +3 -0
  36. package/cjs/components/material-quiz-edit/MaterialQuizEditContent.js +463 -0
  37. package/cjs/components/material-quiz-edit/context.d.ts +6 -0
  38. package/cjs/components/material-quiz-edit/context.js +15 -0
  39. package/cjs/components/material-quiz-edit/index.d.ts +2 -0
  40. package/cjs/components/material-quiz-edit/locales.d.ts +34 -0
  41. package/cjs/components/material-quiz-edit/locales.js +73 -0
  42. package/cjs/components/material-quiz-edit/options/OptionSelectMultiple.d.ts +3 -0
  43. package/cjs/components/material-quiz-edit/options/OptionSelectMultiple.js +204 -0
  44. package/cjs/components/material-quiz-edit/options/OptionSelectMultipleOrder.d.ts +3 -0
  45. package/cjs/components/material-quiz-edit/options/OptionSelectMultipleOrder.js +205 -0
  46. package/cjs/components/material-quiz-edit/options/OptionSelectOne.d.ts +3 -0
  47. package/cjs/components/material-quiz-edit/options/OptionSelectOne.js +207 -0
  48. package/cjs/components/material-quiz-edit/options/OptionText.d.ts +3 -0
  49. package/cjs/components/material-quiz-edit/options/OptionText.js +99 -0
  50. package/cjs/components/material-quiz-edit/utils/editValue.d.ts +15 -0
  51. package/cjs/components/material-quiz-edit/utils/editValue.js +37 -0
  52. package/cjs/components/material-quiz-edit/utils/randomId.d.ts +4 -0
  53. package/cjs/components/material-quiz-edit/utils/randomId.js +12 -0
  54. package/cjs/components/shared/QuestionBox.d.ts +16 -0
  55. package/cjs/components/shared/QuestionBox.js +111 -0
  56. package/cjs/components/shared/QuizDraggbleDroppedOption.d.ts +12 -0
  57. package/cjs/components/shared/QuizDraggbleDroppedOption.js +31 -0
  58. package/cjs/components/shared/QuizDraggbleDummyOption.d.ts +8 -0
  59. package/cjs/components/shared/QuizDraggbleDummyOption.js +36 -0
  60. package/cjs/components/shared/QuizDraggbleOption.d.ts +14 -0
  61. package/cjs/components/shared/QuizDraggbleOption.js +191 -0
  62. package/cjs/components/shared/StyledMarkdown.d.ts +3 -0
  63. package/cjs/components/shared/StyledMarkdown.js +14 -0
  64. package/cjs/components/shared/index.d.ts +7 -0
  65. package/cjs/components/shared/question-checkbox/QuestionCheckbox.d.ts +8 -0
  66. package/cjs/components/shared/question-checkbox/QuestionCheckbox.js +26 -0
  67. package/cjs/components/shared/question-checkbox/QuestionCheckboxContext.d.ts +9 -0
  68. package/cjs/components/shared/question-checkbox/QuestionCheckboxContext.js +42 -0
  69. package/cjs/components/shared/question-checkbox/QuestionCheckboxOption.d.ts +9 -0
  70. package/cjs/components/shared/question-checkbox/QuestionCheckboxOption.js +188 -0
  71. package/cjs/components/shared/question-radio/QuestionRadio.d.ts +8 -0
  72. package/cjs/components/shared/question-radio/QuestionRadio.js +26 -0
  73. package/cjs/components/shared/question-radio/QuestionRadioContext.d.ts +9 -0
  74. package/cjs/components/shared/question-radio/QuestionRadioContext.js +42 -0
  75. package/cjs/components/shared/question-radio/QuestionRadioOption.d.ts +9 -0
  76. package/cjs/components/shared/question-radio/QuestionRadioOption.js +156 -0
  77. package/cjs/helpers/index.d.ts +50 -0
  78. package/cjs/helpers/index.js +86 -0
  79. package/cjs/index.d.ts +3 -0
  80. package/cjs/index.js +27 -0
  81. package/es/components/eb-sortable/EbDraggable.d.ts +18 -0
  82. package/es/components/eb-sortable/EbDraggable.js +105 -0
  83. package/es/components/eb-sortable/EbDroppable.d.ts +13 -0
  84. package/es/components/eb-sortable/EbDroppable.js +53 -0
  85. package/es/components/eb-sortable/EbSortable.d.ts +17 -0
  86. package/es/components/material-quiz/MaterialQuiz.d.ts +4 -0
  87. package/es/components/material-quiz/MaterialQuiz.i18n.d.ts +25 -0
  88. package/es/components/material-quiz/MaterialQuiz.i18n.js +50 -0
  89. package/es/components/material-quiz/MaterialQuiz.js +106 -0
  90. package/es/components/material-quiz/MaterialQuizAnswerExplanation.d.ts +3 -0
  91. package/es/components/material-quiz/MaterialQuizAnswerExplanation.js +48 -0
  92. package/es/components/material-quiz/MaterialQuizError.d.ts +3 -0
  93. package/es/components/material-quiz/MaterialQuizInfo.d.ts +3 -0
  94. package/es/components/material-quiz/MaterialQuizInfo.js +68 -0
  95. package/es/components/material-quiz/MaterialQuizSelectMultiple.d.ts +3 -0
  96. package/es/components/material-quiz/MaterialQuizSelectMultiple.js +197 -0
  97. package/es/components/material-quiz/MaterialQuizSelectMultipleOrder.d.ts +3 -0
  98. package/es/components/material-quiz/MaterialQuizSelectMultipleOrder.js +461 -0
  99. package/es/components/material-quiz/MaterialQuizSelectOne.d.ts +3 -0
  100. package/es/components/material-quiz/MaterialQuizSelectOne.js +185 -0
  101. package/es/components/material-quiz/MaterialQuizShimmer.d.ts +3 -0
  102. package/es/components/material-quiz/MaterialQuizShimmer.js +54 -0
  103. package/es/components/material-quiz/MaterialQuizText.d.ts +3 -0
  104. package/es/components/material-quiz/MaterialQuizText.js +174 -0
  105. package/es/components/material-quiz/QuizResultBadge.d.ts +7 -0
  106. package/es/components/material-quiz/QuizResultBadge.js +42 -0
  107. package/es/components/material-quiz/QuizSubmitStatusText.d.ts +7 -0
  108. package/es/components/material-quiz/QuizSubmitStatusText.js +32 -0
  109. package/es/components/material-quiz/context/MaterialQuizContext.d.ts +31 -0
  110. package/es/components/material-quiz/context/MaterialQuizContext.js +124 -0
  111. package/es/components/material-quiz/index.d.ts +3 -0
  112. package/es/components/material-quiz-edit/MaterialQuizEdit.d.ts +25 -0
  113. package/es/components/material-quiz-edit/MaterialQuizEdit.js +86 -0
  114. package/es/components/material-quiz-edit/MaterialQuizEditContent.d.ts +3 -0
  115. package/es/components/material-quiz-edit/MaterialQuizEditContent.js +456 -0
  116. package/es/components/material-quiz-edit/context.d.ts +6 -0
  117. package/es/components/material-quiz-edit/context.js +6 -0
  118. package/es/components/material-quiz-edit/index.d.ts +2 -0
  119. package/es/components/material-quiz-edit/locales.d.ts +34 -0
  120. package/es/components/material-quiz-edit/locales.js +68 -0
  121. package/es/components/material-quiz-edit/options/OptionSelectMultiple.d.ts +3 -0
  122. package/es/components/material-quiz-edit/options/OptionSelectMultiple.js +197 -0
  123. package/es/components/material-quiz-edit/options/OptionSelectMultipleOrder.d.ts +3 -0
  124. package/es/components/material-quiz-edit/options/OptionSelectMultipleOrder.js +198 -0
  125. package/es/components/material-quiz-edit/options/OptionSelectOne.d.ts +3 -0
  126. package/es/components/material-quiz-edit/options/OptionSelectOne.js +200 -0
  127. package/es/components/material-quiz-edit/options/OptionText.d.ts +3 -0
  128. package/es/components/material-quiz-edit/options/OptionText.js +93 -0
  129. package/es/components/material-quiz-edit/utils/editValue.d.ts +15 -0
  130. package/es/components/material-quiz-edit/utils/editValue.js +32 -0
  131. package/es/components/material-quiz-edit/utils/randomId.d.ts +4 -0
  132. package/es/components/material-quiz-edit/utils/randomId.js +8 -0
  133. package/es/components/shared/QuestionBox.d.ts +16 -0
  134. package/es/components/shared/QuestionBox.js +101 -0
  135. package/es/components/shared/QuizDraggbleDroppedOption.d.ts +12 -0
  136. package/es/components/shared/QuizDraggbleDroppedOption.js +25 -0
  137. package/es/components/shared/QuizDraggbleDummyOption.d.ts +8 -0
  138. package/es/components/shared/QuizDraggbleDummyOption.js +29 -0
  139. package/es/components/shared/QuizDraggbleOption.d.ts +14 -0
  140. package/es/components/shared/QuizDraggbleOption.js +184 -0
  141. package/es/components/shared/StyledMarkdown.d.ts +3 -0
  142. package/es/components/shared/StyledMarkdown.js +8 -0
  143. package/es/components/shared/index.d.ts +7 -0
  144. package/es/components/shared/question-checkbox/QuestionCheckbox.d.ts +8 -0
  145. package/es/components/shared/question-checkbox/QuestionCheckbox.js +19 -0
  146. package/es/components/shared/question-checkbox/QuestionCheckboxContext.d.ts +9 -0
  147. package/es/components/shared/question-checkbox/QuestionCheckboxContext.js +33 -0
  148. package/es/components/shared/question-checkbox/QuestionCheckboxOption.d.ts +9 -0
  149. package/es/components/shared/question-checkbox/QuestionCheckboxOption.js +181 -0
  150. package/es/components/shared/question-radio/QuestionRadio.d.ts +8 -0
  151. package/es/components/shared/question-radio/QuestionRadio.js +19 -0
  152. package/es/components/shared/question-radio/QuestionRadioContext.d.ts +9 -0
  153. package/es/components/shared/question-radio/QuestionRadioContext.js +33 -0
  154. package/es/components/shared/question-radio/QuestionRadioOption.d.ts +9 -0
  155. package/es/components/shared/question-radio/QuestionRadioOption.js +149 -0
  156. package/es/helpers/index.d.ts +50 -0
  157. package/es/helpers/index.js +78 -0
  158. package/es/index.d.ts +3 -0
  159. package/es/index.js +10 -0
  160. package/package.json +75 -0
@@ -0,0 +1,197 @@
1
+ import React from 'react';
2
+ import { useIntl } from 'react-intl';
3
+ import { getOrgMaterialQuizResponseGet, getOrgMaterialQuizResponseList, postOrgMaterialQuizResponseAdd } from '@elice/api-client';
4
+ import { shouldResetOptions, checkUserLectureTestEnded, getOptionStatus, getQuizResult } from '../../helpers/index.js';
5
+ import '../shared/QuizDraggbleOption.js';
6
+ import '../shared/QuizDraggbleDummyOption.js';
7
+ import '../shared/question-radio/QuestionRadio.js';
8
+ import '../shared/question-radio/QuestionRadioOption.js';
9
+ import QuestionCheckbox from '../shared/question-checkbox/QuestionCheckbox.js';
10
+ import QuestionCheckboxOption from '../shared/question-checkbox/QuestionCheckboxOption.js';
11
+ import QuestionBox from '../shared/QuestionBox.js';
12
+ import StyledMarkdown from '../shared/StyledMarkdown.js';
13
+ import { useMaterialQuizState, useMaterialQuizDispatch } from './context/MaterialQuizContext.js';
14
+ import QuizResultBadge from './QuizResultBadge.js';
15
+ import QuizSubmitStatusText from './QuizSubmitStatusText.js';
16
+
17
+ const MaterialQuizSelectMultiple = () => {
18
+ // context
19
+ const {
20
+ course,
21
+ lecture,
22
+ materialQuiz,
23
+ userId
24
+ } = useMaterialQuizState();
25
+ const {
26
+ onSubmit,
27
+ onNext,
28
+ refreshOrgMaterialQuiz
29
+ } = useMaterialQuizDispatch(); // state
30
+
31
+ const intl = useIntl();
32
+ const [selectedAnswer, setSelectedAnswer] = React.useState([]);
33
+ const [materialQuizResponse, setMaterialQuizResponse] = React.useState();
34
+ const [submitStatus, setSubmitStatus] = React.useState('idle'); // Whether user has clicked any options
35
+
36
+ const [isActive, setIsActive] = React.useState(false);
37
+ const [hasSubmitted, setHasSubmitted] = React.useState(false); // quiz response fetcher
38
+
39
+ React.useEffect(() => {
40
+ if (!userId && (materialQuiz === null || materialQuiz === void 0 ? void 0 : materialQuiz.lastQuizResponseId)) {
41
+ const controller = new AbortController();
42
+ const {
43
+ signal
44
+ } = controller;
45
+ getOrgMaterialQuizResponseGet({
46
+ quizResponseId: materialQuiz.lastQuizResponseId
47
+ }, {
48
+ signal
49
+ }).then(response => {
50
+ setMaterialQuizResponse(response.quizResponse); // when user submitted answers and not get the result yet, update selected options (for example, test quiz)
51
+ // when is is a survey type quiz
52
+
53
+ if (!shouldResetOptions({
54
+ materialQuizResponse: response.quizResponse
55
+ })) {
56
+ setSelectedAnswer(response.quizResponse.answer);
57
+ }
58
+
59
+ setSelectedAnswer(response.quizResponse.answer);
60
+ }).catch(error => {
61
+ console.error(error);
62
+ });
63
+ return () => controller.abort();
64
+ }
65
+ }, [materialQuiz, userId]); // quiz response fetcher
66
+
67
+ React.useEffect(() => {
68
+ if (userId && materialQuiz) {
69
+ const controller = new AbortController();
70
+ const {
71
+ signal
72
+ } = controller;
73
+ getOrgMaterialQuizResponseList({
74
+ materialQuizId: materialQuiz.id,
75
+ filterUserIds: [userId],
76
+ isContainOnlyLast: true,
77
+ isIncludeAnswer: true,
78
+ offset: 0,
79
+ count: 1
80
+ }, {
81
+ signal
82
+ }).then(response => {
83
+ const quizResponse = response.quizResponses[0];
84
+ setMaterialQuizResponse(quizResponse);
85
+
86
+ if (Array.isArray(quizResponse.answer)) {
87
+ setSelectedAnswer(quizResponse.answer);
88
+ }
89
+ }).catch(error => {
90
+ console.error(error);
91
+ });
92
+ return () => controller.abort();
93
+ }
94
+ }, [materialQuiz, userId]); // submit handler
95
+
96
+ const handleSubmit = async () => {
97
+ if (!materialQuiz) {
98
+ return;
99
+ }
100
+
101
+ setSubmitStatus('pending');
102
+
103
+ try {
104
+ const {
105
+ quizResponseId
106
+ } = await postOrgMaterialQuizResponseAdd({
107
+ materialQuizId: materialQuiz.id,
108
+ answer: selectedAnswer
109
+ });
110
+ const {
111
+ quizResponse
112
+ } = await getOrgMaterialQuizResponseGet({
113
+ quizResponseId
114
+ });
115
+ setIsActive(false);
116
+ setMaterialQuizResponse(quizResponse);
117
+ void refreshOrgMaterialQuiz();
118
+ onSubmit(true, getQuizResult(quizResponse));
119
+ setSubmitStatus('resolved');
120
+ setHasSubmitted(true);
121
+ } catch (error) {
122
+ console.error(error);
123
+ onSubmit(false);
124
+ setSubmitStatus('rejected');
125
+ }
126
+ };
127
+
128
+ return React.createElement(QuestionBox, {
129
+ title: intl.formatMessage({
130
+ id: 'materialQuiz.myAnswer'
131
+ }),
132
+ onNext: onNext,
133
+ isNextActive: hasSubmitted && typeof onNext === 'function',
134
+ submitResult: React.createElement(QuizResultBadge, {
135
+ materialQuizResponse: materialQuizResponse
136
+ }),
137
+ submitStatus: React.createElement(QuizSubmitStatusText, {
138
+ status: submitStatus
139
+ }),
140
+ footerActions: [{
141
+ border: true,
142
+ disabled: selectedAnswer.length === 0 || checkUserLectureTestEnded(lecture) || !!userId,
143
+ loading: submitStatus === 'pending',
144
+ tabIndex: 0,
145
+ transparent: false,
146
+ role: 'primary',
147
+ onClick: handleSubmit,
148
+ children: intl.formatMessage({
149
+ id: 'materialQuiz.submit'
150
+ })
151
+ }]
152
+ }, React.createElement(QuestionCheckbox, {
153
+ onSelect: index => {
154
+ if (checkUserLectureTestEnded(lecture) || !!userId) {
155
+ return;
156
+ }
157
+
158
+ setHasSubmitted(false);
159
+ setIsActive(true);
160
+ setSelectedAnswer(prevState => {
161
+ const newState = prevState.includes(index) ? prevState.filter(ident => ident !== index) : [...prevState, index];
162
+ return newState;
163
+ });
164
+ },
165
+ selectedOptions: selectedAnswer,
166
+ disabled: submitStatus === 'pending' || checkUserLectureTestEnded(lecture) || !!userId
167
+ }, (materialQuiz === null || materialQuiz === void 0 ? void 0 : materialQuiz.optionInfo) ? materialQuiz.optionInfo.map((option, index) => {
168
+ const getIsSelected = (index, materialQuizResponse) => {
169
+ var _a;
170
+
171
+ if (!materialQuizResponse || typeof materialQuizResponse.answer === 'string') {
172
+ return false;
173
+ }
174
+
175
+ return (_a = materialQuizResponse.answer.includes(index)) !== null && _a !== void 0 ? _a : false;
176
+ };
177
+
178
+ const status = getOptionStatus({
179
+ materialQuizResponse,
180
+ isSelected: getIsSelected(index, materialQuizResponse),
181
+ isActive
182
+ });
183
+ return React.createElement(QuestionCheckboxOption, {
184
+ key: index,
185
+ value: index,
186
+ status: status,
187
+ isAnswer: !!userId && Array.isArray(materialQuiz.answerInfo) && materialQuiz.answerInfo.includes(index)
188
+ }, (course === null || course === void 0 ? void 0 : course.preference.renderMarkdownInQuizOptions) ? React.createElement(StyledMarkdown, {
189
+ children: option,
190
+ paddingx: 0,
191
+ paddingy: 0,
192
+ dark: false
193
+ }) : option);
194
+ }) : null));
195
+ };
196
+
197
+ export { MaterialQuizSelectMultiple as default };
@@ -0,0 +1,3 @@
1
+ import React from 'react';
2
+ declare const MaterialQuizSelectMultipleOrder: React.FC;
3
+ export default MaterialQuizSelectMultipleOrder;
@@ -0,0 +1,461 @@
1
+ import React from 'react';
2
+ import { useIntl } from 'react-intl';
3
+ import { getOrgMaterialQuizResponseGet, getOrgMaterialQuizResponseList, postOrgMaterialQuizResponseAdd } from '@elice/api-client';
4
+ import { Flex, Text, Icon } from '@elice/blocks';
5
+ import { base } from '@elice/design-tokens';
6
+ import { eilSortItem } from '@elice/icons';
7
+ import styled from 'styled-components';
8
+ import { checkUserLectureTestEnded, getQuizResult, getQuizResultStatus, QuizResultStatus } from '../../helpers/index.js';
9
+ import EbDroppable from '../eb-sortable/EbDroppable.js';
10
+ import QuestionBox from '../shared/QuestionBox.js';
11
+ import QuizDraggbleDroppedOption from '../shared/QuizDraggbleDroppedOption.js';
12
+ import QuizDraggbleDummyOption from '../shared/QuizDraggbleDummyOption.js';
13
+ import QuizDraggbleOption from '../shared/QuizDraggbleOption.js';
14
+ import { useMaterialQuizState, useMaterialQuizDispatch } from './context/MaterialQuizContext.js';
15
+ import QuizResultBadge from './QuizResultBadge.js';
16
+ import QuizSubmitStatusText from './QuizSubmitStatusText.js';
17
+
18
+ const StyledVerticalDivider = styled.div.withConfig({
19
+ componentId: "sc-10067nt-0"
20
+ })(["display:flex;flex-direction:column;align-items:center;justify-content:center;flex:none !important;padding:1rem;", ""], ({
21
+ vertical
22
+ }) => {
23
+ return vertical ? `
24
+ display: none;
25
+ ` : '';
26
+ });
27
+ const StyledHorizontalDivider = styled.hr.withConfig({
28
+ componentId: "sc-10067nt-1"
29
+ })(["display:none;", ""], ({
30
+ vertical
31
+ }) => {
32
+ return vertical ? `
33
+ display: block;
34
+ margin: 1rem 0;
35
+ width: 100%;
36
+ border: solid 1px ${base.color.navy5};
37
+ ` : '';
38
+ });
39
+ const StyledQuizOptionsDropZone = styled(EbDroppable).withConfig({
40
+ componentId: "sc-10067nt-2"
41
+ })(["display:flex;flex-direction:column;flex:1 1 50%;padding:1rem;border-radius:8px;background-color:", ";& > div{margin-bottom:1rem;}&.ui-droppable-hover{outline:1px dashed ", ";}"], base.color.navy6, base.color.gray4);
42
+ const StyledQuizAnswersDropZone = styled.div.withConfig({
43
+ componentId: "sc-10067nt-3"
44
+ })(["position:relative;display:flex;flex-direction:column;flex:1 1 50%;padding:1rem;border-radius:8px;background-color:", ";& > div{margin-bottom:1rem;}"], base.color.navy6);
45
+ const StyledOptionBox = styled.div.withConfig({
46
+ componentId: "sc-10067nt-4"
47
+ })(["display:flex;", ""], ({
48
+ vertical
49
+ }) => {
50
+ return vertical ? `
51
+ flex-direction: column;
52
+ ` : '';
53
+ });
54
+
55
+ const MaterialQuizSelectMultipleOrder = () => {
56
+ // context
57
+ const {
58
+ lecture,
59
+ materialQuiz,
60
+ userId,
61
+ vertical,
62
+ course
63
+ } = useMaterialQuizState();
64
+ const {
65
+ onSubmit,
66
+ onNext,
67
+ refreshOrgMaterialQuiz
68
+ } = useMaterialQuizDispatch(); // state
69
+
70
+ const intl = useIntl();
71
+ const [materialQuizResponse, setMaterialQuizResponse] = React.useState();
72
+ const [submitStatus, setSubmitStatus] = React.useState('idle');
73
+ const [isActive, setIsActive] = React.useState(false);
74
+ const [optionList, setOptionList] = React.useState([]);
75
+ const [answerList, setAnswerList] = React.useState([]);
76
+ const [correctAnswerList, setCorrectAnswerList] = React.useState([]);
77
+ const [hasSubmitted, setHasSubmitted] = React.useState(false); // ref
78
+
79
+ const optionBoxRef = React.useRef(null); // to make jquery touchable
80
+
81
+ React.useEffect(() => {
82
+ const optionBoxElement = optionBoxRef.current;
83
+
84
+ if (!optionBoxElement) {
85
+ return;
86
+ }
87
+ /**
88
+ * Lightweight script to convert touch handlers to mouse handlers
89
+ * credit: http://stackoverflow.com/a/6141093
90
+ */
91
+
92
+
93
+ function touchHandler(event) {
94
+ const touches = event.changedTouches;
95
+ const first = touches[0];
96
+ let type = '';
97
+
98
+ switch (event.type) {
99
+ case 'touchstart':
100
+ type = 'mousedown';
101
+ break;
102
+
103
+ case 'touchmove':
104
+ type = 'mousemove';
105
+ break;
106
+
107
+ case 'touchend':
108
+ type = 'mouseup';
109
+ break;
110
+
111
+ default:
112
+ return;
113
+ } // initMouseEvent(type, canBubble, cancelable, view, clickCount,
114
+ // screenX, screenY, clientX, clientY, ctrlKey,
115
+ // altKey, shiftKey, metaKey, button, relatedTarget);
116
+
117
+
118
+ const simulatedEvent = document.createEvent('MouseEvent');
119
+ simulatedEvent.initMouseEvent(type, true, true, window, 1, first.screenX, first.screenY, first.clientX, first.clientY, false, false, false, false, 0
120
+ /*left*/
121
+ , null);
122
+ first.target.dispatchEvent(simulatedEvent);
123
+ event.preventDefault();
124
+ }
125
+
126
+ optionBoxElement.addEventListener('touchstart', touchHandler, true);
127
+ optionBoxElement.addEventListener('touchmove', touchHandler, true);
128
+ optionBoxElement.addEventListener('touchend', touchHandler, true);
129
+ optionBoxElement.addEventListener('touchcancel', touchHandler, true);
130
+ return () => {
131
+ optionBoxElement.removeEventListener('touchstart', touchHandler, true);
132
+ optionBoxElement.removeEventListener('touchmove', touchHandler, true);
133
+ optionBoxElement.removeEventListener('touchend', touchHandler, true);
134
+ optionBoxElement.removeEventListener('touchcancel', touchHandler, true);
135
+ };
136
+ }, []); // quiz response fetcher
137
+
138
+ React.useEffect(() => {
139
+ var _a, _b;
140
+
141
+ if (!userId && (materialQuiz === null || materialQuiz === void 0 ? void 0 : materialQuiz.lastQuizResponseId)) {
142
+ const controller = new AbortController();
143
+ const {
144
+ signal
145
+ } = controller;
146
+ getOrgMaterialQuizResponseGet({
147
+ quizResponseId: materialQuiz.lastQuizResponseId
148
+ }, {
149
+ signal
150
+ }).then(response => {
151
+ setMaterialQuizResponse(response.quizResponse);
152
+ const answer = response.quizResponse.answer; // user submitted
153
+
154
+ const optionInfo = materialQuiz.optionInfo; // options
155
+
156
+ const answerList = answer.map(answer => ({
157
+ order: answer,
158
+ value: optionInfo[answer]
159
+ }), []);
160
+ const optionList = optionInfo.filter((item, index) => !answer.includes(index)).map(option => ({
161
+ order: optionInfo.findIndex(optionInfo => optionInfo === option),
162
+ value: option
163
+ }));
164
+ setAnswerList(answerList);
165
+ setOptionList(optionList);
166
+ }).catch(error => {
167
+ console.error(error);
168
+ });
169
+ return () => controller.abort();
170
+ } else {
171
+ setOptionList(((_a = materialQuiz === null || materialQuiz === void 0 ? void 0 : materialQuiz.optionInfo) === null || _a === void 0 ? void 0 : _a.map((option, index) => ({
172
+ order: index,
173
+ value: option
174
+ }))) || []);
175
+ setAnswerList(Array.from({
176
+ length: (_b = materialQuiz === null || materialQuiz === void 0 ? void 0 : materialQuiz.correctOptionCount) !== null && _b !== void 0 ? _b : 0
177
+ }, () => ({
178
+ order: null,
179
+ value: null
180
+ })));
181
+ }
182
+ }, [materialQuiz, userId]); // quiz response fetcher
183
+
184
+ React.useEffect(() => {
185
+ if (userId && materialQuiz) {
186
+ const controller = new AbortController();
187
+ const {
188
+ signal
189
+ } = controller;
190
+ getOrgMaterialQuizResponseList({
191
+ materialQuizId: materialQuiz.id,
192
+ filterUserIds: [userId],
193
+ isContainOnlyLast: true,
194
+ isIncludeAnswer: true,
195
+ offset: 0,
196
+ count: 1
197
+ }, {
198
+ signal
199
+ }).then(response => {
200
+ var _a, _b, _c;
201
+
202
+ const quizResponse = response.quizResponses[0];
203
+ setMaterialQuizResponse(quizResponse);
204
+ const answer = (_a = quizResponse === null || quizResponse === void 0 ? void 0 : quizResponse.answer) !== null && _a !== void 0 ? _a : []; // user submitted
205
+
206
+ const optionInfo = materialQuiz.optionInfo; // options
207
+
208
+ const correctAnswerList = Array.isArray(materialQuiz.answerInfo) ? (_c = (_b = materialQuiz.answerInfo) === null || _b === void 0 ? void 0 : _b.map(answerInfo => {
209
+ var _a, _b;
210
+
211
+ return {
212
+ order: answerInfo,
213
+ value: (_b = (_a = materialQuiz.optionInfo) === null || _a === void 0 ? void 0 : _a[answerInfo]) !== null && _b !== void 0 ? _b : ''
214
+ };
215
+ })) !== null && _c !== void 0 ? _c : [] : [];
216
+ const answerList = answer.map(answer => ({
217
+ order: answer,
218
+ value: optionInfo[answer]
219
+ }), []);
220
+ const optionList = optionInfo.filter((item, index) => !answer.includes(index)).map(option => ({
221
+ order: optionInfo.findIndex(optionInfo => optionInfo === option),
222
+ value: option
223
+ }));
224
+ setCorrectAnswerList(correctAnswerList);
225
+ setAnswerList(answerList);
226
+ setOptionList(optionList);
227
+ }).catch(error => {
228
+ console.error(error);
229
+ });
230
+ return () => controller.abort();
231
+ }
232
+ }, [materialQuiz, userId]); // submit handler
233
+
234
+ const handleSubmit = async () => {
235
+ if (!materialQuiz) {
236
+ return;
237
+ }
238
+
239
+ setSubmitStatus('pending');
240
+
241
+ try {
242
+ const {
243
+ quizResponseId
244
+ } = await postOrgMaterialQuizResponseAdd({
245
+ materialQuizId: materialQuiz.id,
246
+ answer: answerList.map(answer => answer.order)
247
+ });
248
+ const {
249
+ quizResponse
250
+ } = await getOrgMaterialQuizResponseGet({
251
+ quizResponseId
252
+ });
253
+ setIsActive(false);
254
+ setHasSubmitted(true);
255
+ setMaterialQuizResponse(quizResponse);
256
+ void refreshOrgMaterialQuiz();
257
+ onSubmit(true, getQuizResult(quizResponse));
258
+ setSubmitStatus('resolved');
259
+ } catch (error) {
260
+ console.error(error);
261
+ onSubmit(false);
262
+ setSubmitStatus('rejected');
263
+ }
264
+ };
265
+
266
+ const renderQuizDragOption = () => {
267
+ return React.createElement(StyledQuizOptionsDropZone, {
268
+ disabled: !!userId,
269
+ accept: ".quiz-answer",
270
+ onDrop: (event, ui) => {
271
+ if (checkUserLectureTestEnded(lecture)) {
272
+ return;
273
+ }
274
+
275
+ setIsActive(true);
276
+ setHasSubmitted(false);
277
+ const targetId = Number(ui.draggable[0].id);
278
+ setOptionList(prevOptionList => {
279
+ return [...prevOptionList, answerList.find(answer => answer.order === targetId)].sort((a, b) => a.order - b.order);
280
+ });
281
+ setAnswerList(prevAnswerList => {
282
+ const removingIndex = prevAnswerList.findIndex(answer => answer.order === targetId);
283
+ return prevAnswerList.map((answer, answerIndex) => {
284
+ if (answerIndex === removingIndex) {
285
+ return {
286
+ order: null,
287
+ value: null
288
+ };
289
+ } else {
290
+ return answer;
291
+ }
292
+ });
293
+ });
294
+ }
295
+ }, optionList.map((option, index) => {
296
+ return React.createElement(QuizDraggbleOption, {
297
+ disabled: !!userId,
298
+ key: option.order,
299
+ id: option.order.toString(),
300
+ className: "quiz-option",
301
+ content: option.value,
302
+ isMarkdown: !!(course === null || course === void 0 ? void 0 : course.preference.renderMarkdownInQuizOptions)
303
+ });
304
+ }), optionList.length === 0 && !userId ? React.createElement(Flex, {
305
+ align: "center",
306
+ justify: "center",
307
+ style: {
308
+ minWidth: '200px',
309
+ height: '100%'
310
+ }
311
+ }, React.createElement(Text, {
312
+ size: "tiny",
313
+ role: "white"
314
+ }, intl.formatMessage({
315
+ id: 'materialQuiz.order.answerEmpty'
316
+ }))) : null);
317
+ };
318
+
319
+ const renderQuizDragAnswers = () => {
320
+ return React.createElement(StyledQuizAnswersDropZone, null, answerList.map((option, index) => {
321
+ const getRole = () => {
322
+ if (isActive) {
323
+ return 'default';
324
+ }
325
+
326
+ const status = getQuizResultStatus(materialQuizResponse);
327
+
328
+ switch (status) {
329
+ case QuizResultStatus.Correct:
330
+ return 'correct';
331
+
332
+ case QuizResultStatus.Wrong:
333
+ return 'wrong';
334
+
335
+ default:
336
+ return 'default';
337
+ }
338
+ };
339
+
340
+ if (option.value === null) {
341
+ return React.createElement(QuizDraggbleDummyOption, {
342
+ key: index,
343
+ indexOrder: index + 1,
344
+ onDrop: (event, ui) => {
345
+ if (checkUserLectureTestEnded(lecture)) {
346
+ return;
347
+ }
348
+
349
+ setIsActive(true);
350
+ setHasSubmitted(false); // from answerList to answerList
351
+
352
+ if (ui.draggable[0].classList.contains('quiz-answer')) {
353
+ const targetOptionId = Number(ui.draggable[0].id);
354
+ setAnswerList(prevAnswerList => {
355
+ const newState = [...prevAnswerList];
356
+ const from = newState.find(prevAnswer => prevAnswer.order === targetOptionId);
357
+ const fromIndex = newState.findIndex(prevAnswer => prevAnswer.order === targetOptionId);
358
+ const to = newState[index];
359
+ newState[index] = from;
360
+ newState[fromIndex] = to;
361
+ return newState;
362
+ });
363
+ } // from option-list to answerList-list
364
+ else {
365
+ const targetOptionId = Number(ui.draggable[0].id);
366
+ setOptionList(prevOptions => {
367
+ return prevOptions.filter(prevOption => prevOption.order !== targetOptionId);
368
+ });
369
+ setAnswerList(prevAnswerList => {
370
+ return prevAnswerList.map((prevAnswer, prevAnswerIndex) => {
371
+ var _a, _b;
372
+
373
+ if (index === prevAnswerIndex) {
374
+ return {
375
+ order: targetOptionId,
376
+ value: (_b = (_a = optionList.find(option => option.order === targetOptionId)) === null || _a === void 0 ? void 0 : _a.value) !== null && _b !== void 0 ? _b : ''
377
+ };
378
+ } else {
379
+ return prevAnswer;
380
+ }
381
+ });
382
+ });
383
+ }
384
+ }
385
+ });
386
+ } else {
387
+ return React.createElement(QuizDraggbleDroppedOption, {
388
+ key: index,
389
+ id: option.order.toString(),
390
+ content: option.value,
391
+ role: getRole(),
392
+ disabled: !!userId,
393
+ indexOrder: index + 1,
394
+ isMarkdown: !!(course === null || course === void 0 ? void 0 : course.preference.renderMarkdownInQuizOptions)
395
+ });
396
+ }
397
+ }));
398
+ };
399
+
400
+ return React.createElement(QuestionBox, {
401
+ title: intl.formatMessage({
402
+ id: 'materialQuiz.myAnswer'
403
+ }),
404
+ onNext: onNext,
405
+ isNextActive: hasSubmitted && typeof onNext === 'function',
406
+ submitStatus: React.createElement(QuizSubmitStatusText, {
407
+ status: submitStatus
408
+ }),
409
+ submitResult: React.createElement(QuizResultBadge, {
410
+ materialQuizResponse: materialQuizResponse
411
+ }),
412
+ footerActions: [{
413
+ border: true,
414
+ disabled: (materialQuiz === null || materialQuiz === void 0 ? void 0 : materialQuiz.correctOptionCount) !== answerList.filter(answer => answer.order !== null).length || !!userId,
415
+ loading: submitStatus === 'pending',
416
+ tabIndex: 0,
417
+ transparent: false,
418
+ role: 'primary',
419
+ onClick: handleSubmit,
420
+ children: intl.formatMessage({
421
+ id: 'materialQuiz.submit'
422
+ })
423
+ }]
424
+ }, React.createElement(StyledOptionBox, {
425
+ ref: optionBoxRef,
426
+ vertical: vertical
427
+ }, renderQuizDragOption(), React.createElement(StyledVerticalDivider, {
428
+ vertical: vertical
429
+ }, React.createElement(Icon, {
430
+ size: "elephant",
431
+ icon: eilSortItem,
432
+ rotate: 90,
433
+ style: {
434
+ color: base.color.navy3
435
+ }
436
+ })), React.createElement(StyledHorizontalDivider, {
437
+ vertical: vertical
438
+ }), renderQuizDragAnswers()), !!userId ? React.createElement(Flex, {
439
+ margintop: "1rem",
440
+ column: true
441
+ }, React.createElement(StyledQuizOptionsDropZone, null, React.createElement(Text, {
442
+ role: "white",
443
+ size: "small"
444
+ }, intl.formatMessage({
445
+ id: 'materialQuiz.answer'
446
+ })), correctAnswerList.map((correctAnswer, index) => {
447
+ var _a;
448
+
449
+ return React.createElement(QuizDraggbleDroppedOption, {
450
+ key: correctAnswer.order,
451
+ id: (_a = correctAnswer.order) === null || _a === void 0 ? void 0 : _a.toString(),
452
+ content: correctAnswer.value,
453
+ disabled: true,
454
+ role: "correct",
455
+ indexOrder: index + 1,
456
+ isMarkdown: !!(course === null || course === void 0 ? void 0 : course.preference.renderMarkdownInQuizOptions)
457
+ });
458
+ }))) : null);
459
+ };
460
+
461
+ export { MaterialQuizSelectMultipleOrder as default };
@@ -0,0 +1,3 @@
1
+ import React from 'react';
2
+ declare const MaterialQuizSelectOne: React.FC;
3
+ export default MaterialQuizSelectOne;