@selfcommunity/react-ui 0.10.2-courses.175 → 0.10.2-courses.178

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.
@@ -118,21 +118,33 @@ function Student(inProps) {
118
118
  const handleRequest = (0, react_1.useCallback)(() => {
119
119
  setLoadingRequest(true);
120
120
  let request;
121
- let updatedCourse;
122
121
  if (sentRequest) {
123
122
  request = api_services_1.CourseService.leaveOrRemoveCourseRequest(scCourse.id);
124
- updatedCourse = Object.assign(Object.assign({}, scCourse), { join_status: null });
125
123
  }
126
124
  else {
127
125
  request = api_services_1.CourseService.joinOrAcceptInviteToCourse(scCourse.id);
128
- updatedCourse = Object.assign(Object.assign({}, scCourse), { join_status: scCourse.privacy === types_1.SCCoursePrivacyType.PRIVATE ? types_1.SCCourseJoinStatusType.REQUESTED : types_1.SCCourseJoinStatusType.JOINED });
129
126
  }
130
127
  request
131
- .then(() => {
128
+ .then((data) => {
129
+ let updatedCourse;
130
+ if (data) {
131
+ updatedCourse = data;
132
+ }
133
+ else {
134
+ updatedCourse = Object.assign(Object.assign({}, scCourse), { join_status: null });
135
+ }
132
136
  setSCCourse(updatedCourse);
133
137
  setSentRequest((prev) => !prev);
134
138
  setLoadingRequest(false);
135
- enqueueSnackbar((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: sentRequest ? SNACKBAR_MESSAGES.request : scCourse.join_status === null ? SNACKBAR_MESSAGES.enroll : SNACKBAR_MESSAGES.cancel, defaultMessage: sentRequest ? SNACKBAR_MESSAGES.request : scCourse.join_status === null ? SNACKBAR_MESSAGES.enroll : SNACKBAR_MESSAGES.cancel }), {
139
+ enqueueSnackbar((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: updatedCourse.join_status === types_1.SCCourseJoinStatusType.REQUESTED
140
+ ? SNACKBAR_MESSAGES.request
141
+ : updatedCourse.join_status === types_1.SCCourseJoinStatusType.JOINED
142
+ ? SNACKBAR_MESSAGES.enroll
143
+ : SNACKBAR_MESSAGES.cancel, defaultMessage: updatedCourse.join_status === types_1.SCCourseJoinStatusType.REQUESTED
144
+ ? SNACKBAR_MESSAGES.request
145
+ : updatedCourse.join_status === types_1.SCCourseJoinStatusType.JOINED
146
+ ? SNACKBAR_MESSAGES.enroll
147
+ : SNACKBAR_MESSAGES.cancel }), {
136
148
  variant: 'success',
137
149
  autoHideDuration: 3000
138
150
  });
@@ -91,7 +91,6 @@ export interface CoursesProps {
91
91
  |itemPlaceholder|.SCCourses-item-placeholder|Styles applied to the placeholder for an item.|
92
92
  |noResults|.SCCourses-no-results|Styles applied when there are no results.|
93
93
  |search|.SCCourses-search|Styles applied to the search element.|
94
- |showMore|.SCCourses-show-more|Styles applied to the show more button or section.|
95
94
  |studentEmptyView|.SCCourses-student-empty-view|Styles applied to the student empty view.|
96
95
  |teacherEmptyView|.SCCourses-teacher-empty-view|Styles applied to the teacher empty view.|
97
96
 
@@ -14,12 +14,14 @@ const react_intl_1 = require("react-intl");
14
14
  const Errors_1 = require("../../constants/Errors");
15
15
  const Pagination_1 = require("../../constants/Pagination");
16
16
  const PubSub_1 = require("../../constants/PubSub");
17
- const Course_1 = tslib_1.__importDefault(require("../Course"));
17
+ const Course_1 = tslib_1.__importStar(require("../Course"));
18
18
  const Skeleton_1 = tslib_1.__importDefault(require("../Courses/Skeleton"));
19
19
  const constants_1 = require("./constants");
20
20
  const course_1 = require("../../types/course");
21
21
  const CategoryAutocomplete_1 = tslib_1.__importDefault(require("../CategoryAutocomplete"));
22
22
  const CreatePlaceholder_1 = tslib_1.__importDefault(require("../Course/CreatePlaceholder"));
23
+ const InfiniteScroll_1 = tslib_1.__importDefault(require("../../shared/InfiniteScroll"));
24
+ const HiddenPlaceholder_1 = tslib_1.__importDefault(require("../../shared/HiddenPlaceholder"));
23
25
  const classes = {
24
26
  root: `${constants_1.PREFIX}-root`,
25
27
  category: `${constants_1.PREFIX}-category`,
@@ -32,9 +34,9 @@ const classes = {
32
34
  itemPlaceholder: `${constants_1.PREFIX}-item-placeholder`,
33
35
  noResults: `${constants_1.PREFIX}-no-results`,
34
36
  search: `${constants_1.PREFIX}-search`,
35
- showMore: `${constants_1.PREFIX}-show-more`,
36
37
  studentEmptyView: `${constants_1.PREFIX}-student-empty-view`,
37
- teacherEmptyView: `${constants_1.PREFIX}-teacher-empty-view`
38
+ teacherEmptyView: `${constants_1.PREFIX}-teacher-empty-view`,
39
+ endMessage: `${constants_1.PREFIX}-end-message`
38
40
  };
39
41
  const Root = (0, material_1.styled)(material_1.Box, {
40
42
  name: constants_1.PREFIX,
@@ -74,7 +76,6 @@ exports.CoursesChipRoot = (0, material_1.styled)(material_1.Chip, {
74
76
  |itemPlaceholder|.SCCourses-item-placeholder|Styles applied to the placeholder for an item.|
75
77
  |noResults|.SCCourses-no-results|Styles applied when there are no results.|
76
78
  |search|.SCCourses-search|Styles applied to the search element.|
77
- |showMore|.SCCourses-show-more|Styles applied to the show more button or section.|
78
79
  |studentEmptyView|.SCCourses-student-empty-view|Styles applied to the student empty view.|
79
80
  |teacherEmptyView|.SCCourses-teacher-empty-view|Styles applied to the teacher empty view.|
80
81
 
@@ -130,7 +131,6 @@ function Courses(inProps) {
130
131
  * Fetches courses list
131
132
  */
132
133
  const fetchCourses = () => {
133
- setLoading(true);
134
134
  return api_services_1.http
135
135
  .request({
136
136
  url: endpoint.url({}),
@@ -186,7 +186,7 @@ function Courses(inProps) {
186
186
  return api_services_1.http
187
187
  .request({
188
188
  url: next,
189
- method: showMyCourses ? api_services_1.Endpoints.GetJoinedCourses.method : api_services_1.Endpoints.SearchCourses.method
189
+ method: showMyCourses ? api_services_1.Endpoints.GetJoinedCourses.method : showForMe ? api_services_1.Endpoints.CourseSuggestion : api_services_1.Endpoints.SearchCourses.method
190
190
  })
191
191
  .then((res) => {
192
192
  setCourses([...courses, ...res.data.results]);
@@ -210,6 +210,9 @@ function Courses(inProps) {
210
210
  const categoriesIds = categories.map((item) => item.id);
211
211
  setCategories(categoriesIds);
212
212
  };
213
+ const handleScrollUp = () => {
214
+ window.scrollTo({ left: 0, top: 0, behavior: 'smooth' });
215
+ };
213
216
  /**
214
217
  * Renders courses list
215
218
  */
@@ -224,12 +227,19 @@ function Courses(inProps) {
224
227
  // @ts-expect-error this is needed to use showForMe into SCCourses
225
228
  showForMe: showMyCourses, deleteIcon: showMyCourses ? (0, jsx_runtime_1.jsx)(material_1.Icon, { children: "close" }) : null, onDelete: showMyCourses ? () => setShowMyCourses(false) : null, disabled: loading || showForMe }) }))), (0, jsx_runtime_1.jsx)(material_1.Grid, Object.assign({ item: true, xs: 12, md: "auto" }, { children: (0, jsx_runtime_1.jsx)(material_1.FormControl, Object.assign({ fullWidth: true }, { children: (0, jsx_runtime_1.jsx)(CategoryAutocomplete_1.default, { onChange: handleOnChangeCategory, className: classes.category, size: "small", multiple: true }) })) })), authUserId && ((0, jsx_runtime_1.jsx)(material_1.Grid, Object.assign({ item: true }, { children: (0, jsx_runtime_1.jsx)(exports.CoursesChipRoot, { color: showForMe ? 'primary' : 'default', variant: showForMe ? 'filled' : 'outlined', label: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.courses.filterByCoursesForMe", defaultMessage: "ui.courses.filterByCoursesForMe" }), onClick: handleChipClick,
226
229
  // @ts-expect-error this is needed to use showForMe into SCCourses
227
- showForMe: showForMe, deleteIcon: showForMe ? (0, jsx_runtime_1.jsx)(material_1.Icon, { children: "close" }) : null, onDelete: showForMe ? handleDeleteClick : null, disabled: loading || showMyCourses }) })))] })) }))), (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: loading ? ((0, jsx_runtime_1.jsx)(Skeleton_1.default, Object.assign({}, CoursesSkeletonComponentProps, { CourseSkeletonProps: CourseSkeletonComponentProps }))) : ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: !courses.length ? ((0, jsx_runtime_1.jsx)(material_1.Box, Object.assign({ className: classes.noResults }, { children: !canCreateCourse && onlyStaffEnabled ? ((0, jsx_runtime_1.jsxs)(material_1.Stack, Object.assign({ className: classes.studentEmptyView }, { children: [(0, jsx_runtime_1.jsx)(material_1.Stack, Object.assign({ className: classes.emptyBox }, { children: (0, jsx_runtime_1.jsx)(material_1.Stack, Object.assign({ className: classes.emptyRotatedBox }, { children: (0, jsx_runtime_1.jsx)(material_1.Icon, Object.assign({ className: classes.emptyIcon, color: "disabled", fontSize: "large" }, { children: "courses" })) })) })), (0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "h5", textAlign: "center" }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.courses.empty.title", defaultMessage: "ui.courses.empty.title" }) })), (0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "body1", textAlign: "center" }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.courses.empty.info", defaultMessage: "ui.courses.empty.info" }) })), !isMobile && ((0, jsx_runtime_1.jsx)(Skeleton_1.default, Object.assign({ coursesNumber: 4 }, CoursesSkeletonComponentProps, { CourseSkeletonProps: CourseSkeletonComponentProps })))] }))) : ((0, jsx_runtime_1.jsx)(material_1.Box, Object.assign({ className: classes.teacherEmptyView }, { children: (0, jsx_runtime_1.jsx)(Skeleton_1.default, Object.assign({ teacherView: (onlyStaffEnabled && canCreateCourse) || !onlyStaffEnabled, coursesNumber: 1 }, CoursesSkeletonComponentProps, { CourseSkeletonProps: CourseSkeletonComponentProps })) }))) }))) : ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(material_1.Grid, Object.assign({ container: true, spacing: { xs: 2 }, className: classes.courses }, GridContainerComponentProps, { children: (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [courses.map((course) => ((0, jsx_runtime_1.jsx)(material_1.Grid, Object.assign({ item: true, xs: 12, sm: 12, md: 6, lg: 3, className: classes.item }, GridItemComponentProps, { children: (0, jsx_runtime_1.jsx)(Course_1.default, Object.assign({ courseId: course.id }, CourseComponentProps)) }), course.id))), authUserId && courses.length % 2 !== 0 && ((0, jsx_runtime_1.jsx)(material_1.Grid, Object.assign({ item: true, xs: 12, sm: 12, md: 6, lg: 3, className: classes.itemPlaceholder }, GridItemComponentProps, { children: (0, jsx_runtime_1.jsx)(CreatePlaceholder_1.default, { CreateCourseButtonComponentProps: CreateCourseButtonComponentProps }) }), "placeholder-item"))] }) })), Boolean(next) && ((0, jsx_runtime_1.jsx)(material_1.Button, Object.assign({ color: "secondary", variant: "text", onClick: handleNext, className: classes.showMore }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.courses.button.seeMore", defaultMessage: "ui.courses.button.seeMore" }) })))] })) })) })] }));
230
+ showForMe: showForMe, deleteIcon: showForMe ? (0, jsx_runtime_1.jsx)(material_1.Icon, { children: "close" }) : null, onDelete: showForMe ? handleDeleteClick : null, disabled: loading || showMyCourses }) })))] })) }))), (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: !courses.length ? ((0, jsx_runtime_1.jsx)(material_1.Box, Object.assign({ className: classes.noResults }, { children: !canCreateCourse && onlyStaffEnabled ? ((0, jsx_runtime_1.jsxs)(material_1.Stack, Object.assign({ className: classes.studentEmptyView }, { children: [(0, jsx_runtime_1.jsx)(material_1.Stack, Object.assign({ className: classes.emptyBox }, { children: (0, jsx_runtime_1.jsx)(material_1.Stack, Object.assign({ className: classes.emptyRotatedBox }, { children: (0, jsx_runtime_1.jsx)(material_1.Icon, Object.assign({ className: classes.emptyIcon, color: "disabled", fontSize: "large" }, { children: "courses" })) })) })), (0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "h5", textAlign: "center" }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.courses.empty.title", defaultMessage: "ui.courses.empty.title" }) })), (0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "body1", textAlign: "center" }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.courses.empty.info", defaultMessage: "ui.courses.empty.info" }) })), !isMobile && (0, jsx_runtime_1.jsx)(Skeleton_1.default, Object.assign({ coursesNumber: 4 }, CoursesSkeletonComponentProps, { CourseSkeletonProps: CourseSkeletonComponentProps }))] }))) : ((0, jsx_runtime_1.jsx)(material_1.Box, Object.assign({ className: classes.teacherEmptyView }, { children: (0, jsx_runtime_1.jsx)(Skeleton_1.default, Object.assign({ teacherView: (onlyStaffEnabled && canCreateCourse) || !onlyStaffEnabled, coursesNumber: 1 }, CoursesSkeletonComponentProps, { CourseSkeletonProps: CourseSkeletonComponentProps })) }))) }))) : ((0, jsx_runtime_1.jsx)(InfiniteScroll_1.default, Object.assign({ dataLength: courses.length, next: handleNext, hasMoreNext: Boolean(next), loaderNext: isMobile ? ((0, jsx_runtime_1.jsx)(Course_1.CourseSkeleton, { template: course_1.SCCourseTemplateType.PREVIEW })) : ((0, jsx_runtime_1.jsx)(Skeleton_1.default, Object.assign({ coursesNumber: 4 }, CoursesSkeletonComponentProps, { CourseSkeletonProps: CourseSkeletonComponentProps }))), endMessage: (0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ component: "div", className: classes.endMessage }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.courses.endMessage", defaultMessage: "ui.courses.endMessage", values: {
231
+ // eslint-disable-next-line @typescript-eslint/ban-ts-ignore
232
+ // @ts-ignore
233
+ button: (chunk) => ((0, jsx_runtime_1.jsx)(material_1.Button, Object.assign({ color: "secondary", variant: "text", onClick: handleScrollUp }, { children: chunk })))
234
+ } }) })) }, { children: (0, jsx_runtime_1.jsx)(material_1.Grid, Object.assign({ container: true, spacing: { xs: 2 }, className: classes.courses }, GridContainerComponentProps, { children: (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [courses.map((course) => ((0, jsx_runtime_1.jsx)(material_1.Grid, Object.assign({ item: true, xs: 12, sm: 12, md: 6, lg: 3, className: classes.item }, GridItemComponentProps, { children: (0, jsx_runtime_1.jsx)(Course_1.default, Object.assign({ courseId: course.id }, CourseComponentProps)) }), course.id))), authUserId && courses.length % 2 !== 0 && ((0, jsx_runtime_1.jsx)(material_1.Grid, Object.assign({ item: true, xs: 12, sm: 12, md: 6, lg: 3, className: classes.itemPlaceholder }, GridItemComponentProps, { children: (0, jsx_runtime_1.jsx)(CreatePlaceholder_1.default, { CreateCourseButtonComponentProps: CreateCourseButtonComponentProps }) }), "placeholder-item"))] }) })) }))) })] }));
228
235
  /**
229
236
  * Renders root object (if content availability community option is false and user is anonymous, component is hidden)
230
237
  */
