@selfcommunity/react-ui
Version:
React UI Components to integrate a Community created with SelfCommunity Platform.
194 lines (193 loc) • 12.3 kB
JavaScript
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);