catchup-library-web 2.1.6 → 2.2.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "catchup-library-web",
3
- "version": "2.1.6",
3
+ "version": "2.2.1",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "scripts": {
@@ -1,8 +1,4 @@
1
1
  import { useEffect, useState } from "react";
2
- import {
3
- constructAnswerBasedOnData,
4
- retrieveDifficultyByActivityTypeFromData,
5
- } from "../../utilization/CatchtivityUtilization";
6
2
  import DropdownActivityContent from "./DropdownActivityContent";
7
3
  import FillInTheBlanksActivityContent from "./FillInTheBlanksActivityContent";
8
4
  import GroupingActivityContent from "./GroupingActivityContent";
@@ -13,79 +9,215 @@ import OpenEndedActivityContent from "./OpenEndedActivityContent";
13
9
  import OrderingActivityContent from "./OrderingActivityContent";
14
10
  import SelectionBox from "../boxes/SelectionBox";
15
11
  import TrueFalseActivityContent from "./TrueFalseActivityContent";
16
- import { IActivityPreviewByDataProps } from "../../properties/ActivityProperties";
17
12
  import ActivitySolutionContent from "./solution-contents/ActivitySolutionContent";
18
- import i18n from "../../language/i18n";
19
13
  import ActivityEvaluationRubricContent from "./evaluation-rubric-contents/ActivityEvaluationRubricContent";
20
14
  import DividerLine from "../dividers/DividerLine";
15
+ import i18n from "../../language/i18n";
16
+ import {
17
+ constructActivityAnswerMap,
18
+ retrieveDifficultyByActivityTypeFromData,
19
+ } from "../../utilization/CatchtivityUtilization";
20
+ import { IActivityPreviewByDataProps } from "../../properties/ActivityProperties";
21
+ import ActivityEmptyContent from "./empty-contents/ActivityEmptyContent";
22
+
23
+ const ACTIVITY_TEMPLATE_LIST = [
24
+ { type: "ORDERING", materialMap: "orderingMaterialMap" },
25
+ { type: "DROPDOWN", materialMap: "dropdownMaterialMap" },
26
+ { type: "MCSA", materialMap: "MCSAMaterialMap" },
27
+ { type: "MCMA", materialMap: "MCMAMaterialMap" },
28
+ { type: "MATCHING", materialMap: "matchingMaterialMap" },
29
+ { type: "GROUPING", materialMap: "groupingMaterialMap" },
30
+ {
31
+ type: "FILL_IN_THE_BLANKS",
32
+ materialMap: "fillInTheBlanksMaterialMap",
33
+ },
34
+ { type: "OPEN_ENDED", materialMap: "openEndedMaterialMap" },
35
+ { type: "TRUE_FALSE", materialMap: "trueFalseMaterialMap" },
36
+ ];
21
37
 
22
38
  const ActivityPreviewByData = ({
23
39
  data,
24
- showType,
25
- showDescription,
26
- lockedType,
27
- typeOptionList,
28
- showSolution,
29
- showEvaluationRubric,
30
- showDifficulty,
31
- isFullScreen,
40
+ answerType = null,
41
+ showType = true,
42
+ showDescription = true,
43
+ typeList = [],
44
+ showSolution = false,
45
+ showEvaluationRubric = false,
46
+ showDifficulty = true,
47
+ isFullScreen = false,
48
+ showCorrectAnswer = false,
32
49
  }: IActivityPreviewByDataProps) => {
33
- const [key, setKey] = useState(new Date().getTime());
34
50
  const [selectedType, setSelectedType] = useState<string | null>(null);
35
51
  const [optionList, setOptionList] = useState<any[]>([]);
52
+ const [answerMapMap, setAnswerMapMap] = useState<any>({});
53
+ const [activityTemplateTypeList, setActivityTemplateTypeList] = useState<
54
+ any[]
55
+ >([]);
36
56
 
37
57
  useEffect(() => {
38
58
  if (!data) return;
39
- setKey(new Date().getTime());
40
- }, [data]);
41
-
42
- useEffect(() => {
43
- if (!typeOptionList) return;
44
- if (typeOptionList.length === 0) return;
45
- let foundTypeOption;
46
- if (lockedType) {
47
- foundTypeOption = typeOptionList.find(
48
- (typeOption) => typeOption.id === lockedType
59
+ let currentActivityTemplateMapList: any[] = JSON.parse(
60
+ JSON.stringify(ACTIVITY_TEMPLATE_LIST)
61
+ );
62
+ if (typeList.length > 0) {
63
+ currentActivityTemplateMapList = currentActivityTemplateMapList.filter(
64
+ (activityTemplateMap) => typeList.includes(activityTemplateMap.type)
49
65
  );
50
66
  }
51
- if (foundTypeOption) {
52
- setSelectedType(foundTypeOption.id);
53
- } else {
54
- setSelectedType(typeOptionList[0].id);
67
+ const currentActivityTemplateTypeList = [];
68
+ for (const activityTemplateMap of currentActivityTemplateMapList) {
69
+ if (data[activityTemplateMap.materialMap]) {
70
+ currentActivityTemplateTypeList.push(activityTemplateMap);
71
+ }
55
72
  }
56
- }, [typeOptionList, lockedType]);
73
+ setActivityTemplateTypeList(currentActivityTemplateMapList);
74
+ }, [data, answerType, typeList]);
57
75
 
58
76
  useEffect(() => {
59
- if (!data) return;
60
- if (!typeOptionList) return;
61
- if (typeOptionList.length === 0) return;
62
- let currentTypeOptionList = JSON.parse(JSON.stringify(typeOptionList));
63
- if (lockedType) {
64
- currentTypeOptionList = currentTypeOptionList.filter(
65
- (typeOption: any) => typeOption.id === lockedType
66
- );
77
+ if (activityTemplateTypeList.length === 0) return;
78
+ const currentOptionList = [];
79
+ for (const activityTemplateType of activityTemplateTypeList) {
80
+ const currentTypeOption: any = {
81
+ id: activityTemplateType.type,
82
+ value: i18n.t(activityTemplateType.type),
83
+ };
84
+ if (showDifficulty) {
85
+ currentTypeOption.subText = i18n.t(
86
+ retrieveDifficultyByActivityTypeFromData(
87
+ activityTemplateType.type,
88
+ data
89
+ )
90
+ );
91
+ }
92
+ currentOptionList.push(currentTypeOption);
67
93
  }
68
- if (showDifficulty) {
69
- setOptionList(
70
- currentTypeOptionList.map((typeOption: any) => ({
71
- ...typeOption,
72
- subText: i18n.t(
73
- retrieveDifficultyByActivityTypeFromData(typeOption.id, data)
74
- ),
75
- }))
76
- );
77
- } else {
78
- setOptionList(currentTypeOptionList);
94
+ setOptionList(currentOptionList);
95
+ }, [activityTemplateTypeList, showDifficulty]);
96
+
97
+ useEffect(() => {
98
+ if (optionList.length === 0) return;
99
+ setSelectedType(optionList[0].id);
100
+ }, [optionList]);
101
+
102
+ useEffect(() => {
103
+ if (activityTemplateTypeList.length === 0) return;
104
+ const currentAnswerMapMap: any = {};
105
+ for (const activityTemplateMap of activityTemplateTypeList) {
106
+ if (answerType === activityTemplateMap.type) {
107
+ currentAnswerMapMap[activityTemplateMap.type] = data.answerMap;
108
+ } else {
109
+ currentAnswerMapMap[activityTemplateMap.type] =
110
+ constructActivityAnswerMap(
111
+ activityTemplateMap.type,
112
+ JSON.parse(JSON.stringify(data))
113
+ );
114
+ }
115
+ }
116
+ setAnswerMapMap(currentAnswerMapMap);
117
+ }, [activityTemplateTypeList]);
118
+
119
+ const RenderSelectedActivityContent = () => {
120
+ if (!selectedType) return null;
121
+
122
+ const commonProps = {
123
+ answerMap: answerMapMap[selectedType],
124
+ data,
125
+ canAnswerQuestion: () => true,
126
+ changeAnswer: () => {},
127
+ isPreview: true,
128
+ showCorrectAnswer,
129
+ isFullScreen,
130
+ };
131
+
132
+ const isEmpty = answerMapMap[selectedType].isEmpty;
133
+
134
+ switch (selectedType) {
135
+ case "ORDERING":
136
+ return data.orderingBodyMap && data.orderingMaterialMap ? (
137
+ <>
138
+ {isEmpty && <ActivityEmptyContent />}
139
+ <OrderingActivityContent {...commonProps} />
140
+ </>
141
+ ) : null;
142
+
143
+ case "DROPDOWN":
144
+ return data.dropdownBodyMap && data.dropdownMaterialMap ? (
145
+ <>
146
+ {isEmpty && <ActivityEmptyContent />}
147
+ <DropdownActivityContent {...commonProps} />
148
+ </>
149
+ ) : null;
150
+
151
+ case "MCSA":
152
+ return data.MCSABodyMap && data.MCSAMaterialMap ? (
153
+ <>
154
+ {isEmpty && <ActivityEmptyContent />}
155
+ <MCSAActivityContent {...commonProps} />
156
+ </>
157
+ ) : null;
158
+
159
+ case "MCMA":
160
+ return data.MCMABodyMap && data.MCMAMaterialMap ? (
161
+ <>
162
+ {isEmpty && <ActivityEmptyContent />}
163
+ <MCMAActivityContent {...commonProps} />
164
+ </>
165
+ ) : null;
166
+
167
+ case "MATCHING":
168
+ return data.matchingBodyMap && data.matchingMaterialMap ? (
169
+ <>
170
+ {isEmpty && <ActivityEmptyContent />}
171
+ <MatchingActivityContent {...commonProps} />
172
+ </>
173
+ ) : null;
174
+
175
+ case "GROUPING":
176
+ return data.groupingBodyMap && data.groupingMaterialMap ? (
177
+ <>
178
+ {isEmpty && <ActivityEmptyContent />}
179
+ <GroupingActivityContent {...commonProps} />
180
+ </>
181
+ ) : null;
182
+
183
+ case "FILL_IN_THE_BLANKS":
184
+ return data.fillInTheBlanksBodyMap &&
185
+ data.fillInTheBlanksMaterialMap ? (
186
+ <>
187
+ {isEmpty && <ActivityEmptyContent />}
188
+ <FillInTheBlanksActivityContent {...commonProps} />
189
+ </>
190
+ ) : null;
191
+
192
+ case "OPEN_ENDED":
193
+ return data.openEndedBodyMap ? (
194
+ <>
195
+ {isEmpty && <ActivityEmptyContent />}
196
+ <OpenEndedActivityContent
197
+ {...commonProps}
198
+ showMaterialContent={true}
199
+ />
200
+ </>
201
+ ) : null;
202
+
203
+ case "TRUE_FALSE":
204
+ return data.trueFalseBodyMap && data.trueFalseMaterialMap ? (
205
+ <>
206
+ {isEmpty && <ActivityEmptyContent />}
207
+ <TrueFalseActivityContent {...commonProps} />
208
+ </>
209
+ ) : null;
210
+
211
+ default:
212
+ return null;
79
213
  }
80
- }, [data, lockedType, typeOptionList, showDifficulty]);
214
+ };
81
215
 
82
- if (!data) return;
83
- if (!selectedType) return;
84
- let answerMap = constructAnswerBasedOnData(selectedType, data);
216
+ if (!data) return null;
85
217
 
86
218
  return (
87
- <div key={key}>
88
- {showType ? (
219
+ <div>
220
+ {showType && optionList.length > 0 ? (
89
221
  <>
90
222
  <div className="mb-4">
91
223
  {showDescription ? (
@@ -107,130 +239,12 @@ const ActivityPreviewByData = ({
107
239
  <DividerLine />
108
240
  </>
109
241
  ) : null}
110
- <div key={selectedType} className="">
111
- {selectedType === "ORDERING" &&
112
- data["orderingBodyMap"] != null &&
113
- data["orderingMaterialMap"] != null ? (
114
- <OrderingActivityContent
115
- answerMap={answerMap}
116
- changeAnswer={() => {}}
117
- canAnswerQuestion={() => {
118
- return true;
119
- }}
120
- data={data}
121
- isPreview={true}
122
- showCorrectAnswer={true}
123
- />
124
- ) : selectedType === "DROPDOWN" &&
125
- data["dropdownBodyMap"] != null &&
126
- data["dropdownMaterialMap"] != null ? (
127
- <DropdownActivityContent
128
- answerMap={answerMap}
129
- changeAnswer={() => {}}
130
- canAnswerQuestion={() => {
131
- return true;
132
- }}
133
- data={data}
134
- isPreview={true}
135
- showCorrectAnswer={true}
136
- isFullScreen={isFullScreen}
137
- />
138
- ) : selectedType === "MCSA" &&
139
- data["MCSABodyMap"] != null &&
140
- data["MCSAMaterialMap"] != null ? (
141
- <MCSAActivityContent
142
- answerMap={answerMap}
143
- changeAnswer={() => {}}
144
- canAnswerQuestion={() => {
145
- return true;
146
- }}
147
- data={data}
148
- isPreview={true}
149
- showCorrectAnswer={true}
150
- isFullScreen={isFullScreen}
151
- />
152
- ) : selectedType === "MCMA" &&
153
- data["MCMABodyMap"] != null &&
154
- data["MCMAMaterialMap"] != null ? (
155
- <MCMAActivityContent
156
- answerMap={answerMap}
157
- changeAnswer={() => {}}
158
- canAnswerQuestion={() => {
159
- return true;
160
- }}
161
- data={data}
162
- isPreview={true}
163
- showCorrectAnswer={true}
164
- isFullScreen={isFullScreen}
165
- />
166
- ) : selectedType === "MATCHING" &&
167
- data["matchingBodyMap"] != null &&
168
- data["matchingMaterialMap"] != null ? (
169
- <MatchingActivityContent
170
- answerMap={answerMap}
171
- changeAnswer={() => {}}
172
- canAnswerQuestion={() => {
173
- return true;
174
- }}
175
- data={data}
176
- isPreview={true}
177
- showCorrectAnswer={true}
178
- />
179
- ) : selectedType === "GROUPING" &&
180
- data["groupingBodyMap"] != null &&
181
- data["groupingMaterialMap"] != null ? (
182
- <GroupingActivityContent
183
- answerMap={answerMap}
184
- changeAnswer={() => {}}
185
- canAnswerQuestion={() => {
186
- return true;
187
- }}
188
- data={data}
189
- isPreview={true}
190
- showCorrectAnswer={true}
191
- />
192
- ) : selectedType === "FILL_IN_THE_BLANKS" &&
193
- data["fillInTheBlanksBodyMap"] != null &&
194
- data["fillInTheBlanksMaterialMap"] != null ? (
195
- <FillInTheBlanksActivityContent
196
- answerMap={answerMap}
197
- changeAnswer={() => {}}
198
- canAnswerQuestion={() => {
199
- return true;
200
- }}
201
- data={data}
202
- isPreview={true}
203
- showCorrectAnswer={true}
204
- isFullScreen={isFullScreen}
205
- />
206
- ) : selectedType === "OPEN_ENDED" &&
207
- data["openEndedBodyMap"] != null ? (
208
- <OpenEndedActivityContent
209
- answerMap={answerMap}
210
- canAnswerQuestion={() => false}
211
- changeAnswer={() => {}}
212
- showMaterialContent={true}
213
- data={data}
214
- isPreview={true}
215
- isFullScreen={isFullScreen}
216
- />
217
- ) : selectedType === "TRUE_FALSE" &&
218
- data["trueFalseBodyMap"] != null &&
219
- data["trueFalseMaterialMap"] != null ? (
220
- <TrueFalseActivityContent
221
- answerMap={answerMap}
222
- changeAnswer={() => {}}
223
- canAnswerQuestion={() => {
224
- return true;
225
- }}
226
- data={data}
227
- isPreview={true}
228
- showCorrectAnswer={true}
229
- isFullScreen={isFullScreen}
230
- />
231
- ) : null}
242
+
243
+ <div className="flex flex-col my-2 w-full p-5">
244
+ {RenderSelectedActivityContent()}
232
245
  </div>
233
- {showSolution ? (
246
+
247
+ {selectedType && showSolution ? (
234
248
  <div className="my-4">
235
249
  <ActivitySolutionContent
236
250
  activityTemplateType={selectedType}
@@ -238,7 +252,8 @@ const ActivityPreviewByData = ({
238
252
  />
239
253
  </div>
240
254
  ) : null}
241
- {showEvaluationRubric ? (
255
+
256
+ {selectedType && showEvaluationRubric ? (
242
257
  <div className="my-4">
243
258
  <ActivityEvaluationRubricContent
244
259
  activityTemplateType={selectedType}
@@ -19,6 +19,7 @@ const TrueFalseActivityMaterialContent = ({
19
19
  showCorrectAnswer,
20
20
  }: ITrueFalseActivityMaterialProps) => {
21
21
  const [shuffleOptionList, setShuffleOptionList] = useState<any[]>([]);
22
+ const [displayAnswerMap, setDisplayAnswerMap] = useState<any>(answerMap);
22
23
 
23
24
  useEffect(() => {
24
25
  const optionList = [];
@@ -32,9 +33,12 @@ const TrueFalseActivityMaterialContent = ({
32
33
  }, []);
33
34
 
34
35
  useEffect(() => {
35
- if (!showCorrectAnswer) return;
36
- answerMap = materialMap;
37
- }, [showCorrectAnswer]);
36
+ if (showCorrectAnswer) {
37
+ setDisplayAnswerMap(materialMap);
38
+ } else {
39
+ setDisplayAnswerMap(answerMap);
40
+ }
41
+ }, [showCorrectAnswer, materialMap, answerMap]);
38
42
 
39
43
  const checkAnswerState = (correctAnswer: string, learnerAnswer: string) => {
40
44
  if (!isPreview) return null;
@@ -130,7 +134,7 @@ const TrueFalseActivityMaterialContent = ({
130
134
  <div className="flex flex-col items-center justify-center">
131
135
  <BaseImage
132
136
  src={
133
- answerMap.trueList.includes(shuffleOption)
137
+ displayAnswerMap.trueList.includes(shuffleOption)
134
138
  ? "/icons/checkbox.webp"
135
139
  : "/icons/checkbox-empty.webp"
136
140
  }
@@ -146,7 +150,7 @@ const TrueFalseActivityMaterialContent = ({
146
150
  <div className="flex flex-col items-center justify-center">
147
151
  <BaseImage
148
152
  src={
149
- answerMap.falseList.includes(shuffleOption)
153
+ displayAnswerMap.falseList.includes(shuffleOption)
150
154
  ? "/icons/checkbox.webp"
151
155
  : "/icons/checkbox-empty.webp"
152
156
  }
@@ -165,7 +169,7 @@ const TrueFalseActivityMaterialContent = ({
165
169
  </div>
166
170
  ) : (
167
171
  <>
168
- {answerMap.trueList.map((item: string) => (
172
+ {displayAnswerMap.trueList.map((item: string) => (
169
173
  <div className="flex flex-row items-center gap-x-2">
170
174
  <div className="flex-1">
171
175
  <p>{item}</p>
@@ -175,7 +179,7 @@ const TrueFalseActivityMaterialContent = ({
175
179
  </div>
176
180
  </div>
177
181
  ))}
178
- {answerMap.falseList.map((item: string) => (
182
+ {displayAnswerMap.falseList.map((item: string) => (
179
183
  <div className="flex flex-row items-center gap-x-2">
180
184
  <div className="flex-1">
181
185
  <p>{item}</p>
package/src/index.ts CHANGED
@@ -35,7 +35,6 @@ export { default as TrueFalseActivityContent } from "./components/activities/Tru
35
35
  export { default as ActivitySolutionContent } from "./components/activities/solution-contents/ActivitySolutionContent";
36
36
  export { default as ActivityEvaluationRubricContent } from "./components/activities/evaluation-rubric-contents/ActivityEvaluationRubricContent";
37
37
  export { default as ActivityPreviewByData } from "./components/activities/ActivityPreviewByData";
38
- export { default as ActivityPreviewByAnswerData } from "./components/activities/ActivityPreviewByAnswerData";
39
38
 
40
39
  export { default as StatusError } from "./components/errors/StatusError";
41
40
 
@@ -218,18 +218,6 @@ export interface IActivitySolutionProps {
218
218
  }
219
219
 
220
220
  export interface IActivityPreviewByDataProps {
221
- data: any;
222
- showType: boolean;
223
- showDescription: boolean;
224
- lockedType: string;
225
- typeOptionList: any[];
226
- showDifficulty: boolean;
227
- showSolution: boolean;
228
- showEvaluationRubric: boolean;
229
- isFullScreen: boolean;
230
- }
231
-
232
- export interface IActivityPreviewByAnswerDataProps {
233
221
  data: any;
234
222
  answerType?: string | null;
235
223
  showType?: boolean;