@selfcommunity/react-ui 0.9.0-alpha.9 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/lib/cjs/assets/onBoarding/android.d.ts +1 -1
  2. package/lib/cjs/assets/onBoarding/android.js +1 -1
  3. package/lib/cjs/components/EventHeader/EventHeader.js +5 -40
  4. package/lib/cjs/components/EventMembersWidget/TabContentComponent.js +1 -1
  5. package/lib/cjs/components/EventSubscribeButton/EventSubscribeButton.d.ts +2 -2
  6. package/lib/cjs/components/EventSubscribeButton/EventSubscribeButton.js +14 -16
  7. package/lib/cjs/components/Events/Events.js +3 -4
  8. package/lib/cjs/components/NavigationSettingsIconButton/NavigationSettingsIconButton.js +35 -2
  9. package/lib/cjs/components/NavigationToolbar/NavigationToolbar.js +1 -1
  10. package/lib/cjs/components/OnBoardingWidget/ActionsButton.d.ts +7 -0
  11. package/lib/cjs/components/OnBoardingWidget/ActionsButton.js +84 -0
  12. package/lib/cjs/components/OnBoardingWidget/OnBoardingWidget.js +44 -19
  13. package/lib/cjs/components/OnBoardingWidget/Steps/App/App.js +2 -1
  14. package/lib/cjs/components/UserProfileEdit/Section/PublicInfo.js +2 -1
  15. package/lib/cjs/shared/EventActionsMenu/index.js +11 -15
  16. package/lib/cjs/utils/events.d.ts +2 -0
  17. package/lib/cjs/utils/events.js +10 -0
  18. package/lib/esm/assets/onBoarding/android.d.ts +1 -1
  19. package/lib/esm/assets/onBoarding/android.js +1 -1
  20. package/lib/esm/components/EventHeader/EventHeader.js +6 -41
  21. package/lib/esm/components/EventMembersWidget/TabContentComponent.js +1 -1
  22. package/lib/esm/components/EventSubscribeButton/EventSubscribeButton.d.ts +2 -2
  23. package/lib/esm/components/EventSubscribeButton/EventSubscribeButton.js +16 -18
  24. package/lib/esm/components/Events/Events.js +3 -4
  25. package/lib/esm/components/NavigationSettingsIconButton/NavigationSettingsIconButton.js +38 -5
  26. package/lib/esm/components/NavigationToolbar/NavigationToolbar.js +1 -1
  27. package/lib/esm/components/OnBoardingWidget/ActionsButton.d.ts +7 -0
  28. package/lib/esm/components/OnBoardingWidget/ActionsButton.js +81 -0
  29. package/lib/esm/components/OnBoardingWidget/OnBoardingWidget.js +46 -21
  30. package/lib/esm/components/OnBoardingWidget/Steps/App/App.js +2 -1
  31. package/lib/esm/components/UserProfileEdit/Section/PublicInfo.js +2 -1
  32. package/lib/esm/shared/EventActionsMenu/index.js +11 -15
  33. package/lib/esm/utils/events.d.ts +2 -0
  34. package/lib/esm/utils/events.js +6 -0
  35. package/lib/umd/react-ui.js +1 -1
  36. package/package.json +7 -7
@@ -6,13 +6,12 @@ import { useThemeProps } from '@mui/system';
6
6
  import { SCPreferences, useSCFetchEvent, useSCPreferences, useSCUser } from '@selfcommunity/react-core';
7
7
  import { SCEventLocationType, SCEventPrivacyType } from '@selfcommunity/types';
8
8
  import classNames from 'classnames';
9
- import PubSub from 'pubsub-js';
10
- import { useCallback, useEffect, useMemo, useRef } from 'react';
9
+ import { useMemo } from 'react';
11
10
  import { FormattedMessage, useIntl } from 'react-intl';
12
- import { SCGroupEventType, SCTopicType } from '../../constants/PubSub';
13
11
  import Bullet from '../../shared/Bullet';
14
12
  import Calendar from '../../shared/Calendar';
15
13
  import EventActionsMenu from '../../shared/EventActionsMenu';
14
+ import { checkEventFinished } from '../../utils/events';
16
15
  import EditEventButton from '../EditEventButton';
17
16
  import EventInviteButton from '../EventInviteButton';
18
17
  import EventSubscribeButton from '../EventSubscribeButton';
@@ -89,49 +88,15 @@ export default function EventHeader(inProps) {
89
88
  const isMobile = useMediaQuery(theme.breakpoints.down('md'));
90
89
  // INTL
91
90
  const intl = useIntl();
92
- // REFS
93
- const updatesSubscription = useRef(null);
94
91
  // CONST
95
92
  const isEventAdmin = useMemo(() => scUserContext.user && (scEvent === null || scEvent === void 0 ? void 0 : scEvent.managed_by.id) === scUserContext.user.id, [scUserContext.user, scEvent === null || scEvent === void 0 ? void 0 : scEvent.managed_by.id]);
96
- const isEventFinished = useMemo(() => {
97
- if (scEvent && !scEvent.running) {
98
- return new Date().getTime() > new Date(scEvent.end_date || scEvent.start_date).getTime();
99
- }
100
- return false;
101
- }, [scEvent]);
102
- /**
103
- * Subscriber for pubsub callback
104
- */
105
- const onChangeEventMembersHandler = useCallback((msg, data) => {
106
- var _a;
107
- if (data && ((_a = data === null || data === void 0 ? void 0 : data.event) === null || _a === void 0 ? void 0 : _a.id) === (scEvent === null || scEvent === void 0 ? void 0 : scEvent.id)) {
108
- let _event = Object.assign({}, scEvent);
109
- if (msg === `${SCTopicType.GROUP}.${SCGroupEventType.ADD_MEMBER}`) {
110
- _event.subscribers_counter = _event.subscribers_counter + 1;
111
- }
112
- else if (msg === `${SCTopicType.GROUP}.${SCGroupEventType.REMOVE_MEMBER}`) {
113
- _event.subscribers_counter = Math.max(_event.subscribers_counter - 1, 0);
114
- }
115
- setSCEvent(_event);
116
- }
117
- }, [scEvent, setSCEvent]);
93
+ const isEventFinished = useMemo(() => checkEventFinished(scEvent), [scEvent]);
118
94
  /**
119
95
  * Handles callback subscribe/unsubscribe event
120
96
  */
121
- const handleSubscribe = (_event, status) => {
122
- setSCEvent(Object.assign({}, scEvent, { subscription_status: status }));
97
+ const handleSubscribe = (event) => {
98
+ setSCEvent(event);
123
99
  };
124
- /**
125
- * On mount, subscribe to receive events updates (only edit)
126
- */
127
- useEffect(() => {
128
- if (scEvent) {
129
- updatesSubscription.current = PubSub.subscribe(`${SCTopicType.EVENT}.${SCGroupEventType.MEMBERS}`, onChangeEventMembersHandler);
130
- }
131
- return () => {
132
- updatesSubscription.current && PubSub.unsubscribe(updatesSubscription.current);
133
- };
134
- }, [scEvent]);
135
100
  // RENDER
136
101
  if (!scEvent) {
137
102
  return _jsx(EventHeaderSkeleton, {});
@@ -174,5 +139,5 @@ export default function EventHeader(inProps) {
174
139
  month: 'long'
175
140
  }),
176
141
  hour: intl.formatDate(scEvent.start_date, { hour: 'numeric', minute: 'numeric' })
177
- } })) })), _jsx(Typography, Object.assign({ variant: "h5", className: classes.name }, { children: scEvent.name })), _jsxs(Box, Object.assign({ className: classes.visibility }, { children: [_jsx(_Fragment, { children: scEvent.privacy === SCEventPrivacyType.PUBLIC ? (_jsxs(Typography, Object.assign({ className: classes.visibilityItem }, { children: [_jsx(Icon, { children: "public" }), _jsx(FormattedMessage, { id: "ui.eventHeader.visibility.public", defaultMessage: "ui.eventHeader.visibility.public" })] }))) : (_jsxs(Typography, Object.assign({ className: classes.visibilityItem }, { children: [_jsx(Icon, { children: "private" }), _jsx(FormattedMessage, { id: "ui.eventHeader.visibility.private", defaultMessage: "ui.eventHeader.visibility.private" })] }))) }), _jsx(Bullet, {}), _jsx(Typography, Object.assign({ className: classes.visibilityItem }, { children: scEvent.location === SCEventLocationType.PERSON ? (_jsx(FormattedMessage, { id: "ui.eventHeader.location.live", defaultMessage: "ui.eventHeader.location.live" })) : (_jsx(FormattedMessage, { id: "ui.eventHeader.location.online", defaultMessage: "ui.eventHeader.location.online" })) }))] })), _jsx(User, { className: classes.planner, userId: scEvent.managed_by.id, secondary: _jsx(FormattedMessage, { id: "ui.eventHeader.user.manager", defaultMessage: "ui.eventHeader.user.manager" }), elevation: 0, actions: _jsx(_Fragment, { children: isEventAdmin ? (_jsxs(Box, Object.assign({ className: classes.multiActions }, { children: [_jsx(EventInviteButton, { size: isMobile ? 'small' : 'medium', event: scEvent, eventId: scEvent.id, disabled: isEventFinished }), _jsxs(Box, { children: [!isMobile && (_jsx(EditEventButton, { size: isMobile ? 'small' : 'medium', event: scEvent, eventId: scEvent.id, onEditSuccess: (data) => setSCEvent(data), disabled: isEventFinished })), _jsx(EventActionsMenu, Object.assign({ event: scEvent, onEditSuccess: (data) => setSCEvent(data) }, EventActionsProps))] })] }))) : (_jsxs(_Fragment, { children: [_jsx(EventSubscribeButton, Object.assign({ eventId: scEvent.id, onSubscribe: handleSubscribe }, EventSubscribeButtonProps, { disabled: isEventFinished })), _jsx(EventActionsMenu, Object.assign({ eventId: scEvent.id, onEditSuccess: (data) => setSCEvent(data) }, EventActionsProps))] })) }) })] }))] })));
142
+ } })) })), _jsx(Typography, Object.assign({ variant: "h5", className: classes.name }, { children: scEvent.name })), _jsxs(Box, Object.assign({ className: classes.visibility }, { children: [_jsx(_Fragment, { children: scEvent.privacy === SCEventPrivacyType.PUBLIC ? (_jsxs(Typography, Object.assign({ className: classes.visibilityItem }, { children: [_jsx(Icon, { children: "public" }), _jsx(FormattedMessage, { id: "ui.eventHeader.visibility.public", defaultMessage: "ui.eventHeader.visibility.public" })] }))) : (_jsxs(Typography, Object.assign({ className: classes.visibilityItem }, { children: [_jsx(Icon, { children: "private" }), _jsx(FormattedMessage, { id: "ui.eventHeader.visibility.private", defaultMessage: "ui.eventHeader.visibility.private" })] }))) }), _jsx(Bullet, {}), _jsx(Typography, Object.assign({ className: classes.visibilityItem }, { children: scEvent.location === SCEventLocationType.PERSON ? (_jsx(FormattedMessage, { id: "ui.eventHeader.location.live", defaultMessage: "ui.eventHeader.location.live" })) : (_jsx(FormattedMessage, { id: "ui.eventHeader.location.online", defaultMessage: "ui.eventHeader.location.online" })) }))] })), _jsx(User, { className: classes.planner, userId: scEvent.managed_by.id, secondary: _jsx(FormattedMessage, { id: "ui.eventHeader.user.manager", defaultMessage: "ui.eventHeader.user.manager" }), elevation: 0, actions: _jsx(_Fragment, { children: isEventAdmin ? (_jsxs(Box, Object.assign({ className: classes.multiActions }, { children: [_jsx(EventInviteButton, { size: isMobile ? 'small' : 'medium', event: scEvent, disabled: isEventFinished }), _jsxs(Box, { children: [!isMobile && (_jsx(EditEventButton, { size: isMobile ? 'small' : 'medium', event: scEvent, onEditSuccess: setSCEvent, disabled: isEventFinished })), _jsx(EventActionsMenu, Object.assign({ event: scEvent, onEditSuccess: (data) => setSCEvent(data) }, EventActionsProps))] })] }))) : (_jsxs(_Fragment, { children: [_jsx(EventSubscribeButton, Object.assign({ event: scEvent, onSubscribe: handleSubscribe }, EventSubscribeButtonProps, { disabled: isEventFinished })), _jsx(EventActionsMenu, Object.assign({ event: scEvent, onEditSuccess: setSCEvent }, EventActionsProps))] })) }) })] }))] })));
178
143
  }
