@selfcommunity/react-ui 0.10.2-courses.105 → 0.10.2-courses.106
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/cjs/components/Course/CreatePlaceholder.d.ts +6 -0
- package/lib/cjs/components/Course/CreatePlaceholder.js +2 -2
- package/lib/cjs/components/CourseDashboard/Header.js +3 -1
- package/lib/cjs/components/CourseDashboard/Student.js +3 -2
- package/lib/cjs/components/CourseDashboard/Teacher.d.ts +0 -3
- package/lib/cjs/components/CourseDashboard/Teacher.js +2 -3
- package/lib/cjs/components/CourseDashboard/types.d.ts +0 -19
- package/lib/cjs/components/Courses/Courses.d.ts +6 -0
- package/lib/cjs/components/Courses/Courses.js +2 -2
- package/lib/cjs/shared/AccordionLessons/AccordionLessons.js +3 -3
- package/lib/esm/components/Course/CreatePlaceholder.d.ts +6 -0
- package/lib/esm/components/Course/CreatePlaceholder.js +2 -2
- package/lib/esm/components/CourseDashboard/Header.js +3 -1
- package/lib/esm/components/CourseDashboard/Student.js +3 -2
- package/lib/esm/components/CourseDashboard/Teacher.d.ts +0 -3
- package/lib/esm/components/CourseDashboard/Teacher.js +2 -3
- package/lib/esm/components/CourseDashboard/types.d.ts +0 -19
- package/lib/esm/components/Courses/Courses.d.ts +6 -0
- package/lib/esm/components/Courses/Courses.js +2 -2
- package/lib/esm/shared/AccordionLessons/AccordionLessons.js +4 -4
- package/lib/umd/react-ui.js +1 -1
- package/package.json +8 -8
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import { WidgetProps } from '../Widget';
|
|
2
|
+
import { CreateCourseButtonProps } from '../CreateCourseButton';
|
|
2
3
|
export interface CourseSkeletonProps extends WidgetProps {
|
|
4
|
+
/**
|
|
5
|
+
* Props to spread to CreateCourseButton component
|
|
6
|
+
* @default {}
|
|
7
|
+
*/
|
|
8
|
+
CreateCourseButtonComponentProps?: CreateCourseButtonProps;
|
|
3
9
|
/**
|
|
4
10
|
* Overrides or extends the styles applied to the component.
|
|
5
11
|
* @default null
|
|
@@ -51,9 +51,9 @@ function CourseCreatePlaceholder(inProps) {
|
|
|
51
51
|
props: inProps,
|
|
52
52
|
name: constants_1.PREFIX
|
|
53
53
|
});
|
|
54
|
-
const { className } = props, rest = tslib_1.__rest(props, ["className"]);
|
|
54
|
+
const { CreateCourseButtonComponentProps = {}, className } = props, rest = tslib_1.__rest(props, ["CreateCourseButtonComponentProps", "className"]);
|
|
55
55
|
// HOOK
|
|
56
56
|
const { preferences } = (0, react_core_1.useSCPreferences)();
|
|
57
|
-
return ((0, jsx_runtime_1.jsxs)(Root, Object.assign({ className: (0, classnames_1.default)(classes.root, className) }, rest, { children: [(0, jsx_runtime_1.jsxs)(material_1.Box, Object.assign({ position: "relative", className: classes.imageWrapper }, { children: [(0, jsx_runtime_1.jsx)(material_1.CardMedia, { component: "img", image: `${preferences[react_core_1.SCPreferences.IMAGES_USER_DEFAULT_COVER].value}`, alt: "placeholder image", className: classes.image }), (0, jsx_runtime_1.jsx)(material_1.Icon, Object.assign({ className: classes.icon, fontSize: "large" }, { children: "courses" }))] })), (0, jsx_runtime_1.jsx)(material_1.CardActions, Object.assign({ className: classes.actions }, { children: (0, jsx_runtime_1.jsx)(CreateCourseButton_1.default, {}) }))] })));
|
|
57
|
+
return ((0, jsx_runtime_1.jsxs)(Root, Object.assign({ className: (0, classnames_1.default)(classes.root, className) }, rest, { children: [(0, jsx_runtime_1.jsxs)(material_1.Box, Object.assign({ position: "relative", className: classes.imageWrapper }, { children: [(0, jsx_runtime_1.jsx)(material_1.CardMedia, { component: "img", image: `${preferences[react_core_1.SCPreferences.IMAGES_USER_DEFAULT_COVER].value}`, alt: "placeholder image", className: classes.image }), (0, jsx_runtime_1.jsx)(material_1.Icon, Object.assign({ className: classes.icon, fontSize: "large" }, { children: "courses" }))] })), (0, jsx_runtime_1.jsx)(material_1.CardActions, Object.assign({ className: classes.actions }, { children: (0, jsx_runtime_1.jsx)(CreateCourseButton_1.default, Object.assign({}, CreateCourseButtonComponentProps)) }))] })));
|
|
58
58
|
}
|
|
59
59
|
exports.default = CourseCreatePlaceholder;
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
4
4
|
const material_1 = require("@mui/material");
|
|
5
|
+
const types_1 = require("@selfcommunity/types");
|
|
5
6
|
const react_intl_1 = require("react-intl");
|
|
6
7
|
const constants_1 = require("./constants");
|
|
7
8
|
const react_1 = require("react");
|
|
@@ -30,12 +31,13 @@ function HeaderCourseDashboard(props) {
|
|
|
30
31
|
}
|
|
31
32
|
}, [course, hasAction]);
|
|
32
33
|
const iconData = (0, react_1.useMemo)(() => {
|
|
34
|
+
const underId = (course === null || course === void 0 ? void 0 : course.privacy) === types_1.SCCoursePrivacyType.DRAFT ? 'draft' : course === null || course === void 0 ? void 0 : course.privacy;
|
|
33
35
|
return [
|
|
34
36
|
{
|
|
35
37
|
id: 'ui.course.label',
|
|
36
38
|
icon: 'public',
|
|
37
39
|
key: 'privacy',
|
|
38
|
-
underId: `ui.course.privacy.${
|
|
40
|
+
underId: `ui.course.privacy.${underId}`
|
|
39
41
|
},
|
|
40
42
|
{
|
|
41
43
|
id: 'ui.course.type',
|
|
@@ -28,6 +28,7 @@ const classes = {
|
|
|
28
28
|
root: `${constants_1.PREFIX}-root`,
|
|
29
29
|
studentContainer: `${constants_1.PREFIX}-student-container`,
|
|
30
30
|
userWrapper: `${constants_1.PREFIX}-user-wrapper`,
|
|
31
|
+
actionsWrapper: `${constants_1.PREFIX}-actions-wrapper`,
|
|
31
32
|
user: `${constants_1.PREFIX}-user`,
|
|
32
33
|
avatar: `${constants_1.PREFIX}-avatar`,
|
|
33
34
|
progress: `${constants_1.PREFIX}-progress`,
|
|
@@ -112,12 +113,12 @@ function Student(inProps) {
|
|
|
112
113
|
if (!scCourse) {
|
|
113
114
|
return (0, jsx_runtime_1.jsx)(material_1.Skeleton, { animation: "wave", variant: "rounded", width: "160px", height: "28px" });
|
|
114
115
|
}
|
|
115
|
-
return ((0, jsx_runtime_1.jsxs)(material_1.Stack, Object.assign({
|
|
116
|
+
return ((0, jsx_runtime_1.jsxs)(material_1.Stack, Object.assign({ className: classes.actionsWrapper }, { children: [((scCourse === null || scCourse === void 0 ? void 0 : scCourse.join_status) === types_1.SCCourseJoinStatusType.CREATOR || (scCourse === null || scCourse === void 0 ? void 0 : scCourse.join_status) === types_1.SCCourseJoinStatusType.MANAGER) && ((0, jsx_runtime_1.jsx)(ActionButton_1.default, { labelId: messages.dashboard, to: scRoutingContext.url(react_core_1.SCRoutes.COURSE_DASHBOARD_ROUTE_NAME, scCourse), color: "inherit", variant: "outlined" })), ((scCourse === null || scCourse === void 0 ? void 0 : scCourse.join_status) === types_1.SCCourseJoinStatusType.MANAGER || (scCourse === null || scCourse === void 0 ? void 0 : scCourse.join_status) === types_1.SCCourseJoinStatusType.JOINED) &&
|
|
116
117
|
((scCourse === null || scCourse === void 0 ? void 0 : scCourse.join_status) !== null || scCourse.privacy !== types_1.SCCoursePrivacyType.PRIVATE) &&
|
|
117
118
|
scCourse.user_completion_rate < 100 && ((0, jsx_runtime_1.jsx)(ActionButton_1.default, { labelId: scCourse.num_lessons_completed === 0 ? messages.start : messages.continue, to: scRoutingContext.url(react_core_1.SCRoutes.COURSE_LESSON_ROUTE_NAME, getUrlNextLesson(scCourse)) })), scCourse.privacy === types_1.SCCoursePrivacyType.PRIVATE &&
|
|
118
119
|
(scCourse.join_status === null || scCourse.join_status === types_1.SCCourseJoinStatusType.REQUESTED) && ((0, jsx_runtime_1.jsx)(ActionButton_1.default, { labelId: sentRequest ? messages.cancel : messages.request, color: "inherit", variant: "outlined", loading: loadingRequest, onClick: handleRequest }))] })));
|
|
119
120
|
}, [scCourse, sentRequest, loadingRequest, handleRequest]);
|
|
120
|
-
return ((0, jsx_runtime_1.jsxs)(Root, Object.assign({ className: (0, classnames_1.default)(classes.root, classes.studentContainer, className) }, rest, { children: [(0, jsx_runtime_1.jsx)(Header_1.default, { course: scCourse }), (0, jsx_runtime_1.jsx)(material_1.Divider, {}), (0, jsx_runtime_1.jsxs)(material_1.Stack, Object.assign({ className: classes.userWrapper }, { children: [(0, jsx_runtime_1.jsxs)(material_1.Stack, Object.assign({ className: classes.user }, { children: [scCourse ? ((0, jsx_runtime_1.jsx)(material_1.Avatar, { className: classes.avatar, src: scCourse.created_by.avatar, alt: scCourse.created_by.username })) : ((0, jsx_runtime_1.jsx)(material_1.Skeleton, { animation: "wave", variant: "circular", className: classes.avatar })), (0, jsx_runtime_1.jsx)(material_1.Box, { children: scCourse ? ((0, jsx_runtime_1.jsxs)(react_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "body1" }, { children: scCourse.created_by.username })), (0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "body1" }, { children:
|
|
121
|
+
return ((0, jsx_runtime_1.jsxs)(Root, Object.assign({ className: (0, classnames_1.default)(classes.root, classes.studentContainer, className) }, rest, { children: [(0, jsx_runtime_1.jsx)(Header_1.default, { course: scCourse }), (0, jsx_runtime_1.jsx)(material_1.Divider, {}), (0, jsx_runtime_1.jsxs)(material_1.Stack, Object.assign({ className: classes.userWrapper }, { children: [(0, jsx_runtime_1.jsxs)(material_1.Stack, Object.assign({ className: classes.user }, { children: [scCourse ? ((0, jsx_runtime_1.jsx)(material_1.Avatar, { className: classes.avatar, src: scCourse.created_by.avatar, alt: scCourse.created_by.username })) : ((0, jsx_runtime_1.jsx)(material_1.Skeleton, { animation: "wave", variant: "circular", className: classes.avatar })), (0, jsx_runtime_1.jsx)(material_1.Box, { children: scCourse ? ((0, jsx_runtime_1.jsxs)(react_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "body1" }, { children: scCourse.created_by.username })), (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.header.user.creator", defaultMessage: "ui.course.dashboard.header.user.creator" }) }))] })) : ((0, jsx_runtime_1.jsxs)(react_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(material_1.Skeleton, { animation: "wave", variant: "text", width: "105px", height: "21px" }), (0, jsx_runtime_1.jsx)(material_1.Skeleton, { animation: "wave", variant: "text", width: "74px", height: "21px" })] })) })] })), actionButton] })), (0, jsx_runtime_1.jsx)(material_1.Divider, {}), ((scCourse === null || scCourse === void 0 ? void 0 : scCourse.join_status) === types_1.SCCourseJoinStatusType.CREATOR ||
|
|
121
122
|
(scCourse === null || scCourse === void 0 ? void 0 : scCourse.join_status) === types_1.SCCourseJoinStatusType.MANAGER ||
|
|
122
123
|
(scCourse === null || scCourse === void 0 ? void 0 : scCourse.join_status) === types_1.SCCourseJoinStatusType.JOINED ||
|
|
123
124
|
(scCourse === null || scCourse === void 0 ? void 0 : scCourse.privacy) !== types_1.SCCoursePrivacyType.PRIVATE) && ((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: scCourse ? (0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "body1" }, { children: scCourse.description })) : (0, jsx_runtime_1.jsx)(material_1.Skeleton, { animation: "wave", variant: "text", height: "130px" }) }))] })), ((scCourse === null || scCourse === void 0 ? void 0 : scCourse.join_status) === types_1.SCCourseJoinStatusType.MANAGER || (scCourse === null || scCourse === void 0 ? void 0 : scCourse.join_status) === types_1.SCCourseJoinStatusType.JOINED) && ((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.jsx)(material_1.Stack, Object.assign({ className: classes.percentageWrapper }, { children: scCourse ? ((0, jsx_runtime_1.jsxs)(react_1.Fragment, { 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.jsxs)(react_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(material_1.Skeleton, { animation: "wave", variant: "text", width: "168px", height: "19px" }), (0, jsx_runtime_1.jsx)(material_1.Skeleton, { animation: "wave", variant: "text", width: "108px", height: "19px" })] })) })), (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 === null || scCourse === void 0 ? void 0 : 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: [scCourse ? ((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: {
|
|
@@ -1,11 +1,8 @@
|
|
|
1
1
|
import { HTMLAttributes } from 'react';
|
|
2
|
-
import { CourseDashboardPage } from './types';
|
|
3
2
|
import { SCCourseType } from '@selfcommunity/types';
|
|
4
3
|
export interface TeacherCourseDashboardProps {
|
|
5
4
|
courseId?: number;
|
|
6
5
|
course?: SCCourseType;
|
|
7
|
-
page: CourseDashboardPage;
|
|
8
|
-
onTabChange: (page: CourseDashboardPage) => void;
|
|
9
6
|
className?: HTMLAttributes<HTMLDivElement>['className'];
|
|
10
7
|
[p: string]: any;
|
|
11
8
|
}
|
|
@@ -43,15 +43,14 @@ function Teacher(inProps) {
|
|
|
43
43
|
props: inProps,
|
|
44
44
|
name: constants_1.PREFIX
|
|
45
45
|
});
|
|
46
|
-
const { courseId, course,
|
|
46
|
+
const { courseId, course, className } = props, rest = tslib_1.__rest(props, ["courseId", "course", "className"]);
|
|
47
47
|
// STATES
|
|
48
|
-
const [tabValue, setTabValue] = (0, react_1.useState)(types_1.TabContentEnum
|
|
48
|
+
const [tabValue, setTabValue] = (0, react_1.useState)(types_1.TabContentEnum.STUDENTS);
|
|
49
49
|
// HOOKS
|
|
50
50
|
const { scCourse } = (0, react_core_1.useSCFetchCourse)({ id: courseId, course, params: { view: api_services_1.CourseInfoViewType.DASHBOARD } });
|
|
51
51
|
// HANDLERS
|
|
52
52
|
const handleTabChange = (0, react_1.useCallback)((_evt, newTabValue) => {
|
|
53
53
|
setTabValue(newTabValue);
|
|
54
|
-
onTabChange(types_1.TabContentEnum[newTabValue]);
|
|
55
54
|
}, [setTabValue]);
|
|
56
55
|
return ((0, jsx_runtime_1.jsxs)(Root, Object.assign({ className: (0, classnames_1.default)(classes.root, className) }, rest, { children: [(0, jsx_runtime_1.jsx)(Header_1.default, { course: scCourse, hasAction: true }), (0, jsx_runtime_1.jsxs)(material_1.Stack, Object.assign({ className: classes.infoWrapper }, { children: [(0, jsx_runtime_1.jsx)(Info_1.default, { title: "ui.course.dashboard.teacher.info.students", course: scCourse, position: "first" }), (0, jsx_runtime_1.jsx)(Info_1.default, { title: "ui.course.dashboard.teacher.info.completion", course: scCourse, position: "second" })] })), (0, jsx_runtime_1.jsxs)(lab_1.TabContext, Object.assign({ value: tabValue }, { children: [(0, jsx_runtime_1.jsx)(lab_1.TabList, Object.assign({ className: classes.tabList, onChange: handleTabChange, textColor: "primary", indicatorColor: "primary", variant: "standard", centered: true }, { children: TAB_DATA.map((data, i) => ((0, jsx_runtime_1.jsx)(material_1.Tab, { label: (0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "h6" }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: data.label, defaultMessage: data.label }) })), value: data.value, className: classes.tab }, i))) })), (0, jsx_runtime_1.jsx)(lab_1.TabPanel, Object.assign({ className: classes.tabPanel, value: types_1.TabContentEnum.STUDENTS }, { children: (0, jsx_runtime_1.jsx)(Students_1.default, { course: scCourse }) })), (0, jsx_runtime_1.jsx)(lab_1.TabPanel, Object.assign({ className: classes.tabPanel, value: types_1.TabContentEnum.COMMENTS }, { children: (0, jsx_runtime_1.jsx)(Comments_1.default, { course: scCourse }) }))] }))] })));
|
|
57
56
|
}
|
|
@@ -1,24 +1,5 @@
|
|
|
1
|
-
export declare type CourseDashboardPage = 'students' | 'comments';
|
|
2
1
|
export declare type TabContentType = '1' | '2';
|
|
3
2
|
export declare enum TabContentEnum {
|
|
4
3
|
STUDENTS = "1",
|
|
5
4
|
COMMENTS = "2"
|
|
6
5
|
}
|
|
7
|
-
declare type LessonsUserType = {
|
|
8
|
-
id: number;
|
|
9
|
-
name: string;
|
|
10
|
-
avatar: string;
|
|
11
|
-
date: string;
|
|
12
|
-
comment: string;
|
|
13
|
-
};
|
|
14
|
-
declare type CommentsLessonType = {
|
|
15
|
-
id: number;
|
|
16
|
-
name: string;
|
|
17
|
-
users: LessonsUserType[];
|
|
18
|
-
};
|
|
19
|
-
export declare type CommentsType = {
|
|
20
|
-
total: number;
|
|
21
|
-
next: boolean;
|
|
22
|
-
lessons: CommentsLessonType[];
|
|
23
|
-
};
|
|
24
|
-
export {};
|
|
@@ -2,6 +2,7 @@ import { GridProps } from '@mui/material';
|
|
|
2
2
|
import React from 'react';
|
|
3
3
|
import { CourseProps, CourseSkeletonProps } from '../Course';
|
|
4
4
|
import { CoursesSkeletonProps } from '../Courses/Skeleton';
|
|
5
|
+
import { CreateCourseButtonProps } from '../CreateCourseButton';
|
|
5
6
|
export declare const CoursesChipRoot: import("@emotion/styled").StyledComponent<import("@mui/material").ChipOwnProps & import("@mui/material/OverridableComponent").CommonProps & Omit<Pick<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "key" | keyof React.HTMLAttributes<HTMLDivElement>> & {
|
|
6
7
|
ref?: React.Ref<HTMLDivElement>;
|
|
7
8
|
}, "avatar" | "className" | "style" | "classes" | "label" | "tabIndex" | "color" | "children" | "sx" | "variant" | "disabled" | "size" | "icon" | "clickable" | "deleteIcon" | "onDelete" | "skipFocusWhenDisabled"> & import("@mui/system").MUIStyledCommonProps<import("@mui/material").Theme>, {}, {}>;
|
|
@@ -31,6 +32,11 @@ export interface CoursesProps {
|
|
|
31
32
|
* @default {}
|
|
32
33
|
*/
|
|
33
34
|
CoursesSkeletonComponentProps?: CoursesSkeletonProps;
|
|
35
|
+
/**
|
|
36
|
+
* Props to spread to CreateCourseButton component
|
|
37
|
+
* @default {}
|
|
38
|
+
*/
|
|
39
|
+
CreateCourseButtonComponentProps?: CreateCourseButtonProps;
|
|
34
40
|
/**
|
|
35
41
|
* Props spread to grid container
|
|
36
42
|
* @default {}
|
|
@@ -88,7 +88,7 @@ function Courses(inProps) {
|
|
|
88
88
|
props: inProps,
|
|
89
89
|
name: constants_1.PREFIX
|
|
90
90
|
});
|
|
91
|
-
const { endpointQueryParams = { limit: 8, offset: Pagination_1.DEFAULT_PAGINATION_OFFSET }, className, CourseComponentProps = {}, CoursesSkeletonComponentProps = {}, CourseSkeletonComponentProps = { template: course_1.SCCourseTemplateType.PREVIEW }, GridContainerComponentProps = {}, GridItemComponentProps = {}, showFilters = true, filters } = props, rest = tslib_1.__rest(props, ["endpointQueryParams", "className", "CourseComponentProps", "CoursesSkeletonComponentProps", "CourseSkeletonComponentProps", "GridContainerComponentProps", "GridItemComponentProps", "showFilters", "filters"]);
|
|
91
|
+
const { endpointQueryParams = { limit: 8, offset: Pagination_1.DEFAULT_PAGINATION_OFFSET }, className, CourseComponentProps = {}, CoursesSkeletonComponentProps = {}, CourseSkeletonComponentProps = { template: course_1.SCCourseTemplateType.PREVIEW }, CreateCourseButtonComponentProps = {}, GridContainerComponentProps = {}, GridItemComponentProps = {}, showFilters = true, filters } = props, rest = tslib_1.__rest(props, ["endpointQueryParams", "className", "CourseComponentProps", "CoursesSkeletonComponentProps", "CourseSkeletonComponentProps", "CreateCourseButtonComponentProps", "GridContainerComponentProps", "GridItemComponentProps", "showFilters", "filters"]);
|
|
92
92
|
// STATE
|
|
93
93
|
const [courses, setCourses] = (0, react_1.useState)([]);
|
|
94
94
|
const [loading, setLoading] = (0, react_1.useState)(true);
|
|
@@ -224,7 +224,7 @@ function Courses(inProps) {
|
|
|
224
224
|
// @ts-expect-error this is needed to use showForMe into SCCourses
|
|
225
225
|
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
226
|
// @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" }) })), (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, {}) }), '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" }) })))] })) })) })] }));
|
|
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" }) })), (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" }) })))] })) })) })] }));
|
|
228
228
|
/**
|
|
229
229
|
* Renders root object (if content availability community option is false and user is anonymous, component is hidden)
|
|
230
230
|
*/
|
|
@@ -40,8 +40,8 @@ function AccordionLessons(inProps) {
|
|
|
40
40
|
if (!course) {
|
|
41
41
|
return ((0, jsx_runtime_1.jsx)(Root, Object.assign({ className: (0, classnames_1.default)(classes.root, className) }, { children: (0, jsx_runtime_1.jsx)(material_1.Box, Object.assign({ className: classes.accordion }, { children: (0, jsx_runtime_1.jsxs)(material_1.Box, Object.assign({ className: classes.summary }, { children: [(0, jsx_runtime_1.jsx)(material_1.Skeleton, { animation: "wave", variant: "text", width: "210px", height: "21px" }), (0, jsx_runtime_1.jsx)(material_1.Skeleton, { animation: "wave", variant: "text", width: "54px", height: "21px" })] })) })) })));
|
|
42
42
|
}
|
|
43
|
-
return ((0, jsx_runtime_1.jsx)(
|
|
44
|
-
|
|
45
|
-
|
|
43
|
+
return ((0, jsx_runtime_1.jsx)(react_1.Fragment, { children: ((_a = course.sections) === null || _a === void 0 ? void 0 : _a.length) > 0 ? ((0, jsx_runtime_1.jsx)(Root, Object.assign({ className: (0, classnames_1.default)(classes.root, className) }, { children: course.sections.map((section) => ((0, jsx_runtime_1.jsxs)(material_1.Accordion, Object.assign({ className: classes.accordion, expanded: expanded === section.id, onChange: handleChange(section.id), disableGutters: true, elevation: 0, square: true }, { children: [(0, jsx_runtime_1.jsxs)(material_1.AccordionSummary, Object.assign({ className: classes.summary, expandIcon: (0, jsx_runtime_1.jsx)(material_1.Icon, { children: "expand_less" }) }, { children: [(0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ component: "span", variant: "body1" }, { children: section.name })), !isMobile && ((0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ component: "span", variant: "body1" }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.course.table.lessons.title", defaultMessage: "ui.course.table.lessons.title", values: {
|
|
44
|
+
lessonsNumber: section.lessons.length
|
|
45
|
+
} }) })))] })), section.lessons.map((lesson) => ((0, jsx_runtime_1.jsxs)(material_1.AccordionDetails, Object.assign({ className: classes.details }, { children: [lesson.completion_status === types_1.SCCourseLessonCompletionStatusType.COMPLETED ? ((0, jsx_runtime_1.jsx)(material_1.Icon, Object.assign({ fontSize: "small", color: "primary" }, { children: "circle_checked" }))) : ((0, jsx_runtime_1.jsx)(material_1.Box, { className: classes.circle })), (0, jsx_runtime_1.jsx)(material_1.Typography, { children: lesson.name })] }), lesson.id)))] }), section.id))) }))) : ((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.accordionLessons.empty", defaultMessage: "ui.course.accordionLessons.empty" }) }))) }));
|
|
46
46
|
}
|
|
47
47
|
exports.default = AccordionLessons;
|
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import { WidgetProps } from '../Widget';
|
|
2
|
+
import { CreateCourseButtonProps } from '../CreateCourseButton';
|
|
2
3
|
export interface CourseSkeletonProps extends WidgetProps {
|
|
4
|
+
/**
|
|
5
|
+
* Props to spread to CreateCourseButton component
|
|
6
|
+
* @default {}
|
|
7
|
+
*/
|
|
8
|
+
CreateCourseButtonComponentProps?: CreateCourseButtonProps;
|
|
3
9
|
/**
|
|
4
10
|
* Overrides or extends the styles applied to the component.
|
|
5
11
|
* @default null
|
|
@@ -49,8 +49,8 @@ export default function CourseCreatePlaceholder(inProps) {
|
|
|
49
49
|
props: inProps,
|
|
50
50
|
name: PREFIX
|
|
51
51
|
});
|
|
52
|
-
const { className } = props, rest = __rest(props, ["className"]);
|
|
52
|
+
const { CreateCourseButtonComponentProps = {}, className } = props, rest = __rest(props, ["CreateCourseButtonComponentProps", "className"]);
|
|
53
53
|
// HOOK
|
|
54
54
|
const { preferences } = useSCPreferences();
|
|
55
|
-
return (_jsxs(Root, Object.assign({ className: classNames(classes.root, className) }, rest, { children: [_jsxs(Box, Object.assign({ position: "relative", className: classes.imageWrapper }, { children: [_jsx(CardMedia, { component: "img", image: `${preferences[SCPreferences.IMAGES_USER_DEFAULT_COVER].value}`, alt: "placeholder image", className: classes.image }), _jsx(Icon, Object.assign({ className: classes.icon, fontSize: "large" }, { children: "courses" }))] })), _jsx(CardActions, Object.assign({ className: classes.actions }, { children: _jsx(CreateCourseButton, {}) }))] })));
|
|
55
|
+
return (_jsxs(Root, Object.assign({ className: classNames(classes.root, className) }, rest, { children: [_jsxs(Box, Object.assign({ position: "relative", className: classes.imageWrapper }, { children: [_jsx(CardMedia, { component: "img", image: `${preferences[SCPreferences.IMAGES_USER_DEFAULT_COVER].value}`, alt: "placeholder image", className: classes.image }), _jsx(Icon, Object.assign({ className: classes.icon, fontSize: "large" }, { children: "courses" }))] })), _jsx(CardActions, Object.assign({ className: classes.actions }, { children: _jsx(CreateCourseButton, Object.assign({}, CreateCourseButtonComponentProps)) }))] })));
|
|
56
56
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { Box, Button, Icon, Skeleton, Stack, Typography } from '@mui/material';
|
|
3
|
+
import { SCCoursePrivacyType } from '@selfcommunity/types';
|
|
3
4
|
import { FormattedMessage, useIntl } from 'react-intl';
|
|
4
5
|
import { PREFIX } from './constants';
|
|
5
6
|
import { memo, useMemo } from 'react';
|
|
@@ -28,12 +29,13 @@ function HeaderCourseDashboard(props) {
|
|
|
28
29
|
}
|
|
29
30
|
}, [course, hasAction]);
|
|
30
31
|
const iconData = useMemo(() => {
|
|
32
|
+
const underId = (course === null || course === void 0 ? void 0 : course.privacy) === SCCoursePrivacyType.DRAFT ? 'draft' : course === null || course === void 0 ? void 0 : course.privacy;
|
|
31
33
|
return [
|
|
32
34
|
{
|
|
33
35
|
id: 'ui.course.label',
|
|
34
36
|
icon: 'public',
|
|
35
37
|
key: 'privacy',
|
|
36
|
-
underId: `ui.course.privacy.${
|
|
38
|
+
underId: `ui.course.privacy.${underId}`
|
|
37
39
|
},
|
|
38
40
|
{
|
|
39
41
|
id: 'ui.course.type',
|
|
@@ -26,6 +26,7 @@ const classes = {
|
|
|
26
26
|
root: `${PREFIX}-root`,
|
|
27
27
|
studentContainer: `${PREFIX}-student-container`,
|
|
28
28
|
userWrapper: `${PREFIX}-user-wrapper`,
|
|
29
|
+
actionsWrapper: `${PREFIX}-actions-wrapper`,
|
|
29
30
|
user: `${PREFIX}-user`,
|
|
30
31
|
avatar: `${PREFIX}-avatar`,
|
|
31
32
|
progress: `${PREFIX}-progress`,
|
|
@@ -110,12 +111,12 @@ function Student(inProps) {
|
|
|
110
111
|
if (!scCourse) {
|
|
111
112
|
return _jsx(Skeleton, { animation: "wave", variant: "rounded", width: "160px", height: "28px" });
|
|
112
113
|
}
|
|
113
|
-
return (_jsxs(Stack, Object.assign({
|
|
114
|
+
return (_jsxs(Stack, Object.assign({ className: classes.actionsWrapper }, { children: [((scCourse === null || scCourse === void 0 ? void 0 : scCourse.join_status) === SCCourseJoinStatusType.CREATOR || (scCourse === null || scCourse === void 0 ? void 0 : scCourse.join_status) === SCCourseJoinStatusType.MANAGER) && (_jsx(ActionButton, { labelId: messages.dashboard, to: scRoutingContext.url(SCRoutes.COURSE_DASHBOARD_ROUTE_NAME, scCourse), color: "inherit", variant: "outlined" })), ((scCourse === null || scCourse === void 0 ? void 0 : scCourse.join_status) === SCCourseJoinStatusType.MANAGER || (scCourse === null || scCourse === void 0 ? void 0 : scCourse.join_status) === SCCourseJoinStatusType.JOINED) &&
|
|
114
115
|
((scCourse === null || scCourse === void 0 ? void 0 : scCourse.join_status) !== null || scCourse.privacy !== SCCoursePrivacyType.PRIVATE) &&
|
|
115
116
|
scCourse.user_completion_rate < 100 && (_jsx(ActionButton, { labelId: scCourse.num_lessons_completed === 0 ? messages.start : messages.continue, to: scRoutingContext.url(SCRoutes.COURSE_LESSON_ROUTE_NAME, getUrlNextLesson(scCourse)) })), scCourse.privacy === SCCoursePrivacyType.PRIVATE &&
|
|
116
117
|
(scCourse.join_status === null || scCourse.join_status === SCCourseJoinStatusType.REQUESTED) && (_jsx(ActionButton, { labelId: sentRequest ? messages.cancel : messages.request, color: "inherit", variant: "outlined", loading: loadingRequest, onClick: handleRequest }))] })));
|
|
117
118
|
}, [scCourse, sentRequest, loadingRequest, handleRequest]);
|
|
118
|
-
return (_jsxs(Root, Object.assign({ className: classNames(classes.root, classes.studentContainer, className) }, rest, { children: [_jsx(HeaderCourseDashboard, { course: scCourse }), _jsx(Divider, {}), _jsxs(Stack, Object.assign({ className: classes.userWrapper }, { children: [_jsxs(Stack, Object.assign({ className: classes.user }, { children: [scCourse ? (_jsx(Avatar, { className: classes.avatar, src: scCourse.created_by.avatar, alt: scCourse.created_by.username })) : (_jsx(Skeleton, { animation: "wave", variant: "circular", className: classes.avatar })), _jsx(Box, { children: scCourse ? (_jsxs(Fragment, { children: [_jsx(Typography, Object.assign({ variant: "body1" }, { children: scCourse.created_by.username })), _jsx(Typography, Object.assign({ variant: "body1" }, { children:
|
|
119
|
+
return (_jsxs(Root, Object.assign({ className: classNames(classes.root, classes.studentContainer, className) }, rest, { children: [_jsx(HeaderCourseDashboard, { course: scCourse }), _jsx(Divider, {}), _jsxs(Stack, Object.assign({ className: classes.userWrapper }, { children: [_jsxs(Stack, Object.assign({ className: classes.user }, { children: [scCourse ? (_jsx(Avatar, { className: classes.avatar, src: scCourse.created_by.avatar, alt: scCourse.created_by.username })) : (_jsx(Skeleton, { animation: "wave", variant: "circular", className: classes.avatar })), _jsx(Box, { children: scCourse ? (_jsxs(Fragment, { children: [_jsx(Typography, Object.assign({ variant: "body1" }, { children: scCourse.created_by.username })), _jsx(Typography, Object.assign({ variant: "body1" }, { children: _jsx(FormattedMessage, { id: "ui.course.dashboard.header.user.creator", defaultMessage: "ui.course.dashboard.header.user.creator" }) }))] })) : (_jsxs(Fragment, { children: [_jsx(Skeleton, { animation: "wave", variant: "text", width: "105px", height: "21px" }), _jsx(Skeleton, { animation: "wave", variant: "text", width: "74px", height: "21px" })] })) })] })), actionButton] })), _jsx(Divider, {}), ((scCourse === null || scCourse === void 0 ? void 0 : scCourse.join_status) === SCCourseJoinStatusType.CREATOR ||
|
|
119
120
|
(scCourse === null || scCourse === void 0 ? void 0 : scCourse.join_status) === SCCourseJoinStatusType.MANAGER ||
|
|
120
121
|
(scCourse === null || scCourse === void 0 ? void 0 : scCourse.join_status) === SCCourseJoinStatusType.JOINED ||
|
|
121
122
|
(scCourse === null || scCourse === void 0 ? void 0 : scCourse.privacy) !== SCCoursePrivacyType.PRIVATE) && (_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: scCourse ? _jsx(Typography, Object.assign({ variant: "body1" }, { children: scCourse.description })) : _jsx(Skeleton, { animation: "wave", variant: "text", height: "130px" }) }))] })), ((scCourse === null || scCourse === void 0 ? void 0 : scCourse.join_status) === SCCourseJoinStatusType.MANAGER || (scCourse === null || scCourse === void 0 ? void 0 : scCourse.join_status) === SCCourseJoinStatusType.JOINED) && (_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: [_jsx(Stack, Object.assign({ className: classes.percentageWrapper }, { children: scCourse ? (_jsxs(Fragment, { 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 } }) }))] })) : (_jsxs(Fragment, { children: [_jsx(Skeleton, { animation: "wave", variant: "text", width: "168px", height: "19px" }), _jsx(Skeleton, { animation: "wave", variant: "text", width: "108px", height: "19px" })] })) })), _jsx(LinearProgress, { className: classes.progress, variant: "determinate", value: scCourse === null || scCourse === void 0 ? void 0 : scCourse.user_completion_rate })] })), (scCourse === null || scCourse === void 0 ? void 0 : 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: [scCourse ? (_jsx(Typography, Object.assign({ variant: "h5" }, { children: _jsx(FormattedMessage, { id: "ui.course.table.sections.title", defaultMessage: "ui.course.table.sections.title", values: {
|
|
@@ -1,11 +1,8 @@
|
|
|
1
1
|
import { HTMLAttributes } from 'react';
|
|
2
|
-
import { CourseDashboardPage } from './types';
|
|
3
2
|
import { SCCourseType } from '@selfcommunity/types';
|
|
4
3
|
export interface TeacherCourseDashboardProps {
|
|
5
4
|
courseId?: number;
|
|
6
5
|
course?: SCCourseType;
|
|
7
|
-
page: CourseDashboardPage;
|
|
8
|
-
onTabChange: (page: CourseDashboardPage) => void;
|
|
9
6
|
className?: HTMLAttributes<HTMLDivElement>['className'];
|
|
10
7
|
[p: string]: any;
|
|
11
8
|
}
|
|
@@ -41,15 +41,14 @@ function Teacher(inProps) {
|
|
|
41
41
|
props: inProps,
|
|
42
42
|
name: PREFIX
|
|
43
43
|
});
|
|
44
|
-
const { courseId, course,
|
|
44
|
+
const { courseId, course, className } = props, rest = __rest(props, ["courseId", "course", "className"]);
|
|
45
45
|
// STATES
|
|
46
|
-
const [tabValue, setTabValue] = useState(TabContentEnum
|
|
46
|
+
const [tabValue, setTabValue] = useState(TabContentEnum.STUDENTS);
|
|
47
47
|
// HOOKS
|
|
48
48
|
const { scCourse } = useSCFetchCourse({ id: courseId, course, params: { view: CourseInfoViewType.DASHBOARD } });
|
|
49
49
|
// HANDLERS
|
|
50
50
|
const handleTabChange = useCallback((_evt, newTabValue) => {
|
|
51
51
|
setTabValue(newTabValue);
|
|
52
|
-
onTabChange(TabContentEnum[newTabValue]);
|
|
53
52
|
}, [setTabValue]);
|
|
54
53
|
return (_jsxs(Root, Object.assign({ className: classNames(classes.root, className) }, rest, { children: [_jsx(HeaderCourseDashboard, { course: scCourse, hasAction: true }), _jsxs(Stack, Object.assign({ className: classes.infoWrapper }, { children: [_jsx(InfoCourseDashboard, { title: "ui.course.dashboard.teacher.info.students", course: scCourse, position: "first" }), _jsx(InfoCourseDashboard, { title: "ui.course.dashboard.teacher.info.completion", course: scCourse, position: "second" })] })), _jsxs(TabContext, Object.assign({ value: tabValue }, { children: [_jsx(TabList, Object.assign({ className: classes.tabList, onChange: handleTabChange, textColor: "primary", indicatorColor: "primary", variant: "standard", centered: true }, { children: TAB_DATA.map((data, i) => (_jsx(Tab, { label: _jsx(Typography, Object.assign({ variant: "h6" }, { children: _jsx(FormattedMessage, { id: data.label, defaultMessage: data.label }) })), value: data.value, className: classes.tab }, i))) })), _jsx(TabPanel, Object.assign({ className: classes.tabPanel, value: TabContentEnum.STUDENTS }, { children: _jsx(Students, { course: scCourse }) })), _jsx(TabPanel, Object.assign({ className: classes.tabPanel, value: TabContentEnum.COMMENTS }, { children: _jsx(Comments, { course: scCourse }) }))] }))] })));
|
|
55
54
|
}
|
|
@@ -1,24 +1,5 @@
|
|
|
1
|
-
export declare type CourseDashboardPage = 'students' | 'comments';
|
|
2
1
|
export declare type TabContentType = '1' | '2';
|
|
3
2
|
export declare enum TabContentEnum {
|
|
4
3
|
STUDENTS = "1",
|
|
5
4
|
COMMENTS = "2"
|
|
6
5
|
}
|
|
7
|
-
declare type LessonsUserType = {
|
|
8
|
-
id: number;
|
|
9
|
-
name: string;
|
|
10
|
-
avatar: string;
|
|
11
|
-
date: string;
|
|
12
|
-
comment: string;
|
|
13
|
-
};
|
|
14
|
-
declare type CommentsLessonType = {
|
|
15
|
-
id: number;
|
|
16
|
-
name: string;
|
|
17
|
-
users: LessonsUserType[];
|
|
18
|
-
};
|
|
19
|
-
export declare type CommentsType = {
|
|
20
|
-
total: number;
|
|
21
|
-
next: boolean;
|
|
22
|
-
lessons: CommentsLessonType[];
|
|
23
|
-
};
|
|
24
|
-
export {};
|
|
@@ -2,6 +2,7 @@ import { GridProps } from '@mui/material';
|
|
|
2
2
|
import React from 'react';
|
|
3
3
|
import { CourseProps, CourseSkeletonProps } from '../Course';
|
|
4
4
|
import { CoursesSkeletonProps } from '../Courses/Skeleton';
|
|
5
|
+
import { CreateCourseButtonProps } from '../CreateCourseButton';
|
|
5
6
|
export declare const CoursesChipRoot: import("@emotion/styled").StyledComponent<import("@mui/material").ChipOwnProps & import("@mui/material/OverridableComponent").CommonProps & Omit<Pick<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "key" | keyof React.HTMLAttributes<HTMLDivElement>> & {
|
|
6
7
|
ref?: React.Ref<HTMLDivElement>;
|
|
7
8
|
}, "avatar" | "className" | "style" | "classes" | "label" | "tabIndex" | "color" | "children" | "sx" | "variant" | "disabled" | "size" | "icon" | "clickable" | "deleteIcon" | "onDelete" | "skipFocusWhenDisabled"> & import("@mui/system").MUIStyledCommonProps<import("@mui/material").Theme>, {}, {}>;
|
|
@@ -31,6 +32,11 @@ export interface CoursesProps {
|
|
|
31
32
|
* @default {}
|
|
32
33
|
*/
|
|
33
34
|
CoursesSkeletonComponentProps?: CoursesSkeletonProps;
|
|
35
|
+
/**
|
|
36
|
+
* Props to spread to CreateCourseButton component
|
|
37
|
+
* @default {}
|
|
38
|
+
*/
|
|
39
|
+
CreateCourseButtonComponentProps?: CreateCourseButtonProps;
|
|
34
40
|
/**
|
|
35
41
|
* Props spread to grid container
|
|
36
42
|
* @default {}
|
|
@@ -85,7 +85,7 @@ export default function Courses(inProps) {
|
|
|
85
85
|
props: inProps,
|
|
86
86
|
name: PREFIX
|
|
87
87
|
});
|
|
88
|
-
const { endpointQueryParams = { limit: 8, offset: DEFAULT_PAGINATION_OFFSET }, className, CourseComponentProps = {}, CoursesSkeletonComponentProps = {}, CourseSkeletonComponentProps = { template: SCCourseTemplateType.PREVIEW }, GridContainerComponentProps = {}, GridItemComponentProps = {}, showFilters = true, filters } = props, rest = __rest(props, ["endpointQueryParams", "className", "CourseComponentProps", "CoursesSkeletonComponentProps", "CourseSkeletonComponentProps", "GridContainerComponentProps", "GridItemComponentProps", "showFilters", "filters"]);
|
|
88
|
+
const { endpointQueryParams = { limit: 8, offset: DEFAULT_PAGINATION_OFFSET }, className, CourseComponentProps = {}, CoursesSkeletonComponentProps = {}, CourseSkeletonComponentProps = { template: SCCourseTemplateType.PREVIEW }, CreateCourseButtonComponentProps = {}, GridContainerComponentProps = {}, GridItemComponentProps = {}, showFilters = true, filters } = props, rest = __rest(props, ["endpointQueryParams", "className", "CourseComponentProps", "CoursesSkeletonComponentProps", "CourseSkeletonComponentProps", "CreateCourseButtonComponentProps", "GridContainerComponentProps", "GridItemComponentProps", "showFilters", "filters"]);
|
|
89
89
|
// STATE
|
|
90
90
|
const [courses, setCourses] = useState([]);
|
|
91
91
|
const [loading, setLoading] = useState(true);
|
|
@@ -221,7 +221,7 @@ export default function Courses(inProps) {
|
|
|
221
221
|
// @ts-expect-error this is needed to use showForMe into SCCourses
|
|
222
222
|
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
223
|
// @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" }) })), _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, {}) }), '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" }) })))] })) })) })] }));
|
|
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" }) })), _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" }) })))] })) })) })] }));
|
|
225
225
|
/**
|
|
226
226
|
* Renders root object (if content availability community option is false and user is anonymous, component is hidden)
|
|
227
227
|
*/
|
|
@@ -2,7 +2,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import { Accordion, AccordionDetails, AccordionSummary, Box, Icon, Skeleton, styled, Typography, useMediaQuery, useTheme, useThemeProps } from '@mui/material';
|
|
3
3
|
import { FormattedMessage } from 'react-intl';
|
|
4
4
|
import classNames from 'classnames';
|
|
5
|
-
import { useCallback, useState } from 'react';
|
|
5
|
+
import { Fragment, useCallback, useState } from 'react';
|
|
6
6
|
import { SCCourseLessonCompletionStatusType } from '@selfcommunity/types';
|
|
7
7
|
const PREFIX = 'SCAccordionLessons';
|
|
8
8
|
const classes = {
|
|
@@ -37,7 +37,7 @@ export default function AccordionLessons(inProps) {
|
|
|
37
37
|
if (!course) {
|
|
38
38
|
return (_jsx(Root, Object.assign({ className: classNames(classes.root, className) }, { children: _jsx(Box, Object.assign({ className: classes.accordion }, { children: _jsxs(Box, Object.assign({ className: classes.summary }, { children: [_jsx(Skeleton, { animation: "wave", variant: "text", width: "210px", height: "21px" }), _jsx(Skeleton, { animation: "wave", variant: "text", width: "54px", height: "21px" })] })) })) })));
|
|
39
39
|
}
|
|
40
|
-
return (_jsx(
|
|
41
|
-
|
|
42
|
-
|
|
40
|
+
return (_jsx(Fragment, { children: ((_a = course.sections) === null || _a === void 0 ? void 0 : _a.length) > 0 ? (_jsx(Root, Object.assign({ className: classNames(classes.root, className) }, { children: course.sections.map((section) => (_jsxs(Accordion, Object.assign({ className: classes.accordion, expanded: expanded === section.id, onChange: handleChange(section.id), disableGutters: true, elevation: 0, square: true }, { children: [_jsxs(AccordionSummary, Object.assign({ className: classes.summary, expandIcon: _jsx(Icon, { children: "expand_less" }) }, { children: [_jsx(Typography, Object.assign({ component: "span", variant: "body1" }, { children: section.name })), !isMobile && (_jsx(Typography, Object.assign({ component: "span", variant: "body1" }, { children: _jsx(FormattedMessage, { id: "ui.course.table.lessons.title", defaultMessage: "ui.course.table.lessons.title", values: {
|
|
41
|
+
lessonsNumber: section.lessons.length
|
|
42
|
+
} }) })))] })), section.lessons.map((lesson) => (_jsxs(AccordionDetails, Object.assign({ className: classes.details }, { children: [lesson.completion_status === SCCourseLessonCompletionStatusType.COMPLETED ? (_jsx(Icon, Object.assign({ fontSize: "small", color: "primary" }, { children: "circle_checked" }))) : (_jsx(Box, { className: classes.circle })), _jsx(Typography, { children: lesson.name })] }), lesson.id)))] }), section.id))) }))) : (_jsx(Typography, Object.assign({ variant: "body1" }, { children: _jsx(FormattedMessage, { id: "ui.course.accordionLessons.empty", defaultMessage: "ui.course.accordionLessons.empty" }) }))) }));
|
|
43
43
|
}
|