catchup-library-web 1.19.0 → 1.20.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/dist/index.d.mts +4 -5
  2. package/dist/index.d.ts +4 -5
  3. package/dist/index.js +278 -327
  4. package/dist/index.mjs +298 -347
  5. package/package.json +1 -1
  6. package/src/components/activities/ActivityPreviewByAnswerData.tsx +3 -3
  7. package/src/components/activities/ActivityPreviewByData.tsx +3 -4
  8. package/src/components/activities/DropdownActivityContent.tsx +3 -9
  9. package/src/components/activities/FillInTheBlanksActivityContent.tsx +4 -10
  10. package/src/components/activities/GroupingActivityContent.tsx +3 -3
  11. package/src/components/activities/MCMAActivityContent.tsx +3 -2
  12. package/src/components/activities/MCSAActivityContent.tsx +3 -2
  13. package/src/components/activities/MatchingActivityContent.tsx +3 -3
  14. package/src/components/activities/OpenEndedActivityContent.tsx +4 -2
  15. package/src/components/activities/OrderingActivityContent.tsx +3 -2
  16. package/src/components/activities/TrueFalseActivityContent.tsx +3 -2
  17. package/src/components/activities/{body-content → body-contents}/ShowBodyMediaByContentType.tsx +1 -1
  18. package/src/components/activities/{evaluation-rubric-content → evaluation-rubric-contents}/ActivityEvaluationRubricContent.tsx +1 -1
  19. package/src/components/activities/{material-content → material-contents}/DropdownActivityMaterialContent.tsx +3 -3
  20. package/src/components/activities/{material-content → material-contents}/FillInTheBlanksActivityMaterialContent.tsx +2 -2
  21. package/src/components/activities/material-contents/GroupingActivityMaterialContent.tsx +354 -0
  22. package/src/components/activities/{material-content → material-contents}/MCMAActivityMaterialContent.tsx +2 -2
  23. package/src/components/activities/{material-content → material-contents}/MCSAActivityMaterialContent.tsx +2 -2
  24. package/src/components/activities/material-contents/MatchingActivityMaterialContent.tsx +342 -0
  25. package/src/components/activities/{material-content → material-contents}/OrderingActivityMaterialContent.tsx +9 -7
  26. package/src/components/activities/{material-content → material-contents}/ShowMaterialMediaByContentType.tsx +6 -6
  27. package/src/components/activities/{material-content → material-contents}/TrueFalseActivityMaterialContent.tsx +1 -1
  28. package/src/components/activities/{solution-content → solution-contents}/ActivitySolutionContent.tsx +1 -1
  29. package/src/index.ts +4 -4
  30. package/src/properties/ActivityProperties.ts +1 -2
  31. package/src/components/activities/material-content/GroupingActivityMaterialContent.tsx +0 -359
  32. package/src/components/activities/material-content/MatchingActivityMaterialContent.tsx +0 -332
  33. /package/src/components/activities/{body-content → body-contents}/ActivityBodyContent.tsx +0 -0
  34. /package/src/components/activities/{empty-content → empty-contents}/ActivityEmptyContent.tsx +0 -0
  35. /package/src/components/activities/{material-content → material-contents}/OpenEndedActivityMaterialContent.tsx +0 -0