231
238
  if (!contentAvailability && !scUserContext.user) {
232
- return null;
239
+ return (0, jsx_runtime_1.jsx)(HiddenPlaceholder_1.default, {});
240
+ }
241
+ if (loading) {
242
+ return (0, jsx_runtime_1.jsx)(Skeleton_1.default, Object.assign({}, CoursesSkeletonComponentProps, { CourseSkeletonProps: CourseSkeletonComponentProps }));
233
243
  }
234
244
  return ((0, jsx_runtime_1.jsx)(Root, Object.assign({ className: (0, classnames_1.default)(classes.root, className) }, rest, { children: c })));
235
245
  }
@@ -16,8 +16,8 @@ const notistack_1 = require("notistack");
16
16
  const react_core_1 = require("@selfcommunity/react-core");
17
17
  const Errors_1 = require("../../../constants/Errors");
18
18
  const types_1 = require("../types");
19
- const hooks_1 = require("../hooks");
20
19
  const ConfirmDialog_1 = tslib_1.__importDefault(require("../../../shared/ConfirmDialog/ConfirmDialog"));
20
+ const hooks_1 = require("../hooks");
21
21
  const classes = {
22
22
  cellWidth: `${constants_1.PREFIX}-cell-width`,
23
23
  cellAlignRight: `${constants_1.PREFIX}-cell-align-right`,
@@ -42,7 +42,7 @@ function LessonRow(props) {
42
42
  // CONTEXTS
43
43
  const scRoutingContext = (0, react_core_1.useSCRouting)();
44
44
  // HOOKS
45
- const { isDisabled } = (0, hooks_1.useDisabled)();
45
+ const { isDisabled } = (0, hooks_1.useIsDisabled)();
46
46
  const { enqueueSnackbar } = (0, notistack_1.useSnackbar)();
47
47
  // HANDLERS
48
48
  const handleAbleEditMode = (0, react_1.useCallback)(() => setTimeout(() => setEditMode(true)), [setEditMode]);
@@ -40,7 +40,7 @@ function SectionRow(props) {
40
40
  const [editMode, setEditMode] = (0, react_1.useState)(false);
41
41
  const [lessons, setLessons] = (0, react_1.useState)([]);
42
42
  // HOOKS
43
- const { isDisabled } = (0, hooks_1.useDisabled)();
43
+ const { isDisabled } = (0, hooks_1.useIsDisabled)();
44
44
  const intl = (0, react_intl_1.useIntl)();
45
45
  const { enqueueSnackbar } = (0, notistack_1.useSnackbar)();
46
46
  // EFFECTS
@@ -144,6 +144,6 @@ function SectionRow(props) {
144
144
  ? api_services_1.Endpoints.CreateCourseSection.url({ id: course.id })
145
145
  : api_services_1.Endpoints.PatchCourseSection.url({ id: course.id, section_id: section.id }),
146
146
  method: isNewRow ? api_services_1.Endpoints.CreateCourseSection.method : api_services_1.Endpoints.PatchCourseSection.method
147
- }, row: section, isNewRow: isNewRow, handleManageRow: handleManageSection, editMode: editMode, handleDisableEditMode: handleDisableEditMode }) }), (0, jsx_runtime_1.jsx)(material_1.TableCell, Object.assign({ className: classes.cellAlignCenter }, { children: isDisabled ? ((0, jsx_runtime_1.jsx)(material_1.Skeleton, { animation: false, variant: "rectangular", width: "250px", height: "38px", sx: { margin: 'auto', borderRadius: '5px' } })) : ((0, jsx_runtime_1.jsx)(LessonReleaseMenu_1.default, { course: course, section: section })) })), (0, jsx_runtime_1.jsx)(material_1.TableCell, Object.assign({ className: classes.cellAlignRight }, { children: (0, jsx_runtime_1.jsxs)(material_1.Stack, Object.assign({ className: classes.actionsWrapper }, { children: [(0, jsx_runtime_1.jsx)(AddButton_1.default, { label: "ui.editCourse.tab.lessons.table.lesson", handleAddRow: handleAddTempLesson, color: "primary", variant: "outlined", disabled: isDisabled }), (0, jsx_runtime_1.jsxs)(MenuRow_1.default, Object.assign({ disabled: isDisabled }, { children: [(0, jsx_runtime_1.jsx)(material_1.MenuItem, Object.assign({ onClick: handleAbleEditMode }, { 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.editCourse.tab.lessons.table.menu.rename", defaultMessage: "ui.editCourse.tab.lessons.table.menu.rename" }) })) })), (0, jsx_runtime_1.jsx)(material_1.MenuItem, Object.assign({ onClick: handleOpenDialog }, { 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.editCourse.tab.lessons.table.menu.delete", defaultMessage: "ui.editCourse.tab.lessons.table.menu.delete" }) })) }))] }))] })) }))] })), (0, jsx_runtime_1.jsx)(material_1.TableRow, { children: (0, jsx_runtime_1.jsxs)(material_1.TableCell, Object.assign({ className: classes.tableBodyCollapseWrapper, colSpan: 4 }, { children: [(0, jsx_runtime_1.jsx)(material_1.Collapse, Object.assign({ in: expand, timeout: "auto", unmountOnExit: true }, { children: (0, jsx_runtime_1.jsx)(dnd_1.DragDropContext, Object.assign({ onDragEnd: handleDragEnd }, { children: (0, jsx_runtime_1.jsx)(material_1.Table, { children: (0, jsx_runtime_1.jsx)(dnd_1.Droppable, Object.assign({ droppableId: "droppable-2" }, { children: (outerProvider) => ((0, jsx_runtime_1.jsxs)(material_1.TableBody, Object.assign({ ref: outerProvider.innerRef }, outerProvider.droppableProps, { children: [lessons.map((lesson, i, array) => ((0, jsx_runtime_1.jsx)(dnd_1.Draggable, Object.assign({ draggableId: i.toString(), index: i, isDragDisabled: isDisabled }, { children: (innerProvider) => ((0, jsx_runtime_1.jsx)(LessonRow_1.default, { provider: innerProvider, course: course, section: section, lesson: lesson, isNewRow: isNewLocalRow && i + 1 === array.length, handleManageLesson: handleManageLesson }, i)) }), i))), outerProvider.placeholder] }))) })) }) })) })), open && (0, jsx_runtime_1.jsx)(ConfirmDialog_1.default, { open: true, onClose: handleOpenDialog, onConfirm: handleDeleteSection })] })) })] }));
147
+ }, row: section, isNewRow: isNewRow, handleManageRow: handleManageSection, editMode: editMode, handleDisableEditMode: handleDisableEditMode }) }), (0, jsx_runtime_1.jsx)(material_1.TableCell, Object.assign({ className: classes.cellAlignCenter }, { children: (0, jsx_runtime_1.jsx)(LessonReleaseMenu_1.default, { course: course, section: section }) })), (0, jsx_runtime_1.jsx)(material_1.TableCell, Object.assign({ className: classes.cellAlignRight }, { children: (0, jsx_runtime_1.jsxs)(material_1.Stack, Object.assign({ className: classes.actionsWrapper }, { children: [(0, jsx_runtime_1.jsx)(AddButton_1.default, { label: "ui.editCourse.tab.lessons.table.lesson", handleAddRow: handleAddTempLesson, color: "primary", variant: "outlined", disabled: isDisabled }), (0, jsx_runtime_1.jsxs)(MenuRow_1.default, Object.assign({ disabled: isDisabled }, { children: [(0, jsx_runtime_1.jsx)(material_1.MenuItem, Object.assign({ onClick: handleAbleEditMode }, { 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.editCourse.tab.lessons.table.menu.rename", defaultMessage: "ui.editCourse.tab.lessons.table.menu.rename" }) })) })), (0, jsx_runtime_1.jsx)(material_1.MenuItem, Object.assign({ onClick: handleOpenDialog }, { 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.editCourse.tab.lessons.table.menu.delete", defaultMessage: "ui.editCourse.tab.lessons.table.menu.delete" }) })) }))] }))] })) }))] })), (0, jsx_runtime_1.jsx)(material_1.TableRow, { children: (0, jsx_runtime_1.jsxs)(material_1.TableCell, Object.assign({ className: classes.tableBodyCollapseWrapper, colSpan: 4 }, { children: [(0, jsx_runtime_1.jsx)(material_1.Collapse, Object.assign({ in: expand, timeout: "auto", unmountOnExit: true }, { children: (0, jsx_runtime_1.jsx)(dnd_1.DragDropContext, Object.assign({ onDragEnd: handleDragEnd }, { children: (0, jsx_runtime_1.jsx)(material_1.Table, { children: (0, jsx_runtime_1.jsx)(dnd_1.Droppable, Object.assign({ droppableId: "droppable-2" }, { children: (outerProvider) => ((0, jsx_runtime_1.jsxs)(material_1.TableBody, Object.assign({ ref: outerProvider.innerRef }, outerProvider.droppableProps, { children: [lessons.map((lesson, i, array) => ((0, jsx_runtime_1.jsx)(dnd_1.Draggable, Object.assign({ draggableId: i.toString(), index: i, isDragDisabled: isDisabled }, { children: (innerProvider) => ((0, jsx_runtime_1.jsx)(LessonRow_1.default, { provider: innerProvider, course: course, section: section, lesson: lesson, isNewRow: isNewLocalRow && i + 1 === array.length, handleManageLesson: handleManageLesson }, i)) }), i))), outerProvider.placeholder] }))) })) }) })) })), open && (0, jsx_runtime_1.jsx)(ConfirmDialog_1.default, { open: true, onClose: handleOpenDialog, onConfirm: handleDeleteSection })] })) })] }));
148
148
  }
