@selfcommunity/react-templates
Version:
React Templates Components to integrate a Community created with SelfCommunity.
200 lines (199 loc) • 13.5 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 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;