UNPKG

@selfcommunity/react-ui

Version:

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

146 lines (137 loc) 6.12 kB
import { __rest } from "tslib"; import { jsx as _jsx } from "react/jsx-runtime"; import { useEffect, useMemo, useState } from 'react'; import { styled } from '@mui/material'; import { CacheStrategies, Logger } from '@selfcommunity/utils'; import { useSCContext, useSCFetchCourse, useSCUser } from '@selfcommunity/react-core'; import { SCCoursePrivacyType, SCCourseJoinStatusType } from '@selfcommunity/types'; import { LoadingButton } from '@mui/lab'; import { FormattedMessage } from 'react-intl'; import classNames from 'classnames'; import { useThemeProps } from '@mui/system'; import { SCOPE_SC_UI } from '../../constants/Errors'; import { SCCourseEventType, SCTopicType } from '../../constants/PubSub'; import PubSub from 'pubsub-js'; const PREFIX = 'SCCourseJoinButton'; const classes = { root: `${PREFIX}-root` }; const Root = styled(LoadingButton, { name: PREFIX, slot: 'Root', overridesResolver: (props, styles) => styles.root })(({ theme }) => ({})); /** * > API documentation for the Community-JS Course Subscribe Button component. Learn about the available props and the CSS API. #### Import ```jsx import {CourseJoinButton} from '@selfcommunity/react-ui'; ``` #### Component Name The name `SCCourseJoinButton` can be used when providing style overrides in the theme. #### CSS |Rule Name|Global class|Description| |---|---|---| |root|.SCCourseJoinButton-root|Styles applied to the root element.| * @param inProps */ export default function CourseJoinButton(inProps) { // PROPS const props = useThemeProps({ props: inProps, name: PREFIX }); const { className, courseId, course, user, onJoin } = props, rest = __rest(props, ["className", "courseId", "course", "user", "onJoin"]); // STATE const [status, setStatus] = useState(null); // CONTEXT const scContext = useSCContext(); const scUserContext = useSCUser(); const scCoursesManager = scUserContext.managers.courses; // CONST const authUserId = scUserContext.user ? scUserContext.user.id : null; const { scCourse } = useSCFetchCourse({ id: courseId, course, cacheStrategy: authUserId ? CacheStrategies.CACHE_FIRST : CacheStrategies.STALE_WHILE_REVALIDATE }); const isCourseAdmin = useMemo(() => scCourse && scCourse.join_status === SCCourseJoinStatusType.CREATOR, [scCourse]); useEffect(() => { /** * Call scCoursesManager.joinStatus inside an effect * to avoid warning rendering child during update parent state */ if (authUserId) { setStatus(scCoursesManager.joinStatus(scCourse)); } }, [authUserId, scCoursesManager.joinStatus, scCourse]); /** * Notify UI when a member is added to a course * @param course * @param user */ function notifyChanges(course, user) { if (course && user) { PubSub.publish(`${SCTopicType.GROUP}.${SCCourseEventType.ADD_MEMBER}`, { course, user }); } } const join = (user) => { scCoursesManager .join(scCourse, user === null || user === void 0 ? void 0 : user.id) .then(() => { const _status = scCourse.privacy === SCCoursePrivacyType.PRIVATE && scCourse.join_status !== SCCourseJoinStatusType.INVITED ? SCCourseJoinStatusType.REQUESTED : SCCourseJoinStatusType.JOINED; notifyChanges(scCourse, user); onJoin && onJoin(scCourse, _status); }) .catch((e) => { Logger.error(SCOPE_SC_UI, e); }); }; const leave = () => { scCoursesManager .leave(scCourse) .then(() => { onJoin && onJoin(scCourse, null); }) .catch((e) => { Logger.error(SCOPE_SC_UI, e); }); }; const handleClick = () => { if (!scUserContext.user) { scContext.settings.handleAnonymousAction(); } else { status === SCCourseJoinStatusType.JOINED && !(user === null || user === void 0 ? void 0 : user.id) ? leave() : (user === null || user === void 0 ? void 0 : user.id) ? join(user) : join(); } }; /** * Get current translated status */ const getStatus = useMemo(() => { let _status; switch (status) { case SCCourseJoinStatusType.REQUESTED: _status = _jsx(FormattedMessage, { defaultMessage: "ui.courseJoinButton.waitingApproval", id: "ui.courseJoinButton.waitingApproval" }); break; case SCCourseJoinStatusType.JOINED: _status = _jsx(FormattedMessage, { defaultMessage: "ui.courseJoinButton.leave", id: "ui.courseJoinButton.leave" }); break; case SCCourseJoinStatusType.INVITED: _status = _jsx(FormattedMessage, { defaultMessage: "ui.courseJoinButton.accept", id: "ui.courseJoinButton.accept" }); break; default: scCourse.privacy === SCCoursePrivacyType.OPEN ? (_status = _jsx(FormattedMessage, { defaultMessage: "ui.courseJoinButton.join", id: "ui.courseJoinButton.join" })) : (_status = _jsx(FormattedMessage, { defaultMessage: "ui.courseJoinButton.requestAccess", id: "ui.courseJoinButton.requestAccess" })); break; } return _status; }, [status, scCourse]); if (!scCourse || (isCourseAdmin && (user === null || user === void 0 ? void 0 : user.id) === scUserContext.user.id) || (isCourseAdmin && !(user === null || user === void 0 ? void 0 : user.id))) { return null; } return (_jsx(Root, Object.assign({ size: "small", variant: "outlined", onClick: handleClick, loading: scUserContext.user ? scCoursesManager.isLoading(scCourse) : null, disabled: status === SCCourseJoinStatusType.REQUESTED, className: classNames(classes.root, className) }, rest, { children: isCourseAdmin ? _jsx(FormattedMessage, { defaultMessage: "ui.courseJoinButton.accept", id: "ui.courseJoinButton.accept" }) : getStatus }))); }