@@ -44,7 +44,7 @@ export default function TabContentComponent(props) {
44
44
  // EFFECTS
45
45
  useEffect(() => {
46
46
  updatesInvited.current = PubSub.subscribe(`${SCTopicType.EVENT}.${SCGroupEventType.INVITE_MEMBER}`, handleInviteMember);
47
- updatesParticipants.current = PubSub.subscribe(`${SCTopicType.EVENT}.${SCGroupEventType.ADD_MEMBER}`, handleToggleMember);
47
+ updatesParticipants.current = PubSub.subscribe(`${SCTopicType.EVENT}.${SCGroupEventType.MEMBERS}`, handleToggleMember);
48
48
  return () => {
49
49
  updatesInvited.current && PubSub.unsubscribe(updatesInvited.current);
50
50
  updatesParticipants.current && PubSub.unsubscribe(updatesParticipants.current);
@@ -1,4 +1,4 @@
1
- import { SCEventSubscriptionStatusType, SCEventType, SCUserType } from '@selfcommunity/types';
1
+ import { SCEventType, SCUserType } from '@selfcommunity/types';
2
2
  export interface EventSubscribeButtonProps {
3
3
  /**
4
4
  * Overrides or extends the styles applied to the component.
@@ -25,7 +25,7 @@ export interface EventSubscribeButtonProps {
25
25
  * @param user
26
26
  * @param joined
27
27
  */
28
- onSubscribe?: (event: SCEventType, status: SCEventSubscriptionStatusType | null) => any;
28
+ onSubscribe?: (event: SCEventType) => any;
29
29
  /**
30
30
  * Others properties
31
31
  */
@@ -4,12 +4,12 @@ import { LoadingButton } from '@mui/lab';
4
4
  import { Box, Button, Checkbox, CircularProgress, FormControlLabel, Icon, Menu, MenuItem, SwipeableDrawer, useMediaQuery, useTheme } from '@mui/material';
5
5
  import { styled } from '@mui/material/styles';
6
6
  import { useThemeProps } from '@mui/system';
7
- import { getEventStatus, useSCContext, useSCFetchEvent, useSCUser } from '@selfcommunity/react-core';
7
+ import { useSCContext, useSCFetchEvent, useSCUser } from '@selfcommunity/react-core';
8
8
  import { SCEventPrivacyType, SCEventSubscriptionStatusType } from '@selfcommunity/types';
9
9
  import { CacheStrategies, Logger } from '@selfcommunity/utils';
10
10
  import classNames from 'classnames';
11
11
  import PubSub from 'pubsub-js';
12
- import { useEffect, useMemo, useState } from 'react';
12
+ import { useCallback, useEffect, useMemo, useState } from 'react';
13
13
  import { FormattedMessage } from 'react-intl';
14
14
  import { SCOPE_SC_UI } from '../../constants/Errors';
15
15
  import { SCGroupEventType, SCTopicType } from '../../constants/PubSub';
@@ -93,19 +93,19 @@ export default function EventSubscribeButton(inProps) {
93
93
  const isMobile = useMediaQuery(theme.breakpoints.down('md'));
94
94
  // CONST
95
95
  const authUserId = scUserContext.user ? scUserContext.user.id : null;
96
- const { scEvent } = useSCFetchEvent({
96
+ const { scEvent, setSCEvent } = useSCFetchEvent({
97
97
  id: eventId,
98
98
  event,
99
99
  cacheStrategy: authUserId ? CacheStrategies.CACHE_FIRST : CacheStrategies.STALE_WHILE_REVALIDATE
100
100
  });
101
101
  const isEventAdmin = useMemo(() => { var _a; return scUserContext.user && ((_a = scEvent === null || scEvent === void 0 ? void 0 : scEvent.managed_by) === null || _a === void 0 ? void 0 : _a.id) === scUserContext.user.id; }, [scUserContext.user, (_a = scEvent === null || scEvent === void 0 ? void 0 : scEvent.managed_by) === null || _a === void 0 ? void 0 : _a.id]);
102
102
  // HANDLERS
103
- const handleOpen = (event) => {
103
+ const handleOpen = useCallback((event) => {
104
104
  setAnchorEl(event.currentTarget);
105
- };
106
- const handleClose = () => {
105
+ }, [setAnchorEl]);
106
+ const handleClose = useCallback(() => {
107
107
  setAnchorEl(null);
108
- };
108
+ }, [setAnchorEl]);
109
109
  useEffect(() => {
110
110
  /**
111
111
  * Call scEventsManager.subscriptionStatus inside an effect
@@ -115,25 +115,23 @@ export default function EventSubscribeButton(inProps) {
115
115
  setStatus(scEventsManager === null || scEventsManager === void 0 ? void 0 : scEventsManager.subscriptionStatus(scEvent));
116
116
  }
117
117
  }, [authUserId, scEventsManager === null || scEventsManager === void 0 ? void 0 : scEventsManager.subscriptionStatus, scEvent]);
118
- const toggleEventAttendance = (eventStatus) => {
118
+ const toggleEventAttendance = useCallback((eventStatus) => {
119
119
  setLoading(true);
120
120
  const isGoing = eventStatus === SCEventSubscriptionStatusType.GOING ||
121
121
  !(scEvent === null || scEvent === void 0 ? void 0 : scEvent.subscription_status) ||
122
122
  (scEvent === null || scEvent === void 0 ? void 0 : scEvent.subscription_status) === SCEventSubscriptionStatusType.INVITED;
123
- const toggleAction = isGoing
124
- ? scEventsManager.toggleEventAttendance(scEvent, (user === null || user === void 0 ? void 0 : user.id) || null)
125
- : scEventsManager.toggleEventNonattendance(scEvent);
123
+ const toggleAction = isGoing ? scEventsManager.toggleEventAttendance(scEvent) : scEventsManager.toggleEventNonattendance(scEvent);
126
124
  toggleAction
127
- .then(() => {
128
- onSubscribe === null || onSubscribe === void 0 ? void 0 : onSubscribe(scEvent, getEventStatus(scEvent, isGoing));
125
+ .then((data) => {
126
+ onSubscribe ? onSubscribe(data) : setSCEvent(data);
129
127
  setLoading(false);
130
- PubSub.publish(`${SCTopicType.EVENT}.${SCGroupEventType.ADD_MEMBER}`, scUserContext.user);
128
+ PubSub.publish(`${SCTopicType.EVENT}.${SCGroupEventType.MEMBERS}`);
131
129
  })
132
130
  .catch((e) => {
133
131
  Logger.error(SCOPE_SC_UI, e);
134
132
  });
135
- };
136
- const handleToggleAction = (event) => {
133
+ }, [scEvent, scEventsManager, onSubscribe, setLoading]);
134
+ const handleToggleAction = useCallback((event) => {
137
135
  setAnchorEl(null);
138
136
  if (!scUserContext.user) {
139
137
  scContext.settings.handleAnonymousAction();
@@ -141,9 +139,9 @@ export default function EventSubscribeButton(inProps) {
141
139
  else if (status !== undefined) {
142
140
  toggleEventAttendance(event.target.value);
143
141
  }
144
- };
142
+ }, [scUserContext.user, status, scContext.settings]);
145
143
  function renderMenuItems() {
146
- return (_jsx(Box, { children: options.map((option) => (_jsx(MenuItem, Object.assign({ className: classes.item, disabled: loading }, { children: _jsx(FormControlLabel, { label: option.label, control: loading ? (_jsx(CircularProgress, { color: 'primary', size: 20 })) : (_jsx(Checkbox, { size: "small", checked: status === option.value, value: option.value, onChange: handleToggleAction, name: `${option.value}-option`, inputProps: { 'aria-label': `${option.label}` } })), labelPlacement: "start" }) }), option.value))) }));
144
+ return (_jsx(Box, { children: options.map((option) => (_jsx(MenuItem, Object.assign({ className: classes.item, disabled: loading }, { children: _jsx(FormControlLabel, { label: option.label, control: loading ? (_jsx(CircularProgress, { color: "primary", size: 20 })) : (_jsx(Checkbox, { size: "small", checked: status === option.value, value: option.value, onChange: handleToggleAction, name: `${option.value}-option`, inputProps: { 'aria-label': `${option.label}` } })), labelPlacement: "start" }) }), option.value))) }));
147
145
  }
148
146
  /**
149
147
  * Get current translated status
@@ -142,13 +142,13 @@ export default function Events(inProps) {
142
142
  * On mount, fetches events list
143
143
  */
144
144
  useEffect(() => {
145
- if (!contentAvailability) {
145
+ if (!contentAvailability && !authUserId) {
146
146
  return;
147
147
  }
148
148
  else {
149
149
  query === '' && fetchEvents();
150
150
  }
151
- }, [contentAvailability, dateSearch, location, showFollowed, showPastEvents, showMyEvents, query]);
151
+ }, [contentAvailability, authUserId, dateSearch, location, showFollowed, showPastEvents, showMyEvents, query]);
152
152
  /**
153
153
  * Subscriber for pubsub callback
154
154
  */
@@ -211,7 +211,6 @@ export default function Events(inProps) {
211
211
  /**
212
212
  * Renders events list
213
213
  */
214
- console.log(location);
215
214
  const c = (_jsxs(_Fragment, { children: [showFilters && (_jsx(Grid, Object.assign({ container: true, className: classes.filters, gap: 2 }, { children: filters ? (filters) : !general ? (_jsxs(_Fragment, { children: [(events.length !== 0 || (events.length === 0 && showMyEvents)) && (_jsx(Grid, Object.assign({ item: true }, { children: _jsx(EventsChipRoot
216
215
  // eslint-disable-next-line @typescript-eslint/ban-ts-ignore
217
216
  // @ts-ignore
@@ -244,7 +243,7 @@ export default function Events(inProps) {
244
243
  // eslint-disable-next-line @typescript-eslint/ban-ts-ignore
245
244
  // @ts-ignore
246
245
  showFollowed: showFollowed, deleteIcon: showFollowed ? _jsx(Icon, { children: "close" }) : null, onDelete: showFollowed ? handleDeleteClick : null, disabled: loading || (!events.length && !showFollowed) }) }))), _jsx(Grid, Object.assign({ item: true }, { children: _jsx(PastEventsFilter, { showPastEvents: showPastEvents, handleClick: handleChipPastClick, handleDeleteClick: handleDeletePastClick, disabled: dateSearch !== SCEventDateFilterType.ANY || loading || (!events.length && !showPastEvents) }) }))] })) }))), _jsx(_Fragment, { children: loading ? (_jsx(Skeleton, Object.assign({}, EventsSkeletonComponentProps, { EventSkeletonProps: EventSkeletonComponentProps }))) : (_jsx(_Fragment, { children: !events.length ? (_jsx(Box, Object.assign({ className: classes.noResults }, { children: (onlyStaffEnabled && !UserUtils.isStaff(scUserContext.user)) ||
247
- (onlyStaffEnabled && UserUtils.isStaff(scUserContext.user) && general) ? (_jsxs(_Fragment, { children: [_jsx(EventSkeleton, Object.assign({}, EventSkeletonComponentProps)), _jsx(Typography, Object.assign({ variant: "body1" }, { children: _jsx(FormattedMessage, { id: "ui.events.noEvents.title", defaultMessage: "ui.events.noEvents.title" }) }))] })) : (_jsxs(_Fragment, { children: [_jsx(EventSkeleton, Object.assign({}, EventSkeletonComponentProps, { skeletonsAnimation: false, actions: _jsx(CreateEventButton, {}) })), _jsx(Typography, Object.assign({ variant: "body1" }, { children: _jsx(FormattedMessage, { id: "ui.events.noEvents.title.onlyStaff", defaultMessage: "ui.events.noEvents.title.onlyStaff" }) }))] })) }))) : (_jsxs(_Fragment, { children: [_jsx(Grid, Object.assign({ container: true, spacing: { xs: 2 }, className: classes.events }, GridContainerComponentProps, { children: _jsxs(_Fragment, { children: [events.map((event) => (_jsx(Grid, Object.assign({ item: true, xs: 12, sm: 12, md: 6, className: classes.item }, GridItemComponentProps, { children: _jsx(Event, Object.assign({ event: event, eventId: event.id }, EventComponentProps)) }), event.id))), authUserId && events.length % 2 !== 0 && (_jsx(Grid, Object.assign({ item: true, xs: 12, sm: 12, md: 6, className: classes.itemSkeleton }, GridItemComponentProps, { children: _jsx(EventSkeleton, Object.assign({}, EventSkeletonComponentProps, { skeletonsAnimation: false, actions: _jsx(CreateEventButton, Object.assign({ variant: "outlined", color: "primary", size: "small" }, { children: _jsx(FormattedMessage, { id: "ui.events.skeleton.action.add", defaultMessage: "ui.events.skeleton.action.add" }) })) })) }), 'skeleton-item'))] }) })), Boolean(next) && (_jsx(Button, Object.assign({ color: "secondary", variant: "text", onClick: handleNext, className: classes.showMore }, { children: _jsx(FormattedMessage, { id: "ui.events.button.seeMore", defaultMessage: "ui.events.button.seeMore" }) })))] })) })) })] }));
246
+ (onlyStaffEnabled && UserUtils.isStaff(scUserContext.user) && general) ? (_jsxs(_Fragment, { children: [_jsx(EventSkeleton, Object.assign({}, EventSkeletonComponentProps, { skeletonsAnimation: false })), _jsx(Typography, Object.assign({ variant: "body1" }, { children: _jsx(FormattedMessage, { id: "ui.events.noEvents.title", defaultMessage: "ui.events.noEvents.title" }) }))] })) : (_jsxs(_Fragment, { children: [_jsx(EventSkeleton, Object.assign({}, EventSkeletonComponentProps, { skeletonsAnimation: false, actions: _jsx(CreateEventButton, {}) })), _jsx(Typography, Object.assign({ variant: "body1" }, { children: _jsx(FormattedMessage, { id: "ui.events.noEvents.title.onlyStaff", defaultMessage: "ui.events.noEvents.title.onlyStaff" }) }))] })) }))) : (_jsxs(_Fragment, { children: [_jsx(Grid, Object.assign({ container: true, spacing: { xs: 2 }, className: classes.events }, GridContainerComponentProps, { children: _jsxs(_Fragment, { children: [events.map((event) => (_jsx(Grid, Object.assign({ item: true, xs: 12, sm: 12, md: 6, className: classes.item }, GridItemComponentProps, { children: _jsx(Event, Object.assign({ event: event, eventId: event.id }, EventComponentProps)) }), event.id))), authUserId && events.length % 2 !== 0 && (_jsx(Grid, Object.assign({ item: true, xs: 12, sm: 12, md: 6, className: classes.itemSkeleton }, GridItemComponentProps, { children: _jsx(EventSkeleton, Object.assign({}, EventSkeletonComponentProps, { skeletonsAnimation: false, actions: _jsx(CreateEventButton, Object.assign({ variant: "outlined", color: "primary", size: "small" }, { children: _jsx(FormattedMessage, { id: "ui.events.skeleton.action.add", defaultMessage: "ui.events.skeleton.action.add" }) })) })) }), 'skeleton-item'))] }) })), Boolean(next) && (_jsx(Button, Object.assign({ color: "secondary", variant: "text", onClick: handleNext, className: classes.showMore }, { children: _jsx(FormattedMessage, { id: "ui.events.button.seeMore", defaultMessage: "ui.events.button.seeMore" }) })))] })) })) })] }));
248
247
  /**
249
248
  * Renders root object (if content availability community option is false and user is anonymous, component is hidden)
250
249
  */