@@ -1,359 +0,0 @@
1
- import { useEffect, useRef, useState } from "react";
2
- import { useDrop } from "react-dnd";
3
- import ShowMaterialMediaByContentType from "./ShowMaterialMediaByContentType";
4
- import { InlineMath } from "react-katex";
5
- import { constructInputWithSpecialExpressionList } from "../../../utilization/CatchtivityUtilization";
6
- import DividerLine from "../../dividers/DividerLine";
7
- import { IGroupingActivityMaterialProps } from "../../../properties/ActivityProperties";
8
- import DraggableItem from "../../dnds/DraggableItem";
9
- import DroppableItem from "../../dnds/DroppableItem";
10
- import useScreenSize from "../../../hooks/useScreenSize";
11
-
12
- const GroupingActivityMaterialContent = ({
13
- uniqueValue,
14
- answer,
15
- materialMap,
16
- contentMap,
17
- checkCanAnswerQuestion,
18
- onChange,
19
- isPreview,
20
- showCorrectAnswer,
21
- }: IGroupingActivityMaterialProps) => {
22
- const [selectedValue, setSelectedValue] = useState(null);
23
- const [selectedTargetKey, setSelectedTargetKey] = useState(null);
24
- const [isShuffled, setIsShuffled] = useState(false);
25
- const [shuffledMaterialList, setShuffledMaterialList] = useState([]);
26
- const { screenSize, containerSize } = useScreenSize();
27
- const [{ isOver, canDrop }, drop] = useDrop({
28
- accept: "GROUPING",
29
- drop: () => {},
30
- collect: (monitor: any) => ({
31
- isOver: monitor.isOver(),
32
- canDrop: monitor.canDrop(),
33
- }),
34
- });
35
- const ref = useRef<HTMLDivElement>(null);
36
- const itemsRef = useRef<HTMLDivElement>(null);
37
- const [maxWidth, setMaxWidth] = useState<number>(0);
38
-
39
- useEffect(() => {
40
- if (!ref) return;
41
- if (!ref.current) return;
42
- if (!screenSize) return;
43
- setMaxWidth(ref.current.offsetWidth - 12);
44
- }, [ref, screenSize]);
45
-
46
- // useEffect(() => {
47
- // if (!itemsRef) return;
48
- // if (!itemsRef.current) return;
49
- // if (!containerSize) return;
50
- // itemsRef.current.style.width = `${containerSize.width - 200}px`;
51
- // }, [itemsRef, containerSize]);
52
-
53
- useEffect(() => {
54
- const shuffleArray = (array: any) => {
55
- if (!isShuffled) {
56
- const copyArray = JSON.parse(JSON.stringify(array));
57
- for (let i = copyArray.length - 1; i > 0; i--) {
58
- const j = Math.floor(Math.random() * (i + 1));
59
- [copyArray[i], copyArray[j]] = [copyArray[j], copyArray[i]];
60
- }
61
- setIsShuffled(true);
62
- return copyArray;
63
- }
64
- return array;
65
- };
66
- const materialList: any = [];
67
- Object.keys(materialMap).forEach((materialKey) => {
68
- for (const materialValue of materialMap[materialKey]) {
69
- materialList.push(materialValue);
70
- }
71
- });
72
- setShuffledMaterialList(shuffleArray(materialList));
73
- }, []);
74
-
75
- useEffect(() => {
76
- if (!showCorrectAnswer) return;
77
- answer.data.find(
78
- (answerData: any) => answerData.type === "GROUPING"
79
- ).answerMap = materialMap;
80
- }, [showCorrectAnswer]);
81
-
82
- const retrieveAnswerMap = () => {
83
- const foundIndex = answer.data.findIndex(
84
- (answerData: any) => answerData.type === "GROUPING"
85
- );
86
- const answerMap = answer.data[foundIndex].answerMap;
87
- return answerMap;
88
- };
89
-
90
- const retrieveFilteredMaterialList = (answerMap: any) => {
91
- const selectedValueList: any = [];
92
- Object.keys(answerMap).forEach((key) => {
93
- answerMap[key].forEach((value: string) => {
94
- selectedValueList.push(value);
95
- });
96
- });
97
- return shuffledMaterialList.filter(
98
- (material) =>
99
- selectedValueList.findIndex((value: string) => material === value) ===
100
- -1
101
- );
102
- };
103
-
104
- const checkAnswerState = (correctAnswerList: any, learnerAnswer: string) => {
105
- if (!isPreview) return null;
106
- if (!learnerAnswer) return "EMPTY";
107
- if (!correctAnswerList) return "EMPTY";
108
- const foundIndex = correctAnswerList.findIndex(
109
- (correctAnswer: string) => correctAnswer === learnerAnswer
110
- );
111
- if (foundIndex !== -1) {
112
- return "CORRECT";
113
- }
114
- return "INCORRECT";
115
- };
116
-
117
- const handleGroupingActivityItemOnChange = (
118
- selectedTargetKey: string,
119
- selectedValue: string
120
- ) => {
121
- if (checkCanAnswerQuestion()) {
122
- onChange(answer, selectedTargetKey, selectedValue, null);
123
- setSelectedValue(null);
124
- }
125
- };
126
-
127
- const answerMap = retrieveAnswerMap();
128
- const filteredMaterialList = retrieveFilteredMaterialList(answerMap);
129
-
130
- return (
131
- <>
132
- <div
133
- ref={itemsRef}
134
- className="flex-1 flex flex-row gap-x-4 gap-y-4 overflow-auto py-2"
135
- >
136
- {filteredMaterialList.map((materialValue, index) => {
137
- return (
138
- <DraggableItem
139
- key={index}
140
- item={{ index: materialValue }}
141
- type={"GROUPING"}
142
- component={
143
- <div
144
- className={`${
145
- selectedValue === materialValue
146
- ? "border-catchup-blue"
147
- : "border-catchup-lighter-gray"
148
- } h-catchup-activity-covering-box-item flex flex-col items-center justify-center border-2 rounded-catchup-xlarge cursor-pointer transition-all duration-300`}
149
- onMouseDown={() => {
150
- if (checkCanAnswerQuestion()) {
151
- setSelectedValue(materialValue);
152
- }
153
- }}
154
- onMouseUp={() => {
155
- if (checkCanAnswerQuestion()) {
156
- setSelectedValue(null);
157
- }
158
- }}
159
- >
160
- {contentMap.type === "TEXT" ? (
161
- <div
162
- className={`flex flex-col items-center justify-center m-4 min-h-[64px] min-w-[200px]`}
163
- >
164
- <p className="text-xl text-center whitespace-pre-wrap">
165
- {constructInputWithSpecialExpressionList(
166
- materialValue
167
- ).map((inputPart, index) => (
168
- <span
169
- key={index}
170
- className={`${
171
- inputPart.isBold ? "font-bold" : ""
172
- } ${inputPart.isUnderline ? "underline" : ""}`}
173
- >
174
- {inputPart.isEquation ? (
175
- <span className="text-2xl">
176
- <InlineMath math={inputPart.value} />
177
- </span>
178
- ) : (
179
- inputPart.value
180
- )}
181
- </span>
182
- ))}
183
- </p>
184
- </div>
185
- ) : (
186
- <ShowMaterialMediaByContentType
187
- key={`${uniqueValue}-${index}`}
188
- contentType={contentMap.type}
189
- src={materialValue}
190
- canFullScreen={true}
191
- />
192
- )}
193
- </div>
194
- }
195
- moveCardHandler={() => {
196
- if (!selectedTargetKey) return;
197
- if (!selectedValue) return;
198
- handleGroupingActivityItemOnChange(
199
- selectedTargetKey,
200
- selectedValue
201
- );
202
- }}
203
- />
204
- );
205
- })}
206
- </div>
207
- {filteredMaterialList.length > 0 ? <DividerLine /> : null}
208
- {Object.keys(answerMap).map((answerMapKey, index) => (
209
- <div key={index} className="flex flex-row w-full">
210
- <div className="w-1/3">
211
- <div
212
- className={`border-catchup-blue h-catchup-activity-outer-box-item flex flex-col items-center justify-center border-2 rounded-catchup-xlarge transition-all duration-300 my-3`}
213
- >
214
- <div
215
- className={`flex flex-col items-center justify-center transition-all duration-300 m-4`}
216
- >
217
- <p className="text-xl p-5 whitespace-pre-wrap">
218
- {constructInputWithSpecialExpressionList(answerMapKey).map(
219
- (inputPart, index) => (
220
- <span
221
- key={index}
222
- className={`${inputPart.isBold ? "font-bold" : ""} ${
223
- inputPart.isUnderline ? "underline" : ""
224
- }`}
225
- >
226
- {inputPart.isEquation ? (
227
- <span className="text-2xl">
228
- <InlineMath math={inputPart.value} />
229
- </span>
230
- ) : (
231
- inputPart.value
232
- )}
233
- </span>
234
- )
235
- )}
236
- </p>
237
- </div>
238
- </div>
239
- </div>
240
- <div className="mx-4 w-[2px] bg-catchup-lighter-gray"></div>
241
- <div className="flex-1" ref={ref}>
242
- <div className="h-full py-3">
243
- <div
244
- className={`${
245
- canDrop
246
- ? selectedTargetKey === answerMapKey
247
- ? "bg-catchup-light-blue"
248
- : "bg-catchup-light-blue opacity-40"
249
- : ""
250
- } flex-1 border-catchup-blue rounded-catchup-xlarge border-2 h-full p-1`}
251
- >
252
- <DroppableItem
253
- key={index}
254
- item={{ index: answerMapKey }}
255
- type={"GROUPING"}
256
- target={selectedTargetKey}
257
- setTarget={setSelectedTargetKey}
258
- dropRef={drop}
259
- component={
260
- <div
261
- className="h-full flex-1 flex flex-row items-center overflow-x-auto"
262
- style={{
263
- maxWidth: maxWidth,
264
- }}
265
- >
266
- {answerMap[answerMapKey].map(
267
- (answerMapValue: string, answerMapIndex: number) => {
268
- const learnerAnswerState = checkAnswerState(
269
- materialMap[answerMapKey],
270
- answerMapValue
271
- );
272
- return (
273
- <div className="p-1">
274
- <div className="h-catchup-activity-box-item">
275
- <div
276
- className={`${
277
- learnerAnswerState === "EMPTY"
278
- ? "border-catchup-lighter-gray"
279
- : learnerAnswerState === "CORRECT"
280
- ? "border-catchup-green"
281
- : learnerAnswerState === "INCORRECT"
282
- ? "border-catchup-red"
283
- : "border-catchup-blue"
284
- } border-2 rounded-catchup-xlarge h-full flex flex-col items-center justify-center transition-all duration-300 cursor-pointer`}
285
- onClick={(e) => {
286
- e.preventDefault();
287
- if (checkCanAnswerQuestion()) {
288
- onChange(
289
- answer,
290
- answerMapKey,
291
- null,
292
- answerMapIndex
293
- );
294
- setSelectedValue(null);
295
- }
296
- }}
297
- >
298
- {contentMap.type === "TEXT" ? (
299
- <div
300
- className={`flex flex-col items-center justify-center transition-all duration-300 min-h-[64px] min-w-[200px]`}
301
- >
302
- <div className="m-2">
303
- <p className="text-xl text-center whitespace-pre-wrap">
304
- {constructInputWithSpecialExpressionList(
305
- answerMapValue
306
- ).map((inputPart, index) => (
307
- <span
308
- key={index}
309
- className={`${
310
- inputPart.isBold
311
- ? "font-bold"
312
- : ""
313
- } ${
314
- inputPart.isUnderline
315
- ? "underline"
316
- : ""
317
- }`}
318
- >
319
- {inputPart.isEquation ? (
320
- <span className="text-2xl">
321
- <InlineMath
322
- math={inputPart.value}
323
- />
324
- </span>
325
- ) : (
326
- inputPart.value
327
- )}
328
- </span>
329
- ))}
330
- </p>
331
- </div>
332
- </div>
333
- ) : (
334
- <ShowMaterialMediaByContentType
335
- key={`${uniqueValue}-${index}`}
336
- contentType={contentMap.type}
337
- src={answerMapValue}
338
- canFullScreen={false}
339
- />
340
- )}
341
- </div>
342
- </div>
343
- </div>
344
- );
345
- }
346
- )}
347
- </div>
348
- }
349
- />
350
- </div>
351
- </div>
352
- </div>
353
- </div>
354
- ))}
355
- </>
356
- );
357
- };
358
-
359
- export default GroupingActivityMaterialContent;
@@ -1,332 +0,0 @@
1
- import { useEffect, useRef, useState } from "react";
2
- import { useDrop } from "react-dnd";
3
- import ShowMaterialMediaByContentType from "./ShowMaterialMediaByContentType";
4
- import { InlineMath } from "react-katex";
5
- import useScreenSize from "../../../hooks/useScreenSize";
6
- import { constructInputWithSpecialExpressionList } from "../../../utilization/CatchtivityUtilization";
7
- import { IMatchingActivityMaterialProps } from "../../../properties/ActivityProperties";
8
- import DraggableItem from "../../dnds/DraggableItem";
9
- import DroppableItem from "../../dnds/DroppableItem";
10
- import DividerLine from "../../dividers/DividerLine";
11
-
12
- const MatchingActivityMaterialContent = ({
13
- uniqueValue,
14
- answer,
15
- materialMap,
16
- contentMap,
17
- checkCanAnswerQuestion,
18
- onChange,
19
- isPreview,
20
- showCorrectAnswer,
21
- }: IMatchingActivityMaterialProps) => {
22
- const [selectedValue, setSelectedValue] = useState(null);
23
- const [selectedTargetKey, setSelectedTargetKey] = useState(null);
24
- const [isShuffled, setIsShuffled] = useState(false);
25
- const [shuffledMaterialList, setShuffledMaterialList] = useState([]);
26
- const [{ isOver, canDrop }, drop] = useDrop({
27
- accept: "MATCHING",
28
- drop: () => {},
29
- collect: (monitor) => ({
30
- isOver: monitor.isOver(),
31
- canDrop: monitor.canDrop(),
32
- }),
33
- });
34
- const { containerSize } = useScreenSize();
35
- const itemsRef = useRef<HTMLDivElement>(null);
36
-
37
- useEffect(() => {
38
- const shuffleArray = (array: any) => {
39
- if (!isShuffled) {
40
- const copyArray = JSON.parse(JSON.stringify(array));
41
- for (let i = copyArray.length - 1; i > 0; i--) {
42
- const j = Math.floor(Math.random() * (i + 1));
43
- [copyArray[i], copyArray[j]] = [copyArray[j], copyArray[i]];
44
- }
45
- setIsShuffled(true);
46
- return copyArray;
47
- }
48
- return array;
49
- };
50
- const materialList: any = [];
51
- Object.keys(materialMap).forEach((materialKey) => {
52
- materialList.push(materialMap[materialKey]);
53
- });
54
- setShuffledMaterialList(shuffleArray(materialList));
55
- }, []);
56
-
57
- useEffect(() => {
58
- if (!showCorrectAnswer) return;
59
- answer.data.find(
60
- (answerData: any) => answerData.type === "MATCHING"
61
- ).answerMap = materialMap;
62
- }, [showCorrectAnswer]);
63
-
64
- useEffect(() => {
65
- if (!itemsRef) return;
66
- if (!itemsRef.current) return;
67
- if (!containerSize) return;
68
- itemsRef.current.style.width = `${containerSize.width - 220}px`;
69
- }, [itemsRef, containerSize]);
70
-
71
- const retrieveAnswerMap = () => {
72
- const foundIndex = answer.data.findIndex(
73
- (answerData: any) => answerData.type === "MATCHING"
74
- );
75
- const answerMap = answer.data[foundIndex].answerMap;
76
- const sortedAnswerMapKeys = Object.keys(answerMap).sort((a, b) =>
77
- answerMap[a]
78
- ? answerMap[b]
79
- ? answerMap[a].localeCompare(answerMap[b])
80
- : 1
81
- : -1
82
- );
83
- const sortedAnswerMap: any = {};
84
- for (const answerMapKey of sortedAnswerMapKeys) {
85
- sortedAnswerMap[answerMapKey] = answerMap[answerMapKey];
86
- }
87
- return sortedAnswerMap;
88
- };
89
-
90
- const retrieveFilteredMaterialList = (answerMap: any) => {
91
- const selectedValueList: any = [];
92
- Object.keys(answerMap).forEach((key) => {
93
- selectedValueList.push(answerMap[key]);
94
- });
95
-
96
- return shuffledMaterialList.filter(
97
- (material) =>
98
- selectedValueList.findIndex((value: string) => material === value) ===
99
- -1
100
- );
101
- };
102
-
103
- const checkAnswerState = (correctAnswer: string, learnerAnswer: string) => {
104
- if (!isPreview) return null;
105
- if (!learnerAnswer) return "EMPTY";
106
- if (correctAnswer === learnerAnswer) {
107
- return "CORRECT";
108
- }
109
- return "INCORRECT";
110
- };
111
-
112
- const handleMatchingActivityItemOnChange = (
113
- selectedTargetKey: string,
114
- selectedValue: string | null
115
- ) => {
116
- if (checkCanAnswerQuestion()) {
117
- onChange(answer, selectedTargetKey, selectedValue);
118
- setSelectedValue(null);
119
- }
120
- };
121
-
122
- const answerMap = retrieveAnswerMap();
123
- const filteredMaterialList = retrieveFilteredMaterialList(answerMap);
124
-
125
- return (
126
- <>
127
- <div
128
- ref={itemsRef}
129
- className="flex-1 flex flex-row gap-x-4 gap-y-4 overflow-auto py-2"
130
- >
131
- {filteredMaterialList.map((materialValue, index) => (
132
- <DraggableItem
133
- key={index}
134
- item={{ index: materialValue }}
135
- type={"MATCHING"}
136
- component={
137
- <div
138
- className={`${
139
- selectedValue === materialValue
140
- ? "border-catchup-blue"
141
- : "border-catchup-lighter-gray"
142
- } h-catchup-activity-covering-box-item flex flex-col items-center justify-center border-2 rounded-catchup-xlarge cursor-pointer transition-all duration-300`}
143
- onMouseDown={() => {
144
- if (checkCanAnswerQuestion()) {
145
- setSelectedValue(materialValue);
146
- }
147
- }}
148
- onMouseUp={() => {
149
- if (checkCanAnswerQuestion()) {
150
- setSelectedValue(null);
151
- }
152
- }}
153
- >
154
- {contentMap.type === "TEXT" ? (
155
- <div
156
- className={`flex flex-col items-center justify-center m-4 min-h-[64px] min-w-[200px]`}
157
- >
158
- <p className="text-xl p-5 whitespace-pre-wrap">
159
- {constructInputWithSpecialExpressionList(
160
- materialValue
161
- ).map((inputPart, index) => (
162
- <span
163
- key={index}
164
- className={`${inputPart.isBold ? "font-bold" : ""} ${
165
- inputPart.isUnderline ? "underline" : ""
166
- }`}
167
- >
168
- {inputPart.isEquation ? (
169
- <span className="text-2xl">
170
- <InlineMath math={inputPart.value} />
171
- </span>
172
- ) : (
173
- inputPart.value
174
- )}
175
- </span>
176
- ))}
177
- </p>
178
- </div>
179
- ) : (
180
- <ShowMaterialMediaByContentType
181
- key={`${uniqueValue}-${index}`}
182
- contentType={contentMap.type}
183
- src={materialValue}
184
- canFullScreen={true}
185
- />
186
- )}
187
- </div>
188
- }
189
- moveCardHandler={() => {
190
- if (!selectedTargetKey) return;
191
- if (!selectedValue) return;
192
- handleMatchingActivityItemOnChange(
193
- selectedTargetKey,
194
- selectedValue
195
- );
196
- }}
197
- />
198
- ))}
199
- </div>
200
- {filteredMaterialList.length > 0 ? <DividerLine /> : null}
201
- {Object.keys(answerMap).map((answerMapKey, index) => {
202
- const learnerAnswerState = checkAnswerState(
203
- materialMap[answerMapKey],
204
- answerMap[answerMapKey]
205
- );
206
-
207
- return (
208
- <div key={index} className="flex flex-row w-full">
209
- <div className="w-1/3">
210
- <div
211
- className={`h-catchup-activity-outer-box-item flex flex-col items-center justify-center border-2 rounded-catchup-xlarge transition-all duration-300 my-3 ${
212
- learnerAnswerState === "EMPTY"
213
- ? "border-catchup-blue"
214
- : learnerAnswerState === "CORRECT"
215
- ? "border-catchup-green"
216
- : learnerAnswerState === "INCORRECT"
217
- ? "border-catchup-red"
218
- : "border-catchup-blue"
219
- }`}
220
- >
221
- <div
222
- className={`flex flex-col items-center justify-center transition-all duration-300 m-4`}
223
- >
224
- <p className="text-xl p-5 whitespace-pre-wrap">
225
- {constructInputWithSpecialExpressionList(answerMapKey).map(
226
- (inputPart, index) => (
227
- <span
228
- key={index}
229
- className={`${inputPart.isBold ? "font-bold" : ""} ${
230
- inputPart.isUnderline ? "underline" : ""
231
- }`}
232
- >
233
- {inputPart.isEquation ? (
234
- <span className="text-2xl">
235
- <InlineMath math={inputPart.value} />
236
- </span>
237
- ) : (
238
- inputPart.value
239
- )}
240
- </span>
241
- )
242
- )}
243
- </p>
244
- </div>
245
- </div>
246
- </div>
247
- <div className="mx-4 w-[2px] bg-catchup-lighter-gray"></div>
248
- <div className="flex-1">
249
- <div
250
- className={`${
251
- canDrop
252
- ? selectedTargetKey === answerMapKey
253
- ? "bg-catchup-light-blue"
254
- : "bg-catchup-light-blue opacity-40"
255
- : ""
256
- } h-catchup-activity-outer-box-item flex flex-col items-center justify-center border-2 rounded-catchup-xlarge cursor-pointer transition-all duration-300 my-3 ${
257
- learnerAnswerState === "EMPTY"
258
- ? "border-catchup-blue"
259
- : learnerAnswerState === "CORRECT"
260
- ? "border-catchup-green"
261
- : learnerAnswerState === "INCORRECT"
262
- ? "border-catchup-red"
263
- : "border-catchup-blue"
264
- }`}
265
- onClick={() => {
266
- if (checkCanAnswerQuestion()) {
267
- setSelectedValue(null);
268
- }
269
- }}
270
- >
271
- <DroppableItem
272
- key={index}
273
- item={{ index: answerMapKey }}
274
- type={"MATCHING"}
275
- target={selectedTargetKey}
276
- setTarget={setSelectedTargetKey}
277
- dropRef={drop}
278
- component={
279
- <div
280
- className={`h-full flex-1 flex flex-row items-center justify-center `} // w-[calc((100vw_-_214px)_/_2)]
281
- onClick={(e) => {
282
- e.preventDefault();
283
- if (checkCanAnswerQuestion()) {
284
- handleMatchingActivityItemOnChange(
285
- answerMapKey,
286
- null
287
- );
288
- }
289
- }}
290
- >
291
- {contentMap.type === "TEXT" ? (
292
- <p className="text-xl p-5 whitespace-pre-wrap">
293
- {constructInputWithSpecialExpressionList(
294
- answerMap[answerMapKey]
295
- ).map((inputPart, index) => (
296
- <span
297
- key={index}
298
- className={`${
299
- inputPart.isBold ? "font-bold" : ""
300
- } ${inputPart.isUnderline ? "underline" : ""}`}
301
- >
302
- {inputPart.isEquation ? (
303
- <span className="text-2xl">
304
- <InlineMath math={inputPart.value} />
305
- </span>
306
- ) : (
307
- inputPart.value
308
- )}
309
- </span>
310
- ))}
311
- </p>
312
- ) : (
313
- <ShowMaterialMediaByContentType
314
- key={`${uniqueValue}-${index}`}
315
- contentType={contentMap.type}
316
- src={answerMap[answerMapKey]}
317
- canFullScreen={false}
318
- />
319
- )}
320
- </div>
321
- }
322
- />
323
- </div>
324
- </div>
325
- </div>
326
- );
327
- })}
328
- </>
329
- );
330
- };
331
-
332
- export default MatchingActivityMaterialContent;