UNPKG

@selfcommunity/react-ui

Version:

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

194 lines (193 loc) • 12.3 kB
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime"; import { FormattedMessage, useIntl } from 'react-intl'; import { PREFIX } from './constants'; import { memo, useCallback, useEffect, useMemo, useRef, useState } from 'react'; import { DragDropContext, Draggable, Droppable } from '@hello-pangea/dnd'; import { SCCourseTypologyType } from '@selfcommunity/types'; import { CourseService } from '@selfcommunity/api-services'; import { Logger } from '@selfcommunity/utils'; import { SCOPE_SC_UI } from '../../constants/Errors'; import { useSnackbar } from 'notistack'; import { Box, Stack, Table, TableBody, TableCell, TableContainer, TableHead, TableRow, Typography } from '@mui/material'; import Status from './Status'; import EmptyStatus from '../../shared/EmptyStatus'; import AddButton from './Lessons/AddButton'; import SectionRow from './Lessons/SectionRow'; import { ActionLessonType, RowType } from './types'; import { useIsDisabled } from './hooks'; import ConfirmDialog from '../../shared/ConfirmDialog/ConfirmDialog'; import CourseTypePopover from '../../shared/CourseTypePopover'; import classNames from 'classnames'; const classes = { lessonTitle: `${PREFIX}-lesson-title`, lessonInfoWrapper: `${PREFIX}-lesson-info-wrapper`, lessonsInnerWrapper: `${PREFIX}-lessons-inner-wrapper`, lessonsSectionsWrapper: `${PREFIX}-lessons-sections-wrapper`, lessonsSections: `${PREFIX}-lessons-sections`, circle: `${PREFIX}-circle`, tableContainer: `${PREFIX}-table-container`, table: `${PREFIX}-table`, tableHeader: `${PREFIX}-table-header`, tableHeaderTypography: `${PREFIX}-table-header-typography`, tableBody: `${PREFIX}-table-body`, cellWidth: `${PREFIX}-cell-width`, cellAlignRight: `${PREFIX}-cell-align-right`, cellAlignCenter: `${PREFIX}-cell-align-center`, lessonEmptyStatus: `${PREFIX}-lesson-empty-status`, emptyStatusButton: `${PREFIX}-empty-status-button`, contrastColor: `${PREFIX}-contrast-color` }; function Lessons(props) { // PROPS const { course, setCourse, handleTabChange } = props; // STATES const [sections, setSections] = useState([]); const [dialog, setDialog] = useState(null); // REFS const ref = useRef(null); // HOOKS const { isDisabled } = useIsDisabled(); const { enqueueSnackbar } = useSnackbar(); const intl = useIntl(); // EFFECTS useEffect(() => { if (course.sections) { setSections(course.sections); } }, [course]); // MEMOS const isNewRow = useMemo(() => { var _a; return sections.length > ((_a = course.sections) === null || _a === void 0 ? void 0 : _a.length); }, [course, sections]); const headerCells = useMemo(() => [ { className: undefined, id: 'ui.editCourse.tab.lessons.table.header.lessonName' }, ...(course.type !== SCCourseTypologyType.SELF ? [ { className: classes.cellAlignCenter, id: 'ui.editCourse.tab.lessons.table.header.calendar' } ] : []), { className: classes.cellAlignRight, id: 'ui.editCourse.tab.lessons.table.header.actions' } ], [course]); // FUNCTIONS const getSection = useCallback((id) => { return { id, name: intl.formatMessage({ id: 'ui.editCourse.tab.lessons.table.newSection', defaultMessage: 'ui.editCourse.tab.lessons.table.newSection' }, { num: id }) }; }, []); // HANDLERS const handleDragEnd = useCallback((e) => { if (!e.destination || e.destination.index === e.source.index) { return; } const tempSections = Array.from(course.sections); const [sourceData] = tempSections.splice(e.source.index, 1); tempSections.splice(e.destination.index, 0, sourceData); const data = { sections_order: tempSections.map((tempSection) => tempSection.id) }; CourseService.patchCourse(course.id, data) .then(() => { setCourse(Object.assign(Object.assign({}, course), { sections: tempSections })); enqueueSnackbar(_jsx(FormattedMessage, { id: "ui.editCourse.tab.lessons.table.snackbar.save", defaultMessage: "ui.editCourse.tab.lessons.table.snackbar.save" }), { variant: 'success', autoHideDuration: 3000 }); }) .catch((error) => { Logger.error(SCOPE_SC_UI, error); enqueueSnackbar(_jsx(FormattedMessage, { id: "ui.common.error.action", defaultMessage: "ui.common.error.action" }), { variant: 'error', autoHideDuration: 3000 }); }); }, [course]); const handleAddTempSection = useCallback(() => { setSections((prevSections) => (prevSections.length > 0 ? [...prevSections, getSection(prevSections.length + 1)] : [getSection(1)])); }, [setSections]); const handleManageSection = useCallback((section, type, newRow = false) => { switch (type) { case ActionLessonType.ADD: { const newSection = Object.assign(Object.assign({}, section), { lessons: [] }); setCourse(Object.assign(Object.assign({}, course), { num_sections: course.num_sections + 1, sections: [...course.sections, newSection] })); break; } case ActionLessonType.RENAME: setCourse(Object.assign(Object.assign({}, course), { sections: course.sections.map((prevSection) => { if (prevSection.id === section.id) { return Object.assign(Object.assign({}, prevSection), { name: section.name }); } return prevSection; }) })); break; case ActionLessonType.DELETE: { if (newRow) { setCourse(Object.assign(Object.assign({}, course), { sections: course.sections.filter((prevSection) => prevSection.id !== section.id) })); } else { setCourse(Object.assign(Object.assign({}, course), { num_sections: course.num_sections - 1, num_lessons: course.num_lessons - section.num_lessons, sections: course.sections.filter((prevSection) => prevSection.id !== section.id) })); } break; } case ActionLessonType.UPDATE: setCourse(Object.assign(Object.assign({}, course), { sections: course.sections.map((prevSection) => { if (prevSection.id === section.id) { return Object.assign(Object.assign({}, prevSection), { lessons: section.lessons }); } return prevSection; }) })); break; case type.endsWith(ActionLessonType.UPDATE) && type: { if (newRow) { setCourse(Object.assign(Object.assign({}, course), { sections: course.sections.map((prevSection) => { if (prevSection.id === section.id) { return section; } return prevSection; }) })); } else { let numLessons = course.num_lessons; if (type === ActionLessonType.ADD_UPDATE) { numLessons = course.num_lessons + 1; } else if (type === ActionLessonType.DELETE_UPDATE) { numLessons = course.num_lessons - 1; } setCourse(Object.assign(Object.assign({}, course), { num_lessons: numLessons, sections: course.sections.map((prevSection) => { if (prevSection.id === section.id) { return section; } return prevSection; }) })); } } } }, [course]); const handleOpenDialog = useCallback((row) => { setDialog(row); }, [setDialog]); const handleDeleteRow = useCallback(() => { switch (dialog.row) { case RowType.SECTION: ref.current.handleDeleteSection(dialog.section); break; case RowType.LESSON: ref.current.handleDeleteLesson(dialog.section, dialog.lesson); } handleOpenDialog(null); }, [dialog, handleOpenDialog]); return (_jsxs(Box, { children: [_jsx(Typography, Object.assign({ className: classNames(classes.lessonTitle, classes.contrastColor), variant: "h4" }, { children: _jsx(FormattedMessage, { id: "ui.editCourse.tab.lessons", defaultMessage: "ui.editCourse.tab.lessons" }) })), _jsxs(Stack, Object.assign({ className: classes.lessonInfoWrapper }, { children: [_jsx(CourseTypePopover, { course: course }), _jsx(Status, { course: course, handleTabChange: handleTabChange })] })), sections.length === 0 && (_jsx(EmptyStatus, { icon: "courses", title: "ui.editCourse.tab.lessons.table.empty.title", description: "ui.editCourse.tab.lessons.table.empty.description", actions: _jsx(AddButton, { className: classes.emptyStatusButton, label: "ui.editCourse.tab.lessons.table.section", handleAddRow: handleAddTempSection, color: "inherit", variant: "outlined" }), className: classes.lessonEmptyStatus })), sections.length > 0 && (_jsxs(Box, Object.assign({ className: classes.lessonsInnerWrapper }, { children: [_jsxs(Stack, Object.assign({ className: classes.lessonsSectionsWrapper }, { children: [_jsxs(Stack, Object.assign({ className: classes.lessonsSections }, { children: [_jsx(Typography, Object.assign({ variant: "h5" }, { children: _jsx(FormattedMessage, { id: "ui.course.table.sections.title", defaultMessage: "ui.course.table.sections.title", values: { sectionsNumber: course.num_sections } }) })), _jsx(Box, { className: classes.circle }), _jsx(Typography, Object.assign({ variant: "h5" }, { children: _jsx(FormattedMessage, { id: "ui.course.table.lessons.title", defaultMessage: "ui.course.table.lessons.title", values: { lessonsNumber: course.num_lessons } }) }))] })), _jsx(AddButton, { label: "ui.editCourse.tab.lessons.table.section", handleAddRow: handleAddTempSection, color: "primary", variant: "contained", disabled: isDisabled })] })), _jsx(DragDropContext, Object.assign({ onDragEnd: handleDragEnd }, { children: _jsx(TableContainer, Object.assign({ className: classes.tableContainer }, { children: _jsxs(Table, Object.assign({ className: classes.table }, { children: [_jsx(TableHead, Object.assign({ className: classes.tableHeader }, { children: _jsxs(TableRow, { children: [_jsx(TableCell, { className: classes.cellWidth }), headerCells.map((cell, i) => (_jsx(TableCell, Object.assign({ className: cell.className }, { children: _jsx(Typography, Object.assign({ className: classes.tableHeaderTypography, variant: "overline" }, { children: _jsx(FormattedMessage, { id: cell.id, defaultMessage: cell.id }) })) }), i)))] }) })), _jsx(Droppable, Object.assign({ droppableId: "droppable-1" }, { children: (outerProvider) => (_jsxs(TableBody, Object.assign({ ref: outerProvider.innerRef }, outerProvider.droppableProps, { className: classes.tableBody }, { children: [sections.map((section, i, array) => (_jsx(Draggable, Object.assign({ draggableId: i.toString(), index: i, isDragDisabled: isDisabled }, { children: (innerProvider) => (_jsx(SectionRow, { course: course, provider: innerProvider, section: section, isNewRow: isNewRow && i + 1 === array.length, handleManageSection: handleManageSection, handleOpenDialog: handleOpenDialog, ref: ref }, i)) }), i))), outerProvider.placeholder] }))) }))] })) })) })), dialog && _jsx(ConfirmDialog, { open: true, onClose: () => handleOpenDialog(null), onConfirm: handleDeleteRow })] })))] })); } export default memo(Lessons);