@@ -1,13 +1,16 @@
1
1
  import { __rest } from "tslib";
2
- import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
3
  import { useMemo, useState } from 'react';
4
4
  import { styled } from '@mui/material/styles';
5
- import { Divider, Icon, IconButton, List, ListItem, ListItemButton, Menu, MenuItem, SwipeableDrawer, useMediaQuery, useTheme } from '@mui/material';
5
+ import { Divider, Icon, IconButton, List, ListItem, ListItemButton, ListItemIcon, Menu, MenuItem, SwipeableDrawer, useMediaQuery, useTheme } from '@mui/material';
6
6
  import { Link, SCPreferences, SCRoutes, UserUtils, useSCPreferences, useSCRouting, useSCUser } from '@selfcommunity/react-core';
7
7
  import classNames from 'classnames';
8
8
  import { useThemeProps } from '@mui/system';
9
9
  import { FormattedMessage } from 'react-intl';
10
- import { UserService } from '@selfcommunity/api-services';
10
+ import { PreferenceService, UserService } from '@selfcommunity/api-services';
11
+ import { SCOPE_SC_UI } from '../../constants/Errors';
12
+ import { Logger } from '@selfcommunity/utils';
13
+ import { SCPreferenceName } from '@selfcommunity/types';
11
14
  const PREFIX = 'SCNavigationSettingsIconButton';
