UNPKG

@selfcommunity/react-templates

Version:

React Templates Components to integrate a Community created with SelfCommunity.

200 lines (199 loc) • 13.5 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 system_1 = require("@mui/system"); const material_1 = require("@mui/material"); const constants_1 = require("./constants"); const types_1 = require("@selfcommunity/types"); const react_core_1 = require("@selfcommunity/react-core"); const classnames_1 = tslib_1.__importDefault(require("classnames")); const react_ui_1 = require("@selfcommunity/react-ui"); const api_services_1 = require("@selfcommunity/api-services"); const react_intl_1 = require("react-intl"); const notistack_1 = require("notistack"); const react_ui_2 = require("@selfcommunity/react-ui"); const classes = { root: `${constants_1.PREFIX}-root`, containerRoot: `${constants_1.PREFIX}-container-root`, navigation: `${constants_1.PREFIX}-navigation`, navigationTitle: `${constants_1.PREFIX}-navigation-title`, previewInfo: `${constants_1.PREFIX}-preview-info`, button: `${constants_1.PREFIX}-button` }; const Root = (0, material_1.styled)(material_1.Box, { name: constants_1.PREFIX, slot: 'Root', overridesResolver: (_props, styles) => [styles.root] })(() => ({})); const Container = (0, material_1.styled)(material_1.Box, { name: constants_1.PREFIX, slot: 'ContainerRoot', overridesResolver: (_props, styles) => styles.containerRoot, shouldForwardProp: (prop) => prop !== 'open' })(() => ({})); function Lesson(inProps) { var _a, _b, _c; // PROPS const props = (0, system_1.useThemeProps)({ props: inProps, name: constants_1.PREFIX }); const { className = null, courseId, sectionId, lessonId, LessonAppbarProps = {}, LessonDrawerProps = {}, editMode = false, previewMode = false, onEditModeClose = null, onLessonChange = null, onActivePanelChange = null, onLessonStatusChange = null, lessonAction = null } = props, rest = tslib_1.__rest(props, ["className", "courseId", "sectionId", "lessonId", "LessonAppbarProps", "LessonDrawerProps", "editMode", "previewMode", "onEditModeClose", "onLessonChange", "onActivePanelChange", "onLessonStatusChange", "lessonAction"]); // HOOKS const theme = (0, material_1.useTheme)(); const isMobile = (0, material_1.useMediaQuery)(theme.breakpoints.down('md')); const [_lessonId, setLessonId] = (0, react_1.useState)(lessonId); const [_sectionId, setSectionId] = (0, react_1.useState)(sectionId); const { scLesson, setSCLesson } = (0, react_core_1.useSCFetchLesson)({ id: _lessonId, courseId, sectionId: _sectionId }); const { scCourse, refreshCourse } = (0, react_core_1.useSCFetchCourse)({ id: courseId, params: { view: editMode || previewMode ? api_services_1.CourseInfoViewType.EDIT : api_services_1.CourseInfoViewType.USER } }); const { enqueueSnackbar } = (0, notistack_1.useSnackbar)(); const scRoutingContext = (0, react_core_1.useSCRouting)(); // STATE const [activePanel, setActivePanel] = (0, react_1.useState)(lessonAction); const [settings, setSettings] = (0, react_1.useState)(null); const [updating, setUpdating] = (0, react_1.useState)(false); const [lessonContent, setLessonContent] = (0, react_1.useState)(''); const [lessonMedias, setLessonMedias] = (0, react_1.useState)((_a = scLesson === null || scLesson === void 0 ? void 0 : scLesson.medias) !== null && _a !== void 0 ? _a : []); const [loading, setLoading] = (0, react_1.useState)(false); const [completed, setCompleted] = (0, react_1.useState)(null); const availableLessons = (0, react_1.useMemo)(() => { if (!(scCourse === null || scCourse === void 0 ? void 0 : scCourse.sections)) return []; return scCourse.sections.flatMap((section) => section.lessons.map((lesson) => (Object.assign(Object.assign({}, lesson), { section })))); }, [scCourse]); const [currentLessonIndex, setCurrentLessonIndex] = (0, react_1.useState)(availableLessons.findIndex((lesson) => lesson.id === lessonId)); const isPrevDisabled = availableLessons.length === 0 || currentLessonIndex <= 0 || ((_b = availableLessons[currentLessonIndex - 1]) === null || _b === void 0 ? void 0 : _b.locked); const isNextDisabled = availableLessons.length === 0 || currentLessonIndex >= availableLessons.length - 1 || ((_c = availableLessons[currentLessonIndex + 1]) === null || _c === void 0 ? void 0 : _c.locked); const [openDialog, setOpenDialog] = (0, react_1.useState)(false); const isCourseAdmin = (0, react_1.useMemo)(() => scCourse && scCourse.join_status === types_1.SCCourseJoinStatusType.CREATOR, [scCourse]); //EFFECTS (0, react_1.useEffect)(() => { const index = availableLessons.findIndex((lesson) => lesson.id === lessonId); setCurrentLessonIndex(index); }, [lessonId, availableLessons]); (0, react_1.useEffect)(() => { if (scLesson) { setCompleted(scLesson.completion_status === types_1.SCCourseLessonCompletionStatusType.COMPLETED); } }, [scLesson]); // HANDLERS /** * Handles lesson settings change * @param newSettings */ const handleSettingsChange = (newSettings) => { setSettings(newSettings); }; const handleOpenDrawer = (panel) => { setActivePanel((prevPanel) => (prevPanel === panel ? null : panel)); onActivePanelChange && onActivePanelChange(panel); }; const handleCloseDrawer = () => { setActivePanel(null); onEditModeClose && onEditModeClose(); onActivePanelChange && onActivePanelChange(null); }; const handleLessonContentEdit = (html) => { setLessonContent(html); }; const handleLessonMediaEdit = (medias) => { setLessonMedias(medias); }; const handleChangeLesson = (l, s) => { setLessonId(l.id); setSectionId(s.id); onLessonChange && onLessonChange(l.id, s.id); }; /** * Handles Lesson Edit */ const handleLessonUpdate = () => { setUpdating(true); const mediaIds = lessonMedias.map((media) => media.id); const data = Object.assign(Object.assign({}, settings), { type: scLesson.type, name: scLesson.name, text: lessonContent, medias: mediaIds }); api_services_1.CourseService.updateCourseLesson(scCourse.id, sectionId, scLesson.id, data) .then((data) => { setUpdating(false); setSCLesson(data); enqueueSnackbar((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "templates.lesson.save.success", defaultMessage: "templates.lesson.save.success" }), { variant: 'success', autoHideDuration: 3000 }); }) .catch((error) => { setUpdating(false); enqueueSnackbar((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "templates.lesson.save.error", defaultMessage: "templates.lesson.save.error" }), { variant: 'error', autoHideDuration: 3000 }); console.log(error); }); }; /** * Handles prev lesson navigation */ const handlePrev = () => { if (isPrevDisabled) return; const newLessonIndex = currentLessonIndex - 1; const newLesson = availableLessons[newLessonIndex]; setCurrentLessonIndex(newLessonIndex); handleChangeLesson(newLesson, newLesson.section); }; /** * Handles next lesson navigation */ const handleNext = () => { if (isNextDisabled) return; const newLessonIndex = currentLessonIndex + 1; const newLesson = availableLessons[newLessonIndex]; setCurrentLessonIndex(newLessonIndex); handleChangeLesson(newLesson, newLesson.section); }; /** * Handles toggle lesson complete/uncompleted */ const toggleLessonCompletion = () => { setLoading(true); const service = completed ? () => api_services_1.CourseService.markLessonIncomplete(scLesson.course_id, scLesson.section_id, scLesson.id) : () => api_services_1.CourseService.markLessonComplete(scLesson.course_id, scLesson.section_id, scLesson.id); service() .then(() => { setCompleted(!completed); setLoading(false); refreshCourse(); if (!completed && scCourse.num_lessons === scCourse.num_lessons_completed + 1) { setOpenDialog(true); } onLessonStatusChange === null || onLessonStatusChange === void 0 ? void 0 : onLessonStatusChange(); }) .catch((error) => { setLoading(false); console.log(error); }); }; /** * Handles complete lesson dialog close */ const handleCloseDialog = (0, react_1.useCallback)(() => { setOpenDialog(false); }, [setOpenDialog]); /** * Rendering */ if (!scLesson || !scCourse) { return (0, jsx_runtime_1.jsx)(react_ui_1.HiddenPlaceholder, {}); } return ((0, jsx_runtime_1.jsxs)(react_1.Fragment, { children: [(0, jsx_runtime_1.jsxs)(Root, Object.assign({ className: (0, classnames_1.default)(classes.root, className) }, rest, { children: [(0, jsx_runtime_1.jsx)(react_ui_1.LessonAppbar, Object.assign({ showComments: scLesson.comments_enabled, editMode: editMode, activePanel: activePanel, title: scCourse.name, handleOpen: handleOpenDrawer, onSave: handleLessonUpdate, updating: updating }, LessonAppbarProps)), (0, jsx_runtime_1.jsxs)(Container, Object.assign({ open: Boolean(activePanel) || editMode, className: classes.containerRoot }, { children: [previewMode && ((0, jsx_runtime_1.jsx)(material_1.Alert, Object.assign({ severity: "info", className: classes.previewInfo }, { children: (0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "body1" }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "templates.lesson.previewMode", defaultMessage: "templates.lesson.previewMode", values: { link: (chunks) => ((0, jsx_runtime_1.jsx)(react_core_1.Link, Object.assign({ to: scRoutingContext.url(react_core_1.SCRoutes.COURSE_LESSON_EDIT_ROUTE_NAME, (0, react_ui_2.getUrlLesson)(scCourse, scLesson)) }, { children: chunks }), "templates.lesson.previewMode.link")), linkBack: (chunks) => ((0, jsx_runtime_1.jsx)(react_core_1.Link, Object.assign({ to: scRoutingContext.url(react_core_1.SCRoutes.COURSE_DASHBOARD_ROUTE_NAME, scCourse) }, { children: chunks }), "templates.lesson.previewMode.linkBack")) } }) })) }))), (0, jsx_runtime_1.jsx)(material_1.Box, Object.assign({ className: classes.navigation }, { children: (0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "body2", color: "text.secondary" }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "templates.lesson.number", defaultMessage: "templates.lesson.number", values: { from: currentLessonIndex + 1, to: availableLessons.length } }) })) })), (0, jsx_runtime_1.jsxs)(material_1.Box, Object.assign({ className: classes.navigationTitle }, { children: [(0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "h5" }, { children: scLesson.name })), (0, jsx_runtime_1.jsxs)(material_1.Box, { children: [(0, jsx_runtime_1.jsx)(material_1.IconButton, Object.assign({ onClick: handlePrev, disabled: isPrevDisabled }, { children: (0, jsx_runtime_1.jsx)(material_1.Icon, { children: "arrow_back" }) })), (0, jsx_runtime_1.jsx)(material_1.IconButton, Object.assign({ onClick: handleNext, disabled: isNextDisabled }, { children: (0, jsx_runtime_1.jsx)(material_1.Icon, { children: "arrow_next" }) }))] })] })), (0, jsx_runtime_1.jsx)(react_ui_1.LessonObject, { course: scCourse, lesson: scLesson, editMode: editMode, onContentChange: handleLessonContentEdit, onMediaChange: handleLessonMediaEdit }), !isCourseAdmin && !editMode && !previewMode && ((0, jsx_runtime_1.jsx)(material_1.Button, Object.assign({ className: classes.button, loading: loading, size: "small", variant: completed ? 'outlined' : 'contained', startIcon: !completed && (0, jsx_runtime_1.jsx)(material_1.Icon, { children: "arrow_next" }), endIcon: completed && (0, jsx_runtime_1.jsx)(material_1.Icon, { children: "circle_checked" }), onClick: toggleLessonCompletion }, { children: completed ? ((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "templates.lesson.button.completed", defaultMessage: "templates.lesson.button.completed" })) : ((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "templates.lesson.button.complete", defaultMessage: "templates.lesson.button.complete" })) })))] })), (0, jsx_runtime_1.jsx)(react_ui_1.LessonDrawer, Object.assign({ course: scCourse, lesson: scLesson, editMode: isMobile ? activePanel === react_ui_1.SCLessonActionsType.SETTINGS : editMode, previewMode: previewMode, activePanel: activePanel, handleClose: handleCloseDrawer, handleChangeLesson: handleChangeLesson, LessonEditFormProps: { lesson: scLesson, onSave: handleLessonUpdate, updating: updating, onSettingsChange: handleSettingsChange } }, LessonDrawerProps))] })), openDialog && (0, jsx_runtime_1.jsx)(react_ui_1.CourseCompletedDialog, { course: scCourse, onClose: handleCloseDialog })] })); } exports.default = Lesson;