@selfcommunity/react-ui 0.10.2-courses.161 → 0.10.2-courses.163

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.
@@ -149,7 +149,8 @@ function Student(inProps) {
149
149
  (scCourse.join_status === types_1.SCCourseJoinStatusType.CREATOR ||
150
150
  scCourse.join_status === types_1.SCCourseJoinStatusType.MANAGER ||
151
151
  scCourse.join_status === types_1.SCCourseJoinStatusType.JOINED)) ||
152
- scCourse.privacy === types_1.SCCoursePrivacyType.OPEN) && ((0, jsx_runtime_1.jsxs)(react_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "h6", className: classes.margin }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.course.dashboard.student.description", defaultMessage: "ui.course.dashboard.student.description" }) })), (0, jsx_runtime_1.jsx)(material_1.Stack, Object.assign({ className: classes.box }, { children: (0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "body1" }, { children: scCourse.description })) }))] })), ((scCourse.privacy === types_1.SCCoursePrivacyType.PRIVATE &&
152
+ scCourse.privacy === types_1.SCCoursePrivacyType.OPEN ||
153
+ scCourse.privacy === types_1.SCCoursePrivacyType.DRAFT) && ((0, jsx_runtime_1.jsxs)(react_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "h6", className: classes.margin }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.course.dashboard.student.description", defaultMessage: "ui.course.dashboard.student.description" }) })), (0, jsx_runtime_1.jsx)(material_1.Stack, Object.assign({ className: classes.box }, { children: (0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "body1" }, { children: scCourse.description })) }))] })), ((scCourse.privacy === types_1.SCCoursePrivacyType.PRIVATE &&
153
154
  (scCourse.join_status === types_1.SCCourseJoinStatusType.MANAGER || scCourse.join_status === types_1.SCCourseJoinStatusType.JOINED)) ||