12
15
  const classes = {
13
16
  root: `${PREFIX}-root`,
@@ -35,7 +38,9 @@ const PREFERENCES = [
35
38
  SCPreferences.CONFIGURATIONS_FOLLOW_ENABLED,
36
39
  SCPreferences.CONFIGURATIONS_POST_TYPE_ENABLED,
37
40
  SCPreferences.CONFIGURATIONS_DISCUSSION_TYPE_ENABLED,
38
- SCPreferences.ADDONS_LOYALTY_POINTS_COLLECTION
41
+ SCPreferences.ADDONS_LOYALTY_POINTS_COLLECTION,
42
+ SCPreferences.CONFIGURATIONS_ONBOARDING_ENABLED,
43
+ SCPreferences.CONFIGURATIONS_ONBOARDING_HIDDEN
39
44
  ];
40
45
  /**
41
46
  * > API documentation for the Community-JS Navigation Settings Icon Button component. Learn about the available props and the CSS API.
@@ -72,6 +77,7 @@ export default function NavigationSettingsIconButton(inProps) {
72
77
  const scUserContext = useSCUser();
73
78
  // MEMO
74
79
  const isAdmin = useMemo(() => UserUtils.isAdmin(scUserContext.user), [scUserContext.user]);
80
+ const isCommunityCreator = useMemo(() => UserUtils.isCommunityCreator(scUserContext.user), [scUserContext.user]);
75
81
  const isModerator = useMemo(() => UserUtils.isModerator(scUserContext.user), [scUserContext.user]);
76
82
  // HOOKS
77
83
  const theme = useTheme();
@@ -92,7 +98,7 @@ export default function NavigationSettingsIconButton(inProps) {
92
98
  setAnchorEl(null);
93
99
  };
94
100
  /**
95
- * Fetches paltform url
101
+ * Fetches platform url
96
102
  * @param query
97
103
  */
98
104
  const fetchPlatform = (query) => {
@@ -101,6 +107,27 @@ export default function NavigationSettingsIconButton(inProps) {
101
107
  window.open(platformUrl, '_blank').focus();
102
108
  });
103
109
  };
110
+ /**
111
+ * Handles preferences update
112
+ */
113
+ const handlePreferencesUpdate = () => {
114
+ PreferenceService.getAllPreferences().then((preferences) => {
115
+ const prefs = preferences['results'].reduce((obj, p) => (Object.assign(Object.assign({}, obj), { [`${p.section}.${p.name}`]: p })), {});
116
+ scPreferences.setPreferences(prefs);
117
+ });
118
+ };
119
+ /**
120
+ * Updates onBoarding dynamic preference
121
+ */
122
+ const showOnBoarding = () => {
123
+ PreferenceService.updatePreferences({ [`${SCPreferenceName.ONBOARDING_HIDDEN}`]: false })
124
+ .then(() => {
125
+ handlePreferencesUpdate();
126
+ })
127
+ .catch((e) => {
128
+ Logger.error(SCOPE_SC_UI, e);
129
+ });
130
+ };
104
131
  const handleLogout = () => {
105
132
  scUserContext.logout();
106
133
  };