149
149
  exports.default = (0, react_1.memo)(SectionRow);
@@ -58,7 +58,7 @@ function Lessons(props) {
58
58
  // STATES
59
59
  const [sections, setSections] = (0, react_1.useState)([]);
60
60
  // HOOKS
61
- const { isDisabled } = (0, hooks_1.useDisabled)();
61
+ const { isDisabled } = (0, hooks_1.useIsDisabled)();
62
62
  const { enqueueSnackbar } = (0, notistack_1.useSnackbar)();
63
63
  const intl = (0, react_intl_1.useIntl)();
64
64
  // EFFECTS
@@ -1,3 +1,3 @@
1
- export declare const useDisabled: () => {
1
+ export declare const useIsDisabled: () => {
2
2
  isDisabled: boolean;
3
3
  };
@@ -1,11 +1,11 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.useDisabled = void 0;
3
+ exports.useIsDisabled = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const react_1 = require("react");
6
6
  const pubsub_js_1 = tslib_1.__importDefault(require("pubsub-js"));
7
7
  const PubSub_1 = require("../../constants/PubSub");
8
- const useDisabled = () => {
8
+ const useIsDisabled = () => {
9
9
  // STATES
10
10
  const [isDisabled, setIsDisabled] = (0, react_1.useState)(false);
11
11
  // REFS
@@ -19,4 +19,4 @@ const useDisabled = () => {
19
19
  }, [setIsDisabled]);
20
20
  return { isDisabled };
21
21
  };
22
- exports.useDisabled = useDisabled;
22
+ exports.useIsDisabled = useIsDisabled;
@@ -19,6 +19,7 @@ const api_services_1 = require("@selfcommunity/api-services");
19
19
  const Errors_1 = require("../../constants/Errors");
20
20
  const utils_1 = require("@selfcommunity/utils");
21
21
  const course_1 = require("../../utils/course");
22
+ const hooks_1 = require("../EditCourse/hooks");
22
23
  const messages = (0, react_intl_1.defineMessages)({
23
24
  pickerPlaceholder: {
24
25
  id: 'ui.lessonReleaseMenu.scheduled.picker.placeholder',
@@ -49,13 +50,13 @@ const classes = {
49
50
  const Root = (0, styles_1.styled)(material_1.FormControl, {
50
51
  name: constants_1.PREFIX,
51
52
  slot: 'Root',
52
- overridesResolver: (props, styles) => [styles.root]
53
+ overridesResolver: (_props, styles) => [styles.root]
53
54
  })(() => ({}));
54
55
  const PopoverRoot = (0, styles_1.styled)(material_1.Popover, {
55
56
  name: constants_1.PREFIX,
56
57
  slot: 'PopoverRoot',
57
- overridesResolver: (props, styles) => styles.popoverRoot
58
- })(({ theme }) => ({}));
58
+ overridesResolver: (_props, styles) => styles.popoverRoot
59
+ })(() => ({}));
59
60
  function LessonReleaseMenu(inProps) {
60
61
  // PROPS
61
62
  const props = (0, system_1.useThemeProps)({
@@ -72,6 +73,8 @@ function LessonReleaseMenu(inProps) {
72
73
  const [unit, setUnit] = (0, react_1.useState)(_unit);
73
74
  const [anchorEl, setAnchorEl] = (0, react_1.useState)(null);
74
75
  const [open, setOpen] = (0, react_1.useState)(false);
76
+ // HOOKS
77
+ const { isDisabled } = (0, hooks_1.useIsDisabled)();
75
78
  //INTL
76
79
  const intl = (0, react_intl_1.useIntl)();
77
80
  const handleUnitChange = (e) => {
@@ -125,7 +128,7 @@ function LessonReleaseMenu(inProps) {
125
128
  } }, { children: (0, jsx_runtime_1.jsx)(x_date_pickers_1.MobileDateTimePicker, { className: classes.picker, disablePast: true, label: drippedAt && ((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.lessonReleaseMenu.scheduled.picker.placeholder", defaultMessage: "ui.lessonReleaseMenu.scheduled.picker.placeholder" })), defaultValue: drippedAt, slots: {
126
129
  //actionBar: PickerActionBar,
127
130
  tabs: (props) => (0, jsx_runtime_1.jsx)(x_date_pickers_1.DateTimePickerTabs, Object.assign({}, props)),
128
- textField: (params) => ((0, jsx_runtime_1.jsx)(material_1.TextField, Object.assign({}, params, { error: false, InputProps: Object.assign(Object.assign({}, params.InputProps), { placeholder: `${intl.formatMessage(messages.pickerPlaceholder)}`, endAdornment: ((0, jsx_runtime_1.jsx)(material_1.InputAdornment, Object.assign({ position: "end" }, { children: (0, jsx_runtime_1.jsx)(material_1.IconButton, { children: (0, jsx_runtime_1.jsx)(material_1.Icon, { children: "expand_more" }) }) }))) }) })))
131
+ textField: (params) => ((0, jsx_runtime_1.jsx)(material_1.TextField, Object.assign({}, params, { error: false, InputProps: Object.assign(Object.assign({}, params.InputProps), { placeholder: `${intl.formatMessage(messages.pickerPlaceholder)}`, endAdornment: ((0, jsx_runtime_1.jsx)(material_1.InputAdornment, Object.assign({ position: "end" }, { children: (0, jsx_runtime_1.jsx)(material_1.IconButton, Object.assign({ disabled: isDisabled }, { children: (0, jsx_runtime_1.jsx)(material_1.Icon, { children: "expand_more" }) })) }))) }) })))
129
132
  }, slotProps: {
130
133
  tabs: {
131
134
  hidden: false
@@ -138,9 +141,9 @@ function LessonReleaseMenu(inProps) {
138
141
  actionBar: {
139
142
  actions: ['cancel', 'clear', 'accept']
140
143
  }
141
- }, onChange: (value) => setDrippedAt(value), onAccept: handleUpdate, onClear: () => setDrippedAt(null) }) }))) : ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(material_1.TextField, { size: "small", placeholder: placeholderStructured, defaultValue: null, onClick: handleClick, InputProps: {
142
- endAdornment: ((0, jsx_runtime_1.jsx)(material_1.InputAdornment, Object.assign({ position: "end" }, { children: (0, jsx_runtime_1.jsx)(material_1.IconButton, Object.assign({ onClick: handleClick }, { children: (0, jsx_runtime_1.jsx)(material_1.Icon, { children: "expand_more" }) })) })))
143
- } }), (0, jsx_runtime_1.jsxs)(PopoverRoot, Object.assign({ className: classes.popoverRoot, open: open, anchorEl: anchorEl, onClose: handleClose, anchorOrigin: {
144
+ }, onChange: (value) => setDrippedAt(value), onAccept: handleUpdate, onClear: () => setDrippedAt(null), disabled: isDisabled }) }))) : ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(material_1.TextField, { size: "small", placeholder: placeholderStructured, defaultValue: null, onClick: isDisabled ? undefined : handleClick, InputProps: {
145
+ endAdornment: ((0, jsx_runtime_1.jsx)(material_1.InputAdornment, Object.assign({ position: "end" }, { children: (0, jsx_runtime_1.jsx)(material_1.IconButton, Object.assign({ onClick: handleClick, disabled: isDisabled }, { children: (0, jsx_runtime_1.jsx)(material_1.Icon, { children: "expand_more" }) })) })))
146
+ }, disabled: isDisabled }), (0, jsx_runtime_1.jsxs)(PopoverRoot, Object.assign({ className: classes.popoverRoot, open: open, anchorEl: anchorEl, onClose: handleClose, anchorOrigin: {
144
147
  vertical: 'bottom',
145
148
  horizontal: 'left'
146
149
  }, transformOrigin: {
@@ -116,21 +116,33 @@ function Student(inProps) {
116
116
  const handleRequest = useCallback(() => {
117
117
  setLoadingRequest(true);
118
118
  let request;
119
- let updatedCourse;
120
119
  if (sentRequest) {
121
120
  request = CourseService.leaveOrRemoveCourseRequest(scCourse.id);
122
- updatedCourse = Object.assign(Object.assign({}, scCourse), { join_status: null });
123
121
  }
124
122
  else {
125
123
  request = CourseService.joinOrAcceptInviteToCourse(scCourse.id);
126
- updatedCourse = Object.assign(Object.assign({}, scCourse), { join_status: scCourse.privacy === SCCoursePrivacyType.PRIVATE ? SCCourseJoinStatusType.REQUESTED : SCCourseJoinStatusType.JOINED });
127
124
  }
128
125
  request
129
- .then(() => {
126
+ .then((data) => {
127
+ let updatedCourse;
128
+ if (data) {
129
+ updatedCourse = data;
130
+ }
131
+ else {
132
+ updatedCourse = Object.assign(Object.assign({}, scCourse), { join_status: null });
133
+ }
130
134
  setSCCourse(updatedCourse);
131
135
  setSentRequest((prev) => !prev);
132
136
  setLoadingRequest(false);
133
- enqueueSnackbar(_jsx(FormattedMessage, { id: sentRequest ? SNACKBAR_MESSAGES.request : scCourse.join_status === null ? SNACKBAR_MESSAGES.enroll : SNACKBAR_MESSAGES.cancel, defaultMessage: sentRequest ? SNACKBAR_MESSAGES.request : scCourse.join_status === null ? SNACKBAR_MESSAGES.enroll : SNACKBAR_MESSAGES.cancel }), {
137
+ enqueueSnackbar(_jsx(FormattedMessage, { id: updatedCourse.join_status === SCCourseJoinStatusType.REQUESTED
138
+ ? SNACKBAR_MESSAGES.request
139
+ : updatedCourse.join_status === SCCourseJoinStatusType.JOINED
140
+ ? SNACKBAR_MESSAGES.enroll
141
+ : SNACKBAR_MESSAGES.cancel, defaultMessage: updatedCourse.join_status === SCCourseJoinStatusType.REQUESTED
142
+ ? SNACKBAR_MESSAGES.request
143
+ : updatedCourse.join_status === SCCourseJoinStatusType.JOINED
144
+ ? SNACKBAR_MESSAGES.enroll
145
+ : SNACKBAR_MESSAGES.cancel }), {
134
146
  variant: 'success',
135
147
  autoHideDuration: 3000
136
148
  });
@@ -91,7 +91,6 @@ export interface CoursesProps {
91
91
  |itemPlaceholder|.SCCourses-item-placeholder|Styles applied to the placeholder for an item.|
92
92
  |noResults|.SCCourses-no-results|Styles applied when there are no results.|
93
93
  |search|.SCCourses-search|Styles applied to the search element.|
94
- |showMore|.SCCourses-show-more|Styles applied to the show more button or section.|
95
94
  |studentEmptyView|.SCCourses-student-empty-view|Styles applied to the student empty view.|
96
95
  |teacherEmptyView|.SCCourses-teacher-empty-view|Styles applied to the teacher empty view.|
97
96
 
@@ -11,12 +11,14 @@ import { FormattedMessage } from 'react-intl';
11
11
  import { SCOPE_SC_UI } from '../../constants/Errors';
12
12
  import { DEFAULT_PAGINATION_OFFSET } from '../../constants/Pagination';
13
13
  import { SCCourseEventType, SCTopicType } from '../../constants/PubSub';
14
- import Course from '../Course';
14
+ import Course, { CourseSkeleton } from '../Course';
15
15
  import Skeleton from '../Courses/Skeleton';
16
16
  import { PREFIX } from './constants';
17
17
  import { SCCourseTemplateType } from '../../types/course';
18
18
  import CategoryAutocomplete from '../CategoryAutocomplete';
19
19
  import CourseCreatePlaceholder from '../Course/CreatePlaceholder';
20
+ import InfiniteScroll from '../../shared/InfiniteScroll';
21
+ import HiddenPlaceholder from '../../shared/HiddenPlaceholder';
20
22
  const classes = {
21
23
  root: `${PREFIX}-root`,
22
24
  category: `${PREFIX}-category`,
@@ -29,9 +31,9 @@ const classes = {
29
31
  itemPlaceholder: `${PREFIX}-item-placeholder`,
30
32
  noResults: `${PREFIX}-no-results`,
31
33
  search: `${PREFIX}-search`,
32
- showMore: `${PREFIX}-show-more`,
33
34
  studentEmptyView: `${PREFIX}-student-empty-view`,
34
- teacherEmptyView: `${PREFIX}-teacher-empty-view`
35
+ teacherEmptyView: `${PREFIX}-teacher-empty-view`,
36
+ endMessage: `${PREFIX}-end-message`
35
37
  };
36
38
  const Root = styled(Box, {
37
39
  name: PREFIX,
@@ -71,7 +73,6 @@ export const CoursesChipRoot = styled(Chip, {
71
73
  |itemPlaceholder|.SCCourses-item-placeholder|Styles applied to the placeholder for an item.|
72
74
  |noResults|.SCCourses-no-results|Styles applied when there are no results.|
73
75
  |search|.SCCourses-search|Styles applied to the search element.|
74
- |showMore|.SCCourses-show-more|Styles applied to the show more button or section.|
75
76
  |studentEmptyView|.SCCourses-student-empty-view|Styles applied to the student empty view.|
76
77
  |teacherEmptyView|.SCCourses-teacher-empty-view|Styles applied to the teacher empty view.|
77
78
 
@@ -127,7 +128,6 @@ export default function Courses(inProps) {
127
128
  * Fetches courses list
128
129
  */
129
130
  const fetchCourses = () => {
130
- setLoading(true);
131
131
  return http
132
132
  .request({
133
133
  url: endpoint.url({}),
@@ -183,7 +183,7 @@ export default function Courses(inProps) {
183
183
  return http
184
184
  .request({
185
185
  url: next,
186
- method: showMyCourses ? Endpoints.GetJoinedCourses.method : Endpoints.SearchCourses.method
186
+ method: showMyCourses ? Endpoints.GetJoinedCourses.method : showForMe ? Endpoints.CourseSuggestion : Endpoints.SearchCourses.method
187
187
  })
188
188
  .then((res) => {
189
189
  setCourses([...courses, ...res.data.results]);
@@ -207,6 +207,9 @@ export default function Courses(inProps) {
207
207
  const categoriesIds = categories.map((item) => item.id);
208
208
  setCategories(categoriesIds);
209
209
  };
210
+ const handleScrollUp = () => {
211
+ window.scrollTo({ left: 0, top: 0, behavior: 'smooth' });
212
+ };
210
213
  /**
211
214
  * Renders courses list
212
215
  */
@@ -221,12 +224,19 @@ export default function Courses(inProps) {
221
224
  // @ts-expect-error this is needed to use showForMe into SCCourses
222
225
  showForMe: showMyCourses, deleteIcon: showMyCourses ? _jsx(Icon, { children: "close" }) : null, onDelete: showMyCourses ? () => setShowMyCourses(false) : null, disabled: loading || showForMe }) }))), _jsx(Grid, Object.assign({ item: true, xs: 12, md: "auto" }, { children: _jsx(FormControl, Object.assign({ fullWidth: true }, { children: _jsx(CategoryAutocomplete, { onChange: handleOnChangeCategory, className: classes.category, size: "small", multiple: true }) })) })), authUserId && (_jsx(Grid, Object.assign({ item: true }, { children: _jsx(CoursesChipRoot, { color: showForMe ? 'primary' : 'default', variant: showForMe ? 'filled' : 'outlined', label: _jsx(FormattedMessage, { id: "ui.courses.filterByCoursesForMe", defaultMessage: "ui.courses.filterByCoursesForMe" }), onClick: handleChipClick,
223
226
  // @ts-expect-error this is needed to use showForMe into SCCourses
224
- showForMe: showForMe, deleteIcon: showForMe ? _jsx(Icon, { children: "close" }) : null, onDelete: showForMe ? handleDeleteClick : null, disabled: loading || showMyCourses }) })))] })) }))), _jsx(_Fragment, { children: loading ? (_jsx(Skeleton, Object.assign({}, CoursesSkeletonComponentProps, { CourseSkeletonProps: CourseSkeletonComponentProps }))) : (_jsx(_Fragment, { children: !courses.length ? (_jsx(Box, Object.assign({ className: classes.noResults }, { children: !canCreateCourse && onlyStaffEnabled ? (_jsxs(Stack, Object.assign({ className: classes.studentEmptyView }, { children: [_jsx(Stack, Object.assign({ className: classes.emptyBox }, { children: _jsx(Stack, Object.assign({ className: classes.emptyRotatedBox }, { children: _jsx(Icon, Object.assign({ className: classes.emptyIcon, color: "disabled", fontSize: "large" }, { children: "courses" })) })) })), _jsx(Typography, Object.assign({ variant: "h5", textAlign: "center" }, { children: _jsx(FormattedMessage, { id: "ui.courses.empty.title", defaultMessage: "ui.courses.empty.title" }) })), _jsx(Typography, Object.assign({ variant: "body1", textAlign: "center" }, { children: _jsx(FormattedMessage, { id: "ui.courses.empty.info", defaultMessage: "ui.courses.empty.info" }) })), !isMobile && (_jsx(Skeleton, Object.assign({ coursesNumber: 4 }, CoursesSkeletonComponentProps, { CourseSkeletonProps: CourseSkeletonComponentProps })))] }))) : (_jsx(Box, Object.assign({ className: classes.teacherEmptyView }, { children: _jsx(Skeleton, Object.assign({ teacherView: (onlyStaffEnabled && canCreateCourse) || !onlyStaffEnabled, coursesNumber: 1 }, CoursesSkeletonComponentProps, { CourseSkeletonProps: CourseSkeletonComponentProps })) }))) }))) : (_jsxs(_Fragment, { children: [_jsx(Grid, Object.assign({ container: true, spacing: { xs: 2 }, className: classes.courses }, GridContainerComponentProps, { children: _jsxs(_Fragment, { children: [courses.map((course) => (_jsx(Grid, Object.assign({ item: true, xs: 12, sm: 12, md: 6, lg: 3, className: classes.item }, GridItemComponentProps, { children: _jsx(Course, Object.assign({ courseId: course.id }, CourseComponentProps)) }), course.id))), authUserId && courses.length % 2 !== 0 && (_jsx(Grid, Object.assign({ item: true, xs: 12, sm: 12, md: 6, lg: 3, className: classes.itemPlaceholder }, GridItemComponentProps, { children: _jsx(CourseCreatePlaceholder, { CreateCourseButtonComponentProps: CreateCourseButtonComponentProps }) }), "placeholder-item"))] }) })), Boolean(next) && (_jsx(Button, Object.assign({ color: "secondary", variant: "text", onClick: handleNext, className: classes.showMore }, { children: _jsx(FormattedMessage, { id: "ui.courses.button.seeMore", defaultMessage: "ui.courses.button.seeMore" }) })))] })) })) })] }));
227
+ showForMe: showForMe, deleteIcon: showForMe ? _jsx(Icon, { children: "close" }) : null, onDelete: showForMe ? handleDeleteClick : null, disabled: loading || showMyCourses }) })))] })) }))), _jsx(_Fragment, { children: !courses.length ? (_jsx(Box, Object.assign({ className: classes.noResults }, { children: !canCreateCourse && onlyStaffEnabled ? (_jsxs(Stack, Object.assign({ className: classes.studentEmptyView }, { children: [_jsx(Stack, Object.assign({ className: classes.emptyBox }, { children: _jsx(Stack, Object.assign({ className: classes.emptyRotatedBox }, { children: _jsx(Icon, Object.assign({ className: classes.emptyIcon, color: "disabled", fontSize: "large" }, { children: "courses" })) })) })), _jsx(Typography, Object.assign({ variant: "h5", textAlign: "center" }, { children: _jsx(FormattedMessage, { id: "ui.courses.empty.title", defaultMessage: "ui.courses.empty.title" }) })), _jsx(Typography, Object.assign({ variant: "body1", textAlign: "center" }, { children: _jsx(FormattedMessage, { id: "ui.courses.empty.info", defaultMessage: "ui.courses.empty.info" }) })), !isMobile && _jsx(Skeleton, Object.assign({ coursesNumber: 4 }, CoursesSkeletonComponentProps, { CourseSkeletonProps: CourseSkeletonComponentProps }))] }))) : (_jsx(Box, Object.assign({ className: classes.teacherEmptyView }, { children: _jsx(Skeleton, Object.assign({ teacherView: (onlyStaffEnabled && canCreateCourse) || !onlyStaffEnabled, coursesNumber: 1 }, CoursesSkeletonComponentProps, { CourseSkeletonProps: CourseSkeletonComponentProps })) }))) }))) : (_jsx(InfiniteScroll, Object.assign({ dataLength: courses.length, next: handleNext, hasMoreNext: Boolean(next), loaderNext: isMobile ? (_jsx(CourseSkeleton, { template: SCCourseTemplateType.PREVIEW })) : (_jsx(Skeleton, Object.assign({ coursesNumber: 4 }, CoursesSkeletonComponentProps, { CourseSkeletonProps: CourseSkeletonComponentProps }))), endMessage: _jsx(Typography, Object.assign({ component: "div", className: classes.endMessage }, { children: _jsx(FormattedMessage, { id: "ui.courses.endMessage", defaultMessage: "ui.courses.endMessage", values: {
228
+ // eslint-disable-next-line @typescript-eslint/ban-ts-ignore
229
+ // @ts-ignore
230
+ button: (chunk) => (_jsx(Button, Object.assign({ color: "secondary", variant: "text", onClick: handleScrollUp }, { children: chunk })))
231
+ } }) })) }, { children: _jsx(Grid, Object.assign({ container: true, spacing: { xs: 2 }, className: classes.courses }, GridContainerComponentProps, { children: _jsxs(_Fragment, { children: [courses.map((course) => (_jsx(Grid, Object.assign({ item: true, xs: 12, sm: 12, md: 6, lg: 3, className: classes.item }, GridItemComponentProps, { children: _jsx(Course, Object.assign({ courseId: course.id }, CourseComponentProps)) }), course.id))), authUserId && courses.length % 2 !== 0 && (_jsx(Grid, Object.assign({ item: true, xs: 12, sm: 12, md: 6, lg: 3, className: classes.itemPlaceholder }, GridItemComponentProps, { children: _jsx(CourseCreatePlaceholder, { CreateCourseButtonComponentProps: CreateCourseButtonComponentProps }) }), "placeholder-item"))] }) })) }))) })] }));
225
232
  /**
226
233
  * Renders root object (if content availability community option is false and user is anonymous, component is hidden)
227
234
  */
