all repos — caroster @ 023ece6b1795904bfe86c87c7d6fb9135203ad67

[Octree] Group carpool to your event https://caroster.io

fix: 🐛 Fix onboarding steps

#215
Tim Izzo tim@octree.ch
Wed, 15 Dec 2021 10:51:45 +0100
commit

023ece6b1795904bfe86c87c7d6fb9135203ad67

parent

7a66195e62a0d97514c3517fded0e0a4543c0623

M frontend/containers/CarColumns/AddCar.tsxfrontend/containers/CarColumns/AddCar.tsx

@@ -15,7 +15,6 @@ const {t} = useTranslation();

return ( <Container maxWidth="sm" className={classes.container}> <Button - className="tour_car_add1" classes={{containedSecondary: classes.button}} fullWidth variant="contained"
M frontend/containers/CarColumns/index.tsxfrontend/containers/CarColumns/index.tsx

@@ -18,15 +18,13 @@ const CarColumns = (props: Props) => {

const event = useEventStore(s => s.event); const {cars} = event || {}; const slider = useRef(null); - const isCreator = useTourStore(s => s.isCreator); - const step = useTourStore(s => s.step); - const prev = useTourStore(s => s.prev); + const tourStep = useTourStore(s => s.step); const classes = useStyles(); // On tour step changes : component update useEffect(() => { - tourStep(prev, step, isCreator, slider.current); - }, [step]); + onTourChange(slider.current); + }, [tourStep]); return ( <div className={classes.container}>

@@ -53,19 +51,14 @@ </div>

); }; -const tourStep = (prev, step, isCreator, slider) => { - const fromTo = (step1, step2) => prev === step1 && step === step2; - const first = () => slider?.slickGoTo(0, true); - const last = () => - slider?.slickGoTo(slider?.innerSlider.state.slideCount, true); +const onTourChange = slider => { + const {prev, step, isCreator} = useTourStore.getState(); + const fromTo = (step1: number, step2: number) => + prev === step1 && step === step2; if (isCreator) { - if (fromTo(2, 3) || fromTo(4, 3)) first(); - else if (fromTo(3, 4)) last(); - } else { - if (fromTo(1, 2)) first(); - else if (fromTo(0, 1) || fromTo(2, 1)) last(); - } + if (fromTo(2, 3) || fromTo(4, 3)) slider?.slickGoTo(0, true); + } else if (fromTo(0, 1)) slider?.slickGoTo(0, true); }; const sortCars = (a: CarType, b: CarType) => {

@@ -106,10 +99,9 @@ '& li': {

display: 'block', }, }, - '& .slick-dots li:first-child button:before, & .slick-dots li:last-child button:before': - { - color: theme.palette.primary.main, - }, + '& .slick-dots li:first-child button:before, & .slick-dots li:last-child button:before': { + color: theme.palette.primary.main, + }, }, slider: { flexGrow: 1,
M frontend/containers/EventBar/index.jsfrontend/containers/EventBar/index.tsx

@@ -18,25 +18,23 @@ import useSettings from '../../hooks/useSettings';

import EventMenu from '../EventMenu'; import EventDetails from '../EventDetails'; -const EventBar = ({event, onAdd, onSave, onShare, onTourRestart}) => { +const EventBar = ({event, onAdd, onSave, onShare}) => { const {t} = useTranslation(); const router = useRouter(); const [detailsOpen, toggleDetails] = useReducer(i => !i, false); + const classes = useStyles({detailsOpen}); const [anchorEl, setAnchorEl] = useState(null); const isEditing = useEventStore(s => s.isEditing); const setIsEditing = useEventStore(s => s.setIsEditing); const token = useAuthStore(s => s.token); const {user} = useProfile(); const settings = useSettings(); - const isCreator = useTourStore(s => s.isCreator); - const prev = useTourStore(s => s.prev); - const step = useTourStore(s => s.step); - const classes = useStyles({detailsOpen}); + const setTour = useTourStore(s => s.setTour); + const tourStep = useTourStore(s => s.step); - // On tour step changes : component update useEffect(() => { - tourStep(prev, step, isCreator, toggleDetails); - }, [step]); + onTourChange(toggleDetails); + }, [tourStep]); useEffect(() => { if (!detailsOpen) setIsEditing(false);

@@ -50,6 +48,8 @@ });

const signIn = () => router.push('/auth/login'); const goToDashboard = () => router.push('/dashboard'); const goProfile = () => router.push('/profile'); + + const onTourRestart = () => setTour({showWelcome: true}); const noUserMenuActions = [ {

@@ -202,15 +202,15 @@ </AppBar>

); }; -const tourStep = (prev, step, isCreator, toggleDetails) => { - const fromTo = (step1, step2) => prev === step1 && step === step2; +const onTourChange = (toggleDetails: Function) => { + const {prev, step, isCreator} = useTourStore.getState(); + const fromTo = (step1: number, step2: number) => + prev === step1 && step === step2; if (isCreator) { if (fromTo(1, 0) || fromTo(0, 1) || fromTo(3, 2) || fromTo(2, 3)) toggleDetails(); - } else { - if (fromTo(4, 3) || fromTo(3, 4)) toggleDetails(); - } + } else if (fromTo(2, 3) || fromTo(3, 2)) toggleDetails(); }; const useStyles = makeStyles(theme => ({
M frontend/containers/Fab/index.jsfrontend/containers/Fab/index.tsx

@@ -10,7 +10,7 @@

return ( <div className={classes.container}> <FabMui - className="tour_car_add2" + className="tour_car_add1" color="secondary" variant={variant} {...props}
A frontend/containers/OnBoardingTour/index.tsx

@@ -0,0 +1,40 @@

+import Joyride from 'react-joyride'; +import {useTheme} from '@material-ui/core/styles'; +import {useTranslation} from 'react-i18next'; +import useTour from '../../hooks/useTour'; + +interface Props {} + +const OnBoardingTour = (props: Props) => { + const theme = useTheme(); + const {t} = useTranslation(); + const {run, steps, step, onTourChange} = useTour(); + + return ( + <Joyride + run={run} + steps={steps} + stepIndex={step} + callback={onTourChange} + locale={t('joyride', {returnObjects: true})} + continuous={true} + showProgress={true} + disableScrolling={true} + disableScrollParentFix={true} + scrollToFirstStep={false} + floaterProps={{ + disableAnimation: true, + }} + styles={{ + options: { + primaryColor: theme.palette.primary.main, + }, + tooltipContent: { + whiteSpace: 'pre-wrap', + }, + }} + /> + ); +}; + +export default OnBoardingTour;
M frontend/containers/WelcomeDialog/index.jsfrontend/containers/WelcomeDialog/index.tsx

@@ -15,6 +15,11 @@ const showWelcome = useTourStore(s => s.showWelcome);

const setTour = useTourStore(s => s.setTour); const classes = useStyles(); + const onStartTour = () => + setTour({showWelcome: false, run: true, step: 0, prev: -1}); + + const onCancel = () => setTour({showWelcome: false}); + return ( <Dialog open={showWelcome}> <CardMedia

@@ -25,15 +30,10 @@ <DialogContent>

<DialogContentText>{t('tour.welcome.text')}</DialogContentText> </DialogContent> <DialogActions> - <Button onClick={() => setTour({showWelcome: false})} id="TourCancel"> + <Button onClick={onCancel} id="TourCancel"> {t('tour.welcome.nope')} </Button> - <Button - onClick={() => - setTour({showWelcome: false, run: false, step: 0, prev: -1}) - } - id="TourConfirm" - > + <Button onClick={onStartTour} id="TourConfirm"> {t('tour.welcome.onboard')} </Button> </DialogActions>
M frontend/hooks/useTour.tsfrontend/hooks/useTour.ts

@@ -57,14 +57,12 @@ {content: t`tour.creator.step2`, target: '.tour_event_edit'},

{content: t`tour.creator.step3`, target: '.tour_event_share'}, {content: t`tour.creator.step4`, target: '.tour_waiting_list'}, {content: t`tour.creator.step5`, target: '.tour_car_add1'}, - {content: t`tour.creator.step6`, target: '.tour_car_add2'}, ].map(step => ({...step, ...STEP_SETTINGS})) : [ - {content: t`tour.user.step1`, target: '.tour_car_add2'}, - {content: t`tour.user.step2`, target: '.tour_car_add1'}, - {content: t`tour.user.step3`, target: '.tour_waiting_list'}, - {content: t`tour.user.step4`, target: '.tour_event_infos'}, - {content: t`tour.user.step5`, target: '.tour_event_share'}, + {content: t`tour.user.step1`, target: '.tour_car_add1'}, + {content: t`tour.user.step2`, target: '.tour_waiting_list'}, + {content: t`tour.user.step3`, target: '.tour_event_infos'}, + {content: t`tour.user.step4`, target: '.tour_event_share'}, ].map(step => ({...step, ...STEP_SETTINGS})); }, [isCreator]);

@@ -100,10 +98,6 @@ setOnboarding({onboardingUser: true});

} }; - const onTourRestart = () => { - setTour({showWelcome: true}); - }; - const onTourChange = (data: CallBackProps) => { const {action, index, type, status} = data;

@@ -132,7 +126,6 @@ run,

steps, step, onTourChange, - onTourRestart, }; };
M frontend/locales/en.jsonfrontend/locales/en.json

