UNPKG

@selfcommunity/react-ui

Version:

React UI Components to integrate a Community created with SelfCommunity Platform.

215 lines (214 loc) • 18.6 kB
"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);