228
235
  if (!contentAvailability && !scUserContext.user) {
229
- return null;
236
+ return _jsx(HiddenPlaceholder, {});
237
+ }
238
+ if (loading) {
239
+ return _jsx(Skeleton, Object.assign({}, CoursesSkeletonComponentProps, { CourseSkeletonProps: CourseSkeletonComponentProps }));
230
240
  }
231
241
  return (_jsx(Root, Object.assign({ className: classNames(classes.root, className) }, rest, { children: c })));
232
242
  }
@@ -13,8 +13,8 @@ import { useSnackbar } from 'notistack';
13
13
  import { Link, SCRoutes, useSCRouting } from '@selfcommunity/react-core';
14
14
  import { SCOPE_SC_UI } from '../../../constants/Errors';
15
15
  import { ActionLessonType } from '../types';
16
- import { useDisabled } from '../hooks';
17
16
  import ConfirmDialog from '../../../shared/ConfirmDialog/ConfirmDialog';
17
+ import { useIsDisabled } from '../hooks';
18
18
  const classes = {
19
19
  cellWidth: `${PREFIX}-cell-width`,
20
20
  cellAlignRight: `${PREFIX}-cell-align-right`,
@@ -39,7 +39,7 @@ function LessonRow(props) {
39
39
  // CONTEXTS
40
40
  const scRoutingContext = useSCRouting();
41
41
  // HOOKS
42
- const { isDisabled } = useDisabled();
42
+ const { isDisabled } = useIsDisabled();
43
43
  const { enqueueSnackbar } = useSnackbar();
44
44
  // HANDLERS
45
45
  const handleAbleEditMode = useCallback(() => setTimeout(() => setEditMode(true)), [setEditMode]);
@@ -1,7 +1,7 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { DragDropContext, Draggable, Droppable } from '@hello-pangea/dnd';
3
3
  import { Fragment, memo, useCallback, useEffect, useMemo, useState } from 'react';
4
- import { Collapse, Icon, IconButton, MenuItem, Skeleton, Stack, Table, TableBody, TableCell, TableRow, Typography } from '@mui/material';
4
+ import { Collapse, Icon, IconButton, MenuItem, Stack, Table, TableBody, TableCell, TableRow, Typography } from '@mui/material';
5
5
  import classNames from 'classnames';
6
6
  import { PREFIX } from '../constants';
7
7
  import LessonRow from './LessonRow';
@@ -16,7 +16,7 @@ import LessonReleaseMenu from '../../LessonReleaseMenu';
16
16
  import { SCCourseLessonTypologyType } from '@selfcommunity/types';
17
17
  import { CourseService, Endpoints } from '@selfcommunity/api-services';
18
18
  import { ActionLessonType } from '../types';
19
- import { useDisabled } from '../hooks';
19
+ import { useIsDisabled } from '../hooks';
20
20
  import ConfirmDialog from '../../../shared/ConfirmDialog/ConfirmDialog';
21
21
  const classes = {
22
22
  tableBodyIconWrapper: `${PREFIX}-table-body-icon-wrapper`,
@@ -37,7 +37,7 @@ function SectionRow(props) {
37
37
  const [editMode, setEditMode] = useState(false);
38
38
  const [lessons, setLessons] = useState([]);
39
39
  // HOOKS
40
- const { isDisabled } = useDisabled();
40
+ const { isDisabled } = useIsDisabled();
41
41
  const intl = useIntl();
42
42
  const { enqueueSnackbar } = useSnackbar();
43
43
  // EFFECTS
@@ -141,6 +141,6 @@ function SectionRow(props) {
141
141
  ? Endpoints.CreateCourseSection.url({ id: course.id })
142
142
  : Endpoints.PatchCourseSection.url({ id: course.id, section_id: section.id }),
143
143
  method: isNewRow ? Endpoints.CreateCourseSection.method : Endpoints.PatchCourseSection.method
144
- }, row: section, isNewRow: isNewRow, handleManageRow: handleManageSection, editMode: editMode, handleDisableEditMode: handleDisableEditMode }) }), _jsx(TableCell, Object.assign({ className: classes.cellAlignCenter }, { children: isDisabled ? (_jsx(Skeleton, { animation: false, variant: "rectangular", width: "250px", height: "38px", sx: { margin: 'auto', borderRadius: '5px' } })) : (_jsx(LessonReleaseMenu, { course: course, section: section })) })), _jsx(TableCell, Object.assign({ className: classes.cellAlignRight }, { children: _jsxs(Stack, Object.assign({ className: classes.actionsWrapper }, { children: [_jsx(AddButton, { label: "ui.editCourse.tab.lessons.table.lesson", handleAddRow: handleAddTempLesson, color: "primary", variant: "outlined", disabled: isDisabled }), _jsxs(MenuRow, Object.assign({ disabled: isDisabled }, { children: [_jsx(MenuItem, Object.assign({ onClick: handleAbleEditMode }, { children: _jsx(Typography, Object.assign({ variant: "body1" }, { children: _jsx(FormattedMessage, { id: "ui.editCourse.tab.lessons.table.menu.rename", defaultMessage: "ui.editCourse.tab.lessons.table.menu.rename" }) })) })), _jsx(MenuItem, Object.assign({ onClick: handleOpenDialog }, { children: _jsx(Typography, Object.assign({ variant: "body1" }, { children: _jsx(FormattedMessage, { id: "ui.editCourse.tab.lessons.table.menu.delete", defaultMessage: "ui.editCourse.tab.lessons.table.menu.delete" }) })) }))] }))] })) }))] })), _jsx(TableRow, { children: _jsxs(TableCell, Object.assign({ className: classes.tableBodyCollapseWrapper, colSpan: 4 }, { children: [_jsx(Collapse, Object.assign({ in: expand, timeout: "auto", unmountOnExit: true }, { children: _jsx(DragDropContext, Object.assign({ onDragEnd: handleDragEnd }, { children: _jsx(Table, { children: _jsx(Droppable, Object.assign({ droppableId: "droppable-2" }, { children: (outerProvider) => (_jsxs(TableBody, Object.assign({ ref: outerProvider.innerRef }, outerProvider.droppableProps, { children: [lessons.map((lesson, i, array) => (_jsx(Draggable, Object.assign({ draggableId: i.toString(), index: i, isDragDisabled: isDisabled }, { children: (innerProvider) => (_jsx(LessonRow, { provider: innerProvider, course: course, section: section, lesson: lesson, isNewRow: isNewLocalRow && i + 1 === array.length, handleManageLesson: handleManageLesson }, i)) }), i))), outerProvider.placeholder] }))) })) }) })) })), open && _jsx(ConfirmDialog, { open: true, onClose: handleOpenDialog, onConfirm: handleDeleteSection })] })) })] }));
144
+ }, row: section, isNewRow: isNewRow, handleManageRow: handleManageSection, editMode: editMode, handleDisableEditMode: handleDisableEditMode }) }), _jsx(TableCell, Object.assign({ className: classes.cellAlignCenter }, { children: _jsx(LessonReleaseMenu, { course: course, section: section }) })), _jsx(TableCell, Object.assign({ className: classes.cellAlignRight }, { children: _jsxs(Stack, Object.assign({ className: classes.actionsWrapper }, { children: [_jsx(AddButton, { label: "ui.editCourse.tab.lessons.table.lesson", handleAddRow: handleAddTempLesson, color: "primary", variant: "outlined", disabled: isDisabled }), _jsxs(MenuRow, Object.assign({ disabled: isDisabled }, { children: [_jsx(MenuItem, Object.assign({ onClick: handleAbleEditMode }, { children: _jsx(Typography, Object.assign({ variant: "body1" }, { children: _jsx(FormattedMessage, { id: "ui.editCourse.tab.lessons.table.menu.rename", defaultMessage: "ui.editCourse.tab.lessons.table.menu.rename" }) })) })), _jsx(MenuItem, Object.assign({ onClick: handleOpenDialog }, { children: _jsx(Typography, Object.assign({ variant: "body1" }, { children: _jsx(FormattedMessage, { id: "ui.editCourse.tab.lessons.table.menu.delete", defaultMessage: "ui.editCourse.tab.lessons.table.menu.delete" }) })) }))] }))] })) }))] })), _jsx(TableRow, { children: _jsxs(TableCell, Object.assign({ className: classes.tableBodyCollapseWrapper, colSpan: 4 }, { children: [_jsx(Collapse, Object.assign({ in: expand, timeout: "auto", unmountOnExit: true }, { children: _jsx(DragDropContext, Object.assign({ onDragEnd: handleDragEnd }, { children: _jsx(Table, { children: _jsx(Droppable, Object.assign({ droppableId: "droppable-2" }, { children: (outerProvider) => (_jsxs(TableBody, Object.assign({ ref: outerProvider.innerRef }, outerProvider.droppableProps, { children: [lessons.map((lesson, i, array) => (_jsx(Draggable, Object.assign({ draggableId: i.toString(), index: i, isDragDisabled: isDisabled }, { children: (innerProvider) => (_jsx(LessonRow, { provider: innerProvider, course: course, section: section, lesson: lesson, isNewRow: isNewLocalRow && i + 1 === array.length, handleManageLesson: handleManageLesson }, i)) }), i))), outerProvider.placeholder] }))) })) }) })) })), open && _jsx(ConfirmDialog, { open: true, onClose: handleOpenDialog, onConfirm: handleDeleteSection })] })) })] }));
145
145
  }