@@ -119,6 +146,9 @@ export default function NavigationSettingsIconButton(inProps) {
119
146
  ...(isAdmin
120
147
  ? [
121
148
  _jsx(Divider, {}, "admin_divider"),
149
+ isCommunityCreator &&
150
+ preferences[SCPreferences.CONFIGURATIONS_ONBOARDING_ENABLED] &&
151
+ preferences[SCPreferences.CONFIGURATIONS_ONBOARDING_HIDDEN] && (_jsx(ListItem, Object.assign({ className: classes.item }, { children: _jsxs(ListItemButton, Object.assign({ onClick: showOnBoarding }, { children: [_jsx(FormattedMessage, { id: "ui.navigationSettingsIconButton.onboarding", defaultMessage: "ui.navigationSettingsIconButton.onboarding" }), _jsx(ListItemIcon, { children: _jsx(Icon, { children: "magic_wand" }) })] })) }), "onboarding")),
122
152
  _jsx(ListItem, Object.assign({ className: classes.item }, { children: _jsx(ListItemButton, Object.assign({ onClick: () => fetchPlatform('') }, { children: _jsx(FormattedMessage, { id: "ui.navigationSettingsIconButton.platform", defaultMessage: "ui.navigationSettingsIconButton.platform" }) })) }), "platform")
123
153
  ]
124
154
  : []),
@@ -147,6 +177,9 @@ export default function NavigationSettingsIconButton(inProps) {
147
177
  ...(isAdmin
148
178
  ? [
149
179
  _jsx(Divider, {}, "platform_divider"),
180
+ isCommunityCreator &&
181
+ preferences[SCPreferences.CONFIGURATIONS_ONBOARDING_ENABLED] &&
182
+ preferences[SCPreferences.CONFIGURATIONS_ONBOARDING_HIDDEN] && (_jsxs(MenuItem, Object.assign({ className: classes.item, onClick: showOnBoarding }, { children: [_jsx(FormattedMessage, { id: "ui.navigationSettingsIconButton.onboarding", defaultMessage: "ui.navigationSettingsIconButton.onboarding" }), _jsx(ListItemIcon, { children: _jsx(Icon, { children: "magic_wand" }) })] }), "onboarding")),
150
183
  _jsx(MenuItem, Object.assign({ className: classes.item, onClick: () => fetchPlatform('') }, { children: _jsx(FormattedMessage, { id: "ui.navigationSettingsIconButton.platform", defaultMessage: "ui.navigationSettingsIconButton.platform" }) }), "platform")
151
184
  ]
152
185
  : []),
@@ -142,7 +142,7 @@ export default function NavigationToolbar(inProps) {
142
142
  (preferences[SCPreferences.CONFIGURATIONS_CONTENT_AVAILABILITY] || scUserContext.user) && (_jsx(IconButton, Object.assign({ className: classNames(classes.explore, { [classes.active]: value.startsWith(scRoutingContext.url(SCRoutes.EXPLORE_ROUTE_NAME, {})) }), "aria-label": "Explore", to: scRoutingContext.url(SCRoutes.EXPLORE_ROUTE_NAME, {}), component: Link }, { children: _jsx(Icon, { children: "explore" }) }))), groupsEnabled && scUserContext.user && (_jsx(IconButton, Object.assign({ className: classNames(classes.groups, {
143
143
  [classes.active]: value.startsWith(scRoutingContext.url(SCRoutes.GROUPS_SUBSCRIBED_ROUTE_NAME, {})) ||
144
144
  value.startsWith(scRoutingContext.url(SCRoutes.GROUPS_ROUTE_NAME, {}))
145
- }), "aria-label": "Groups", to: scRoutingContext.url(SCRoutes.GROUPS_SUBSCRIBED_ROUTE_NAME, {}), component: Link }, { children: _jsx(Icon, { children: "groups" }) }))), eventsEnabled && (_jsx(IconButton, Object.assign({ className: classNames(classes.events, {
145
+ }), "aria-label": "Groups", to: scRoutingContext.url(SCRoutes.GROUPS_SUBSCRIBED_ROUTE_NAME, {}), component: Link }, { children: _jsx(Icon, { children: "groups" }) }))), eventsEnabled && (scUserContext.user || preferences[SCPreferences.CONFIGURATIONS_CONTENT_AVAILABILITY]) && (_jsx(IconButton, Object.assign({ className: classNames(classes.events, {
146
146
  [classes.active]: value.startsWith(scRoutingContext.url(SCRoutes.EVENTS_ROUTE_NAME, {}))
147
147
  }), "aria-label": "Groups", to: scRoutingContext.url(SCRoutes.EVENTS_ROUTE_NAME, {}), component: Link }, { children: _jsx(Icon, { children: "CalendarIcon" }) })))] })));
