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