146
146
  export default memo(SectionRow);
@@ -13,7 +13,7 @@ import EmptyStatus from '../../shared/EmptyStatus';
13
13
  import AddButton from './Lessons/AddButton';
14
14
  import SectionRow from './Lessons/SectionRow';
15
15
  import { ActionLessonType } from './types';
16
- import { useDisabled } from './hooks';
16
+ import { useIsDisabled } from './hooks';
17
17
  import classNames from 'classnames';
18
18
  const classes = {
19
19
  lessonTitle: `${PREFIX}-lesson-title`,
@@ -55,7 +55,7 @@ function Lessons(props) {
55
55
  // STATES
56
56
  const [sections, setSections] = useState([]);
57
57
  // HOOKS
58
- const { isDisabled } = useDisabled();
58
+ const { isDisabled } = useIsDisabled();
59
59
  const { enqueueSnackbar } = useSnackbar();
60
60
  const intl = useIntl();
61
61
  // EFFECTS
@@ -1,3 +1,3 @@
1
- export declare const useDisabled: () => {
1
+ export declare const useIsDisabled: () => {
2
2
  isDisabled: boolean;
3
3
  };
@@ -1,7 +1,7 @@
1
1
  import { useEffect, useRef, useState } from 'react';
2
2
  import PubSub from 'pubsub-js';
3
3
  import { SCGroupEventType, SCTopicType } from '../../constants/PubSub';
4
- export const useDisabled = () => {
4
+ export const useIsDisabled = () => {
5
5
  // STATES
6
6
  const [isDisabled, setIsDisabled] = useState(false);
7
7
  // REFS
@@ -17,6 +17,7 @@ import { CourseService } from '@selfcommunity/api-services';
17
17
  import { SCOPE_SC_UI } from '../../constants/Errors';
18
18
  import { Logger } from '@selfcommunity/utils';
19
19
  import { getDripDelayAndUnit } from '../../utils/course';
20
+ import { useIsDisabled } from '../EditCourse/hooks';
20
21
  const messages = defineMessages({
21
22
  pickerPlaceholder: {
22
23
  id: 'ui.lessonReleaseMenu.scheduled.picker.placeholder',
@@ -47,13 +48,13 @@ const classes = {
47
48
  const Root = styled(FormControl, {
48
49
  name: PREFIX,
49
50
  slot: 'Root',
50
- overridesResolver: (props, styles) => [styles.root]
51
+ overridesResolver: (_props, styles) => [styles.root]
51
52
  })(() => ({}));
52
53
  const PopoverRoot = styled(Popover, {
53
54
  name: PREFIX,
54
55
  slot: 'PopoverRoot',
55
- overridesResolver: (props, styles) => styles.popoverRoot
56
- })(({ theme }) => ({}));
56
+ overridesResolver: (_props, styles) => styles.popoverRoot
57
+ })(() => ({}));
57
58
  export default function LessonReleaseMenu(inProps) {
58
59
  // PROPS
59
60
  const props = useThemeProps({
@@ -70,6 +71,8 @@ export default function LessonReleaseMenu(inProps) {
70
71
  const [unit, setUnit] = useState(_unit);
71
72
  const [anchorEl, setAnchorEl] = useState(null);
72
73
  const [open, setOpen] = useState(false);
74
+ // HOOKS
75
+ const { isDisabled } = useIsDisabled();
73
76
  //INTL
74
77
  const intl = useIntl();
75
78
  const handleUnitChange = (e) => {
@@ -123,7 +126,7 @@ export default function LessonReleaseMenu(inProps) {
123
126
  } }, { children: _jsx(MobileDateTimePicker, { className: classes.picker, disablePast: true, label: drippedAt && (_jsx(FormattedMessage, { id: "ui.lessonReleaseMenu.scheduled.picker.placeholder", defaultMessage: "ui.lessonReleaseMenu.scheduled.picker.placeholder" })), defaultValue: drippedAt, slots: {
124
127
  //actionBar: PickerActionBar,
125
128
  tabs: (props) => _jsx(DateTimePickerTabs, Object.assign({}, props)),
126
- textField: (params) => (_jsx(TextField, Object.assign({}, params, { error: false, InputProps: Object.assign(Object.assign({}, params.InputProps), { placeholder: `${intl.formatMessage(messages.pickerPlaceholder)}`, endAdornment: (_jsx(InputAdornment, Object.assign({ position: "end" }, { children: _jsx(IconButton, { children: _jsx(Icon, { children: "expand_more" }) }) }))) }) })))
129
+ textField: (params) => (_jsx(TextField, Object.assign({}, params, { error: false, InputProps: Object.assign(Object.assign({}, params.InputProps), { placeholder: `${intl.formatMessage(messages.pickerPlaceholder)}`, endAdornment: (_jsx(InputAdornment, Object.assign({ position: "end" }, { children: _jsx(IconButton, Object.assign({ disabled: isDisabled }, { children: _jsx(Icon, { children: "expand_more" }) })) }))) }) })))
127
130
  }, slotProps: {
128
131
  tabs: {
129
132
  hidden: false
@@ -136,9 +139,9 @@ export default function LessonReleaseMenu(inProps) {
136
139
  actionBar: {
137
140
  actions: ['cancel', 'clear', 'accept']
138
141
  }
139
- }, onChange: (value) => setDrippedAt(value), onAccept: handleUpdate, onClear: () => setDrippedAt(null) }) }))) : (_jsxs(_Fragment, { children: [_jsx(TextField, { size: "small", placeholder: placeholderStructured, defaultValue: null, onClick: handleClick, InputProps: {
140
- endAdornment: (_jsx(InputAdornment, Object.assign({ position: "end" }, { children: _jsx(IconButton, Object.assign({ onClick: handleClick }, { children: _jsx(Icon, { children: "expand_more" }) })) })))
141
- } }), _jsxs(PopoverRoot, Object.assign({ className: classes.popoverRoot, open: open, anchorEl: anchorEl, onClose: handleClose, anchorOrigin: {
142
+ }, onChange: (value) => setDrippedAt(value), onAccept: handleUpdate, onClear: () => setDrippedAt(null), disabled: isDisabled }) }))) : (_jsxs(_Fragment, { children: [_jsx(TextField, { size: "small", placeholder: placeholderStructured, defaultValue: null, onClick: isDisabled ? undefined : handleClick, InputProps: {
143
+ endAdornment: (_jsx(InputAdornment, Object.assign({ position: "end" }, { children: _jsx(IconButton, Object.assign({ onClick: handleClick, disabled: isDisabled }, { children: _jsx(Icon, { children: "expand_more" }) })) })))
144
+ }, disabled: isDisabled }), _jsxs(PopoverRoot, Object.assign({ className: classes.popoverRoot, open: open, anchorEl: anchorEl, onClose: handleClose, anchorOrigin: {
142
145
  vertical: 'bottom',
143
146
  horizontal: 'left'
144
147
  }, transformOrigin: {