@selfcommunity/react-ui
Version:
React UI Components to integrate a Community created with SelfCommunity Platform.
215 lines (214 loc) • 18.6 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
const jsx_runtime_1 = require("react/jsx-runtime");
const react_1 = require("react");
const constants_1 = require("./constants");
const material_1 = require("@mui/material");
const classnames_1 = tslib_1.__importDefault(require("classnames"));
const Header_1 = tslib_1.__importDefault(require("./Header"));
const types_1 = require("@selfcommunity/types");
const react_intl_1 = require("react-intl");
const ActionButton_1 = tslib_1.__importDefault(require("./Student/ActionButton"));
const clapping_1 = tslib_1.__importDefault(require("../../assets/courses/clapping"));
const react_core_1 = require("@selfcommunity/react-core");
const AccordionLessons_1 = tslib_1.__importDefault(require("../../shared/AccordionLessons"));
const api_services_1 = require("@selfcommunity/api-services");
const utils_1 = require("@selfcommunity/utils");
const Errors_1 = require("../../constants/Errors");
const notistack_1 = require("notistack");
const Skeleton_1 = tslib_1.__importDefault(require("./Student/Skeleton"));
const UserAvatar_1 = tslib_1.__importDefault(require("../../shared/UserAvatar"));
const BuyButton_1 = tslib_1.__importDefault(require("../BuyButton"));
const BUTTON_MESSAGES = {
dashboard: 'ui.course.dashboard.student.button.dashboard',
request: 'ui.course.dashboard.student.button.request',
signUp: 'ui.course.dashboard.student.button.signUp',
review: 'ui.course.dashboard.student.button.review',
cancel: 'ui.course.dashboard.student.button.cancel',
start: 'ui.course.dashboard.student.button.start',
continue: 'ui.course.dashboard.student.button.continue'
};
const SNACKBAR_MESSAGES = {
cancel: 'ui.course.dashboard.student.snackbar.success.cancel',
enroll: 'ui.course.dashboard.student.snackbar.success.enroll',
request: 'ui.course.dashboard.student.snackbar.success.request'
};
const classes = {
root: `${constants_1.PREFIX}-root`,
studentContainer: `${constants_1.PREFIX}-student-container`,
userWrapper: `${constants_1.PREFIX}-user-wrapper`,
actionsWrapper: `${constants_1.PREFIX}-actions-wrapper`,
user: `${constants_1.PREFIX}-user`,
avatar: `${constants_1.PREFIX}-avatar`,
description: `${constants_1.PREFIX}-description`,
progress: `${constants_1.PREFIX}-progress`,
lessonsSections: `${constants_1.PREFIX}-lessons-sections`,
circle: `${constants_1.PREFIX}-circle`,
accordion: `${constants_1.PREFIX}-accordion`,
margin: `${constants_1.PREFIX}-margin`,
box: `${constants_1.PREFIX}-box`,
percentageWrapper: `${constants_1.PREFIX}-percentage-wrapper`,
completedWrapper: `${constants_1.PREFIX}-completed-wrapper`,
contrastColor: `${constants_1.PREFIX}-contrast-color`
};
function getUrlNextLesson(course) {
var _a, _b, _c;
const data = {
id: course.id,
slug: course.slug
};
if (course.user_completion_rate === 100) {
Object.assign(data, {
section_id: (_a = course.sections) === null || _a === void 0 ? void 0 : _a[0].id,
lesson_id: (_b = course.sections) === null || _b === void 0 ? void 0 : _b[0].lessons[0].id
});
return data;
}
(_c = course.sections) === null || _c === void 0 ? void 0 : _c.some((section) => {
var _a;
const isNextLessonInThisSection = section.num_lessons_completed < section.num_lessons && !section.locked;
if (isNextLessonInThisSection) {
Object.assign(data, {
section_id: section.id,
lesson_id: (_a = section.lessons.find((lesson) => lesson.completion_status === types_1.SCCourseLessonCompletionStatusType.UNCOMPLETED)) === null || _a === void 0 ? void 0 : _a.id
});
}
return isNextLessonInThisSection;
});
return data;
}
function getIsNextLessonLocked(course) {
var _a;
if (course.join_status === null) {
return undefined;
}
return (_a = course.sections) === null || _a === void 0 ? void 0 : _a.every((section) => {
var _a, _b;
return (section.num_lessons_completed < section.num_lessons &&
((_b = (_a = section.lessons) === null || _a === void 0 ? void 0 : _a.find((lesson) => lesson.completion_status === types_1.SCCourseLessonCompletionStatusType.UNCOMPLETED)) === null || _b === void 0 ? void 0 : _b.locked));
});
}
const Root = (0, material_1.styled)(material_1.Box, {
name: constants_1.PREFIX,
slot: 'Root',
overridesResolver: (_props, styles) => styles.root
})(() => ({}));
function Student(inProps) {
// PROPS
const props = (0, material_1.useThemeProps)({
props: inProps,
name: constants_1.PREFIX
});
const { courseId, course, className } = props, rest = tslib_1.__rest(props, ["courseId", "course", "className"]);
// STATES
const [sentRequest, setSentRequest] = (0, react_1.useState)(null);
const [loadingRequest, setLoadingRequest] = (0, react_1.useState)(false);
// CONTEXTS
const scRoutingContext = (0, react_core_1.useSCRouting)();
const scContext = (0, react_core_1.useSCContext)();
const scUserContext = (0, react_core_1.useSCUser)();
// HOOKS
const { scCourse, setSCCourse } = (0, react_core_1.useSCFetchCourse)({ id: courseId, course });
const intl = (0, react_intl_1.useIntl)();
const { enqueueSnackbar } = (0, notistack_1.useSnackbar)();
// PAYMENTS
const { isPaymentsEnabled } = (0, react_core_1.useSCPaymentsEnabled)();
// EFFETCS
(0, react_1.useEffect)(() => {
if (scCourse) {
setSentRequest(scCourse.join_status === types_1.SCCourseJoinStatusType.REQUESTED);
}
}, [scCourse, setSentRequest]);
// HANDLERS
const handleRequest = (0, react_1.useCallback)(() => {
setLoadingRequest(true);
let request;
if (sentRequest) {
request = api_services_1.CourseService.leaveOrRemoveCourseRequest(scCourse.id);
}
else {
request = api_services_1.CourseService.joinOrAcceptInviteToCourse(scCourse.id);
}
request
.then((data) => {
let updatedCourse;
if (data) {
updatedCourse = data;
}
else {
updatedCourse = Object.assign(Object.assign({}, scCourse), { join_status: null });
}
setSCCourse(updatedCourse);
setSentRequest((prev) => !prev);
setLoadingRequest(false);
enqueueSnackbar((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: updatedCourse.join_status === types_1.SCCourseJoinStatusType.REQUESTED
? SNACKBAR_MESSAGES.request
: updatedCourse.join_status === types_1.SCCourseJoinStatusType.JOINED
? SNACKBAR_MESSAGES.enroll
: SNACKBAR_MESSAGES.cancel, defaultMessage: updatedCourse.join_status === types_1.SCCourseJoinStatusType.REQUESTED
? SNACKBAR_MESSAGES.request
: updatedCourse.join_status === types_1.SCCourseJoinStatusType.JOINED
? SNACKBAR_MESSAGES.enroll
: SNACKBAR_MESSAGES.cancel }), {
variant: 'success',
autoHideDuration: 3000
});
})
.catch((error) => {
enqueueSnackbar((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.common.error.action", defaultMessage: "ui.common.error.action" }), {
variant: 'error',
autoHideDuration: 3000
});
utils_1.Logger.error(Errors_1.SCOPE_SC_UI, error);
});
}, [scCourse, sentRequest, setLoadingRequest]);
const handleAnonymousAction = (0, react_1.useCallback)(() => {
scContext.settings.handleAnonymousAction();
}, [scContext.settings.handleAnonymousAction]);
// MEMOS
const actionButton = (0, react_1.useMemo)(() => {
var _a, _b, _c;
if (!scCourse) {
return (0, jsx_runtime_1.jsx)(material_1.Skeleton, { animation: "wave", variant: "rectangular", width: "130px", height: "20px" });
}
return ((0, jsx_runtime_1.jsxs)(material_1.Stack, Object.assign({ className: classes.actionsWrapper }, { children: [(scCourse.join_status === types_1.SCCourseJoinStatusType.CREATOR || scCourse.join_status === types_1.SCCourseJoinStatusType.MANAGER) && ((0, jsx_runtime_1.jsx)(ActionButton_1.default, { labelId: BUTTON_MESSAGES.dashboard, to: scRoutingContext.url(react_core_1.SCRoutes.COURSE_DASHBOARD_ROUTE_NAME, scCourse), color: "inherit", variant: "outlined" })), (((scCourse.privacy === types_1.SCCoursePrivacyType.PRIVATE || scCourse.privacy === types_1.SCCoursePrivacyType.SECRET) &&
(scCourse.join_status === types_1.SCCourseJoinStatusType.MANAGER || scCourse.join_status === types_1.SCCourseJoinStatusType.JOINED)) ||
(scCourse.privacy === types_1.SCCoursePrivacyType.OPEN && scCourse.join_status !== types_1.SCCourseJoinStatusType.CREATOR)) &&
(!isPaymentsEnabled ||
!((_a = scCourse.paywalls) === null || _a === void 0 ? void 0 : _a.length) ||
(isPaymentsEnabled &&
((_b = scCourse.paywalls) === null || _b === void 0 ? void 0 : _b.length) > 0 &&
(scCourse.join_status === types_1.SCCourseJoinStatusType.JOINED || scCourse.join_status === types_1.SCCourseJoinStatusType.MANAGER))) && ((0, jsx_runtime_1.jsx)(ActionButton_1.default, { labelId: scCourse.join_status === null
? BUTTON_MESSAGES.signUp
: scCourse.user_completion_rate === 0
? BUTTON_MESSAGES.start
: scCourse.user_completion_rate === 100
? BUTTON_MESSAGES.review
: BUTTON_MESSAGES.continue, to: scCourse.join_status !== null ? scRoutingContext.url(react_core_1.SCRoutes.COURSE_LESSON_ROUTE_NAME, getUrlNextLesson(scCourse)) : undefined, disabled: scCourse.join_status !== null ? getIsNextLessonLocked(scCourse) : undefined, color: scCourse.user_completion_rate === 100 ? 'inherit' : undefined, variant: scCourse.user_completion_rate === 100 ? 'outlined' : undefined, loading: scCourse.join_status === null ? loadingRequest : undefined, onClick: !scUserContext.user ? handleAnonymousAction : scCourse.join_status === null ? handleRequest : undefined })), scCourse.privacy === types_1.SCCoursePrivacyType.PRIVATE &&
(scCourse.join_status === null || scCourse.join_status === types_1.SCCourseJoinStatusType.REQUESTED) ? ((0, jsx_runtime_1.jsx)(ActionButton_1.default, { labelId: sentRequest ? BUTTON_MESSAGES.cancel : BUTTON_MESSAGES.request, color: "inherit", variant: "outlined", loading: loadingRequest, onClick: handleRequest })) : (isPaymentsEnabled &&
((_c = scCourse.paywalls) === null || _c === void 0 ? void 0 : _c.length) > 0 &&
!(scCourse.join_status === types_1.SCCourseJoinStatusType.CREATOR) && (0, jsx_runtime_1.jsx)(BuyButton_1.default, { contentType: types_1.SCContentType.COURSE, content: scCourse }))] })));
}, [scCourse, sentRequest, loadingRequest, handleRequest]);
if (!scCourse) {
return (0, jsx_runtime_1.jsx)(Skeleton_1.default, {});
}
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: [(0, jsx_runtime_1.jsx)(react_core_1.Link, Object.assign({}, (!scCourse.created_by.deleted && {
to: scRoutingContext.url(react_core_1.SCRoutes.USER_PROFILE_ROUTE_NAME, scCourse.created_by)
}), { children: (0, jsx_runtime_1.jsx)(UserAvatar_1.default, Object.assign({ hide: !scCourse.created_by.community_badge, smaller: true }, { children: (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.jsxs)(material_1.Box, { children: [(0, jsx_runtime_1.jsx)(react_core_1.Link, Object.assign({}, (!scCourse.created_by.deleted && {
to: scRoutingContext.url(react_core_1.SCRoutes.USER_PROFILE_ROUTE_NAME, scCourse.created_by)
}), { 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" }) }))] })] })), actionButton] })), (0, jsx_runtime_1.jsx)(material_1.Divider, {}), (((scCourse.privacy === types_1.SCCoursePrivacyType.PRIVATE || scCourse.privacy === types_1.SCCoursePrivacyType.SECRET) &&
(scCourse.join_status === types_1.SCCourseJoinStatusType.CREATOR ||
scCourse.join_status === types_1.SCCourseJoinStatusType.MANAGER ||
scCourse.join_status === types_1.SCCourseJoinStatusType.JOINED)) ||
scCourse.privacy === types_1.SCCoursePrivacyType.OPEN ||
scCourse.privacy === types_1.SCCoursePrivacyType.DRAFT) &&
scCourse.description && ((0, jsx_runtime_1.jsxs)(react_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "h6", className: (0, classnames_1.default)(classes.margin, classes.contrastColor) }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.course.dashboard.student.description", defaultMessage: "ui.course.dashboard.student.description" }) })), (0, jsx_runtime_1.jsx)(material_1.Stack, Object.assign({ className: classes.box }, { children: (0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "body1", className: classes.description }, { children: scCourse.description })) }))] })), (((scCourse.privacy === types_1.SCCoursePrivacyType.PRIVATE || scCourse.privacy === types_1.SCCoursePrivacyType.SECRET) &&
(scCourse.join_status === types_1.SCCourseJoinStatusType.MANAGER || scCourse.join_status === types_1.SCCourseJoinStatusType.JOINED)) ||
(scCourse.privacy === types_1.SCCoursePrivacyType.OPEN && scCourse.join_status !== types_1.SCCourseJoinStatusType.CREATOR)) && ((0, jsx_runtime_1.jsxs)(react_1.Fragment, { children: [scCourse.join_status !== null && ((0, jsx_runtime_1.jsxs)(react_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "h6", className: (0, classnames_1.default)(classes.margin, classes.contrastColor) }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.course.dashboard.student.progress", defaultMessage: "ui.course.dashboard.student.progress" }) })), (0, jsx_runtime_1.jsxs)(material_1.Stack, Object.assign({ className: classes.box }, { children: [(0, jsx_runtime_1.jsxs)(material_1.Stack, Object.assign({ className: classes.percentageWrapper }, { children: [(0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "body1" }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.course.dashboard.student.progress.described", defaultMessage: "ui.course.dashboard.student.progress.described", values: { progress: scCourse.num_lessons_completed, end: scCourse.num_lessons } }) })), (0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "body1" }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.course.dashboard.student.progress.percentage", defaultMessage: "ui.course.dashboard.student.progress.percentage", values: { percentage: scCourse.user_completion_rate } }) }))] })), (0, jsx_runtime_1.jsx)(material_1.LinearProgress, { className: classes.progress, variant: "determinate", value: scCourse.user_completion_rate })] }))] })), scCourse.user_completion_rate === 100 && ((0, jsx_runtime_1.jsxs)(material_1.Stack, Object.assign({ className: (0, classnames_1.default)(classes.completedWrapper, classes.margin) }, { children: [(0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "h3", className: classes.contrastColor }, { 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.default, 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: (0, classnames_1.default)(classes.margin, classes.contrastColor) }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.course.dashboard.student.contents", defaultMessage: "ui.course.dashboard.student.contents" }) })), (0, jsx_runtime_1.jsxs)(material_1.Stack, Object.assign({ className: classes.lessonsSections }, { children: [(0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "h5" }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.course.table.sections.title", defaultMessage: "ui.course.table.sections.title", values: {
sectionsNumber: scCourse.num_sections
} }) })), (0, jsx_runtime_1.jsx)(material_1.Box, { className: classes.circle }), (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.lessons.title", defaultMessage: "ui.course.table.lessons.title", values: {
lessonsNumber: scCourse.num_lessons
} }) }))] })), (0, jsx_runtime_1.jsx)(AccordionLessons_1.default, { course: scCourse, className: classes.accordion })] }))] })));
}
exports.default = (0, react_1.memo)(Student);