@selfcommunity/react-ui
Version:
React UI Components to integrate a Community created with SelfCommunity Platform.
185 lines (176 loc) • 18 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
const jsx_runtime_1 = require("react/jsx-runtime");
const material_1 = require("@mui/material");
const system_1 = require("@mui/system");
const react_core_1 = require("@selfcommunity/react-core");
const types_1 = require("@selfcommunity/types");
const classnames_1 = tslib_1.__importDefault(require("classnames"));
const react_1 = require("react");
const react_intl_1 = require("react-intl");
const course_1 = require("../../types/course");
const CourseParticipantsButton_1 = tslib_1.__importDefault(require("../CourseParticipantsButton"));
const Widget_1 = tslib_1.__importDefault(require("../Widget"));
const constants_1 = require("./constants");
const Skeleton_1 = tslib_1.__importDefault(require("./Skeleton"));
const course_2 = require("../../utils/course");
const UserAvatar_1 = tslib_1.__importDefault(require("../../shared/UserAvatar"));
const BaseItemButton_1 = tslib_1.__importDefault(require("../../shared/BaseItemButton"));
const classes = {
root: `${constants_1.PREFIX}-root`,
chip: `${constants_1.PREFIX}-chip`,
previewRoot: `${constants_1.PREFIX}-preview-root`,
previewActions: `${constants_1.PREFIX}-preview-actions`,
previewAvatar: `${constants_1.PREFIX}-preview-avatar`,
previewCategory: `${constants_1.PREFIX}-preview-category`,
previewCompletedStatus: `${constants_1.PREFIX}-preview-completed-status`,
previewContent: `${constants_1.PREFIX}-preview-content`,
previewCreator: `${constants_1.PREFIX}-preview-creator`,
previewImage: `${constants_1.PREFIX}-preview-image`,
previewImageWrapper: `${constants_1.PREFIX}-preview-image-wrapper`,
previewInfo: `${constants_1.PREFIX}-preview-info`,
previewName: `${constants_1.PREFIX}-preview-name`,
previewNameWrapper: `${constants_1.PREFIX}-preview-name-wrapper`,
previewProgress: `${constants_1.PREFIX}-preview-progress`,
previewProgressBar: `${constants_1.PREFIX}-preview-progress-bar`,
snippetRoot: `${constants_1.PREFIX}-snippet-root`,
snippetAvatar: `${constants_1.PREFIX}-snippet-avatar`,
snippetAvatarUserProfile: `${constants_1.PREFIX}-snippet-avatar-user-profile-view`,
snippetImage: `${constants_1.PREFIX}-snippet-image`
};
const Root = (0, material_1.styled)(Widget_1.default, {
name: constants_1.PREFIX,
slot: 'Root',
overridesResolver: (_props, styles) => styles.root
})(() => ({}));
const PreviewRoot = (0, material_1.styled)(material_1.Box, {
name: constants_1.PREFIX,
slot: 'PreviewRoot',
overridesResolver: (_props, styles) => styles.previewRoot
})(() => ({}));
const SnippetRoot = (0, material_1.styled)(BaseItemButton_1.default, {
name: constants_1.PREFIX,
slot: 'SnippetRoot',
overridesResolver: (_props, styles) => styles.snippetRoot
})(() => ({}));
/**
* > API documentation for the Community-JS Course component. Learn about the available props and the CSS API.
*
*
* This component renders a course item.
* Take a look at our <strong>demo</strong> component [here](/docs/sdk/community-js/react-ui/Components/Course)
#### Import
```jsx
import {course} from '@selfcommunity/react-ui';
```
#### Component Name
The name `SCCourse` can be used when providing style overrides in the theme.
#### CSS
|Rule Name|Global class|Description|
|---|---|---|
|root|.SCCourses-root|Styles applied to the root element.|
|chip|.SCCourses-chip|Styles applied to the chip element.|
|previewRoot|.SCCourses-preview-root|Styles applied to the root element in the preview template.|
|previewActions|.SCCourses-preview-actions|Styles applied to the actions section in the preview template.|
|previewAvatar|.SCCourses-preview-avatar|Styles applied to the avatar in the preview template.|
|previewCategory|.SCCourses-preview-category|Styles applied to the category element in the preview template.|
|previewCompletedStatus|.SCCourses-preview-completed-status|Styles applied to indicate the completed status in the preview template.|
|previewContent|.SCCourses-preview-content|Styles applied to the content section in the preview template.|
|previewCreator|.SCCourses-preview-creator|Styles applied to the creator element in the preview template.|
|previewImage|.SCCourses-preview-image|Styles applied to the image in the preview template.|
|previewImageWrapper|.SCCourses-preview-image-wrapper|Styles applied to the wrapper of the image in the preview template.|
|previewInfo|.SCCourses-preview-info|Styles applied to the info section in the preview template.|
|previewName|.SCCourses-preview-name|Styles applied to the name element in the preview template.|
|previewNameWrapper|.SCCourses-preview-name-wrapper|Styles applied to the name wrapper in the preview template.|
|previewProgress|.SCCourses-preview-progress|Styles applied to indicate the progress section in the preview template.|
|previewProgressBar|.SCCourses-preview-progress-bar|Styles applied to the progress bar in the preview template.|
|snippetRoot|.SCCourses-snippet-root|Styles applied to the root element in the snippet template.|
|snippetAvatar|.SCCourses-snippet-avatar|Styles applied to the avatar element in the snippet template.|
|snippetImage|.SCCourses-snippet-image|Styles applied to the image element in the snippet template.|
*
* @param inProps
*/
function Course(inProps) {
var _a, _b, _c, _d, _e, _f, _g;
// PROPS
const props = (0, system_1.useThemeProps)({
props: inProps,
name: constants_1.PREFIX
});
const { id = `course_object_${props.courseId ? props.courseId : props.course ? props.course.id : ''}`, courseId = null, course = null, className = null, template = course_1.SCCourseTemplateType.PREVIEW, actions, CourseParticipantsButtonComponentProps = {}, CourseSkeletonComponentProps = {}, userProfileSnippet } = props, rest = tslib_1.__rest(props, ["id", "courseId", "course", "className", "template", "actions", "CourseParticipantsButtonComponentProps", "CourseSkeletonComponentProps", "userProfileSnippet"]);
// STATE
const { scCourse } = (0, react_core_1.useSCFetchCourse)({ id: courseId, course });
const theme = (0, material_1.useTheme)();
const isMobile = (0, material_1.useMediaQuery)(theme.breakpoints.between('xs', 'md'));
const MAX_VISIBLE_CATEGORIES = isMobile ? 3 : 1;
// CONTEXT
const scRoutingContext = (0, react_core_1.useSCRouting)();
const isCourseAdmin = (0, react_1.useMemo)(() => scCourse && (scCourse.join_status === types_1.SCCourseJoinStatusType.CREATOR || scCourse.join_status === types_1.SCCourseJoinStatusType.MANAGER), [scCourse]);
/**
* Renders course object
*/
if (!scCourse) {
return (0, jsx_runtime_1.jsx)(Skeleton_1.default, Object.assign({ template: template }, CourseSkeletonComponentProps, rest, { actions: actions }));
}
const renderProgress = () => {
if ((0, course_2.isCourseCompleted)(scCourse)) {
return ((0, jsx_runtime_1.jsxs)(material_1.Box, Object.assign({ className: classes.previewCompletedStatus }, { children: [(0, jsx_runtime_1.jsx)(material_1.Icon, Object.assign({ color: "success" }, { children: "circle_checked" })), (0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "body1" }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { defaultMessage: "ui.course.completed", id: "ui.course.completed" }) }))] })));
}
else if (scCourse.join_status === types_1.SCCourseJoinStatusType.JOINED) {
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(material_1.Typography, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.course.completion.percentage", defaultMessage: "ui.course.completion.percentage", values: { percentage: `${Math.round(scCourse.user_completion_rate)}%` } }) }), (0, jsx_runtime_1.jsx)(material_1.LinearProgress, { className: classes.previewProgressBar, variant: "determinate", color: "primary", value: scCourse.user_completion_rate })] }));
}
else if (isCourseAdmin) {
return (0, jsx_runtime_1.jsx)(CourseParticipantsButton_1.default, Object.assign({ course: scCourse }, CourseParticipantsButtonComponentProps));
}
};
const chipLabel = (() => {
if (isCourseAdmin) {
return scCourse.privacy ? ((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { defaultMessage: "ui.course.status.published", id: "ui.course.status.published" })) : ((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { defaultMessage: "ui.course.status.draft", id: "ui.course.status.draft" }));
}
else if ((0, course_2.isCourseCompleted)(scCourse)) {
return (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { defaultMessage: "ui.course.status.completed", id: "ui.course.status.completed" });
}
else if (scCourse.join_status === types_1.SCCourseJoinStatusType.JOINED) {
return (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { defaultMessage: "ui.course.status.joined", id: "ui.course.status.joined" });
}
else if ((0, course_2.isCourseNew)(scCourse)) {
return (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { defaultMessage: "ui.course.status.new", id: "ui.course.status.new" });
}
return null;
})();
/**
* Renders course object
*/
let contentObj;
if (template === course_1.SCCourseTemplateType.PREVIEW) {
contentObj = ((0, jsx_runtime_1.jsxs)(PreviewRoot, Object.assign({ className: classes.previewRoot }, { children: [(0, jsx_runtime_1.jsxs)(material_1.Box, Object.assign({ className: classes.previewImageWrapper }, { children: [(0, jsx_runtime_1.jsx)(material_1.CardMedia, { component: "img", image: scCourse.image_medium, alt: scCourse.name, className: classes.previewImage }), (isCourseAdmin || (0, course_2.isCourseCompleted)(scCourse) || (0, course_2.isCourseNew)(scCourse) || scCourse.join_status === types_1.SCCourseJoinStatusType.JOINED) && ((0, jsx_runtime_1.jsx)(material_1.Chip, { size: "small", component: "div", color: (0, course_2.isCourseCompleted)(scCourse) || (isCourseAdmin && scCourse.privacy)
? 'primary'
: isCourseAdmin && !scCourse.privacy
? 'default'
: scCourse.join_status === types_1.SCCourseJoinStatusType.JOINED
? 'warning'
: 'secondary', label: chipLabel, className: classes.chip })), (0, jsx_runtime_1.jsx)(react_core_1.Link, Object.assign({}, (!((_a = scCourse.created_by) === null || _a === void 0 ? void 0 : _a.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: !((_b = scCourse.created_by) === null || _b === void 0 ? void 0 : _b.community_badge), smaller: true }, { children: (0, jsx_runtime_1.jsx)(material_1.Avatar, { alt: scCourse.name, src: (_c = scCourse.created_by) === null || _c === void 0 ? void 0 : _c.avatar, className: classes.previewAvatar }) })) }))] })), (0, jsx_runtime_1.jsxs)(material_1.CardContent, Object.assign({ className: classes.previewContent }, { children: [(0, jsx_runtime_1.jsx)(react_core_1.Link, Object.assign({ className: classes.previewCreator }, (!((_d = scCourse.created_by) === null || _d === void 0 ? void 0 : _d.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: "body2" }, { children: (_e = scCourse.created_by) === null || _e === void 0 ? void 0 : _e.username })) })), (0, jsx_runtime_1.jsx)(react_core_1.Link, Object.assign({ to: scRoutingContext.url(react_core_1.SCRoutes.COURSE_ROUTE_NAME, scCourse), className: classes.previewNameWrapper }, { children: (0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "h6", className: classes.previewName }, { children: scCourse.name })) })), (0, jsx_runtime_1.jsxs)(material_1.Typography, Object.assign({ className: classes.previewInfo }, { children: [(0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: scCourse.privacy ? `ui.course.privacy.${scCourse.privacy}` : 'ui.course.privacy.draft', defaultMessage: scCourse.privacy ? `ui.course.privacy.${scCourse.privacy}` : 'ui.course.privacy.draft' }), ' - ', (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: `ui.course.type.${scCourse.type}`, defaultMessage: `ui.course.type.${scCourse.type}` })] })), (0, jsx_runtime_1.jsxs)(material_1.Box, Object.assign({ className: classes.previewCategory }, { children: [scCourse.categories.slice(0, MAX_VISIBLE_CATEGORIES).map((category) => ((0, jsx_runtime_1.jsx)(material_1.Chip, { size: "small", label: category.name }, category.id))), scCourse.categories.length > MAX_VISIBLE_CATEGORIES && ((0, jsx_runtime_1.jsx)(material_1.Tooltip, Object.assign({ title: (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: scCourse.categories.slice(MAX_VISIBLE_CATEGORIES).map((cat) => ((0, jsx_runtime_1.jsx)(material_1.Box, { children: cat.name }, cat.id))) }) }, { children: (0, jsx_runtime_1.jsx)(material_1.Chip, { size: "small", label: `+${scCourse.categories.length - MAX_VISIBLE_CATEGORIES}`, sx: { cursor: 'pointer' } }) })))] })), (0, jsx_runtime_1.jsx)(material_1.Box, Object.assign({ className: classes.previewProgress }, { children: renderProgress() }))] })), actions !== null && actions !== void 0 ? actions : ((0, jsx_runtime_1.jsx)(material_1.CardActions, Object.assign({ className: classes.previewActions }, { children: (0, jsx_runtime_1.jsx)(material_1.Button, Object.assign({ variant: "outlined", size: "small", component: react_core_1.Link, to: scRoutingContext.url(react_core_1.SCRoutes.COURSE_ROUTE_NAME, scCourse) }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { defaultMessage: "ui.course.see", id: "ui.course.see" }) })) })))] })));
}
else {
contentObj = ((0, jsx_runtime_1.jsx)(SnippetRoot, { ButtonBaseProps: { component: react_core_1.Link, to: scRoutingContext.url(react_core_1.SCRoutes.COURSE_ROUTE_NAME, scCourse) }, elevation: 0, className: classes.snippetRoot, image: (0, jsx_runtime_1.jsxs)(material_1.Box, Object.assign({ className: classes.snippetImage }, { children: [(0, jsx_runtime_1.jsx)(material_1.Avatar, { variant: "square", alt: scCourse.name, src: scCourse.image_medium, className: userProfileSnippet ? classes.snippetAvatarUserProfile : classes.snippetAvatar }), !userProfileSnippet &&
(isCourseAdmin || (0, course_2.isCourseCompleted)(scCourse) || (0, course_2.isCourseNew)(scCourse) || scCourse.join_status === types_1.SCCourseJoinStatusType.JOINED) && ((0, jsx_runtime_1.jsx)(material_1.Chip, { size: "small", component: "div", color: (0, course_2.isCourseCompleted)(scCourse) || (isCourseAdmin && scCourse.privacy)
? 'primary'
: isCourseAdmin && !scCourse.privacy
? 'default'
: scCourse.join_status === types_1.SCCourseJoinStatusType.JOINED
? 'warning'
: 'secondary', label: chipLabel, className: classes.chip }))] })), primary: (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [!userProfileSnippet && ((0, jsx_runtime_1.jsx)(react_core_1.Link, Object.assign({}, (!((_f = scCourse.created_by) === null || _f === void 0 ? void 0 : _f.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({ component: "span" }, { children: (_g = scCourse.created_by) === null || _g === void 0 ? void 0 : _g.username })) }))), (0, jsx_runtime_1.jsx)(react_core_1.Link, Object.assign({ to: scRoutingContext.url(react_core_1.SCRoutes.COURSE_ROUTE_NAME, scCourse) }, { children: (0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "body1" }, { children: scCourse.name })) }))] }), secondary: (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: userProfileSnippet ? ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: !scCourse.hide_member_count && ((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.course.userProfileSnippet.students", defaultMessage: "ui.course.userProfileSnippet.students", values: { students: scCourse.member_count } })) })) : ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: scCourse.privacy ? `ui.course.privacy.${scCourse.privacy}` : 'ui.course.privacy.draft', defaultMessage: scCourse.privacy ? `ui.course.privacy.${scCourse.privacy}` : 'ui.course.privacy.draft' }), ' - ', (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: `ui.course.type.${scCourse.type}`, defaultMessage: `ui.course.type.${scCourse.type}` })] })) }), actions: actions !== null && actions !== void 0 ? actions : ((0, jsx_runtime_1.jsx)(material_1.Button, Object.assign({ size: "small", variant: "outlined", component: react_core_1.Link, to: scRoutingContext.url(react_core_1.SCRoutes.COURSE_ROUTE_NAME, scCourse) }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { defaultMessage: "ui.course.see", id: "ui.course.see" }) }))) }));
}
/**
* Renders root object
*/
return ((0, jsx_runtime_1.jsx)(Root, Object.assign({ id: id, className: (0, classnames_1.default)(classes.root, className, `${constants_1.PREFIX}-${template}`) }, rest, { children: contentObj })));
}
exports.default = Course;