UNPKG

@selfcommunity/react-ui

Version:

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

193 lines (188 loc) • 10.4 kB
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime"; import { useEffect, useMemo, useState } from 'react'; import { styled } from '@mui/material/styles'; import { Box, Typography, Button, Paper, Container, Radio, Alert } from '@mui/material'; import { useThemeProps } from '@mui/system'; import classNames from 'classnames'; import { LiveStreamType } from '../types'; import { useSnackbar } from 'notistack'; import { FormattedMessage, useIntl } from 'react-intl'; import EventImage from '../../../assets/liveStream/event'; import LiveImage from '../../../assets/liveStream/live'; import { LiveStreamApiClient } from '@selfcommunity/api-services'; import { WARNING_THRESHOLD_EXPIRING_SOON } from '../../LiveStreamRoom/constants'; import { Link, SCPreferences, useSCContext, useSCPreferences, useSCUser } from '@selfcommunity/react-core'; import { SCCommunityEnvironment, SCCommunitySubscriptionTier } from '@selfcommunity/types'; import { HUB_PROD, HUB_STAGE } from '../../PlatformWidget/constants'; export const PREFIX = 'SCLiveStreamSelector'; const classes = { root: `${PREFIX}-root`, warning: `${PREFIX}-warning`, options: `${PREFIX}-options`, actions: `${PREFIX}-actions` }; const Root = styled(Container, { name: PREFIX, slot: 'Root' })(({ theme }) => ({})); // Styled components const OptionCard = styled(Paper, { name: PREFIX, slot: 'optionCardRoot', shouldForwardProp: (prop) => prop !== 'selected' })(({ theme, selected }) => ({ '& h6': { fontWeight: 'bold', textTransform: 'uppercase' } })); const FeatureItem = styled(Box, { name: PREFIX, slot: 'featureItemRoot' })(({ theme }) => ({})); /** *> API documentation for the Community-JS LiveStreamSelector component. Learn about the available props and the CSS API. * #### Import ```jsx import {LiveStreamSelector} from '@selfcommunity/react-ui'; ``` #### Component Name The name `SCLiveStreamSelector` can be used when providing style overrides in the theme. #### CSS |Rule Name|Global class|Description| |---|---|---| |root|.SCCreateLivestreamDialog-root|Styles applied to the root element.| * @param inProps */ export default function LiveStreamSelector(inProps) { //PROPS const props = useThemeProps({ props: inProps, name: PREFIX }); const { className, liveSelected, onLiveSelected, onNext } = props; // CONTEXT const scContext = useSCContext(); const scUserContext = useSCUser(); const { enqueueSnackbar } = useSnackbar(); // STATE const [selectedOption, setSelectedOption] = useState(liveSelected); const [timeRemaining, setTimeRemaining] = useState(null); // HOOKS const { preferences } = useSCPreferences(); const isCommunityOwner = useMemo(() => { var _a; return ((_a = scUserContext === null || scUserContext === void 0 ? void 0 : scUserContext.user) === null || _a === void 0 ? void 0 : _a.id) === 1; }, [scUserContext.user]); const isFreeTrialTier = useMemo(() => preferences && SCPreferences.CONFIGURATIONS_SUBSCRIPTION_TIER in preferences && preferences[SCPreferences.CONFIGURATIONS_SUBSCRIPTION_TIER].value && preferences[SCPreferences.CONFIGURATIONS_SUBSCRIPTION_TIER].value === SCCommunitySubscriptionTier.FREE_TRIAL, [preferences]); const isEnterpriseTier = useMemo(() => preferences && SCPreferences.CONFIGURATIONS_SUBSCRIPTION_TIER in preferences && preferences[SCPreferences.CONFIGURATIONS_SUBSCRIPTION_TIER].value && preferences[SCPreferences.CONFIGURATIONS_SUBSCRIPTION_TIER].value === SCCommunitySubscriptionTier.ENTERPRISE, [preferences]); const isStage = useMemo(() => preferences && SCPreferences.STATIC_ENVIRONMENT in preferences && preferences[SCPreferences.STATIC_ENVIRONMENT].value === SCCommunityEnvironment.STAGE, [preferences]); const communityStackId = useMemo(() => preferences && SCPreferences.STATIC_ENVIRONMENT in preferences && preferences[SCPreferences.STATIC_STACKID].value, [preferences]); const intl = useIntl(); const options = [ { title: intl.formatMessage({ id: 'ui.liveStreamForm.selector.scheduleLiveEvent', defaultMessage: 'ui.liveStreamForm.selector.scheduleLiveEvent' }), image: EventImage, type: LiveStreamType.EVENT_LIVE, features: [ intl.formatMessage({ id: 'ui.liveStreamForm.selector.scheduleLiveEventItem1', defaultMessage: 'ui.liveStreamForm.selector.scheduleLiveEventItem1' }), intl.formatMessage({ id: 'ui.liveStreamForm.selector.scheduleLiveEventItem2', defaultMessage: 'ui.liveStreamForm.selector.scheduleLiveEventItem2' }), intl.formatMessage({ id: 'ui.liveStreamForm.selector.scheduleLiveEventItem3', defaultMessage: 'ui.liveStreamForm.selector.scheduleLiveEventItem3' }) ] }, { title: intl.formatMessage({ id: 'ui.liveStreamForm.selector.scheduleLiveStream', defaultMessage: 'ui.liveStreamForm.selector.scheduleLiveStream' }), image: LiveImage, type: LiveStreamType.DIRECT_LIVE, features: [ intl.formatMessage({ id: 'ui.liveStreamForm.selector.scheduleLiveStreamItem1', defaultMessage: 'ui.liveStreamForm.selector.scheduleLiveStreamItem1' }), intl.formatMessage({ id: 'ui.liveStreamForm.selector.scheduleLiveStreamItem2', defaultMessage: 'ui.liveStreamForm.selector.scheduleLiveStreamItem2' }), intl.formatMessage({ id: 'ui.liveStreamForm.selector.scheduleLiveStreamItem3', defaultMessage: 'ui.liveStreamForm.selector.scheduleLiveStreamItem3' }) ] } ]; const handleOptionSelect = (type) => { setSelectedOption(type); onLiveSelected(type); }; const handleNext = () => { if (!selectedOption) { enqueueSnackbar(_jsx(FormattedMessage, { id: "ui.common.error", defaultMessage: "ui.common.error" }), { variant: 'error', autoHideDuration: 3000 }); } else { onNext && onNext(selectedOption); } }; const fetchLivestreamStatus = () => { LiveStreamApiClient.getMonthlyDuration() .then((r) => { setTimeRemaining(r.remaining_minutes); }) .catch((error) => { console.error('Error fetching live status:', error); }); }; useEffect(() => { fetchLivestreamStatus(); }, []); const warning = useMemo(() => { let _message; if (isFreeTrialTier && isCommunityOwner && !isEnterpriseTier) { _message = (_jsx(FormattedMessage, { id: "ui.liveStreamForm.selector.warningSubscriptionRequired", defaultMessage: "ui.liveStreamForm.selector.warningSubscriptionRequired", values: { // eslint-disable-next-line @typescript-eslint/ban-ts-ignore // @ts-ignore link: (...chunks) => (_jsx(Link, Object.assign({ target: "_blank", to: `${isStage ? HUB_STAGE : HUB_PROD}dashboard/community/${communityStackId}/subscription` }, { children: chunks }))) } })); } else if (timeRemaining !== null && timeRemaining <= WARNING_THRESHOLD_EXPIRING_SOON) { if (timeRemaining <= 1) { _message = (_jsx(FormattedMessage, { id: "ui.liveStreamForm.selector.warningMinutesExausted", defaultMessage: "ui.liveStreamForm.selector.warningMinutesExausted" })); } else if (timeRemaining <= WARNING_THRESHOLD_EXPIRING_SOON) { _message = (_jsx(FormattedMessage, { id: "ui.liveStreamForm.selector.warningRemainingMinutes", defaultMessage: "ui.liveStreamForm.selector.warningRemainingMinutes", values: { minutes: timeRemaining } })); } } if (_message) { return (_jsx(Box, Object.assign({ className: classes.warning }, { children: _jsx(Alert, Object.assign({ variant: "filled", severity: "warning" }, { children: _message })) }))); } return null; }, [timeRemaining, isFreeTrialTier]); return (_jsxs(Root, Object.assign({ className: classNames(classes.root, className), maxWidth: "lg", sx: { py: 4 } }, { children: [_jsx(Typography, Object.assign({ variant: "h4", component: "h1", align: "center", gutterBottom: true, sx: { mb: 4, fontWeight: 500 } }, { children: _jsx(FormattedMessage, { id: "ui.liveStreamForm.selector.title", defaultMessage: "ui.liveStreamForm.selector.title" }) })), warning, _jsx(Box, Object.assign({ className: classes.options }, { children: options.map((option, index) => (_jsxs(OptionCard, Object.assign({ selected: selectedOption === option.type, onClick: () => handleOptionSelect(option.type), elevation: 0, role: "button", tabIndex: 0, onKeyDown: (e) => { if (e.key === 'Enter' || e.key === ' ') { handleOptionSelect(index); e.preventDefault(); } } }, { children: [_jsxs(Box, { children: [_jsx(Typography, Object.assign({ variant: "h6" }, { children: option.title })), _jsx(Radio, { checked: selectedOption === option.type })] }), _jsx("img", { src: option.image, alt: "option-image" }), _jsx(Box, Object.assign({ component: "ul" }, { children: option.features.map((feature, featureIndex) => { return (_jsx(FeatureItem, Object.assign({ component: "li" }, { children: _jsx(Typography, Object.assign({ variant: "body2", color: "text.secondary", sx: { flex: 1 } }, { children: feature })) }), featureIndex)); }) }))] }), index))) })), _jsx(Box, Object.assign({ className: classes.actions }, { children: _jsx(Button, Object.assign({ disabled: !selectedOption || !timeRemaining || isFreeTrialTier, variant: "contained", onClick: handleNext, color: "secondary" }, { children: _jsx(FormattedMessage, { id: "ui.liveStreamForm.selector.next", defaultMessage: "ui.liveStreamForm.selector.next" }) })) }))] }))); }