154
155
  (scCourse.privacy === types_1.SCCoursePrivacyType.OPEN && scCourse.join_status !== types_1.SCCourseJoinStatusType.CREATOR)) && ((0, jsx_runtime_1.jsxs)(react_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "h6", className: classes.margin }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.course.dashboard.student.progress", defaultMessage: "ui.course.dashboard.student.description" }) })), (0, jsx_runtime_1.jsxs)(material_1.Stack, Object.assign({ className: classes.box }, { children: [(0, jsx_runtime_1.jsxs)(material_1.Stack, Object.assign({ className: classes.percentageWrapper }, { children: [(0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "body1" }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.course.dashboard.student.progress.described", defaultMessage: "ui.course.dashboard.student.progress.described", values: { progress: scCourse.num_lessons_completed, end: scCourse.num_lessons } }) })), (0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "body1" }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.course.dashboard.student.progress.percentage", defaultMessage: "ui.course.dashboard.student.progress.percentage", values: { percentage: scCourse.user_completion_rate } }) }))] })), (0, jsx_runtime_1.jsx)(material_1.LinearProgress, { className: classes.progress, variant: "determinate", value: scCourse === null || scCourse === void 0 ? void 0 : scCourse.user_completion_rate })] })), scCourse.user_completion_rate === 100 && ((0, jsx_runtime_1.jsxs)(material_1.Stack, Object.assign({ className: (0, classnames_1.default)(classes.completedWrapper, classes.margin) }, { children: [(0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "h3" }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.course.dashboard.student.completed", defaultMessage: "ui.course.dashboard.student.completed" }) })), (0, jsx_runtime_1.jsx)("img", { src: clapping_1.CLAPPING, alt: intl.formatMessage({ id: 'ui.course.dashboard.student.completed', defaultMessage: 'ui.course.dashboard.student.completed' }), width: 32, height: 32 })] }))), (0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "h6", className: classes.margin }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.course.dashboard.student.contents", defaultMessage: "ui.course.dashboard.student.contents" }) })), (0, jsx_runtime_1.jsxs)(material_1.Stack, Object.assign({ className: classes.lessonsSections }, { children: [(0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "h5" }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.course.table.sections.title", defaultMessage: "ui.course.table.sections.title", values: {
155
156
  sectionsNumber: scCourse.num_sections
@@ -97,7 +97,7 @@ const Root = (0, styles_1.styled)(material_1.Box, {
97
97
  * @param inProps
98
98
  */
99
99
  function CourseForm(inProps) {
100
- var _a, _b, _c;
100
+ var _a, _b, _c, _d;
101
101
  //PROPS
102
102
  const props = (0, system_1.useThemeProps)({
103
103
  props: inProps,
@@ -186,7 +186,7 @@ function CourseForm(inProps) {
186
186
  let courseService;
187
187
  if (course) {
188
188
  // Update
189
- const data = Object.assign(Object.assign({ name: field.name, description: field.description, type: field.type, categories: field.categories }, (field.imageOriginalFile && { image_original: field.imageOriginalFile })), (field.privacy && { privacy: field.privacy }));
189
+ const data = Object.assign({ name: field.name, description: field.description, type: field.type, categories: field.categories }, (field.privacy && { privacy: field.privacy }));
190
190
  courseService = api_services_1.CourseService.updateCourse(course.id, data, {
191
191
  headers: { 'Content-Type': 'application/json' }
192
192
  });
@@ -248,11 +248,11 @@ function CourseForm(inProps) {
248
248
  /**
249
249
  * Renders root object
250
250
  */
251
- return ((0, jsx_runtime_1.jsxs)(react_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(Root, Object.assign({ className: (0, classnames_1.default)(classes.root, className) }, rest, { children: (0, jsx_runtime_1.jsxs)(material_1.Box, Object.assign({ className: _step === Course_1.SCCourseFormStepType.GENERAL ? classes.stepOne : classes.stepTwo }, { children: [_step === Course_1.SCCourseFormStepType.GENERAL && ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: Object.values(types_1.SCCourseTypologyType).map((option, index) => ((0, jsx_runtime_1.jsx)(material_1.Card, Object.assign({ className: (0, classnames_1.default)(classes.card, { [classes.selected]: option === field.type }) }, { children: (0, jsx_runtime_1.jsx)(material_1.CardActionArea, Object.assign({ onClick: () => setField((prev) => (Object.assign(Object.assign({}, prev), { ['type']: option }))) }, { children: (0, jsx_runtime_1.jsxs)(material_1.CardContent, { children: [(0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "subtitle2" }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: `ui.courseForm.${option}.title`, defaultMessage: `ui.courseForm.${option}.title` }) })), (0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "body2" }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: `ui.courseForm.${option}.info`, defaultMessage: `ui.courseForm.${option}.info` }) }))] }) })) }), index))) })), _step === Course_1.SCCourseFormStepType.CUSTOMIZATION && ((0, jsx_runtime_1.jsxs)(material_1.FormGroup, Object.assign({ className: classes.form }, { children: [course && ((0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "h5" }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.courseForm.edit.title.general", defaultMessage: "ui.courseForm.edit.title.general" }) }))), (0, jsx_runtime_1.jsx)(material_1.Paper, Object.assign({ style: _backgroundCover, classes: { root: classes.cover } }, { children: (0, jsx_runtime_1.jsx)(UploadCourseCover_1.default, { isCreationMode: true, onChange: handleChangeCover }) })), (0, jsx_runtime_1.jsx)(material_1.TextField, { required: true, className: classes.name, placeholder: `${intl.formatMessage(messages.name)}`, margin: "normal", value: field.name, name: "name", onChange: handleChange, InputProps: {
251
+ return ((0, jsx_runtime_1.jsxs)(react_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(Root, Object.assign({ className: (0, classnames_1.default)(classes.root, className) }, rest, { children: (0, jsx_runtime_1.jsxs)(material_1.Box, Object.assign({ className: _step === Course_1.SCCourseFormStepType.GENERAL ? classes.stepOne : classes.stepTwo }, { children: [_step === Course_1.SCCourseFormStepType.GENERAL && ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: Object.values(types_1.SCCourseTypologyType).map((option, index) => ((0, jsx_runtime_1.jsx)(material_1.Card, Object.assign({ className: (0, classnames_1.default)(classes.card, { [classes.selected]: option === field.type }) }, { children: (0, jsx_runtime_1.jsx)(material_1.CardActionArea, Object.assign({ onClick: () => setField((prev) => (Object.assign(Object.assign({}, prev), { ['type']: option }))) }, { children: (0, jsx_runtime_1.jsxs)(material_1.CardContent, { children: [(0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "subtitle2" }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: `ui.courseForm.${option}.title`, defaultMessage: `ui.courseForm.${option}.title` }) })), (0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "body2" }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: `ui.courseForm.${option}.info`, defaultMessage: `ui.courseForm.${option}.info` }) }))] }) })) }), index))) })), _step === Course_1.SCCourseFormStepType.CUSTOMIZATION && ((0, jsx_runtime_1.jsxs)(material_1.FormGroup, Object.assign({ className: classes.form }, { children: [course && ((0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "h5" }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.courseForm.edit.title.general", defaultMessage: "ui.courseForm.edit.title.general" }) }))), (0, jsx_runtime_1.jsx)(material_1.Paper, Object.assign({ style: _backgroundCover, classes: { root: classes.cover } }, { children: (0, jsx_runtime_1.jsx)(UploadCourseCover_1.default, { courseId: (_a = course === null || course === void 0 ? void 0 : course.id) !== null && _a !== void 0 ? _a : null, isCreationMode: !course, onChange: handleChangeCover }) })), (0, jsx_runtime_1.jsx)(material_1.TextField, { required: true, className: classes.name, placeholder: `${intl.formatMessage(messages.name)}`, margin: "normal", value: field.name, name: "name", onChange: handleChange, InputProps: {
252
252
  endAdornment: (0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "body2" }, { children: Course_1.COURSE_TITLE_MAX_LENGTH - field.name.length }))
253
253
  }, error: Boolean(field.name.length > Course_1.COURSE_TITLE_MAX_LENGTH) || Boolean(error['nameError']), helperText: field.name.length > Course_1.COURSE_TITLE_MAX_LENGTH ? ((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.courseForm.name.error.maxLength", defaultMessage: "ui.courseForm.name.error.maxLength" })) : error['nameError'] ? (error['nameError']) : null }), (0, jsx_runtime_1.jsx)(material_1.TextField, { multiline: true, className: classes.description, placeholder: `${intl.formatMessage(messages.description)}`, margin: "normal", value: field.description, name: "description", onChange: handleChange, InputProps: {
254
- endAdornment: ((0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "body2" }, { children: ((_a = field.description) === null || _a === void 0 ? void 0 : _a.length) ? Course_1.COURSE_DESCRIPTION_MAX_LENGTH - field.description.length : Course_1.COURSE_DESCRIPTION_MAX_LENGTH })))
255
- }, error: Boolean(((_b = field.description) === null || _b === void 0 ? void 0 : _b.length) > Course_1.COURSE_DESCRIPTION_MAX_LENGTH), helperText: ((_c = field.description) === null || _c === void 0 ? void 0 : _c.length) > Course_1.COURSE_DESCRIPTION_MAX_LENGTH ? ((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.courseForm.description.error.maxLength", defaultMessage: "ui.courseForm.description.error.maxLength" })) : null }), (0, jsx_runtime_1.jsx)(CategoryAutocomplete_1.default, { defaultValue: field.categories, TextFieldProps: { label: intl.formatMessage(Object.keys(field.categories).length ? messages.category : messages.categoryEmpty) }, multiple: true, onChange: handleOnChangeCategory }), course && (0, jsx_runtime_1.jsx)(Edit_1.default, { course: course, onPrivacyChange: (privacy) => setField((prev) => (Object.assign(Object.assign({}, prev), { ['privacy']: privacy }))) })] }))), (0, jsx_runtime_1.jsx)(material_1.Box, Object.assign({ className: classes.actions }, { children: (0, jsx_runtime_1.jsx)(lab_1.LoadingButton, Object.assign({ size: "small", loading: field.isSubmitting, disabled: _step === Course_1.SCCourseFormStepType.GENERAL
254
+ endAdornment: ((0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "body2" }, { children: ((_b = field.description) === null || _b === void 0 ? void 0 : _b.length) ? Course_1.COURSE_DESCRIPTION_MAX_LENGTH - field.description.length : Course_1.COURSE_DESCRIPTION_MAX_LENGTH })))
255
+ }, error: Boolean(((_c = field.description) === null || _c === void 0 ? void 0 : _c.length) > Course_1.COURSE_DESCRIPTION_MAX_LENGTH), helperText: ((_d = field.description) === null || _d === void 0 ? void 0 : _d.length) > Course_1.COURSE_DESCRIPTION_MAX_LENGTH ? ((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.courseForm.description.error.maxLength", defaultMessage: "ui.courseForm.description.error.maxLength" })) : null }), (0, jsx_runtime_1.jsx)(CategoryAutocomplete_1.default, { defaultValue: field.categories, TextFieldProps: { label: intl.formatMessage(Object.keys(field.categories).length ? messages.category : messages.categoryEmpty) }, multiple: true, onChange: handleOnChangeCategory }), course && (0, jsx_runtime_1.jsx)(Edit_1.default, { course: course, onPrivacyChange: (privacy) => setField((prev) => (Object.assign(Object.assign({}, prev), { ['privacy']: privacy }))) })] }))), (0, jsx_runtime_1.jsx)(material_1.Box, Object.assign({ className: classes.actions }, { children: (0, jsx_runtime_1.jsx)(lab_1.LoadingButton, Object.assign({ size: "small", loading: field.isSubmitting, disabled: _step === Course_1.SCCourseFormStepType.GENERAL
256
256
  ? !field.type || Object.keys(error).length !== 0
257
257
  : _step === Course_1.SCCourseFormStepType.CUSTOMIZATION &&
258
258
  (!field.name ||
@@ -57,7 +57,7 @@ function UploadCourseCover(inProps) {
57
57
  props: inProps,
58
58
  name: constants_1.PREFIX
59
59
  });
60
- const { courseId, onChange, className = false, isCreationMode = false } = props, rest = tslib_1.__rest(props, ["courseId", "onChange", "className", "isCreationMode"]);
60
+ const { courseId = null, onChange, className = false, isCreationMode = false } = props, rest = tslib_1.__rest(props, ["courseId", "onChange", "className", "isCreationMode"]);
61
61
  //CONTEXT
62
62
  const scUserContext = (0, react_1.useContext)(react_core_1.SCUserContext);
63
63
  //STATE
@@ -72,40 +72,44 @@ function UploadCourseCover(inProps) {
72
72
  }
73
73
  /**
74
74
  * Handles file upload
75
- * @param course
75
+ * @param event
76
76
  */
77
- const handleUpload = (course) => {
78
- fileInput = course.target.files[0];
79
- if (fileInput) {
80
- const reader = new FileReader();
81
- reader.onload = (e) => {
82
- const img = new Image();
83
- img.onload = () => {
84
- isCreationMode ? onChange && onChange(fileInput) : handleSave();
85
- };
86
- // eslint-disable-next-line @typescript-eslint/ban-ts-ignore
87
- // @ts-ignore
88
- img.src = e.target.result;
77
+ const handleUpload = (event) => {
78
+ const selectedFile = event.target.files[0];
79
+ if (!selectedFile)
80
+ return;
81
+ fileInput = selectedFile;
82
+ const reader = new FileReader();
83
+ reader.onload = (e) => {
84
+ const img = new Image();
85
+ img.onload = () => {
86
+ if (isCreationMode) {
87
+ onChange(fileInput);
88
+ }
89
+ else {
90
+ onChange(fileInput);
91
+ handleSave();
92
+ }
89
93
  };
90
- // eslint-disable-next-line @typescript-eslint/ban-ts-ignore
91
- // @ts-ignore
92
- reader.readAsDataURL(fileInput);
93
- }
94
+ img.src = e.target.result;
95
+ };
96
+ reader.readAsDataURL(selectedFile);
94
97
  };
95
98
  /**
96
99
  * Handles cover saving after upload action
97
100
  */
98
101
  function handleSave() {
102
+ if (!fileInput) {
103
+ return;
104
+ }
99
105
  setLoading(true);
100
106
  const formData = new FormData();
101
- // eslint-disable-next-line @typescript-eslint/ban-ts-ignore
107
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
102
108
  // @ts-ignore
103
109
  formData.append('image_original', fileInput);
104
110
  api_services_1.CourseService.changeCourseCover(courseId, formData, { headers: { 'Content-Type': 'multipart/form-data' } })
105
- // eslint-disable-next-line @typescript-eslint/ban-ts-ignore
106
- // @ts-ignore
107
111
  .then((data) => {
108
- onChange && onChange(data.image_medium);
112
+ // onChange && onChange(data.image_medium);
109
113
  setLoading(false);
110
114
  })
111
115
  .catch((error) => {
@@ -63,7 +63,14 @@ function Requests(props) {
63
63
  utils_1.Logger.error(Errors_1.SCOPE_SC_UI, error);
64
64
  });
65
65
  }
66
- }, [state.isLoadingNext, state.initialized, course, dispatch]);
66
+ }, [state.isLoadingNext, state.initialized, course, dispatch, endpointQueryParams]);
67
+ // HANDLERS
68
+ const handleRemoveUser = (0, react_1.useCallback)((_msg, user) => {
69
+ dispatch({
70
+ type: widget_1.actionWidgetTypes.SET_RESULTS,
71
+ payload: { count: state.results.length - 1, results: state.results.filter((result) => result.id !== user.id) }
72
+ });
73
+ }, [state.count, state.results, dispatch]);
67
74
  // EFFECTS
68
75
  (0, react_1.useEffect)(() => {
69
76
  let _t;
@@ -79,14 +86,7 @@ function Requests(props) {
79
86
  return () => {
80
87
  updatedUsers.current && pubsub_js_1.default.unsubscribe(updatedUsers.current);
81
88
  };
82
- }, []);
83
- // HANDLERS
84
- const handleRemoveUser = (0, react_1.useCallback)((user) => {
85
- dispatch({
86
- type: widget_1.actionWidgetTypes.SET_RESULTS,
87
- payload: { count: state.count - 1, results: state.results.filter((result) => result.id !== user.id) }
88
- });
89
- }, [dispatch]);
89
+ }, [handleRemoveUser]);
90
90
  return ((0, jsx_runtime_1.jsxs)(material_1.Box, { children: [(0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "h6" }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.editCourse.tab.requests.title", defaultMessage: "ui.editCourse.tab.requests.title", values: { requestsNumber: state.results.length } }) })), (0, jsx_runtime_1.jsx)(material_1.Stack, Object.assign({ className: classes.usersStatusWrapper }, { children: (0, jsx_runtime_1.jsx)(Status_1.default, { course: course }) })), (0, jsx_runtime_1.jsx)(CourseUsersTable_1.default, { course: course, state: state, dispatch: dispatch, headerCells: headerCells, mode: "requests", emptyStatusTitle: "ui.courseUsersTable.empty.requests.title" })] }));
91
91
  }
92
92
  exports.default = (0, react_1.memo)(Requests);
@@ -70,7 +70,11 @@ function Users(props) {
70
70
  utils_1.Logger.error(Errors_1.SCOPE_SC_UI, error);
71
71
  });
72
72
  }
73
- }, [state.isLoadingNext, state.initialized, course, dispatch]);
73
+ }, [state.isLoadingNext, state.initialized, course, dispatch, endpointQueryParams]);
74
+ // HANDLERS
75
+ const handleAddUser = (0, react_1.useCallback)((_msg, user) => {
76
+ dispatch({ type: widget_1.actionWidgetTypes.LOAD_PREVIOUS_SUCCESS, payload: { count: state.count + 1, results: [user], initialized: true } });
77
+ }, [state.count, dispatch]);
74
78
  // EFFECTS
75
79
  (0, react_1.useEffect)(() => {
76
80
  let _t;
@@ -86,18 +90,17 @@ function Users(props) {
86
90
  return () => {
87
91
  updatedUsers.current && pubsub_js_1.default.unsubscribe(updatedUsers.current);
88
92
  };
89
- }, []);
90
- // HANDLERS
91
- const handleAddUser = (0, react_1.useCallback)((user) => {
92
- dispatch({ type: widget_1.actionWidgetTypes.LOAD_PREVIOUS_SUCCESS, payload: { count: state.count + 1, results: [user], initialized: true } });
93
- }, [dispatch]);
93
+ }, [handleAddUser]);
94
94
  const handleConfirm = (0, react_1.useCallback)((newUsers) => {
95
95
  const data = {
96
96
  joined: newUsers.map((user) => user.id)
97
97
  };
98
98
  api_services_1.CourseService.changeCourseUserRole(course.id, data)
99
99
  .then(() => {
100
- dispatch({ type: widget_1.actionWidgetTypes.RESET });
100
+ dispatch({
101
+ type: widget_1.actionWidgetTypes.LOAD_PREVIOUS_SUCCESS,
102
+ payload: { count: state.count + newUsers.length, results: newUsers, initialized: true }
103
+ });
101
104
  })
102
105
  .catch((error) => {
103
106
  dispatch({ type: widget_1.actionWidgetTypes.LOAD_NEXT_FAILURE, payload: { errorLoadNext: error } });
@@ -95,7 +95,7 @@ function AddUsersButton(inProps) {
95
95
  const handleConfirm = (0, react_1.useCallback)(() => {
96
96
  onConfirm === null || onConfirm === void 0 ? void 0 : onConfirm(invited);
97
97
  setInvited([]);
98
- }, [invited]);
98
+ }, [invited, onConfirm]);
99
99
  // HANDLERS AUTOCOMPLETE
100
100
  const handleInputChange = (0, react_1.useCallback)((_, newValue, reason) => {
101
101
  switch (reason) {
@@ -21,7 +21,7 @@ function ChangeUserStatus(props) {
21
21
  const { enqueueSnackbar } = (0, notistack_1.useSnackbar)();
22
22
  // EFFECTS
23
23
  (0, react_1.useEffect)(() => {
24
- setValue(`ui.editCourse.tab.users.table.select.${user.join_status}`);
24
+ setValue(`ui.editCourse.tab.users.table.select.${user.join_status || 'joined'}`);
25
25
  }, [user, setValue]);
26
26
  // HANDLERS
27
27
  const handleChange = (0, react_1.useCallback)((e) => {
@@ -52,7 +52,7 @@ function CourseUsersTable(inProps) {
52
52
  // EFFECTS
53
53
  (0, react_1.useEffect)(() => {
54
54
  setUsers(state.results);
55
- }, [state.results]);
55
+ }, [state.results, setUsers]);
56
56
  // HANDLERS
57
57
  const handleChange = (0, react_1.useCallback)((e) => {
58
58
  const _value = e.target.value;
@@ -99,7 +99,7 @@ function CourseUsersTable(inProps) {
99
99
  return (0, jsx_runtime_1.jsx)(material_1.TableCell, { width: "14%" }, i);
100
100
  }
101
101
  return ((0, jsx_runtime_1.jsx)(material_1.TableCell, Object.assign({ width: mode === 'dashboard' ? '20%' : '25%' }, { children: (0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "body2" }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: cell.id, defaultMessage: cell.id }) })) }), i));
102
- }) }) }), (0, jsx_runtime_1.jsxs)(material_1.TableBody, { children: [users.length === 0 && (0, jsx_runtime_1.jsx)(RowSkeleton_1.default, { animation: false, editMode: mode !== 'dashboard' }), users.length > 0 &&
103
- users.map((user, i) => ((0, jsx_runtime_1.jsxs)(material_1.TableRow, { children: [(0, jsx_runtime_1.jsx)(material_1.TableCell, { children: (0, jsx_runtime_1.jsxs)(material_1.Stack, Object.assign({ className: classes.avatarWrapper }, { children: [(0, jsx_runtime_1.jsx)(material_1.Avatar, { alt: user.username, src: user.avatar }), (0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "body2" }, { children: user.username }))] })) }), mode === 'dashboard' && ((0, jsx_runtime_1.jsx)(material_1.TableCell, { children: (0, jsx_runtime_1.jsxs)(material_1.Stack, Object.assign({ className: classes.progressWrapper }, { children: [(0, jsx_runtime_1.jsx)(material_1.LinearProgress, { className: classes.progress, variant: "determinate", value: user.user_completion_rate }), (0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "body1" }, { children: `${Math.round(user.user_completion_rate)}%` }))] })) })), mode === 'edit' && ((0, jsx_runtime_1.jsx)(material_1.TableCell, { children: user.join_status !== types_1.SCCourseJoinStatusType.CREATOR && scUserContext.user.id !== user.id ? ((0, jsx_runtime_1.jsx)(ChangeUsersStatus_1.default, { course: course, user: user })) : ((0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "body2" }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: `ui.editCourse.tab.users.table.select.${user.join_status}`, defaultMessage: `ui.editCourse.tab.users.table.select.${user.join_status}` }) }))) })), (0, jsx_runtime_1.jsx)(material_1.TableCell, { children: (0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "body2" }, { children: new Date(mode === 'requests' ? user.date_joined : user.joined_at).toLocaleDateString() })) }), (0, jsx_runtime_1.jsx)(material_1.TableCell, { children: (0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "body2" }, { children: new Date(mode === 'requests' ? user.date_joined : user.last_active_at).toLocaleDateString() })) }), mode === 'dashboard' && ((0, jsx_runtime_1.jsx)(material_1.TableCell, { children: (0, jsx_runtime_1.jsx)(SeeProgressButton_1.default, { course: course, user: user }) })), mode === 'requests' && ((0, jsx_runtime_1.jsx)(material_1.TableCell, { children: (0, jsx_runtime_1.jsx)(RequestButton_1.default, { course: course, user: user }) }))] }, i))), state.isLoadingNext && (0, jsx_runtime_1.jsx)(RowSkeleton_1.default, { editMode: mode !== 'dashboard' })] })] }) }), users.length > 0 && ((0, jsx_runtime_1.jsx)(lab_1.LoadingButton, Object.assign({ size: "small", variant: "outlined", color: "inherit", loading: state.isLoadingNext, disabled: !state.next, className: classes.loadingButton, onClick: handleNext }, { children: (0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "body2" }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.courseUsersTable.btn.label", defaultMessage: "ui.courseUsersTable.btn.label" }) })) }))), users.length === 0 && value.length === 0 && (0, jsx_runtime_1.jsx)(EmptyStatus_1.default, { icon: "face", title: emptyStatusTitle, description: emptyStatusDescription })] }));
102
+ }) }) }), (0, jsx_runtime_1.jsxs)(material_1.TableBody, { children: [users.length > 0 &&
103
+ users.map((user, i) => ((0, jsx_runtime_1.jsxs)(material_1.TableRow, { children: [(0, jsx_runtime_1.jsx)(material_1.TableCell, { children: (0, jsx_runtime_1.jsxs)(material_1.Stack, Object.assign({ className: classes.avatarWrapper }, { children: [(0, jsx_runtime_1.jsx)(material_1.Avatar, { alt: user.username, src: user.avatar }), (0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "body2" }, { children: user.username }))] })) }), mode === 'dashboard' && ((0, jsx_runtime_1.jsx)(material_1.TableCell, { children: (0, jsx_runtime_1.jsxs)(material_1.Stack, Object.assign({ className: classes.progressWrapper }, { children: [(0, jsx_runtime_1.jsx)(material_1.LinearProgress, { className: classes.progress, variant: "determinate", value: user.user_completion_rate }), (0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "body1" }, { children: `${Math.round(user.user_completion_rate)}%` }))] })) })), mode === 'edit' && ((0, jsx_runtime_1.jsx)(material_1.TableCell, { children: user.join_status !== types_1.SCCourseJoinStatusType.CREATOR && scUserContext.user.id !== user.id ? ((0, jsx_runtime_1.jsx)(ChangeUsersStatus_1.default, { course: course, user: user })) : ((0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "body2" }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: `ui.editCourse.tab.users.table.select.${user.join_status}`, defaultMessage: `ui.editCourse.tab.users.table.select.${user.join_status}` }) }))) })), (0, jsx_runtime_1.jsx)(material_1.TableCell, { children: (0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "body2" }, { children: new Date(mode === 'requests' ? user.date_joined : user.joined_at || new Date()).toLocaleDateString() })) }), (0, jsx_runtime_1.jsx)(material_1.TableCell, { children: (0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "body2" }, { children: new Date(mode === 'requests' ? user.date_joined : user.last_active_at || new Date()).toLocaleDateString() })) }), mode === 'dashboard' && ((0, jsx_runtime_1.jsx)(material_1.TableCell, { children: (0, jsx_runtime_1.jsx)(SeeProgressButton_1.default, { course: course, user: user }) })), mode === 'requests' && ((0, jsx_runtime_1.jsx)(material_1.TableCell, { children: (0, jsx_runtime_1.jsx)(RequestButton_1.default, { course: course, user: user }) }))] }, i))), state.isLoadingNext && (0, jsx_runtime_1.jsx)(RowSkeleton_1.default, { editMode: mode !== 'dashboard' })] })] }) }), users.length > 0 && ((0, jsx_runtime_1.jsx)(lab_1.LoadingButton, Object.assign({ size: "small", variant: "outlined", color: "inherit", loading: state.isLoadingNext, disabled: !state.next, className: classes.loadingButton, onClick: handleNext }, { children: (0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "body2" }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.courseUsersTable.btn.label", defaultMessage: "ui.courseUsersTable.btn.label" }) })) }))), users.length === 0 && value.length === 0 && (0, jsx_runtime_1.jsx)(EmptyStatus_1.default, { icon: "face", title: emptyStatusTitle, description: emptyStatusDescription })] }));
104
104
  }
105
105
  exports.default = (0, react_1.memo)(CourseUsersTable);
@@ -147,7 +147,8 @@ function Student(inProps) {
147
147
  (scCourse.join_status === SCCourseJoinStatusType.CREATOR ||
148
148
  scCourse.join_status === SCCourseJoinStatusType.MANAGER ||
149
149
  scCourse.join_status === SCCourseJoinStatusType.JOINED)) ||
150
- scCourse.privacy === SCCoursePrivacyType.OPEN) && (_jsxs(Fragment, { children: [_jsx(Typography, Object.assign({ variant: "h6", className: classes.margin }, { children: _jsx(FormattedMessage, { id: "ui.course.dashboard.student.description", defaultMessage: "ui.course.dashboard.student.description" }) })), _jsx(Stack, Object.assign({ className: classes.box }, { children: _jsx(Typography, Object.assign({ variant: "body1" }, { children: scCourse.description })) }))] })), ((scCourse.privacy === SCCoursePrivacyType.PRIVATE &&
150
+ scCourse.privacy === SCCoursePrivacyType.OPEN ||
151
+ scCourse.privacy === SCCoursePrivacyType.DRAFT) && (_jsxs(Fragment, { children: [_jsx(Typography, Object.assign({ variant: "h6", className: classes.margin }, { children: _jsx(FormattedMessage, { id: "ui.course.dashboard.student.description", defaultMessage: "ui.course.dashboard.student.description" }) })), _jsx(Stack, Object.assign({ className: classes.box }, { children: _jsx(Typography, Object.assign({ variant: "body1" }, { children: scCourse.description })) }))] })), ((scCourse.privacy === SCCoursePrivacyType.PRIVATE &&
151
152
  (scCourse.join_status === SCCourseJoinStatusType.MANAGER || scCourse.join_status === SCCourseJoinStatusType.JOINED)) ||
152
153
  (scCourse.privacy === SCCoursePrivacyType.OPEN && scCourse.join_status !== SCCourseJoinStatusType.CREATOR)) && (_jsxs(Fragment, { children: [_jsx(Typography, Object.assign({ variant: "h6", className: classes.margin }, { children: _jsx(FormattedMessage, { id: "ui.course.dashboard.student.progress", defaultMessage: "ui.course.dashboard.student.description" }) })), _jsxs(Stack, Object.assign({ className: classes.box }, { children: [_jsxs(Stack, Object.assign({ className: classes.percentageWrapper }, { children: [_jsx(Typography, Object.assign({ variant: "body1" }, { children: _jsx(FormattedMessage, { id: "ui.course.dashboard.student.progress.described", defaultMessage: "ui.course.dashboard.student.progress.described", values: { progress: scCourse.num_lessons_completed, end: scCourse.num_lessons } }) })), _jsx(Typography, Object.assign({ variant: "body1" }, { children: _jsx(FormattedMessage, { id: "ui.course.dashboard.student.progress.percentage", defaultMessage: "ui.course.dashboard.student.progress.percentage", values: { percentage: scCourse.user_completion_rate } }) }))] })), _jsx(LinearProgress, { className: classes.progress, variant: "determinate", value: scCourse === null || scCourse === void 0 ? void 0 : scCourse.user_completion_rate })] })), scCourse.user_completion_rate === 100 && (_jsxs(Stack, Object.assign({ className: classNames(classes.completedWrapper, classes.margin) }, { children: [_jsx(Typography, Object.assign({ variant: "h3" }, { children: _jsx(FormattedMessage, { id: "ui.course.dashboard.student.completed", defaultMessage: "ui.course.dashboard.student.completed" }) })), _jsx("img", { src: CLAPPING, alt: intl.formatMessage({ id: 'ui.course.dashboard.student.completed', defaultMessage: 'ui.course.dashboard.student.completed' }), width: 32, height: 32 })] }))), _jsx(Typography, Object.assign({ variant: "h6", className: classes.margin }, { children: _jsx(FormattedMessage, { id: "ui.course.dashboard.student.contents", defaultMessage: "ui.course.dashboard.student.contents" }) })), _jsxs(Stack, Object.assign({ className: classes.lessonsSections }, { children: [_jsx(Typography, Object.assign({ variant: "h5" }, { children: _jsx(FormattedMessage, { id: "ui.course.table.sections.title", defaultMessage: "ui.course.table.sections.title", values: {
153
154
  sectionsNumber: scCourse.num_sections
@@ -95,7 +95,7 @@ const Root = styled(Box, {
95
95
  * @param inProps
96
96
  */
97
97
  export default function CourseForm(inProps) {
98
- var _a, _b, _c;
98
+ var _a, _b, _c, _d;
99
99
  //PROPS
100
100
  const props = useThemeProps({
101
101
  props: inProps,
@@ -184,7 +184,7 @@ export default function CourseForm(inProps) {
184
184
  let courseService;
185
185
  if (course) {
186
186
  // Update
187
- const data = Object.assign(Object.assign({ name: field.name, description: field.description, type: field.type, categories: field.categories }, (field.imageOriginalFile && { image_original: field.imageOriginalFile })), (field.privacy && { privacy: field.privacy }));
187
+ const data = Object.assign({ name: field.name, description: field.description, type: field.type, categories: field.categories }, (field.privacy && { privacy: field.privacy }));
188
188
  courseService = CourseService.updateCourse(course.id, data, {
189
189
  headers: { 'Content-Type': 'application/json' }
190
190
  });
@@ -246,11 +246,11 @@ export default function CourseForm(inProps) {
246
246
  /**
247
247
  * Renders root object
248
248
  */
249
- return (_jsxs(Fragment, { children: [_jsx(Root, Object.assign({ className: classNames(classes.root, className) }, rest, { children: _jsxs(Box, Object.assign({ className: _step === SCCourseFormStepType.GENERAL ? classes.stepOne : classes.stepTwo }, { children: [_step === SCCourseFormStepType.GENERAL && (_jsx(_Fragment, { children: Object.values(SCCourseTypologyType).map((option, index) => (_jsx(Card, Object.assign({ className: classNames(classes.card, { [classes.selected]: option === field.type }) }, { children: _jsx(CardActionArea, Object.assign({ onClick: () => setField((prev) => (Object.assign(Object.assign({}, prev), { ['type']: option }))) }, { children: _jsxs(CardContent, { children: [_jsx(Typography, Object.assign({ variant: "subtitle2" }, { children: _jsx(FormattedMessage, { id: `ui.courseForm.${option}.title`, defaultMessage: `ui.courseForm.${option}.title` }) })), _jsx(Typography, Object.assign({ variant: "body2" }, { children: _jsx(FormattedMessage, { id: `ui.courseForm.${option}.info`, defaultMessage: `ui.courseForm.${option}.info` }) }))] }) })) }), index))) })), _step === SCCourseFormStepType.CUSTOMIZATION && (_jsxs(FormGroup, Object.assign({ className: classes.form }, { children: [course && (_jsx(Typography, Object.assign({ variant: "h5" }, { children: _jsx(FormattedMessage, { id: "ui.courseForm.edit.title.general", defaultMessage: "ui.courseForm.edit.title.general" }) }))), _jsx(Paper, Object.assign({ style: _backgroundCover, classes: { root: classes.cover } }, { children: _jsx(UploadCourseCover, { isCreationMode: true, onChange: handleChangeCover }) })), _jsx(TextField, { required: true, className: classes.name, placeholder: `${intl.formatMessage(messages.name)}`, margin: "normal", value: field.name, name: "name", onChange: handleChange, InputProps: {
249
+ return (_jsxs(Fragment, { children: [_jsx(Root, Object.assign({ className: classNames(classes.root, className) }, rest, { children: _jsxs(Box, Object.assign({ className: _step === SCCourseFormStepType.GENERAL ? classes.stepOne : classes.stepTwo }, { children: [_step === SCCourseFormStepType.GENERAL && (_jsx(_Fragment, { children: Object.values(SCCourseTypologyType).map((option, index) => (_jsx(Card, Object.assign({ className: classNames(classes.card, { [classes.selected]: option === field.type }) }, { children: _jsx(CardActionArea, Object.assign({ onClick: () => setField((prev) => (Object.assign(Object.assign({}, prev), { ['type']: option }))) }, { children: _jsxs(CardContent, { children: [_jsx(Typography, Object.assign({ variant: "subtitle2" }, { children: _jsx(FormattedMessage, { id: `ui.courseForm.${option}.title`, defaultMessage: `ui.courseForm.${option}.title` }) })), _jsx(Typography, Object.assign({ variant: "body2" }, { children: _jsx(FormattedMessage, { id: `ui.courseForm.${option}.info`, defaultMessage: `ui.courseForm.${option}.info` }) }))] }) })) }), index))) })), _step === SCCourseFormStepType.CUSTOMIZATION && (_jsxs(FormGroup, Object.assign({ className: classes.form }, { children: [course && (_jsx(Typography, Object.assign({ variant: "h5" }, { children: _jsx(FormattedMessage, { id: "ui.courseForm.edit.title.general", defaultMessage: "ui.courseForm.edit.title.general" }) }))), _jsx(Paper, Object.assign({ style: _backgroundCover, classes: { root: classes.cover } }, { children: _jsx(UploadCourseCover, { courseId: (_a = course === null || course === void 0 ? void 0 : course.id) !== null && _a !== void 0 ? _a : null, isCreationMode: !course, onChange: handleChangeCover }) })), _jsx(TextField, { required: true, className: classes.name, placeholder: `${intl.formatMessage(messages.name)}`, margin: "normal", value: field.name, name: "name", onChange: handleChange, InputProps: {
250
250
  endAdornment: _jsx(Typography, Object.assign({ variant: "body2" }, { children: COURSE_TITLE_MAX_LENGTH - field.name.length }))
251
251
  }, error: Boolean(field.name.length > COURSE_TITLE_MAX_LENGTH) || Boolean(error['nameError']), helperText: field.name.length > COURSE_TITLE_MAX_LENGTH ? (_jsx(FormattedMessage, { id: "ui.courseForm.name.error.maxLength", defaultMessage: "ui.courseForm.name.error.maxLength" })) : error['nameError'] ? (error['nameError']) : null }), _jsx(TextField, { multiline: true, className: classes.description, placeholder: `${intl.formatMessage(messages.description)}`, margin: "normal", value: field.description, name: "description", onChange: handleChange, InputProps: {
252
- endAdornment: (_jsx(Typography, Object.assign({ variant: "body2" }, { children: ((_a = field.description) === null || _a === void 0 ? void 0 : _a.length) ? COURSE_DESCRIPTION_MAX_LENGTH - field.description.length : COURSE_DESCRIPTION_MAX_LENGTH })))
253
- }, error: Boolean(((_b = field.description) === null || _b === void 0 ? void 0 : _b.length) > COURSE_DESCRIPTION_MAX_LENGTH), helperText: ((_c = field.description) === null || _c === void 0 ? void 0 : _c.length) > COURSE_DESCRIPTION_MAX_LENGTH ? (_jsx(FormattedMessage, { id: "ui.courseForm.description.error.maxLength", defaultMessage: "ui.courseForm.description.error.maxLength" })) : null }), _jsx(CategoryAutocomplete, { defaultValue: field.categories, TextFieldProps: { label: intl.formatMessage(Object.keys(field.categories).length ? messages.category : messages.categoryEmpty) }, multiple: true, onChange: handleOnChangeCategory }), course && _jsx(CourseEdit, { course: course, onPrivacyChange: (privacy) => setField((prev) => (Object.assign(Object.assign({}, prev), { ['privacy']: privacy }))) })] }))), _jsx(Box, Object.assign({ className: classes.actions }, { children: _jsx(LoadingButton, Object.assign({ size: "small", loading: field.isSubmitting, disabled: _step === SCCourseFormStepType.GENERAL
252
+ endAdornment: (_jsx(Typography, Object.assign({ variant: "body2" }, { children: ((_b = field.description) === null || _b === void 0 ? void 0 : _b.length) ? COURSE_DESCRIPTION_MAX_LENGTH - field.description.length : COURSE_DESCRIPTION_MAX_LENGTH })))
253
+ }, error: Boolean(((_c = field.description) === null || _c === void 0 ? void 0 : _c.length) > COURSE_DESCRIPTION_MAX_LENGTH), helperText: ((_d = field.description) === null || _d === void 0 ? void 0 : _d.length) > COURSE_DESCRIPTION_MAX_LENGTH ? (_jsx(FormattedMessage, { id: "ui.courseForm.description.error.maxLength", defaultMessage: "ui.courseForm.description.error.maxLength" })) : null }), _jsx(CategoryAutocomplete, { defaultValue: field.categories, TextFieldProps: { label: intl.formatMessage(Object.keys(field.categories).length ? messages.category : messages.categoryEmpty) }, multiple: true, onChange: handleOnChangeCategory }), course && _jsx(CourseEdit, { course: course, onPrivacyChange: (privacy) => setField((prev) => (Object.assign(Object.assign({}, prev), { ['privacy']: privacy }))) })] }))), _jsx(Box, Object.assign({ className: classes.actions }, { children: _jsx(LoadingButton, Object.assign({ size: "small", loading: field.isSubmitting, disabled: _step === SCCourseFormStepType.GENERAL
254
254
  ? !field.type || Object.keys(error).length !== 0
255
255
  : _step === SCCourseFormStepType.CUSTOMIZATION &&
256
256
  (!field.name ||
@@ -55,7 +55,7 @@ export default function UploadCourseCover(inProps) {
55
55
  props: inProps,
56
56
  name: PREFIX
57
57
  });
58
- const { courseId, onChange, className = false, isCreationMode = false } = props, rest = __rest(props, ["courseId", "onChange", "className", "isCreationMode"]);
58
+ const { courseId = null, onChange, className = false, isCreationMode = false } = props, rest = __rest(props, ["courseId", "onChange", "className", "isCreationMode"]);
59
59
  //CONTEXT
60
60
  const scUserContext = useContext(SCUserContext);
61
61
  //STATE
@@ -70,40 +70,44 @@ export default function UploadCourseCover(inProps) {
70
70
  }
71
71
  /**
72
72
  * Handles file upload
73
- * @param course
73
+ * @param event
74
74
  */
75
- const handleUpload = (course) => {
76
- fileInput = course.target.files[0];
77
- if (fileInput) {
78
- const reader = new FileReader();
79
- reader.onload = (e) => {
80
- const img = new Image();
81
- img.onload = () => {
82
- isCreationMode ? onChange && onChange(fileInput) : handleSave();
83
- };
84
- // eslint-disable-next-line @typescript-eslint/ban-ts-ignore
85
- // @ts-ignore
86
- img.src = e.target.result;
75
+ const handleUpload = (event) => {
76
+ const selectedFile = event.target.files[0];
77
+ if (!selectedFile)
78
+ return;
79
+ fileInput = selectedFile;
80
+ const reader = new FileReader();
81
+ reader.onload = (e) => {
82
+ const img = new Image();
83
+ img.onload = () => {
84
+ if (isCreationMode) {
85
+ onChange(fileInput);
86
+ }
87
+ else {
88
+ onChange(fileInput);
89
+ handleSave();
90
+ }
87
91
  };
88
- // eslint-disable-next-line @typescript-eslint/ban-ts-ignore
89
- // @ts-ignore
90
- reader.readAsDataURL(fileInput);
91
- }
92
+ img.src = e.target.result;
93
+ };
94
+ reader.readAsDataURL(selectedFile);
92
95
  };
93
96
  /**
94
97
  * Handles cover saving after upload action
95
98
  */
96
99
  function handleSave() {
100
+ if (!fileInput) {
101
+ return;
102
+ }
97
103
  setLoading(true);
98
104
  const formData = new FormData();
99
- // eslint-disable-next-line @typescript-eslint/ban-ts-ignore
105
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
100
106
  // @ts-ignore
101
107
  formData.append('image_original', fileInput);
102
108
  CourseService.changeCourseCover(courseId, formData, { headers: { 'Content-Type': 'multipart/form-data' } })
103
- // eslint-disable-next-line @typescript-eslint/ban-ts-ignore
104
- // @ts-ignore
105
109
  .then((data) => {
106
- onChange && onChange(data.image_medium);
110
+ // onChange && onChange(data.image_medium);
107
111
  setLoading(false);
108
112
  })
109
113
  .catch((error) => {
@@ -60,7 +60,14 @@ function Requests(props) {
60
60
  Logger.error(SCOPE_SC_UI, error);
61
61
  });
62
62
  }
63
- }, [state.isLoadingNext, state.initialized, course, dispatch]);
63
+ }, [state.isLoadingNext, state.initialized, course, dispatch, endpointQueryParams]);
64
+ // HANDLERS
65
+ const handleRemoveUser = useCallback((_msg, user) => {
66
+ dispatch({
67
+ type: actionWidgetTypes.SET_RESULTS,
68
+ payload: { count: state.results.length - 1, results: state.results.filter((result) => result.id !== user.id) }
69
+ });
70
+ }, [state.count, state.results, dispatch]);
64
71
  // EFFECTS
65
72
  useEffect(() => {
66
73
  let _t;
@@ -76,14 +83,7 @@ function Requests(props) {
76
83
  return () => {
77
84
  updatedUsers.current && PubSub.unsubscribe(updatedUsers.current);
78
85
  };
79
- }, []);
80
- // HANDLERS
81
- const handleRemoveUser = useCallback((user) => {
82
- dispatch({
83
- type: actionWidgetTypes.SET_RESULTS,
84
- payload: { count: state.count - 1, results: state.results.filter((result) => result.id !== user.id) }
85
- });
86
- }, [dispatch]);
86
+ }, [handleRemoveUser]);
87
87
  return (_jsxs(Box, { children: [_jsx(Typography, Object.assign({ variant: "h6" }, { children: _jsx(FormattedMessage, { id: "ui.editCourse.tab.requests.title", defaultMessage: "ui.editCourse.tab.requests.title", values: { requestsNumber: state.results.length } }) })), _jsx(Stack, Object.assign({ className: classes.usersStatusWrapper }, { children: _jsx(Status, { course: course }) })), _jsx(CourseUsersTable, { course: course, state: state, dispatch: dispatch, headerCells: headerCells, mode: "requests", emptyStatusTitle: "ui.courseUsersTable.empty.requests.title" })] }));
88
88
  }
89
89
  export default memo(Requests);
@@ -67,7 +67,11 @@ function Users(props) {
67
67
  Logger.error(SCOPE_SC_UI, error);
68
68
  });
69
69
  }
70
- }, [state.isLoadingNext, state.initialized, course, dispatch]);
70
+ }, [state.isLoadingNext, state.initialized, course, dispatch, endpointQueryParams]);
71
+ // HANDLERS
72
+ const handleAddUser = useCallback((_msg, user) => {
73
+ dispatch({ type: actionWidgetTypes.LOAD_PREVIOUS_SUCCESS, payload: { count: state.count + 1, results: [user], initialized: true } });
74
+ }, [state.count, dispatch]);
71
75
  // EFFECTS
72
76
  useEffect(() => {
73
77
  let _t;
@@ -83,18 +87,17 @@ function Users(props) {
83
87
  return () => {
84
88
  updatedUsers.current && PubSub.unsubscribe(updatedUsers.current);
85
89
  };
86
- }, []);
87
- // HANDLERS
88
- const handleAddUser = useCallback((user) => {
89
- dispatch({ type: actionWidgetTypes.LOAD_PREVIOUS_SUCCESS, payload: { count: state.count + 1, results: [user], initialized: true } });
90
- }, [dispatch]);
90
+ }, [handleAddUser]);
91
91
  const handleConfirm = useCallback((newUsers) => {
92
92
  const data = {
93
93
  joined: newUsers.map((user) => user.id)
94
94
  };
95
95
  CourseService.changeCourseUserRole(course.id, data)
96
96
  .then(() => {
97
- dispatch({ type: actionWidgetTypes.RESET });
97
+ dispatch({
98
+ type: actionWidgetTypes.LOAD_PREVIOUS_SUCCESS,
99
+ payload: { count: state.count + newUsers.length, results: newUsers, initialized: true }
100
+ });
98
101
  })
99
102
  .catch((error) => {
100
103
  dispatch({ type: actionWidgetTypes.LOAD_NEXT_FAILURE, payload: { errorLoadNext: error } });
@@ -93,7 +93,7 @@ function AddUsersButton(inProps) {
93
93
  const handleConfirm = useCallback(() => {
94
94
  onConfirm === null || onConfirm === void 0 ? void 0 : onConfirm(invited);
95
95
  setInvited([]);
96
- }, [invited]);
96
+ }, [invited, onConfirm]);
97
97
  // HANDLERS AUTOCOMPLETE
98
98
  const handleInputChange = useCallback((_, newValue, reason) => {
99
99
  switch (reason) {
@@ -19,7 +19,7 @@ function ChangeUserStatus(props) {
19
19
  const { enqueueSnackbar } = useSnackbar();
20
20
  // EFFECTS
21
21
  useEffect(() => {
22
- setValue(`ui.editCourse.tab.users.table.select.${user.join_status}`);
22
+ setValue(`ui.editCourse.tab.users.table.select.${user.join_status || 'joined'}`);
23
23
  }, [user, setValue]);
24
24
  // HANDLERS
25
25
  const handleChange = useCallback((e) => {
@@ -49,7 +49,7 @@ function CourseUsersTable(inProps) {
49
49
  // EFFECTS
50
50
  useEffect(() => {
51
51
  setUsers(state.results);
52
- }, [state.results]);
52
+ }, [state.results, setUsers]);
53
53
  // HANDLERS
54
54
  const handleChange = useCallback((e) => {
55
55
  const _value = e.target.value;
@@ -96,7 +96,7 @@ function CourseUsersTable(inProps) {
96
96
  return _jsx(TableCell, { width: "14%" }, i);
97
97
  }
98
98
  return (_jsx(TableCell, Object.assign({ width: mode === 'dashboard' ? '20%' : '25%' }, { children: _jsx(Typography, Object.assign({ variant: "body2" }, { children: _jsx(FormattedMessage, { id: cell.id, defaultMessage: cell.id }) })) }), i));
99
- }) }) }), _jsxs(TableBody, { children: [users.length === 0 && _jsx(RowSkeleton, { animation: false, editMode: mode !== 'dashboard' }), users.length > 0 &&
100
- users.map((user, i) => (_jsxs(TableRow, { children: [_jsx(TableCell, { children: _jsxs(Stack, Object.assign({ className: classes.avatarWrapper }, { children: [_jsx(Avatar, { alt: user.username, src: user.avatar }), _jsx(Typography, Object.assign({ variant: "body2" }, { children: user.username }))] })) }), mode === 'dashboard' && (_jsx(TableCell, { children: _jsxs(Stack, Object.assign({ className: classes.progressWrapper }, { children: [_jsx(LinearProgress, { className: classes.progress, variant: "determinate", value: user.user_completion_rate }), _jsx(Typography, Object.assign({ variant: "body1" }, { children: `${Math.round(user.user_completion_rate)}%` }))] })) })), mode === 'edit' && (_jsx(TableCell, { children: user.join_status !== SCCourseJoinStatusType.CREATOR && scUserContext.user.id !== user.id ? (_jsx(ChangeUserStatus, { course: course, user: user })) : (_jsx(Typography, Object.assign({ variant: "body2" }, { children: _jsx(FormattedMessage, { id: `ui.editCourse.tab.users.table.select.${user.join_status}`, defaultMessage: `ui.editCourse.tab.users.table.select.${user.join_status}` }) }))) })), _jsx(TableCell, { children: _jsx(Typography, Object.assign({ variant: "body2" }, { children: new Date(mode === 'requests' ? user.date_joined : user.joined_at).toLocaleDateString() })) }), _jsx(TableCell, { children: _jsx(Typography, Object.assign({ variant: "body2" }, { children: new Date(mode === 'requests' ? user.date_joined : user.last_active_at).toLocaleDateString() })) }), mode === 'dashboard' && (_jsx(TableCell, { children: _jsx(SeeProgressButton, { course: course, user: user }) })), mode === 'requests' && (_jsx(TableCell, { children: _jsx(RequestButton, { course: course, user: user }) }))] }, i))), state.isLoadingNext && _jsx(RowSkeleton, { editMode: mode !== 'dashboard' })] })] }) }), users.length > 0 && (_jsx(LoadingButton, Object.assign({ size: "small", variant: "outlined", color: "inherit", loading: state.isLoadingNext, disabled: !state.next, className: classes.loadingButton, onClick: handleNext }, { children: _jsx(Typography, Object.assign({ variant: "body2" }, { children: _jsx(FormattedMessage, { id: "ui.courseUsersTable.btn.label", defaultMessage: "ui.courseUsersTable.btn.label" }) })) }))), users.length === 0 && value.length === 0 && _jsx(EmptyStatus, { icon: "face", title: emptyStatusTitle, description: emptyStatusDescription })] }));
99
+ }) }) }), _jsxs(TableBody, { children: [users.length > 0 &&
100
+ users.map((user, i) => (_jsxs(TableRow, { children: [_jsx(TableCell, { children: _jsxs(Stack, Object.assign({ className: classes.avatarWrapper }, { children: [_jsx(Avatar, { alt: user.username, src: user.avatar }), _jsx(Typography, Object.assign({ variant: "body2" }, { children: user.username }))] })) }), mode === 'dashboard' && (_jsx(TableCell, { children: _jsxs(Stack, Object.assign({ className: classes.progressWrapper }, { children: [_jsx(LinearProgress, { className: classes.progress, variant: "determinate", value: user.user_completion_rate }), _jsx(Typography, Object.assign({ variant: "body1" }, { children: `${Math.round(user.user_completion_rate)}%` }))] })) })), mode === 'edit' && (_jsx(TableCell, { children: user.join_status !== SCCourseJoinStatusType.CREATOR && scUserContext.user.id !== user.id ? (_jsx(ChangeUserStatus, { course: course, user: user })) : (_jsx(Typography, Object.assign({ variant: "body2" }, { children: _jsx(FormattedMessage, { id: `ui.editCourse.tab.users.table.select.${user.join_status}`, defaultMessage: `ui.editCourse.tab.users.table.select.${user.join_status}` }) }))) })), _jsx(TableCell, { children: _jsx(Typography, Object.assign({ variant: "body2" }, { children: new Date(mode === 'requests' ? user.date_joined : user.joined_at || new Date()).toLocaleDateString() })) }), _jsx(TableCell, { children: _jsx(Typography, Object.assign({ variant: "body2" }, { children: new Date(mode === 'requests' ? user.date_joined : user.last_active_at || new Date()).toLocaleDateString() })) }), mode === 'dashboard' && (_jsx(TableCell, { children: _jsx(SeeProgressButton, { course: course, user: user }) })), mode === 'requests' && (_jsx(TableCell, { children: _jsx(RequestButton, { course: course, user: user }) }))] }, i))), state.isLoadingNext && _jsx(RowSkeleton, { editMode: mode !== 'dashboard' })] })] }) }), users.length > 0 && (_jsx(LoadingButton, Object.assign({ size: "small", variant: "outlined", color: "inherit", loading: state.isLoadingNext, disabled: !state.next, className: classes.loadingButton, onClick: handleNext }, { children: _jsx(Typography, Object.assign({ variant: "body2" }, { children: _jsx(FormattedMessage, { id: "ui.courseUsersTable.btn.label", defaultMessage: "ui.courseUsersTable.btn.label" }) })) }))), users.length === 0 && value.length === 0 && _jsx(EmptyStatus, { icon: "face", title: emptyStatusTitle, description: emptyStatusDescription })] }));
101
101
  }
102
102
  export default memo(CourseUsersTable);