@nualang/nualang-ui-components 0.1.1251 → 0.1.1253
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/Assignments/AssignmentCard/AssignmentCard.js +1 -1
- package/dist/Cards/Course/Course.js +27 -15
- package/dist/Forms/ChipInput/ChipInput.js +46 -7
- package/dist/Forms/CreateCourse/CreateCourse.js +3 -1
- package/dist/Forms/CreateCourse/Steps/CourseSettings/CourseSettings.js +52 -7
- package/dist/Forms/UpdateCourse/UpdateCourse.js +12 -4
- package/dist/Lists/Courses/Courses.js +2 -0
- package/dist/Screens/Classrooms/ViewClassroom/ViewClassroom.js +129 -108
- package/dist/Screens/Courses/Courses.js +4 -2
- package/dist/Screens/Courses/ViewCourse/ViewCourse.js +2 -1
- package/dist/Tables/Progress/Progress.js +8 -3
- package/dist/Tables/Progress/ProgressTable.js +1 -1
- package/package.json +1 -1
|
@@ -224,7 +224,7 @@ function AssignmentCard({
|
|
|
224
224
|
children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_material.Box, {
|
|
225
225
|
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_Typography.default, {
|
|
226
226
|
variant: "h4",
|
|
227
|
-
children: assignment.assignedStudents
|
|
227
|
+
children: assignment.assignedStudents?.length
|
|
228
228
|
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_Typography.default, {
|
|
229
229
|
variant: "body2",
|
|
230
230
|
color: "text.secondary",
|
|
@@ -51,7 +51,8 @@ function OverflowMenu({
|
|
|
51
51
|
handleDuplicateCourse,
|
|
52
52
|
course,
|
|
53
53
|
classroomId,
|
|
54
|
-
isClassroomArchived = false
|
|
54
|
+
isClassroomArchived = false,
|
|
55
|
+
canDuplicateCourse
|
|
55
56
|
}) {
|
|
56
57
|
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_material.Menu, {
|
|
57
58
|
id: `card-menu-${courseId}`,
|
|
@@ -86,19 +87,26 @@ function OverflowMenu({
|
|
|
86
87
|
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Typography, {
|
|
87
88
|
children: t("leave_course")
|
|
88
89
|
})]
|
|
89
|
-
}),
|
|
90
|
-
children:
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
90
|
+
}), !isClassroomArchived && /*#__PURE__*/(0, _jsxRuntime.jsx)(_jsxRuntime.Fragment, {
|
|
91
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Tooltip, {
|
|
92
|
+
title: !canDuplicateCourse ? t("duplicate_disabled_tooltip") : "",
|
|
93
|
+
disableHoverListener: canDuplicateCourse,
|
|
94
|
+
arrow: true,
|
|
95
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", {
|
|
96
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_material.MenuItem, {
|
|
97
|
+
onClick: async () => {
|
|
98
|
+
await handleDuplicateCourse(course, classroomId);
|
|
99
|
+
},
|
|
100
|
+
disabled: !canDuplicateCourse || course.duplicated,
|
|
101
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_CardElements.CardMenuIcon, {
|
|
102
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_FileCopy.default, {
|
|
103
|
+
fontSize: "small"
|
|
104
|
+
})
|
|
105
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Typography, {
|
|
106
|
+
children: t("duplicate_course")
|
|
107
|
+
})]
|
|
98
108
|
})
|
|
99
|
-
})
|
|
100
|
-
children: t("duplicate_course")
|
|
101
|
-
})]
|
|
109
|
+
})
|
|
102
110
|
})
|
|
103
111
|
}), handleRemoveCourse && !isClassroomArchived && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_material.MenuItem, {
|
|
104
112
|
onClick: () => handleRemoveCourse(courseId),
|
|
@@ -209,7 +217,8 @@ function CourseCard({
|
|
|
209
217
|
ariaText = "",
|
|
210
218
|
classroomId,
|
|
211
219
|
cardTitleComponent = "h2",
|
|
212
|
-
isClassroomArchived = false
|
|
220
|
+
isClassroomArchived = false,
|
|
221
|
+
email
|
|
213
222
|
}) {
|
|
214
223
|
const [placeholderRef, visible] = (0, _reactIntersectionObserver.useInView)({
|
|
215
224
|
rootMargin: "320px",
|
|
@@ -314,6 +323,8 @@ function CourseCard({
|
|
|
314
323
|
// const memberCount = membersQuery.isSuccess ? membersQuery.data.Items.length : 0;
|
|
315
324
|
|
|
316
325
|
const isPlaysVisible = !disablePlays && exerciseStartTotal > -1;
|
|
326
|
+
const isCollaborator = Array.isArray(course.collaborators) && course.collaborators.some(collab => (typeof collab === 'string' ? collab : collab?.S) === email);
|
|
327
|
+
const canDuplicateCourse = isCreator || course.isShareable === 'everyone' || course.isShareable === 'collaborators' && isCollaborator;
|
|
317
328
|
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_CardElements.CardContainer, {
|
|
318
329
|
sx: disableRaised ? {} : _CardElements.classes.hover,
|
|
319
330
|
raised: disableRaised ? false : anchorEl || isOutlineOpen,
|
|
@@ -526,7 +537,8 @@ function CourseCard({
|
|
|
526
537
|
handleRemoveCourse: handleRemoveCourse,
|
|
527
538
|
handleDuplicateCourse: handleDuplicateCourse,
|
|
528
539
|
course: course,
|
|
529
|
-
isClassroomArchived: isClassroomArchived
|
|
540
|
+
isClassroomArchived: isClassroomArchived,
|
|
541
|
+
canDuplicateCourse: canDuplicateCourse
|
|
530
542
|
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_Members.default, {
|
|
531
543
|
getMemberDetails: getMemberDetails,
|
|
532
544
|
t: t,
|
|
@@ -4,25 +4,62 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.default = void 0;
|
|
7
|
+
var _react = require("react");
|
|
7
8
|
var _CustomChipInput = _interopRequireDefault(require("../../Misc/CustomChipInput/CustomChipInput"));
|
|
8
9
|
var _jsxRuntime = require("react/jsx-runtime");
|
|
9
10
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
11
|
+
// already present, just ensure it's used
|
|
12
|
+
|
|
10
13
|
function ChipInput(props) {
|
|
11
14
|
const {
|
|
15
|
+
t,
|
|
12
16
|
name = "",
|
|
13
17
|
value = [],
|
|
14
18
|
handleChange = () => {},
|
|
15
19
|
label,
|
|
16
20
|
delimiter = /[\s,]+/
|
|
17
21
|
} = props;
|
|
22
|
+
const [errorMessage, setErrorMessage] = (0, _react.useState)("");
|
|
23
|
+
const genericDomains = ['gmail.com', 'yahoo.com', 'hotmail.com', 'outlook.com', 'icloud.com'];
|
|
18
24
|
const handleAddChip = chip => {
|
|
19
25
|
const newChips = chip.split(delimiter).map(c => c.trim().toLowerCase()).filter(Boolean);
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
+
if (props.restrictCollaboratorDomains) {
|
|
27
|
+
const allowedDomain = props.userEmail?.split('@')[1];
|
|
28
|
+
const validChips = newChips.filter(c => {
|
|
29
|
+
const emailPattern = /^[^@]+@[^@]+\.[^@]+$/;
|
|
30
|
+
if (!emailPattern.test(c)) {
|
|
31
|
+
setErrorMessage(t("invalid_email_format"));
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
const domain = c.split('@')[1];
|
|
35
|
+
if (genericDomains.includes(domain)) {
|
|
36
|
+
setErrorMessage(t("generic_email_domain_error"));
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
if (domain !== allowedDomain) {
|
|
40
|
+
setErrorMessage(t("email_domain_mismatch_error", {
|
|
41
|
+
domain: allowedDomain
|
|
42
|
+
}));
|
|
43
|
+
return false;
|
|
44
|
+
}
|
|
45
|
+
return true;
|
|
46
|
+
});
|
|
47
|
+
if (validChips.length === 0) return;
|
|
48
|
+
setErrorMessage("");
|
|
49
|
+
handleChange({
|
|
50
|
+
target: {
|
|
51
|
+
name: name,
|
|
52
|
+
value: [...value, ...validChips]
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
} else {
|
|
56
|
+
handleChange({
|
|
57
|
+
target: {
|
|
58
|
+
name: name,
|
|
59
|
+
value: [...value, ...newChips]
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
}
|
|
26
63
|
};
|
|
27
64
|
const deleteChip = chip => {
|
|
28
65
|
handleChange({
|
|
@@ -37,7 +74,9 @@ function ChipInput(props) {
|
|
|
37
74
|
...props,
|
|
38
75
|
onAdd: handleAddChip,
|
|
39
76
|
onDelete: deleteChip,
|
|
40
|
-
delimiter: delimiter
|
|
77
|
+
delimiter: delimiter,
|
|
78
|
+
helperText: errorMessage || props.helperText,
|
|
79
|
+
error: !!errorMessage || props.error
|
|
41
80
|
});
|
|
42
81
|
}
|
|
43
82
|
var _default = exports.default = ChipInput;
|
|
@@ -20,14 +20,20 @@ function CourseSettings({
|
|
|
20
20
|
errors,
|
|
21
21
|
handleChange,
|
|
22
22
|
handleBlur,
|
|
23
|
-
subscription
|
|
23
|
+
subscription,
|
|
24
|
+
attributes
|
|
24
25
|
}) {
|
|
25
26
|
const {
|
|
26
27
|
visibility,
|
|
27
28
|
enrolmentKey,
|
|
28
29
|
allowedDomains,
|
|
29
|
-
collaborators
|
|
30
|
+
collaborators,
|
|
31
|
+
isShareable,
|
|
32
|
+
duplicated
|
|
30
33
|
} = values;
|
|
34
|
+
const {
|
|
35
|
+
email
|
|
36
|
+
} = attributes || {};
|
|
31
37
|
const generateRandomEnrolmentKey = (0, _react.useCallback)(() => {
|
|
32
38
|
return String(Math.floor(Math.random() * 90000) + 10000);
|
|
33
39
|
}, []);
|
|
@@ -85,11 +91,44 @@ function CourseSettings({
|
|
|
85
91
|
}) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.FormControlLabel, {
|
|
86
92
|
value: "public",
|
|
87
93
|
control: /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Radio, {}),
|
|
88
|
-
label: t("public")
|
|
94
|
+
label: t("public"),
|
|
95
|
+
disabled: duplicated
|
|
89
96
|
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.FormControlLabel, {
|
|
90
97
|
value: "private",
|
|
91
98
|
control: /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Radio, {}),
|
|
92
|
-
label: t("private")
|
|
99
|
+
label: t("private"),
|
|
100
|
+
disabled: duplicated
|
|
101
|
+
})]
|
|
102
|
+
})]
|
|
103
|
+
})
|
|
104
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Grid, {
|
|
105
|
+
size: {
|
|
106
|
+
xs: 12,
|
|
107
|
+
md: 12
|
|
108
|
+
},
|
|
109
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_material.FormControl, {
|
|
110
|
+
component: "fieldset",
|
|
111
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_material.FormLabel, {
|
|
112
|
+
component: "legend",
|
|
113
|
+
children: t("duplication")
|
|
114
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_material.RadioGroup, {
|
|
115
|
+
"aria-label": "duplication",
|
|
116
|
+
name: "isShareable",
|
|
117
|
+
value: isShareable,
|
|
118
|
+
onChange: handleChange,
|
|
119
|
+
onBlur: handleBlur,
|
|
120
|
+
helperText: touched.isShareable ? errors.isShareable : "",
|
|
121
|
+
error: touched.isShareable && Boolean(errors.isShareable),
|
|
122
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_material.FormControlLabel, {
|
|
123
|
+
value: "everyone",
|
|
124
|
+
control: /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Radio, {}),
|
|
125
|
+
label: t("everyone"),
|
|
126
|
+
disabled: duplicated
|
|
127
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.FormControlLabel, {
|
|
128
|
+
value: "collaborators",
|
|
129
|
+
control: /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Radio, {}),
|
|
130
|
+
label: t("collaborators"),
|
|
131
|
+
disabled: duplicated
|
|
93
132
|
})]
|
|
94
133
|
})]
|
|
95
134
|
})
|
|
@@ -176,7 +215,9 @@ function CourseSettings({
|
|
|
176
215
|
margin: "normal",
|
|
177
216
|
variant: "outlined",
|
|
178
217
|
multiline: true,
|
|
179
|
-
fullWidth: true
|
|
218
|
+
fullWidth: true,
|
|
219
|
+
restrictCollaboratorDomains: duplicated,
|
|
220
|
+
userEmail: email
|
|
180
221
|
}), !subscription.isPaidUser && /*#__PURE__*/(0, _jsxRuntime.jsx)(_Tooltip.default, {
|
|
181
222
|
title: subscription.isUpgradePossible ? t("upgrade_plan_explanation") : t("upgrade_subscription_student"),
|
|
182
223
|
placement: "top",
|
|
@@ -195,7 +236,9 @@ function CourseSettings({
|
|
|
195
236
|
margin: "normal",
|
|
196
237
|
variant: "outlined",
|
|
197
238
|
multiline: true,
|
|
198
|
-
fullWidth: true
|
|
239
|
+
fullWidth: true,
|
|
240
|
+
restrictCollaboratorDomains: duplicated,
|
|
241
|
+
userEmail: email
|
|
199
242
|
})
|
|
200
243
|
})]
|
|
201
244
|
})
|
|
@@ -212,6 +255,8 @@ CourseSettings.validationSchema = Yup.object().shape({
|
|
|
212
255
|
otherwise: () => Yup.string().nullable()
|
|
213
256
|
}),
|
|
214
257
|
allowedDomains: Yup.array(Yup.string().test("noSpecialChars", "no_special_characters", value => !(0, _index.containsInvalidSymbols)(value)).matches(_index.domainPattern, "Must be a valid domain e.g 'schooldomain.com'")).nullable(),
|
|
215
|
-
collaborators: Yup.array(Yup.string().test("noSpecialChars", "no_special_characters", value => !(0, _index.containsInvalidSymbols)(value))).nullable()
|
|
258
|
+
collaborators: Yup.array(Yup.string().test("noSpecialChars", "no_special_characters", value => !(0, _index.containsInvalidSymbols)(value))).nullable(),
|
|
259
|
+
isShareable: Yup.string().required("required"),
|
|
260
|
+
duplicated: Yup.bool()
|
|
216
261
|
});
|
|
217
262
|
var _default = exports.default = CourseSettings;
|
|
@@ -31,7 +31,9 @@ function UpdateCourse({
|
|
|
31
31
|
allowedDomains: [],
|
|
32
32
|
tags: [],
|
|
33
33
|
collaborators: [],
|
|
34
|
-
picture: null
|
|
34
|
+
picture: null,
|
|
35
|
+
isShareable: "",
|
|
36
|
+
duplicated: false
|
|
35
37
|
},
|
|
36
38
|
difficulties = ["A1", "A2", "B1", "B2", "C1", "C2"],
|
|
37
39
|
onSubmit,
|
|
@@ -40,7 +42,8 @@ function UpdateCourse({
|
|
|
40
42
|
forLanguages,
|
|
41
43
|
fileSizeLimit,
|
|
42
44
|
subscription,
|
|
43
|
-
verificationStatus
|
|
45
|
+
verificationStatus,
|
|
46
|
+
attributes
|
|
44
47
|
}) {
|
|
45
48
|
const difficultyOptions = difficulties.map((d, idx) => {
|
|
46
49
|
const keyId = `crearolax${(0, _index.randomId)()}${idx}`;
|
|
@@ -64,7 +67,9 @@ function UpdateCourse({
|
|
|
64
67
|
picture,
|
|
65
68
|
banner,
|
|
66
69
|
tags,
|
|
67
|
-
collaborators
|
|
70
|
+
collaborators,
|
|
71
|
+
isShareable,
|
|
72
|
+
duplicated
|
|
68
73
|
} = initialValues;
|
|
69
74
|
return /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
|
|
70
75
|
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_formik.Formik, {
|
|
@@ -137,7 +142,9 @@ function UpdateCourse({
|
|
|
137
142
|
visibility,
|
|
138
143
|
enrolmentKey,
|
|
139
144
|
allowedDomains,
|
|
140
|
-
collaborators
|
|
145
|
+
collaborators,
|
|
146
|
+
isShareable,
|
|
147
|
+
duplicated
|
|
141
148
|
},
|
|
142
149
|
enableReinitialize: enableReinitialize,
|
|
143
150
|
validationSchema: _Steps.CourseSettings.validationSchema,
|
|
@@ -171,6 +178,7 @@ function UpdateCourse({
|
|
|
171
178
|
className: classes.formContent,
|
|
172
179
|
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Steps.CourseSettings, {
|
|
173
180
|
t: t,
|
|
181
|
+
attributes: attributes,
|
|
174
182
|
subscription: subscription,
|
|
175
183
|
handleChange: handleChange,
|
|
176
184
|
handleSubmit: handleSubmit,
|
|
@@ -32,6 +32,7 @@ function CourseList({
|
|
|
32
32
|
disableActions,
|
|
33
33
|
classroomId,
|
|
34
34
|
isClassroomArchived = false,
|
|
35
|
+
email,
|
|
35
36
|
...otherProps
|
|
36
37
|
}) {
|
|
37
38
|
const [items, ref] = (0, _useListScroll.default)({
|
|
@@ -96,6 +97,7 @@ function CourseList({
|
|
|
96
97
|
handleDuplicateCourse: handleDuplicateCourse,
|
|
97
98
|
classroomId: classroomId,
|
|
98
99
|
isClassroomArchived: isClassroomArchived,
|
|
100
|
+
email: email,
|
|
99
101
|
...otherProps
|
|
100
102
|
}, course.courseId)
|
|
101
103
|
}, course.courseId);
|
|
@@ -324,6 +324,111 @@ function OverflowMenu({
|
|
|
324
324
|
}, "UpgradeSubscription")]
|
|
325
325
|
});
|
|
326
326
|
}
|
|
327
|
+
function ClassroomLoading({
|
|
328
|
+
t = text => text
|
|
329
|
+
}) {
|
|
330
|
+
const {
|
|
331
|
+
classes
|
|
332
|
+
} = useStyles();
|
|
333
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
|
|
334
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
|
|
335
|
+
className: classes.cardTop,
|
|
336
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Skeleton.default, {
|
|
337
|
+
variant: "rectangular",
|
|
338
|
+
sx: theme => ({
|
|
339
|
+
[theme.breakpoints.up("md")]: {
|
|
340
|
+
paddingTop: "15%"
|
|
341
|
+
},
|
|
342
|
+
height: 0,
|
|
343
|
+
paddingTop: "25%",
|
|
344
|
+
borderRadius: theme.spacing(2),
|
|
345
|
+
marginBottom: theme.spacing(4)
|
|
346
|
+
})
|
|
347
|
+
})
|
|
348
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
|
|
349
|
+
className: classes.header,
|
|
350
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
|
|
351
|
+
className: classes.headerText,
|
|
352
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Typography, {
|
|
353
|
+
variant: "h5",
|
|
354
|
+
component: "h1",
|
|
355
|
+
gutterBottom: true,
|
|
356
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Skeleton.default, {
|
|
357
|
+
variant: "rectangular",
|
|
358
|
+
height: 32,
|
|
359
|
+
width: 150
|
|
360
|
+
})
|
|
361
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Typography, {
|
|
362
|
+
variant: "body2",
|
|
363
|
+
color: "textSecondary",
|
|
364
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Skeleton.default, {
|
|
365
|
+
variant: "rectangular",
|
|
366
|
+
height: 20,
|
|
367
|
+
width: 250
|
|
368
|
+
})
|
|
369
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_material.Box, {
|
|
370
|
+
display: "flex",
|
|
371
|
+
alignItems: "center",
|
|
372
|
+
mt: 2,
|
|
373
|
+
mb: 1,
|
|
374
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Box, {
|
|
375
|
+
mr: 1,
|
|
376
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Button, {
|
|
377
|
+
variant: "contained",
|
|
378
|
+
color: "primary",
|
|
379
|
+
startIcon: /*#__PURE__*/(0, _jsxRuntime.jsx)(_PersonAdd.default, {}),
|
|
380
|
+
size: "small",
|
|
381
|
+
disabled: true,
|
|
382
|
+
children: t("join")
|
|
383
|
+
})
|
|
384
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_DefaultColourButton.default, {
|
|
385
|
+
startIcon: /*#__PURE__*/(0, _jsxRuntime.jsx)(_MoreVert.default, {}),
|
|
386
|
+
size: "small",
|
|
387
|
+
className: classes.moreOptions,
|
|
388
|
+
disabled: true,
|
|
389
|
+
children: t("more_options")
|
|
390
|
+
})]
|
|
391
|
+
})]
|
|
392
|
+
})
|
|
393
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_ResponsiveTabs.default, {
|
|
394
|
+
t: t,
|
|
395
|
+
tabs: [{
|
|
396
|
+
label: t("courses"),
|
|
397
|
+
id: "Courses"
|
|
398
|
+
}, {
|
|
399
|
+
label: t("assignments"),
|
|
400
|
+
id: "Assignments"
|
|
401
|
+
}, {
|
|
402
|
+
label: t("progress"),
|
|
403
|
+
id: "Discuss"
|
|
404
|
+
}, {
|
|
405
|
+
label: t("members"),
|
|
406
|
+
id: "Members"
|
|
407
|
+
}, {
|
|
408
|
+
label: t("settings"),
|
|
409
|
+
id: "Settings",
|
|
410
|
+
disabled: true
|
|
411
|
+
}],
|
|
412
|
+
centered: true,
|
|
413
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Box, {
|
|
414
|
+
py: 1,
|
|
415
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Courses.default, {
|
|
416
|
+
t: t,
|
|
417
|
+
courses: null
|
|
418
|
+
})
|
|
419
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_material.Box, {
|
|
420
|
+
py: 1,
|
|
421
|
+
children: [t("loading"), "..."]
|
|
422
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Box, {
|
|
423
|
+
py: 1,
|
|
424
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Members.default, {
|
|
425
|
+
t: t,
|
|
426
|
+
members: null
|
|
427
|
+
})
|
|
428
|
+
})]
|
|
429
|
+
})]
|
|
430
|
+
});
|
|
431
|
+
}
|
|
327
432
|
function Classroom({
|
|
328
433
|
t = text => text,
|
|
329
434
|
classroom,
|
|
@@ -395,6 +500,7 @@ function Classroom({
|
|
|
395
500
|
preferred_username,
|
|
396
501
|
isUserInternal,
|
|
397
502
|
assignedCourses,
|
|
503
|
+
email,
|
|
398
504
|
...otherProps
|
|
399
505
|
}) {
|
|
400
506
|
const {
|
|
@@ -658,99 +764,6 @@ function Classroom({
|
|
|
658
764
|
setIsCreatorNotSubscribedUpgradeOpen(false);
|
|
659
765
|
};
|
|
660
766
|
const [avatarOptionClicked, setAvatarOptionClicked] = (0, _react.useState)(false);
|
|
661
|
-
if (!classroom) {
|
|
662
|
-
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
|
|
663
|
-
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
|
|
664
|
-
className: classes.cardTop,
|
|
665
|
-
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Skeleton.default, {
|
|
666
|
-
variant: "rectangular",
|
|
667
|
-
sx: theme => ({
|
|
668
|
-
[theme.breakpoints.up("md")]: {
|
|
669
|
-
paddingTop: "15%"
|
|
670
|
-
},
|
|
671
|
-
height: 0,
|
|
672
|
-
paddingTop: "25%",
|
|
673
|
-
borderRadius: theme.spacing(2),
|
|
674
|
-
marginBottom: theme.spacing(4)
|
|
675
|
-
})
|
|
676
|
-
})
|
|
677
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
|
|
678
|
-
className: classes.header,
|
|
679
|
-
children: /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
|
|
680
|
-
className: classes.headerText,
|
|
681
|
-
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Typography, {
|
|
682
|
-
variant: "h5",
|
|
683
|
-
component: "h1",
|
|
684
|
-
gutterBottom: true,
|
|
685
|
-
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Skeleton.default, {
|
|
686
|
-
variant: "rectangular",
|
|
687
|
-
height: 32,
|
|
688
|
-
width: 150
|
|
689
|
-
})
|
|
690
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Typography, {
|
|
691
|
-
variant: "body2",
|
|
692
|
-
color: "textSecondary",
|
|
693
|
-
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Skeleton.default, {
|
|
694
|
-
variant: "rectangular",
|
|
695
|
-
height: 20,
|
|
696
|
-
width: 250
|
|
697
|
-
})
|
|
698
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_material.Box, {
|
|
699
|
-
display: "flex",
|
|
700
|
-
alignItems: "center",
|
|
701
|
-
mt: 2,
|
|
702
|
-
mb: 1,
|
|
703
|
-
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Box, {
|
|
704
|
-
mr: 1,
|
|
705
|
-
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Button, {
|
|
706
|
-
variant: "contained",
|
|
707
|
-
color: "primary",
|
|
708
|
-
startIcon: /*#__PURE__*/(0, _jsxRuntime.jsx)(_PersonAdd.default, {}),
|
|
709
|
-
size: "small",
|
|
710
|
-
disabled: true,
|
|
711
|
-
children: t("join")
|
|
712
|
-
})
|
|
713
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_DefaultColourButton.default, {
|
|
714
|
-
startIcon: /*#__PURE__*/(0, _jsxRuntime.jsx)(_MoreVert.default, {}),
|
|
715
|
-
size: "small",
|
|
716
|
-
className: classes.moreOptions,
|
|
717
|
-
disabled: true,
|
|
718
|
-
children: t("more_options")
|
|
719
|
-
})]
|
|
720
|
-
})]
|
|
721
|
-
})
|
|
722
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_ResponsiveTabs.default, {
|
|
723
|
-
t: t,
|
|
724
|
-
tabs: [{
|
|
725
|
-
label: t("courses")
|
|
726
|
-
}, {
|
|
727
|
-
label: t("progress")
|
|
728
|
-
}, {
|
|
729
|
-
label: t("members")
|
|
730
|
-
}, {
|
|
731
|
-
label: t("settings"),
|
|
732
|
-
disabled: true
|
|
733
|
-
}],
|
|
734
|
-
centered: true,
|
|
735
|
-
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Box, {
|
|
736
|
-
py: 1,
|
|
737
|
-
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Courses.default, {
|
|
738
|
-
t: t,
|
|
739
|
-
courses: null
|
|
740
|
-
})
|
|
741
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_material.Box, {
|
|
742
|
-
py: 1,
|
|
743
|
-
children: [t("loading"), "..."]
|
|
744
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Box, {
|
|
745
|
-
py: 1,
|
|
746
|
-
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Members.default, {
|
|
747
|
-
t: t,
|
|
748
|
-
members: null
|
|
749
|
-
})
|
|
750
|
-
})]
|
|
751
|
-
})]
|
|
752
|
-
});
|
|
753
|
-
}
|
|
754
767
|
const {
|
|
755
768
|
classroomId,
|
|
756
769
|
classroomName,
|
|
@@ -794,6 +807,12 @@ function Classroom({
|
|
|
794
807
|
handleRemoveCourse(course);
|
|
795
808
|
}
|
|
796
809
|
};
|
|
810
|
+
const duplicateCourse = async course => {
|
|
811
|
+
const confirmed = await confirm(t("duplicate_course"), t("duplicate_course_confirmation"));
|
|
812
|
+
if (confirmed) {
|
|
813
|
+
handleDuplicateCourse(course);
|
|
814
|
+
}
|
|
815
|
+
};
|
|
797
816
|
const deleteClassroom = async id => {
|
|
798
817
|
const confirmed = await confirm(t("delete_classroom"), t("delete_classroom_confirmation"), "", true, t("classroom_deletion_note", {
|
|
799
818
|
courseCount: courses ? courses.length : 0
|
|
@@ -858,9 +877,10 @@ function Classroom({
|
|
|
858
877
|
memberId: memberId,
|
|
859
878
|
username: username,
|
|
860
879
|
disableActions: !(isMember || isCreator),
|
|
861
|
-
handleDuplicateCourse:
|
|
880
|
+
handleDuplicateCourse: duplicateCourse,
|
|
862
881
|
classroomId: classroomId,
|
|
863
|
-
isClassroomArchived: isArchived
|
|
882
|
+
isClassroomArchived: isArchived,
|
|
883
|
+
email: email
|
|
864
884
|
}) : /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
|
|
865
885
|
id: "add-courses-fab",
|
|
866
886
|
children: isCreator ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_ClassCourses.default, {
|
|
@@ -1159,19 +1179,20 @@ function Classroom({
|
|
|
1159
1179
|
tabIndex: tabs.findIndex(tab => tab.id === "Courses"),
|
|
1160
1180
|
variant: "circular"
|
|
1161
1181
|
}, vchatFab, assignmentsFab]];
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1182
|
+
const initialTabValue = (0, _react.useMemo)(() => {
|
|
1183
|
+
if (window.location.hash) {
|
|
1184
|
+
const selectedTabId = window.location.hash.slice(1);
|
|
1185
|
+
const index = tabs.findIndex(tab => tab.id === selectedTabId);
|
|
1186
|
+
const tab = tabs[index];
|
|
1187
|
+
const isDisabled = tab?.disabled;
|
|
1188
|
+
const isRestricted = (tab?.id === "Settings" || tab?.id === "Members") && !isCreator;
|
|
1189
|
+
if (index >= 0 && !isDisabled && !isRestricted) {
|
|
1190
|
+
return index;
|
|
1191
|
+
}
|
|
1171
1192
|
}
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1193
|
+
return 0;
|
|
1194
|
+
}, [isCreator.tabs?.length]); // only recompute if isCreator or tabs change
|
|
1195
|
+
|
|
1175
1196
|
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
|
|
1176
1197
|
children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
|
|
1177
1198
|
className: classes.cardTop,
|
|
@@ -1535,7 +1556,7 @@ function ViewClassroom({
|
|
|
1535
1556
|
return /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
|
|
1536
1557
|
className: classes.root,
|
|
1537
1558
|
children: [isLoading && !classroom && /*#__PURE__*/(0, _jsxRuntime.jsx)(_jsxRuntime.Fragment, {
|
|
1538
|
-
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(
|
|
1559
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(ClassroomLoading, {
|
|
1539
1560
|
t: t
|
|
1540
1561
|
})
|
|
1541
1562
|
}), !isLoading && classroom && Object.keys(classroom).length && /*#__PURE__*/(0, _jsxRuntime.jsx)(_jsxRuntime.Fragment, {
|
|
@@ -63,7 +63,8 @@ function Courses({
|
|
|
63
63
|
getCourseMembers,
|
|
64
64
|
username,
|
|
65
65
|
memberId,
|
|
66
|
-
handleDuplicateCourse
|
|
66
|
+
handleDuplicateCourse,
|
|
67
|
+
email
|
|
67
68
|
}) {
|
|
68
69
|
const {
|
|
69
70
|
classes
|
|
@@ -136,7 +137,8 @@ function Courses({
|
|
|
136
137
|
memberId: memberId,
|
|
137
138
|
username: username,
|
|
138
139
|
handleDuplicateCourse: handleDuplicateCourse,
|
|
139
|
-
cardTitleComponent: "h2"
|
|
140
|
+
cardTitleComponent: "h2",
|
|
141
|
+
email: email
|
|
140
142
|
}) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Box, {
|
|
141
143
|
py: 2,
|
|
142
144
|
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Courses2.default, {
|
|
@@ -701,7 +701,8 @@ function Course({
|
|
|
701
701
|
onSubmit: handleUpdateCourse,
|
|
702
702
|
fileSizeLimit: fileSizeLimit,
|
|
703
703
|
subscription: subscription,
|
|
704
|
-
verificationStatus: verificationStatus
|
|
704
|
+
verificationStatus: verificationStatus,
|
|
705
|
+
attributes: attributes
|
|
705
706
|
})
|
|
706
707
|
}, `tab-content-settings`)
|
|
707
708
|
}] : [])];
|
|
@@ -238,11 +238,16 @@ function Progress({
|
|
|
238
238
|
(0, _react.useEffect)(() => {
|
|
239
239
|
if ("URLSearchParams" in window) {
|
|
240
240
|
const searchParams = (0, _utils2.searchStringToObj)(window.location.search);
|
|
241
|
-
|
|
242
|
-
const assignmentId = searchParams.assignmentId;
|
|
243
|
-
if (searchParams.reportType && !reportType && reportTypes.includes(searchParams.reportType) && reportType !== searchParams.reportType) {
|
|
241
|
+
if (searchParams.reportType && searchParams.reportType !== reportTypes[0] && reportTypes.includes(searchParams.reportType) && reportType !== searchParams.reportType) {
|
|
244
242
|
setReportType(searchParams.reportType);
|
|
245
243
|
}
|
|
244
|
+
}
|
|
245
|
+
}, []);
|
|
246
|
+
(0, _react.useEffect)(() => {
|
|
247
|
+
if ("URLSearchParams" in window) {
|
|
248
|
+
const searchParams = (0, _utils2.searchStringToObj)(window.location.search);
|
|
249
|
+
const courseId = searchParams.courseId;
|
|
250
|
+
const assignmentId = searchParams.assignmentId;
|
|
246
251
|
if (assignmentId && !selectedAssignment && assignments && assignments.length) {
|
|
247
252
|
const assignmentIndex = assignments.findIndex(a => a.assignmentId === assignmentId);
|
|
248
253
|
const assignment = assignments[assignmentIndex];
|