148
148
  return (_jsxs(Root, Object.assign({ className: classNames(className, classes.root) }, rest, { children: [_jsx(NavigationMenuIconButtonComponent, Object.assign({}, NavigationMenuIconButtonComponentProps)), _jsx(Link, Object.assign({ to: scRoutingContext.url(SCRoutes.HOME_ROUTE_NAME, {}), className: classes.logo }, { children: _jsx("img", { src: preferences[SCPreferences.LOGO_NAVBAR_LOGO], alt: "logo" }) })), !scUserContext.user && !preferences[SCPreferences.ADDONS_CLOSED_COMMUNITY] && (_jsx(Button, Object.assign({ color: "inherit", component: Link, to: scRoutingContext.url(SCRoutes.SIGNUP_ROUTE_NAME, {}), className: classes.register }, { children: _jsx(FormattedMessage, { id: "ui.appBar.navigation.register", defaultMessage: "ui.appBar.navigation.register" }) }))), preferences[SCPreferences.CONFIGURATIONS_CUSTOM_NAVBAR_ITEM_ENABLED] && (_jsx(_Fragment, { children: preferences[SCPreferences.CONFIGURATIONS_CUSTOM_NAVBAR_ITEM_TEXT] ? (_jsx(Tooltip, Object.assign({ title: preferences[SCPreferences.CONFIGURATIONS_CUSTOM_NAVBAR_ITEM_TEXT] }, { children: _jsx(Link, Object.assign({ target: "blank", to: preferences[SCPreferences.CONFIGURATIONS_CUSTOM_NAVBAR_ITEM_URL], className: classes.customItem }, { children: _jsx("img", { src: preferences[SCPreferences.CONFIGURATIONS_CUSTOM_NAVBAR_ITEM_IMAGE], alt: "custom_item" }) })) }))) : (_jsx(Link, Object.assign({ target: "blank", to: preferences[SCPreferences.CONFIGURATIONS_CUSTOM_NAVBAR_ITEM_URL], className: classes.customItem }, { children: _jsx("img", { src: preferences[SCPreferences.CONFIGURATIONS_CUSTOM_NAVBAR_ITEM_IMAGE], alt: "custom_item" }) }))) })), _children, (preferences[SCPreferences.CONFIGURATIONS_CONTENT_AVAILABILITY] || scUserContext.user) && !disableSearch ? (_jsx(SearchAutocomplete, Object.assign({ className: classes.search, blurOnSelect: true }, SearchAutocompleteProps))) : (_jsx(Box, { className: classes.search })), startActions, scUserContext.user ? (_jsxs(_Fragment, { children: [showComposer && _jsx(ComposerIconButton, Object.assign({ className: classes.composer }, ComposerIconButtonProps)), _jsx(Tooltip, Object.assign({ title: scUserContext.user.username }, { children: _jsx(IconButton, Object.assign({ component: Link, to: scRoutingContext.url(SCRoutes.USER_PROFILE_ROUTE_NAME, scUserContext.user), "aria-label": "Profile", className: classes.profile }, { children: _jsx(Avatar, { alt: scUserContext.user.username, src: scUserContext.user.avatar }) })) })), _jsxs(_Fragment, { children: [_jsx(IconButton, Object.assign({ className: classNames(classes.notification, {
@@ -0,0 +1,7 @@
1
+ import { IconButtonProps } from '@mui/material';
2
+ export interface OnBoardingActionsButtonProps extends IconButtonProps {
3
+ isExpanded: boolean;
4
+ onExpandChange: () => void;
5
+ onHideOnBoarding: () => void;
6
+ }
7
+ export default function OnBoardingActionsButton(inProps: OnBoardingActionsButtonProps): JSX.Element;
@@ -0,0 +1,81 @@
1
+ import { __rest } from "tslib";
2
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
+ import { useState } from 'react';
4
+ import { styled } from '@mui/material/styles';
5
+ import { Icon, IconButton, List, ListItem, ListItemButton, ListItemIcon, Menu, MenuItem, SwipeableDrawer, useMediaQuery, useTheme } from '@mui/material';
6
+ import classNames from 'classnames';
7
+ import { useThemeProps } from '@mui/system';
8
+ import { FormattedMessage } from 'react-intl';
9
+ import { PreferenceService } from '@selfcommunity/api-services';
10
+ import { SCOPE_SC_UI } from '../../constants/Errors';
11
+ import { Logger } from '@selfcommunity/utils';
12
+ import { SCPreferenceName } from '@selfcommunity/types';
13
+ import { PREFIX } from './constants';
14
+ const classes = {
15
+ root: `${PREFIX}-actions-button-root`,
16
+ drawerRoot: `${PREFIX}-actions-drawer-root`,
17
+ menuRoot: `${PREFIX}-actions-menu-root`,
18
+ paper: `${PREFIX}-actions-paper`,
19
+ item: `${PREFIX}-actions-item`
20
+ };
21
+ const Root = styled(IconButton, {
22
+ name: PREFIX,
23
+ slot: 'Root',
24
+ overridesResolver: (props, styles) => styles.root
25
+ })(() => ({}));
26
+ const SwipeableDrawerRoot = styled(SwipeableDrawer, {
27
+ name: PREFIX,
28
+ slot: 'Root',
29
+ overridesResolver: (props, styles) => styles.drawerRoot
30
+ })(() => ({}));
31
+ const MenuRoot = styled(Menu, {
32
+ name: PREFIX,
33
+ slot: 'Root',
34
+ overridesResolver: (props, styles) => styles.menuRoot
35
+ })(() => ({}));
36
+ export default function OnBoardingActionsButton(inProps) {
37
+ // PROPS
38
+ const props = useThemeProps({
39
+ props: inProps,
40
+ name: PREFIX
41
+ });
42
+ const { className = null, isExpanded, onExpandChange, onHideOnBoarding } = props, rest = __rest(props, ["className", "isExpanded", "onExpandChange", "onHideOnBoarding"]);
43
+ // STATE
44
+ const [anchorEl, setAnchorEl] = useState(null);
45
+ const theme = useTheme();
46
+ const isMobile = useMediaQuery(theme.breakpoints.down('md'));
47
+ // HANDLERS
48
+ const handleOpen = (event) => {
49
+ setAnchorEl(event.currentTarget);
50
+ };
51
+ const handleClose = () => {
52
+ setAnchorEl(null);
53
+ };
54
+ /**
55
+ * Updates onBoarding dynamic preference
56
+ */
57
+ const hideOnBoarding = () => {
58
+ PreferenceService.updatePreferences({ [`${SCPreferenceName.ONBOARDING_HIDDEN}`]: true })
59
+ .then(() => {
60
+ onHideOnBoarding();
61
+ })
62
+ .catch((e) => {
63
+ Logger.error(SCOPE_SC_UI, e);
64
+ });
65
+ };
66
+ const renderList = () => {
67
+ if (isMobile) {
68
+ return [
69
+ isExpanded ? (_jsx(ListItem, Object.assign({ className: classes.item }, { children: _jsxs(ListItemButton, Object.assign({ onClick: onExpandChange }, { children: [_jsx(ListItemIcon, { children: _jsx(Icon, { children: "expand_less" }) }), _jsx(FormattedMessage, { id: "ui.onBoardingWidget.actionsMenu.view.less", defaultMessage: "ui.onBoardingWidget.actionsMenu.view.less" })] })) }), "expand_less")) : (_jsx(ListItem, Object.assign({ className: classes.item }, { children: _jsxs(ListItemButton, Object.assign({ onClick: onExpandChange }, { children: [_jsx(ListItemIcon, { children: _jsx(Icon, { children: "expand_more" }) }), _jsx(FormattedMessage, { id: "ui.onBoardingWidget.actionsMenu.view.more", defaultMessage: "ui.onBoardingWidget.actionsMenu.view.more" })] })) }), "expand_more")),
70
+ _jsx(ListItem, Object.assign({ className: classes.item }, { children: _jsxs(ListItemButton, Object.assign({ onClick: hideOnBoarding }, { children: [_jsx(ListItemIcon, { children: _jsx(Icon, { children: "close" }) }), _jsx(FormattedMessage, { id: "ui.onBoardingWidget.actionsMenu.close", defaultMessage: "ui.onBoardingWidget.actionsMenu.close" })] })) }), "close")
71
+ ];
72
+ }
73
+ else {
74
+ return [
75
+ isExpanded ? (_jsxs(MenuItem, Object.assign({ className: classes.item, onClick: onExpandChange }, { children: [_jsx(ListItemIcon, { children: _jsx(Icon, { children: "expand_less" }) }), _jsx(FormattedMessage, { id: "ui.onBoardingWidget.actionsMenu.view.less", defaultMessage: "ui.onBoardingWidget.actionsMenu.view.less" })] }), "expand_less")) : (_jsxs(MenuItem, Object.assign({ className: classes.item, onClick: onExpandChange }, { children: [_jsx(ListItemIcon, { children: _jsx(Icon, { children: "expand_more" }) }), _jsx(FormattedMessage, { id: "ui.onBoardingWidget.actionsMenu.view.more", defaultMessage: "ui.onBoardingWidget.actionsMenu.view.more" })] }), "expand_more")),
76
+ _jsxs(MenuItem, Object.assign({ className: classes.item, onClick: hideOnBoarding }, { children: [_jsx(ListItemIcon, { children: _jsx(Icon, { children: "close" }) }), _jsx(FormattedMessage, { id: "ui.onBoardingWidget.actionsMenu.close", defaultMessage: "ui.onBoardingWidget.actionsMenu.close" })] }), "close")
77
+ ];
78
+ }
79
+ };
80
+ return (_jsxs(_Fragment, { children: [_jsx(Root, Object.assign({ className: classNames(classes.root, className) }, rest, { onClick: handleOpen }, { children: _jsx(Icon, { children: "more_vert" }) })), isMobile ? (_jsx(SwipeableDrawerRoot, Object.assign({ onClick: () => setAnchorEl(null), className: classes.drawerRoot, anchor: "bottom", open: Boolean(anchorEl), onClose: handleClose, onOpen: handleOpen, PaperProps: { className: classes.paper }, disableSwipeToOpen: true }, { children: _jsx(List, { children: renderList() }) }))) : (_jsx(MenuRoot, Object.assign({ onClick: () => setAnchorEl(null), className: classes.menuRoot, anchorEl: anchorEl, open: Boolean(anchorEl), onClose: handleClose, PaperProps: { className: classes.paper } }, { children: renderList() })))] }));
81
+ }
@@ -8,7 +8,7 @@ import classNames from 'classnames';
8
8
  import { useThemeProps } from '@mui/system';
9
9
  import Category from './Steps/Category';
10
10
  import { PREFIX } from './constants';
11
- import { getTheme, usePreviousValue, UserUtils, useSCContext, useSCFetchCategories, useSCPreferences, useSCTheme, useSCUser } from '@selfcommunity/react-core';
11
+ import { getTheme, SCPreferences, usePreviousValue, UserUtils, useSCContext, useSCFetchCategories, useSCPreferences, useSCTheme, useSCUser } from '@selfcommunity/react-core';
12
12
  import Appearance from './Steps/Appearance';
13
13
  import Profile from './Steps/Profile';
14
14
  import Invite from './Steps/Invite';
@@ -19,13 +19,14 @@ import Content from './Steps/Content';
19
19
  import { SCOPE_SC_UI } from '../../constants/Errors';
20
20
  import { Endpoints, http, OnBoardingService, PreferenceService } from '@selfcommunity/api-services';
21
21
  import { Logger } from '@selfcommunity/utils';
22
- import { SCOnBoardingStepStatusType, SCOnBoardingStepType } from '@selfcommunity/types';
22
+ import { SCOnBoardingStepStatusType, SCOnBoardingStepType, SCOnBoardingStepIdType } from '@selfcommunity/types';
23
23
  import OnBoardingWidgetSkeleton from './Skeleton';
24
24
  import { closeSnackbar, useSnackbar } from 'notistack';
25
25
  import HeaderPlaceholder from '../../assets/onBoarding/header';
26
26
  import BaseDialog from '../../shared/BaseDialog';
27
27
  import PubSub from 'pubsub-js';
28
28
  import { SCCategoryEventType, SCTopicType } from '../../constants/PubSub';
29
+ import OnBoardingActionsButton from './ActionsButton';
29
30
  const classes = {
30
31
  root: `${PREFIX}-root`,
31
32
  content: `${PREFIX}-content`,
@@ -34,7 +35,9 @@ const classes = {
34
35
  intro: `${PREFIX}-intro`,
35
36
  steps: `${PREFIX}-steps`,
36
37
  stepsMobile: `${PREFIX}-steps-mobile`,
37
- stepContent: `${PREFIX}-step-content`
38
+ stepContent: `${PREFIX}-step-content`,
39
+ dialogRoot: `${PREFIX}-dialog-root`,
40
+ dialogContent: `${PREFIX}-dialog-content`
38
41
  };
39
42
  const Root = styled(Widget, {
40
43
  name: PREFIX,
@@ -46,6 +49,11 @@ const AccordionRoot = styled(Accordion, {
46
49
  slot: 'AccordionRoot',
47
50
  overridesResolver: (props, styles) => styles.accordionRoot
48
51
  })(() => ({}));
52
+ const DialogRoot = styled(BaseDialog, {
53
+ name: PREFIX,
54
+ slot: 'Root',
55
+ overridesResolver: (props, styles) => styles.dialogRoot
56
+ })(({ theme }) => ({}));
49
57
  const OnBoardingWidget = (inProps) => {
50
58
  // PROPS
51
59
  const props = useThemeProps({
@@ -70,7 +78,9 @@ const OnBoardingWidget = (inProps) => {
70
78
  const prevContentsStep = usePreviousValue(currentContentsStep);
71
79
  const currentCategoriesStep = steps === null || steps === void 0 ? void 0 : steps.find((s) => s.step === SCOnBoardingStepType.CATEGORIES);
72
80
  const prevCategoriesStep = usePreviousValue(currentCategoriesStep);
73
- const [showCategoriesModal, setShowCategoriesModal] = useState(false);
81
+ const [showNoCategoriesModal, setShowNoCategoriesModal] = useState(false);
82
+ const [showCategoriesWarningModal, setShowWarningCategoriesModal] = useState(false);
83
+ const [isGenerating, setIsGenerating] = useState(false);
74
84
  // CONTEXT
75
85
  const scUserContext = useSCUser();
76
86
  const isAdmin = useMemo(() => UserUtils.isCommunityCreator(scUserContext.user), [scUserContext.user]);
@@ -78,7 +88,11 @@ const OnBoardingWidget = (inProps) => {
78
88
  const scPreferencesContext = useSCPreferences();
79
89
  const scThemeContext = useSCTheme();
80
90
  const { enqueueSnackbar } = useSnackbar();
81
- const [isGenerating, setIsGenerating] = useState(false);
91
+ const showOnBoarding = useMemo(() => scPreferencesContext.preferences &&
92
+ SCPreferences.CONFIGURATIONS_ONBOARDING_ENABLED in scPreferencesContext.preferences &&
93
+ SCPreferences.CONFIGURATIONS_ONBOARDING_HIDDEN in scPreferencesContext.preferences &&
94
+ scPreferencesContext.preferences[SCPreferences.CONFIGURATIONS_ONBOARDING_ENABLED].value &&
95
+ !scPreferencesContext.preferences[SCPreferences.CONFIGURATIONS_ONBOARDING_HIDDEN].value, [scPreferencesContext.preferences]);
82
96
  // HOOKS
83
97
  const theme = useTheme();
84
98
  const isMobile = useMediaQuery(theme.breakpoints.down('md'));
@@ -164,22 +178,29 @@ const OnBoardingWidget = (inProps) => {
164
178
  };
165
179
  const generateContent = (stepId) => __awaiter(void 0, void 0, void 0, function* () {
166
180
  if (!isLoading && !categories.length) {
167
- setShowCategoriesModal(true);
181
+ setShowNoCategoriesModal(true);
182
+ }
183
+ else if (stepId === SCOnBoardingStepIdType.CATEGORIES) {
184
+ setShowWarningCategoriesModal(true);
168
185
  }
169
186
  else {
170
- yield OnBoardingService.startAStep(stepId, GenerateContentsParams)
171
- .then(() => {
172
- setIsGenerating(true);
173
- })
174
- .catch((error) => {
175
- Logger.error(SCOPE_SC_UI, error);
176
- enqueueSnackbar(_jsx(FormattedMessage, { id: "ui.common.error.action", defaultMessage: "ui.common.error.action" }), {
177
- variant: 'error',
178
- autoHideDuration: 3000
179
- });
180
- });
187
+ yield startStep(stepId);
181
188
  }
182
189
  });
190
+ const startStep = (stepId) => __awaiter(void 0, void 0, void 0, function* () {
191
+ showCategoriesWarningModal && setShowWarningCategoriesModal(false);
192
+ yield OnBoardingService.startAStep(stepId, GenerateContentsParams)
193
+ .then(() => {
194
+ setIsGenerating(true);
195
+ })
196
+ .catch((error) => {
197
+ Logger.error(SCOPE_SC_UI, error);
198
+ enqueueSnackbar(_jsx(FormattedMessage, { id: "ui.common.error.action", defaultMessage: "ui.common.error.action" }), {
199
+ variant: 'error',
200
+ autoHideDuration: 3000
201
+ });
202
+ });
203
+ });
183
204
  const handlePreferencesUpdate = () => {
184
205
  PreferenceService.getAllPreferences().then((preferences) => {
185
206
  const prefs = preferences['results'].reduce((obj, p) => (Object.assign(Object.assign({}, obj), { [`${p.section}.${p.name}`]: p })), {});
@@ -189,7 +210,7 @@ const OnBoardingWidget = (inProps) => {
189
210
  };
190
211
  const handleCategoriesClick = () => {
191
212
  fetchPlatform('/contents/interests/');
192
- setShowCategoriesModal(false);
213
+ setShowNoCategoriesModal(false);
193
214
  };
194
215
  /**
195
216
  * Notify when a category info changes
@@ -279,10 +300,10 @@ const OnBoardingWidget = (inProps) => {
279
300
  }
280
301
  return content;
281
302
  };
282
- if (!isAdmin) {
303
+ if (!isAdmin || !showOnBoarding) {
283
304
  return _jsx(HiddenPlaceholder, {});
284
305
  }
285
- return (_jsx(Root, Object.assign({ className: classNames(classes.root, className) }, rest, { children: _jsxs(AccordionRoot, Object.assign({ defaultExpanded: true, onChange: handleExpand, className: classes.accordionRoot, expanded: expanded }, { children: [_jsx(AccordionSummary, Object.assign({ expandIcon: _jsx(Icon, Object.assign({ fontSize: "medium" }, { children: "expand_more" })), "aria-controls": "accordion", id: "onBoarding-accordion" }, { children: _jsx(_Fragment, { children: expanded ? (_jsxs(_Fragment, { children: [!isMobile ? (_jsx(CardMedia, { className: classes.logo, component: "img", src: HeaderPlaceholder })) : (_jsxs(Typography, Object.assign({ variant: "h4" }, { children: [_jsx(Icon, Object.assign({ color: "secondary", fontSize: "medium" }, { children: "ai_stars" })), _jsx(FormattedMessage, { id: "ui.onBoardingWidget.accordion.expanded.title.mobile", defaultMessage: "ui.onBoardingWidget.accordion.expanded.title.mobile", values: {
306
+ return (_jsx(Root, Object.assign({ className: classNames(classes.root, className) }, rest, { children: _jsxs(AccordionRoot, Object.assign({ defaultExpanded: true, className: classes.accordionRoot, expanded: expanded }, { children: [_jsx(AccordionSummary, Object.assign({ expandIcon: _jsx(OnBoardingActionsButton, { isExpanded: expanded, onExpandChange: handleExpand, onHideOnBoarding: handlePreferencesUpdate }), "aria-controls": "accordion", id: "onBoarding-accordion" }, { children: _jsx(_Fragment, { children: expanded ? (_jsxs(_Fragment, { children: [!isMobile ? (_jsx(CardMedia, { className: classes.logo, component: "img", src: HeaderPlaceholder })) : (_jsxs(Typography, Object.assign({ variant: "h4" }, { children: [_jsx(Icon, Object.assign({ color: "secondary", fontSize: "medium" }, { children: "ai_stars" })), _jsx(FormattedMessage, { id: "ui.onBoardingWidget.accordion.expanded.title.mobile", defaultMessage: "ui.onBoardingWidget.accordion.expanded.title.mobile", values: {
286
307
  // eslint-disable-next-line @typescript-eslint/ban-ts-ignore
287
308
  // @ts-ignore
288
309
  b: (chunks) => _jsx("strong", { children: chunks })
@@ -301,6 +322,10 @@ const OnBoardingWidget = (inProps) => {
301
322
  // @ts-ignore
302
323
  // eslint-disable-next-line prettier/prettier
303
324
  icon: (...chunks) => _jsx(Icon, Object.assign({ color: "secondary", fontSize: "medium" }, { children: chunks }))
304
- } }) }))) }) })), _jsx(AccordionDetails, { children: _jsx(Widget, Object.assign({ className: classes.content, elevation: 0 }, { children: loading ? (_jsx(OnBoardingWidgetSkeleton, {})) : (_jsxs(CardContent, { children: [_jsx(List, Object.assign({ className: isMobile ? classes.stepsMobile : classes.steps }, { children: steps === null || steps === void 0 ? void 0 : steps.map((step) => (_jsx(ListItem, { children: isMobile ? (_jsx(Chip, { size: "small", label: _jsxs(_Fragment, { children: [_jsx(FormattedMessage, { id: `ui.onBoardingWidget.${step.step}`, defaultMessage: `ui.onBoardingWidget.${step.step}` }), ' ', step.status === SCOnBoardingStepStatusType.COMPLETED && (_jsx(Icon, Object.assign({ color: (step === null || step === void 0 ? void 0 : step.status) === SCOnBoardingStepStatusType.COMPLETED && (step === null || step === void 0 ? void 0 : step.step) !== (_step === null || _step === void 0 ? void 0 : _step.step) ? 'success' : 'inherit' }, { children: "check" })))] }), onClick: () => handleChange(step), variant: step.step === (_step === null || _step === void 0 ? void 0 : _step.step) ? 'filled' : 'outlined', color: step.status === SCOnBoardingStepStatusType.COMPLETED ? 'success' : 'default' })) : (_jsxs(ListItemButton, Object.assign({ onClick: () => handleChange(step), selected: (step === null || step === void 0 ? void 0 : step.step) === (_step === null || _step === void 0 ? void 0 : _step.step) }, { children: [_jsx(ListItemIcon, { children: _jsx(Checkbox, { edge: "start", checked: step.status === SCOnBoardingStepStatusType.COMPLETED, tabIndex: -1, disableRipple: true, inputProps: { 'aria-labelledby': step.step }, size: 'small' }) }), _jsx(ListItemText, { primary: _jsx(FormattedMessage, { id: `ui.onBoardingWidget.${step.step}`, defaultMessage: `ui.onBoardingWidget.${step.step}` }) })] }))) }, step.id))) })), _jsxs(Box, Object.assign({ className: classes.stepContent }, { children: [_jsx(Fade, Object.assign({ in: true, timeout: 2400 }, { children: _jsx(Box, { children: getStepContent() }) })), showCategoriesModal && (_jsx(BaseDialog, Object.assign({ title: _jsx(FormattedMessage, { id: "ui.onBoardingWidget.ai.no.categories", defaultMessage: "ui.onBoardingWidget.ai.no.categories" }), DialogContentProps: { dividers: false }, open: showCategoriesModal, onClose: () => setShowCategoriesModal(false), actions: _jsx(Button, Object.assign({ color: "secondary", onClick: () => setShowCategoriesModal(false) }, { children: _jsx(FormattedMessage, { id: "ui.onBoardingWidget.ai.no.categories.cancel", defaultMessage: "ui.onBoardingWidget.ai.no.categories.cancel" }) })) }, { children: _jsx(Button, Object.assign({ color: "primary", onClick: handleCategoriesClick, startIcon: _jsx(Icon, Object.assign({ fontSize: "small" }, { children: "edit" })) }, { children: _jsx(FormattedMessage, { id: "ui.onBoardingWidget.ai.no.categories.link", defaultMessage: "ui.onBoardingWidget.ai.no.categories.link" }) })) })))] }))] })) })) })] })) })));
325
+ } }) }))) }) })), _jsx(AccordionDetails, { children: _jsx(Widget, Object.assign({ className: classes.content, elevation: 0 }, { children: loading ? (_jsx(OnBoardingWidgetSkeleton, {})) : (_jsxs(CardContent, { children: [_jsx(List, Object.assign({ className: isMobile ? classes.stepsMobile : classes.steps }, { children: steps === null || steps === void 0 ? void 0 : steps.map((step) => (_jsx(ListItem, { children: isMobile ? (_jsx(Chip, { size: "small", label: _jsxs(_Fragment, { children: [_jsx(FormattedMessage, { id: `ui.onBoardingWidget.${step.step}`, defaultMessage: `ui.onBoardingWidget.${step.step}` }), ' ', step.status === SCOnBoardingStepStatusType.COMPLETED && (_jsx(Icon, Object.assign({ color: (step === null || step === void 0 ? void 0 : step.status) === SCOnBoardingStepStatusType.COMPLETED && (step === null || step === void 0 ? void 0 : step.step) !== (_step === null || _step === void 0 ? void 0 : _step.step) ? 'success' : 'inherit' }, { children: "check" })))] }), onClick: () => handleChange(step), variant: step.step === (_step === null || _step === void 0 ? void 0 : _step.step) ? 'filled' : 'outlined', color: step.status === SCOnBoardingStepStatusType.COMPLETED ? 'success' : 'default' })) : (_jsxs(ListItemButton, Object.assign({ onClick: () => handleChange(step), selected: (step === null || step === void 0 ? void 0 : step.step) === (_step === null || _step === void 0 ? void 0 : _step.step) }, { children: [_jsx(ListItemIcon, { children: _jsx(Checkbox, { edge: "start", checked: step.status === SCOnBoardingStepStatusType.COMPLETED, tabIndex: -1, disableRipple: true, inputProps: { 'aria-labelledby': step.step }, size: 'small' }) }), _jsx(ListItemText, { primary: _jsx(FormattedMessage, { id: `ui.onBoardingWidget.${step.step}`, defaultMessage: `ui.onBoardingWidget.${step.step}` }) })] }))) }, step.id))) })), _jsxs(Box, Object.assign({ className: classes.stepContent }, { children: [_jsx(Fade, Object.assign({ in: true, timeout: 2400 }, { children: _jsx(Box, { children: getStepContent() }) })), showNoCategoriesModal && (_jsx(BaseDialog, Object.assign({ title: _jsx(FormattedMessage, { id: "ui.onBoardingWidget.ai.no.categories", defaultMessage: "ui.onBoardingWidget.ai.no.categories" }), DialogContentProps: { dividers: false }, open: showNoCategoriesModal, onClose: () => setShowNoCategoriesModal(false), actions: _jsx(Button, Object.assign({ color: "secondary", onClick: () => setShowNoCategoriesModal(false) }, { children: _jsx(FormattedMessage, { id: "ui.onBoardingWidget.ai.no.categories.cancel", defaultMessage: "ui.onBoardingWidget.ai.no.categories.cancel" }) })) }, { children: _jsx(Button, Object.assign({ color: "primary", onClick: handleCategoriesClick, startIcon: _jsx(Icon, Object.assign({ fontSize: "small" }, { children: "edit" })) }, { children: _jsx(FormattedMessage, { id: "ui.onBoardingWidget.ai.no.categories.link", defaultMessage: "ui.onBoardingWidget.ai.no.categories.link" }) })) }))), showCategoriesWarningModal && (_jsx(DialogRoot, Object.assign({ className: classes.dialogRoot, title: _jsx(FormattedMessage, { id: "ui.onBoardingWidget.ai.categories.warning.title", defaultMessage: "ui.onBoardingWidget.ai.categories.warning.title" }), DialogContentProps: { dividers: false }, open: showCategoriesWarningModal, onClose: () => setShowWarningCategoriesModal(false), actions: _jsxs(_Fragment, { children: [_jsx(Button, Object.assign({ size: "small", variant: "outlined", color: "primary", onClick: () => setShowWarningCategoriesModal(false) }, { children: _jsx(FormattedMessage, { id: "ui.onBoardingWidget.ai.categories.warning.button.close", defaultMessage: "ui.onBoardingWidget.ai.categories.warning.button.close" }) })), _jsx(Button, Object.assign({ size: "small", variant: "contained", color: "secondary", onClick: () => startStep(SCOnBoardingStepIdType.CATEGORIES), endIcon: _jsx(Icon, Object.assign({ fontSize: "small" }, { children: "magic_wand" })) }, { children: _jsx(FormattedMessage, { id: "ui.onBoardingWidget.ai.categories.warning.button.generate", defaultMessage: "ui.onBoardingWidget.ai.categories.warning.button.generate" }) }))] }) }, { children: _jsxs(Typography, Object.assign({ className: classes.dialogContent }, { children: [_jsx(FormattedMessage, { id: "ui.onBoardingWidget.ai.categories.warning.info", defaultMessage: "ui.onBoardingWidget.ai.categories.warning.info" }), _jsx(FormattedMessage, { id: "ui.onBoardingWidget.ai.categories.warning.confirm", defaultMessage: "ui.onBoardingWidget.ai.categories.warning.confirm", values: {
326
+ // eslint-disable-next-line @typescript-eslint/ban-ts-ignore
327
+ // @ts-ignore
328
+ b: (chunks) => _jsx("b", { children: chunks })
329
+ } })] })) })))] }))] })) })) })] })) })));
305
330
  };
306
331
  export default OnBoardingWidget;
@@ -18,6 +18,7 @@ const classes = {
18
18
  summary: `${PREFIX}-app-summary`,
19
19
  step: `${PREFIX}-app-step`,
20
20
  image: `${PREFIX}-app-image`,
21
+ imageAndroid: `${PREFIX}-app-image-android`,
21
22
  action: `${PREFIX}-app-action`,
22
23
  button: `${PREFIX}-app-button`
23
24
  };
@@ -53,7 +54,7 @@ export default function App(inProps) {
53
54
  // eslint-disable-next-line @typescript-eslint/ban-ts-ignore
54
55
  // @ts-ignore
55
56
  b: (...chunks) => _jsx("strong", { children: chunks })
56
- } }) })), _jsx(CardMedia, { className: classes.image, component: "img", src: AndroidPlaceholder })] })), tab === 1 && (_jsxs(_Fragment, { children: [_jsx(Typography, Object.assign({ className: classes.summary }, { children: _jsx(FormattedMessage, { id: "ui.onBoardingWidget.step.app.ios", defaultMessage: "ui.onBoardingWidget.step.app.ios" }) })), _jsx(Typography, Object.assign({ className: classes.step }, { children: _jsx(FormattedMessage, { id: "ui.onBoardingWidget.step.app.ios.a", defaultMessage: "ui.onBoardingWidget.step.app.ios.a", values: {
57
+ } }) })), _jsx(CardMedia, { className: classes.imageAndroid, component: "img", src: AndroidPlaceholder })] })), tab === 1 && (_jsxs(_Fragment, { children: [_jsx(Typography, Object.assign({ className: classes.summary }, { children: _jsx(FormattedMessage, { id: "ui.onBoardingWidget.step.app.ios", defaultMessage: "ui.onBoardingWidget.step.app.ios" }) })), _jsx(Typography, Object.assign({ className: classes.step }, { children: _jsx(FormattedMessage, { id: "ui.onBoardingWidget.step.app.ios.a", defaultMessage: "ui.onBoardingWidget.step.app.ios.a", values: {
57
58
  // eslint-disable-next-line @typescript-eslint/ban-ts-ignore
58
59
  // @ts-ignore
59
60
  icon: (...chunks) => _jsx(Icon, Object.assign({ fontSize: "medium" }, { children: chunks })),