catchup-library-web 1.0.0 → 1.0.2
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.
- package/dist/index.d.mts +239 -2
- package/dist/index.d.ts +239 -2
- package/dist/index.js +4686 -2
- package/dist/index.mjs +4621 -1
- package/package.json +10 -2
- package/src/components/activities/DropdownActivityContent.tsx +73 -0
- package/src/components/activities/FillInTheBlanksActivityContent.tsx +102 -0
- package/src/components/activities/GroupingActivityContent.tsx +62 -0
- package/src/components/activities/MCMAActivityContent.tsx +65 -0
- package/src/components/activities/MCSAActivityContent.tsx +58 -0
- package/src/components/activities/MatchingActivityContent.tsx +57 -0
- package/src/components/activities/OpenEndedActivityContent.tsx +92 -0
- package/src/components/activities/OrderingActivityContent.tsx +59 -0
- package/src/components/activities/TrueFalseActivityContent.tsx +98 -0
- package/src/components/activities/body-content/ActivityBodyContent.tsx +108 -0
- package/src/components/activities/body-content/ShowBodyMediaByContentType.tsx +404 -0
- package/src/components/activities/empty-content/ActivityEmptyContent.tsx +15 -0
- package/src/components/activities/material-content/DropdownActivityMaterialContent.tsx +227 -0
- package/src/components/activities/material-content/FillInTheBlanksActivityMaterialContent.tsx +270 -0
- package/src/components/activities/material-content/GroupingActivityMaterialContent.tsx +359 -0
- package/src/components/activities/material-content/MCMAActivityMaterialContent.tsx +166 -0
- package/src/components/activities/material-content/MCSAActivityMaterialContent.tsx +165 -0
- package/src/components/activities/material-content/MatchingActivityMaterialContent.tsx +332 -0
- package/src/components/activities/material-content/OpenEndedActivityMaterialContent.tsx +818 -0
- package/src/components/activities/material-content/OrderingActivityMaterialContent.tsx +216 -0
- package/src/components/activities/material-content/ShowMaterialMediaByContentType.tsx +172 -0
- package/src/components/activities/material-content/TrueFalseActivityMaterialContent.tsx +217 -0
- package/src/components/activities/solution-content/ActivitySolutionContent.tsx +86 -0
- package/src/components/dividers/BlueVerticalDividerLine.tsx +13 -0
- package/src/components/dividers/DividerLine.tsx +5 -0
- package/src/components/dividers/VerticalDividerLine.tsx +5 -0
- package/src/components/dnds/DraggableDroppableItem.tsx +62 -0
- package/src/components/dnds/DraggableItem.tsx +41 -0
- package/src/components/dnds/DroppableItem.tsx +38 -0
- package/src/components/dropdowns/MediaDropdown.tsx +51 -0
- package/src/components/groups/InputGroup.tsx +330 -0
- package/src/hooks/useScreenSize.ts +40 -0
- package/src/index.ts +24 -0
- package/src/language/i18n.ts +10 -0
- package/src/properties/ActivityProperties.ts +204 -0
- package/src/properties/ButtonProperties.ts +1 -1
- package/src/properties/CommonProperties.ts +1 -1
- package/src/properties/DividerLineProperties.ts +3 -0
- package/src/properties/DnDProperties.ts +28 -0
- package/src/properties/DropdownProperties.ts +5 -0
- package/src/properties/EnumProperties.ts +11 -0
- package/src/properties/GroupProperties.ts +19 -0
- package/src/utilization/AppUtilization.ts +56 -0
- package/src/utilization/CatchtivityUtilization.ts +1566 -0
- package/src/utilization/StorageUtilization.ts +35 -0
- package/tsconfig.json +2 -1
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
import { InlineMath } from "react-katex";
|
|
2
|
+
import InputGroup from "../../groups/InputGroup";
|
|
3
|
+
import { constructInputWithSpecialExpressionList } from "../../../utilization/CatchtivityUtilization";
|
|
4
|
+
import i18n from "../../../language/i18n";
|
|
5
|
+
import { useEffect } from "react";
|
|
6
|
+
import { useState } from "react";
|
|
7
|
+
import BaseImage from "../../images/BaseImage";
|
|
8
|
+
import { shuffleArray } from "../../../utilization/AppUtilization";
|
|
9
|
+
import DividerLine from "../../dividers/DividerLine";
|
|
10
|
+
import MediaDropdown from "../../dropdowns/MediaDropdown";
|
|
11
|
+
import { IDropdownActivityMaterialProps } from "../../../properties/ActivityProperties";
|
|
12
|
+
import ShowMaterialMediaByContentType from "./ShowMaterialMediaByContentType";
|
|
13
|
+
|
|
14
|
+
const DropdownActivityMaterialContent = ({
|
|
15
|
+
uniqueValue,
|
|
16
|
+
answer,
|
|
17
|
+
materialMap,
|
|
18
|
+
contentMap,
|
|
19
|
+
checkCanAnswerQuestion,
|
|
20
|
+
onChange,
|
|
21
|
+
isPreview,
|
|
22
|
+
showCorrectAnswer,
|
|
23
|
+
}: IDropdownActivityMaterialProps) => {
|
|
24
|
+
const [updated, setUpdated] = useState(false);
|
|
25
|
+
|
|
26
|
+
useEffect(() => {
|
|
27
|
+
if (!showCorrectAnswer) return;
|
|
28
|
+
const foundAnswer = answer.data.find(
|
|
29
|
+
(answerData: any) => answerData.type === "DROPDOWN"
|
|
30
|
+
);
|
|
31
|
+
if (foundAnswer.answerMap.length === 0) return;
|
|
32
|
+
foundAnswer.answerMap = Object.keys(materialMap).map(
|
|
33
|
+
(materialMapKey, index) => Object.keys(materialMap[materialMapKey])[0]
|
|
34
|
+
);
|
|
35
|
+
onChange(answer, 0, Object.keys(materialMap[0])[0]);
|
|
36
|
+
setUpdated(true);
|
|
37
|
+
}, [showCorrectAnswer]);
|
|
38
|
+
|
|
39
|
+
useEffect(() => {
|
|
40
|
+
if (!updated) return;
|
|
41
|
+
setUpdated(false);
|
|
42
|
+
}, [updated]);
|
|
43
|
+
|
|
44
|
+
const retrieveAnswerMap = () => {
|
|
45
|
+
const foundIndex = answer.data.findIndex(
|
|
46
|
+
(answerData: any) => answerData.type === "DROPDOWN"
|
|
47
|
+
);
|
|
48
|
+
return answer.data[foundIndex].answerMap;
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
const checkAnswerState = (correctAnswer: string, learnerAnswer: string) => {
|
|
52
|
+
if (!isPreview) return "HIDDEN";
|
|
53
|
+
if (correctAnswer === learnerAnswer) {
|
|
54
|
+
return "CORRECT";
|
|
55
|
+
}
|
|
56
|
+
return "INCORRECT";
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
const answerMap = retrieveAnswerMap();
|
|
60
|
+
|
|
61
|
+
return (
|
|
62
|
+
<div className="flex flex-row flex-wrap items-center">
|
|
63
|
+
<div className="hidden md:block">
|
|
64
|
+
<span className="font-semibold text-xl opacity-60">
|
|
65
|
+
{i18n.t("please_select_dropdown_text")}
|
|
66
|
+
</span>
|
|
67
|
+
</div>
|
|
68
|
+
<div className="hidden md:contents">
|
|
69
|
+
<DividerLine />
|
|
70
|
+
</div>
|
|
71
|
+
<div className="w-full flex flex-row flex-wrap">
|
|
72
|
+
{Object.keys(answerMap).map((materialKey: string, index: number) => {
|
|
73
|
+
const answerKey = Object.keys(materialMap[materialKey])[0];
|
|
74
|
+
const learnerAnswerState = checkAnswerState(
|
|
75
|
+
answerKey,
|
|
76
|
+
answerMap[materialKey]
|
|
77
|
+
);
|
|
78
|
+
return (
|
|
79
|
+
<div key={index} className="w-full md:w-1/2">
|
|
80
|
+
<div className="mx-2">
|
|
81
|
+
<div className="w-full flex flex-row my-2 gap-x-2">
|
|
82
|
+
<div className="my-auto">
|
|
83
|
+
<p className="text-xl">{parseFloat(materialKey) + 1}.</p>
|
|
84
|
+
</div>
|
|
85
|
+
<div className="w-full relative">
|
|
86
|
+
<div className="flex-1">
|
|
87
|
+
{checkCanAnswerQuestion() ? (
|
|
88
|
+
contentMap.type === "TEXT" ? (
|
|
89
|
+
<div className="flex-1">
|
|
90
|
+
<InputGroup
|
|
91
|
+
type="select"
|
|
92
|
+
value={answerMap[materialKey]}
|
|
93
|
+
optionList={shuffleArray(
|
|
94
|
+
materialMap[materialKey][answerKey]
|
|
95
|
+
).map((materialOption: any) => ({
|
|
96
|
+
text: (
|
|
97
|
+
<span className="text-xl whitespace-pre-wrap">
|
|
98
|
+
{constructInputWithSpecialExpressionList(
|
|
99
|
+
materialOption
|
|
100
|
+
).map((inputPart, index) => (
|
|
101
|
+
<span
|
|
102
|
+
key={index}
|
|
103
|
+
className={`${
|
|
104
|
+
inputPart.isBold ? "font-bold" : ""
|
|
105
|
+
} ${
|
|
106
|
+
inputPart.isUnderline
|
|
107
|
+
? "underline"
|
|
108
|
+
: ""
|
|
109
|
+
}`}
|
|
110
|
+
>
|
|
111
|
+
{inputPart.isEquation ? (
|
|
112
|
+
<span className="text-2xl">
|
|
113
|
+
<InlineMath
|
|
114
|
+
math={inputPart.value}
|
|
115
|
+
/>
|
|
116
|
+
</span>
|
|
117
|
+
) : (
|
|
118
|
+
inputPart.value
|
|
119
|
+
)}
|
|
120
|
+
</span>
|
|
121
|
+
))}
|
|
122
|
+
</span>
|
|
123
|
+
),
|
|
124
|
+
value: materialOption,
|
|
125
|
+
}))}
|
|
126
|
+
onChange={(e) => {
|
|
127
|
+
onChange(answer, materialKey, e.target.value);
|
|
128
|
+
}}
|
|
129
|
+
/>
|
|
130
|
+
</div>
|
|
131
|
+
) : (
|
|
132
|
+
<MediaDropdown
|
|
133
|
+
id={materialKey}
|
|
134
|
+
answer={
|
|
135
|
+
answerMap[materialKey] === "DEFAULT_OPTION" ? (
|
|
136
|
+
<div className="w-catchup-activity-box-item border h-catchup-activity-box-item rounded-catchup-xlarge border-dashed border-catchup-blue">
|
|
137
|
+
<div className="h-full flex flex-col items-center justify-center px-4 py-2">
|
|
138
|
+
<span className="italic">
|
|
139
|
+
{i18n.t("please_select")}
|
|
140
|
+
</span>
|
|
141
|
+
</div>
|
|
142
|
+
</div>
|
|
143
|
+
) : (
|
|
144
|
+
<ShowMaterialMediaByContentType
|
|
145
|
+
key={`${uniqueValue}-${index}`}
|
|
146
|
+
contentType={contentMap.type}
|
|
147
|
+
src={answerMap[materialKey]}
|
|
148
|
+
canFullScreen={false}
|
|
149
|
+
/>
|
|
150
|
+
)
|
|
151
|
+
}
|
|
152
|
+
optionList={materialMap[materialKey][answerKey].map(
|
|
153
|
+
(materialOption: any, index: number) => ({
|
|
154
|
+
id: index,
|
|
155
|
+
media: (
|
|
156
|
+
<div key={index}>
|
|
157
|
+
<ShowMaterialMediaByContentType
|
|
158
|
+
key={`${uniqueValue}-${index}`}
|
|
159
|
+
contentType={contentMap.type}
|
|
160
|
+
src={materialOption}
|
|
161
|
+
canFullScreen={false}
|
|
162
|
+
/>
|
|
163
|
+
</div>
|
|
164
|
+
),
|
|
165
|
+
onClick: (e: any) => {
|
|
166
|
+
onChange(
|
|
167
|
+
answer,
|
|
168
|
+
materialKey,
|
|
169
|
+
e.target.currentSrc
|
|
170
|
+
);
|
|
171
|
+
},
|
|
172
|
+
})
|
|
173
|
+
)}
|
|
174
|
+
/>
|
|
175
|
+
)
|
|
176
|
+
) : (
|
|
177
|
+
<p className="text-xl whitespace-pre-wrap">
|
|
178
|
+
{constructInputWithSpecialExpressionList(
|
|
179
|
+
answerMap[materialKey]
|
|
180
|
+
).map((inputPart, index) => (
|
|
181
|
+
<span
|
|
182
|
+
key={index}
|
|
183
|
+
className={`${
|
|
184
|
+
inputPart.isBold ? "font-bold" : ""
|
|
185
|
+
} ${inputPart.isUnderline ? "underline" : ""}`}
|
|
186
|
+
>
|
|
187
|
+
{inputPart.isEquation ? (
|
|
188
|
+
<span className="text-2xl">
|
|
189
|
+
<InlineMath math={inputPart.value} />
|
|
190
|
+
</span>
|
|
191
|
+
) : (
|
|
192
|
+
inputPart.value
|
|
193
|
+
)}
|
|
194
|
+
</span>
|
|
195
|
+
))}
|
|
196
|
+
</p>
|
|
197
|
+
)}
|
|
198
|
+
</div>
|
|
199
|
+
{learnerAnswerState === "CORRECT" ? (
|
|
200
|
+
<div className="absolute top-[0px] right-4 bg-catchup-white">
|
|
201
|
+
<BaseImage
|
|
202
|
+
src="/icons/checkbox.png"
|
|
203
|
+
alt="chekbbox"
|
|
204
|
+
size="small"
|
|
205
|
+
/>
|
|
206
|
+
</div>
|
|
207
|
+
) : learnerAnswerState === "INCORRECT" ? (
|
|
208
|
+
<div className="absolute top-[0px] right-4 bg-catchup-white">
|
|
209
|
+
<BaseImage
|
|
210
|
+
src="/icons/cross-red.png"
|
|
211
|
+
alt="cross-red"
|
|
212
|
+
size="small"
|
|
213
|
+
/>
|
|
214
|
+
</div>
|
|
215
|
+
) : null}
|
|
216
|
+
</div>
|
|
217
|
+
</div>
|
|
218
|
+
</div>
|
|
219
|
+
</div>
|
|
220
|
+
);
|
|
221
|
+
})}
|
|
222
|
+
</div>
|
|
223
|
+
</div>
|
|
224
|
+
);
|
|
225
|
+
};
|
|
226
|
+
|
|
227
|
+
export default DropdownActivityMaterialContent;
|
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
import { InlineMath } from "react-katex";
|
|
2
|
+
import InputGroup from "../../groups/InputGroup";
|
|
3
|
+
import { constructInputWithSpecialExpressionList } from "../../../utilization/CatchtivityUtilization";
|
|
4
|
+
import i18n from "../../../language/i18n";
|
|
5
|
+
import { useState } from "react";
|
|
6
|
+
import { useEffect } from "react";
|
|
7
|
+
import { useDrop } from "react-dnd";
|
|
8
|
+
import BaseImage from "../../images/BaseImage";
|
|
9
|
+
import { shuffleArray } from "../../../utilization/AppUtilization";
|
|
10
|
+
import DraggableItem from "../../dnds/DraggableItem";
|
|
11
|
+
import DroppableItem from "../../dnds/DroppableItem";
|
|
12
|
+
import ShowMaterialMediaByContentType from "./ShowMaterialMediaByContentType";
|
|
13
|
+
import DividerLine from "../../dividers/DividerLine";
|
|
14
|
+
import { IFillInTheBlanksActivityMaterialProps } from "../../../properties/ActivityProperties";
|
|
15
|
+
|
|
16
|
+
const FillInTheBlanksActivityMaterialContent = ({
|
|
17
|
+
uniqueValue,
|
|
18
|
+
answer,
|
|
19
|
+
optionList,
|
|
20
|
+
materialMap,
|
|
21
|
+
contentMap,
|
|
22
|
+
checkCanAnswerQuestion,
|
|
23
|
+
onChange,
|
|
24
|
+
isPreview,
|
|
25
|
+
showCorrectAnswer,
|
|
26
|
+
}: IFillInTheBlanksActivityMaterialProps) => {
|
|
27
|
+
const [shuffleOptionList, setShuffleOptionList] = useState([]);
|
|
28
|
+
const [selectedOption, setSelectedOption] = useState(null);
|
|
29
|
+
const [pasteOptionIndex, setPasteOptionIndex] = useState(null);
|
|
30
|
+
const [{ isOver, canDrop }, drop] = useDrop({
|
|
31
|
+
accept: "FILL_IN_THE_BLANKS",
|
|
32
|
+
drop: () => {},
|
|
33
|
+
collect: (monitor) => ({
|
|
34
|
+
isOver: monitor.isOver(),
|
|
35
|
+
canDrop: monitor.canDrop(),
|
|
36
|
+
}),
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
useEffect(() => {
|
|
40
|
+
setShuffleOptionList(shuffleArray(optionList));
|
|
41
|
+
}, []);
|
|
42
|
+
|
|
43
|
+
useEffect(() => {
|
|
44
|
+
if (!showCorrectAnswer) return;
|
|
45
|
+
const foundAnswer = answer.data.find(
|
|
46
|
+
(answerData: any) => answerData.type === "FILL_IN_THE_BLANKS"
|
|
47
|
+
);
|
|
48
|
+
if (foundAnswer.answerMap.length === 0) return;
|
|
49
|
+
foundAnswer.answerMap = Object.keys(materialMap).map(
|
|
50
|
+
(materialMapKey, index) => JSON.parse(materialMap[materialMapKey])[0]
|
|
51
|
+
);
|
|
52
|
+
|
|
53
|
+
onChange(answer, 0, JSON.parse(materialMap[0])[0]);
|
|
54
|
+
}, [showCorrectAnswer]);
|
|
55
|
+
|
|
56
|
+
const retrieveAnswerMap = () => {
|
|
57
|
+
const foundIndex = answer.data.findIndex(
|
|
58
|
+
(answerData: any) => answerData.type === "FILL_IN_THE_BLANKS"
|
|
59
|
+
);
|
|
60
|
+
return answer.data[foundIndex].answerMap;
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
const checkAnswerState = (correctAnswerList: any, learnerAnswer: string) => {
|
|
64
|
+
if (!isPreview) return "HIDDEN";
|
|
65
|
+
const foundIndex = correctAnswerList.findIndex(
|
|
66
|
+
(correctAnswer: string) => correctAnswer === learnerAnswer
|
|
67
|
+
);
|
|
68
|
+
if (foundIndex !== -1) {
|
|
69
|
+
return "CORRECT";
|
|
70
|
+
}
|
|
71
|
+
return "INCORRECT";
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
const checkAnswerProvided = (answerMap: any, option: string) => {
|
|
75
|
+
return (
|
|
76
|
+
Object.keys(answerMap).findIndex((key) => answerMap[key] === option) !==
|
|
77
|
+
-1
|
|
78
|
+
);
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
const answerMap = retrieveAnswerMap();
|
|
82
|
+
|
|
83
|
+
return (
|
|
84
|
+
<div className="flex flex-row flex-wrap items-center" onMouseUp={() => {}}>
|
|
85
|
+
<div className="hidden md:block">
|
|
86
|
+
<span className="font-semibold text-xl opacity-60">
|
|
87
|
+
{i18n.t("please_select_fill_in_the_blanks_text")}
|
|
88
|
+
</span>
|
|
89
|
+
</div>
|
|
90
|
+
<div className="hidden md:contents">
|
|
91
|
+
<DividerLine />
|
|
92
|
+
</div>
|
|
93
|
+
|
|
94
|
+
<div className="w-full flex flex-row flex-wrap gap-x-2 gap-y-2 my-2">
|
|
95
|
+
{shuffleOptionList.map((option, index) =>
|
|
96
|
+
checkAnswerProvided(answerMap, option) ? (
|
|
97
|
+
<div className="opacity-30">
|
|
98
|
+
<ShowMaterialMediaByContentType
|
|
99
|
+
key={`${uniqueValue}-${index}`}
|
|
100
|
+
contentType={contentMap.type}
|
|
101
|
+
src={option}
|
|
102
|
+
canFullScreen={true}
|
|
103
|
+
/>
|
|
104
|
+
</div>
|
|
105
|
+
) : (
|
|
106
|
+
<DraggableItem
|
|
107
|
+
key={index}
|
|
108
|
+
item={{ index: option }}
|
|
109
|
+
type={"FILL_IN_THE_BLANKS"}
|
|
110
|
+
component={
|
|
111
|
+
contentMap.type === "TEXT" ? (
|
|
112
|
+
<div
|
|
113
|
+
className="border-catchup-blue border-2 px-2 py-1 rounded-catchup-xlarge cursor-pointer"
|
|
114
|
+
onMouseDown={() => {
|
|
115
|
+
setSelectedOption(option);
|
|
116
|
+
setPasteOptionIndex(null);
|
|
117
|
+
}}
|
|
118
|
+
>
|
|
119
|
+
<p className="italic whitespace-pre-wrap">{option}</p>
|
|
120
|
+
</div>
|
|
121
|
+
) : (
|
|
122
|
+
<div
|
|
123
|
+
className="border-catchup-blue border-2 px-2 py-1 rounded-catchup-xlarge cursor-pointer"
|
|
124
|
+
onMouseDown={() => {
|
|
125
|
+
setSelectedOption(option);
|
|
126
|
+
setPasteOptionIndex(null);
|
|
127
|
+
}}
|
|
128
|
+
>
|
|
129
|
+
<ShowMaterialMediaByContentType
|
|
130
|
+
key={`${uniqueValue}-${index}`}
|
|
131
|
+
contentType={contentMap.type}
|
|
132
|
+
src={option}
|
|
133
|
+
canFullScreen={true}
|
|
134
|
+
/>
|
|
135
|
+
</div>
|
|
136
|
+
)
|
|
137
|
+
}
|
|
138
|
+
moveCardHandler={() => {
|
|
139
|
+
onChange(answer, pasteOptionIndex, selectedOption);
|
|
140
|
+
}}
|
|
141
|
+
/>
|
|
142
|
+
)
|
|
143
|
+
)}
|
|
144
|
+
</div>
|
|
145
|
+
<div className="flex flex-row flex-wrap">
|
|
146
|
+
{Object.keys(answerMap).map((materialKey, index) => {
|
|
147
|
+
const learnerAnswerState = checkAnswerState(
|
|
148
|
+
JSON.parse(materialMap[materialKey]),
|
|
149
|
+
answerMap[materialKey]
|
|
150
|
+
);
|
|
151
|
+
return (
|
|
152
|
+
<div key={index} className="w-full md:w-1/2">
|
|
153
|
+
<div className="mx-2">
|
|
154
|
+
<DroppableItem
|
|
155
|
+
key={index}
|
|
156
|
+
item={{ index }}
|
|
157
|
+
type={"FILL_IN_THE_BLANKS"}
|
|
158
|
+
target={pasteOptionIndex}
|
|
159
|
+
setTarget={setPasteOptionIndex}
|
|
160
|
+
dropRef={drop}
|
|
161
|
+
component={
|
|
162
|
+
<div className="w-full flex flex-row my-2 gap-x-2">
|
|
163
|
+
<div className="my-auto">
|
|
164
|
+
<p className="text-xl">
|
|
165
|
+
{parseFloat(materialKey) + 1}.
|
|
166
|
+
</p>
|
|
167
|
+
</div>
|
|
168
|
+
<div className="flex-1">
|
|
169
|
+
{checkCanAnswerQuestion() ? (
|
|
170
|
+
contentMap.type === "TEXT" ? (
|
|
171
|
+
<div className="relative">
|
|
172
|
+
<div className="flex-1">
|
|
173
|
+
<InputGroup
|
|
174
|
+
type="textarea"
|
|
175
|
+
value={answerMap[materialKey]}
|
|
176
|
+
useMinHeight={false}
|
|
177
|
+
onChange={(e) => {
|
|
178
|
+
onChange(
|
|
179
|
+
answer,
|
|
180
|
+
materialKey,
|
|
181
|
+
e.target.value
|
|
182
|
+
);
|
|
183
|
+
}}
|
|
184
|
+
/>
|
|
185
|
+
</div>
|
|
186
|
+
{learnerAnswerState === "CORRECT" ? (
|
|
187
|
+
<div className="absolute -top-[10px] right-4 bg-catchup-white">
|
|
188
|
+
<BaseImage
|
|
189
|
+
src="/icons/checkbox.png"
|
|
190
|
+
alt="checkbox"
|
|
191
|
+
size="small"
|
|
192
|
+
/>
|
|
193
|
+
</div>
|
|
194
|
+
) : learnerAnswerState === "INCORRECT" ? (
|
|
195
|
+
<div className="absolute -top-[10px] right-4 bg-catchup-white">
|
|
196
|
+
<BaseImage
|
|
197
|
+
src="/icons/cross-red.png"
|
|
198
|
+
alt="cross-red"
|
|
199
|
+
size="small"
|
|
200
|
+
/>
|
|
201
|
+
</div>
|
|
202
|
+
) : null}
|
|
203
|
+
</div>
|
|
204
|
+
) : answerMap[materialKey] === "" ? (
|
|
205
|
+
<div
|
|
206
|
+
className={`w-catchup-activity-box-item border h-catchup-activity-box-item rounded-catchup-xlarge border-dashed ${
|
|
207
|
+
learnerAnswerState === "CORRECT"
|
|
208
|
+
? "border-catchup-green"
|
|
209
|
+
: learnerAnswerState === "INCORRECT"
|
|
210
|
+
? "border-catchup-red"
|
|
211
|
+
: "border-catchup-blue"
|
|
212
|
+
}`}
|
|
213
|
+
>
|
|
214
|
+
<div className="h-full flex flex-col items-center justify-center px-4 py-2">
|
|
215
|
+
<span className="italic">
|
|
216
|
+
{i18n.t("please_drop_here")}
|
|
217
|
+
</span>
|
|
218
|
+
</div>
|
|
219
|
+
</div>
|
|
220
|
+
) : (
|
|
221
|
+
<div
|
|
222
|
+
className="flex-1 cursor-pointer"
|
|
223
|
+
onClick={() => {
|
|
224
|
+
onChange(answer, materialKey, "");
|
|
225
|
+
}}
|
|
226
|
+
>
|
|
227
|
+
<ShowMaterialMediaByContentType
|
|
228
|
+
key={`${uniqueValue}-${index}`}
|
|
229
|
+
contentType={contentMap.type}
|
|
230
|
+
src={answerMap[materialKey]}
|
|
231
|
+
canFullScreen={true}
|
|
232
|
+
/>
|
|
233
|
+
</div>
|
|
234
|
+
)
|
|
235
|
+
) : (
|
|
236
|
+
<p key={materialKey} className="text-xl">
|
|
237
|
+
{constructInputWithSpecialExpressionList(
|
|
238
|
+
answerMap[materialKey]
|
|
239
|
+
).map((inputPart, index) => (
|
|
240
|
+
<span
|
|
241
|
+
key={index}
|
|
242
|
+
className={`${
|
|
243
|
+
inputPart.isBold ? "font-bold" : ""
|
|
244
|
+
} ${inputPart.isUnderline ? "underline" : ""}`}
|
|
245
|
+
>
|
|
246
|
+
{inputPart.isEquation ? (
|
|
247
|
+
<span className="text-2xl">
|
|
248
|
+
<InlineMath math={inputPart.value} />
|
|
249
|
+
</span>
|
|
250
|
+
) : (
|
|
251
|
+
inputPart.value
|
|
252
|
+
)}
|
|
253
|
+
</span>
|
|
254
|
+
))}
|
|
255
|
+
</p>
|
|
256
|
+
)}
|
|
257
|
+
</div>
|
|
258
|
+
</div>
|
|
259
|
+
}
|
|
260
|
+
/>
|
|
261
|
+
</div>
|
|
262
|
+
</div>
|
|
263
|
+
);
|
|
264
|
+
})}
|
|
265
|
+
</div>
|
|
266
|
+
</div>
|
|
267
|
+
);
|
|
268
|
+
};
|
|
269
|
+
|
|
270
|
+
export default FillInTheBlanksActivityMaterialContent;
|