@@ -35,15 +35,13 @@ "step1": "The event information can be modified from this menu.",

"step2": "The event can be edited by clicking on the edit button.", "step3": "Share the event now by copying the link and sharing it by email or in a messaging group.", "step4": "The waiting list includes passengers who do not yet have a seat in a car.", - "step5": "New cars are added from the right column.", - "step6": "A new car can also be added directly from the floating action button." + "step5": "A new car can also be added directly from the floating action button." }, "user": { "step1": "A new car can be added directly from the floating action button.", - "step2": "It is also possible to add a car from the right column.", - "step3": "Would you like a place in a car? Register on the waiting list or directly in a car.", - "step4": "The event information can be accessed from this menu.", - "step5": "Share the event now by copying the link and sharing it by email or in a group messaging." + "step2": "Would you like a place in a car? Register on the waiting list or directly in a car.", + "step3": "The event information can be accessed from this menu.", + "step4": "Share the event now by copying the link and sharing it by email or in a group messaging." } }, "joyride": {
M frontend/locales/fr.jsonfrontend/locales/fr.json

@@ -33,15 +33,15 @@ },

"creator": { "step1": "Vous pouvez voir et modifier les informations de l'événement depuis ce menu.✨", "step2": "Editez l'événement en cliquant sur le bouton d'édition.", - "step3": "Copiez le lien de l'événement dès maintenant pour le partager par email, whatsapp, telegram, etc.. ", + "step3": "Copiez le lien de l'événement dès maintenant pour le partager par email, whatsapp, telegram, etc.. ", "step4": "La liste d'attente regroupe les personnes qui n'ont pas encore été placées dans une voiture.", - "step6": "Ajoutez une nouvelle voiture en cliquant directement sur ce bouton." + "step5": "Ajoutez une nouvelle voiture en cliquant directement sur ce bouton." }, "user": { "step1": "Ajoutez une nouvelle voiture en cliquant directement sur ce bouton.", - "step3": "Vous aimeriez une place dans une voiture ? Inscrivez-vous dans la liste d'attente ou directement dans une voiture.", - "step4": "Les informations de l'événement sont accessibles depuis ce menu.", - "step5": "Copiez le lien de l'événement dès maintenant pour le partager par email, whatsapp, telegram, etc.." + "step2": "Vous aimeriez une place dans une voiture ? Inscrivez-vous dans la liste d'attente ou directement dans une voiture.", + "step3": "Les informations de l'événement sont accessibles depuis ce menu.", + "step4": "Copiez le lien de l'événement dès maintenant pour le partager par email, whatsapp, telegram, etc.." } }, "joyride": {
M frontend/pages/e/[uuid].tsxfrontend/pages/e/[uuid].tsx

@@ -1,11 +1,8 @@

import {useState, useReducer, useEffect} from 'react'; -import {useTheme} from '@material-ui/core/styles'; import {useTranslation} from 'react-i18next'; -import Joyride from 'react-joyride'; import {initializeApollo} from '../../lib/apolloClient'; import useToastStore from '../../stores/useToastStore'; import useEventStore from '../../stores/useEventStore'; -import useTour from '../../hooks/useTour'; import Layout from '../../layouts/Default'; import AddToMyEventDialog from '../../containers/AddToMyEventDialog'; import CarColumns from '../../containers/CarColumns';

@@ -14,6 +11,7 @@ import WelcomeDialog from '../../containers/WelcomeDialog';

import EventBar from '../../containers/EventBar'; import Loading from '../../containers/Loading'; import Fab from '../../containers/Fab'; +import OnBoardingTour from '../../containers/OnBoardingTour'; import { useUpdateEventMutation, Event as EventType,

@@ -33,16 +31,13 @@

const EventPage = props => { const {t} = useTranslation(); const {event} = props; - if (!event) return <ErrorPage statusCode={404} title={t`event.not_found`} />; - return <Event {...props} />; }; const Event = (props: Props) => { const {eventUUID} = props; const {t} = useTranslation(); - const theme = useTheme(); const addToast = useToastStore(s => s.addToast); const setEvent = useEventStore(s => s.setEvent); const eventUpdate = useEventStore(s => s.event);

@@ -54,7 +49,6 @@ const {data: {eventByUUID: event} = {}} = useEventByUuidQuery({

pollInterval: POLL_INTERVAL, variables: {uuid: eventUUID}, }); - const {run, steps, step, onTourChange, onTourRestart} = useTour(); useEffect(() => { if (event) setEvent(event as EventType);

@@ -104,7 +98,6 @@ event={event}

onAdd={setIsAddToMyEvent} onSave={onSave} onShare={onShare} - onTourRestart={onTourRestart} /> <CarColumns toggleNewCar={toggleNewCar} /> <Fab open={openNewCar} onClick={toggleNewCar} aria-label="add-car" />

@@ -115,29 +108,7 @@ open={isAddToMyEvent}

onClose={() => setIsAddToMyEvent(false)} /> <WelcomeDialog /> - <Joyride - run={run} - steps={steps} - stepIndex={step} - callback={onTourChange} - locale={t('joyride', {returnObjects: true})} - continuous={true} - showProgress={true} - disableScrolling={true} - disableScrollParentFix={true} - scrollToFirstStep={false} - floaterProps={{ - disableAnimation: true, - }} - styles={{ - options: { - primaryColor: theme.palette.primary.main, - }, - tooltipContent: { - whiteSpace: 'pre-wrap', - }, - }} - /> + <OnBoardingTour /> </Layout> ); };