all repos — caroster @ 7aa17436c75503123cefb51191e8a757883333e9

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

🐛 Fixes after UX demo
Tim Izzo tim@5ika.ch
Mon, 06 Jan 2025 16:00:15 +0100
commit

7aa17436c75503123cefb51191e8a757883333e9

parent

b8b34223c99fc20b7f329b2950cbe0375ebeec5b

M backend/src/api/email/locales/fr.jsonbackend/src/api/email/locales/fr.json

@@ -1,6 +1,6 @@

{ "template": { - "footer": "<a href='https://octreegva.notion.site/Charte-du-Covoitureur-FR-758f2974306d4c8fa59f259f31b31ae6?pvs=4'>Voir la charte du coivoitureur</a>\n\n\n💝 Vous pensez aussi que Caroster est génial ? Aidez-nous à le maintenir libre et gratuit en faisant une donation !", + "footer": "<a href='https://octreegva.notion.site/Charte-du-Covoitureur-FR-758f2974306d4c8fa59f259f31b31ae6?pvs=4'>Voir la charte du covoitureur</a>\n\n\n💝 Vous pensez aussi que Caroster est génial ? Aidez-nous à le maintenir libre et gratuit en faisant une donation !", "carosterLink": "https://caroster.io" }, "notifications": {
M frontend/containers/AddPassengerButtons/index.tsxfrontend/containers/AddPassengerButtons/index.tsx

@@ -8,6 +8,7 @@ import LoginDialog from '../LoginDialog';

import {useRouter} from 'next/router'; interface Props { + travelId: string; onAddSelf: () => void; onAddOther: () => void; registered: boolean;

@@ -21,7 +22,8 @@ travel: 'travel.passengers.add_to_travel',

}; const AddPassengerButtons = (props: Props) => { - const {onAddSelf, onAddOther, registered, variant, disabled} = props; + const {onAddSelf, onAddOther, registered, variant, disabled, travelId} = + props; const {t} = useTranslation(); const router = useRouter(); const event = useEventStore(s => s.event);

@@ -36,7 +38,7 @@ else onAddSelf();

}; useEffect(() => { - if (router.query.action === 'addSelf') { + if (router.query.action === 'addSelf' && router.query.travel === travelId) { onAddSelf(); router.replace( {pathname: `/${router.locale}/e/${router.query.uuid}`, query: null},

@@ -48,21 +50,23 @@ }, [router, onAddSelf]);

return ( <> - <Stack spacing={2} p={1} pt={2}> - <Button - variant="contained" - color="primary" - fullWidth - onClick={onClickAddSelf} - disabled={disabled || registered} - > - {t( - registered - ? 'travel.passengers.registered' - : 'travel.passengers.add_me' - )} - </Button> - {isCarosterPlus && isAuthenticated && ( + <Stack spacing={2} p={1}> + {(isCarosterPlus || isAuthenticated) && ( + <Button + variant="contained" + color="primary" + fullWidth + onClick={onClickAddSelf} + disabled={disabled || registered} + > + {t( + registered + ? 'travel.passengers.registered' + : 'travel.passengers.add_me' + )} + </Button> + )} + {!isCarosterPlus && ( <Button variant="outlined" color="primary"

@@ -79,7 +83,7 @@ title={t`travel.passengers.add_me`}

content={t`travel.passengers.add_me.loginNotice`} open={showLoginDialog} toggle={toggleLoginDialog} - redirectPath={`/e/${event?.uuid}/?action=addSelf`} + redirectPath={`/e/${event?.uuid}/?action=addSelf&travel=${travelId}`} /> </> );
M frontend/containers/EventBar/LinkedEventSwitch.tsxfrontend/containers/EventBar/LinkedEventSwitch.tsx

@@ -27,8 +27,12 @@ href={router.asPath.replace(loadedEvent.uuid, goEvent.uuid)}

style={{width: isMobile && '100%'}} > <Button - color={loadedEvent.isReturnEvent ? 'inherit' : 'secondary'} - sx={{color: 'rgba(0, 0, 0, 0.87)'}} + color={loadedEvent.isReturnEvent ? 'inherit' : 'primary'} + sx={{ + color: loadedEvent.isReturnEvent + ? 'rgba(0, 0, 0, 0.87)' + : 'rgba(255, 255, 255, 0.87)', + }} > {t`event.linked.goEvent`} ({goEvent.travels?.data?.length || 0}) </Button>

@@ -38,8 +42,12 @@ href={router.asPath.replace(loadedEvent.uuid, returnEvent.uuid)}

style={{width: isMobile && '100%'}} > <Button - color={!loadedEvent.isReturnEvent ? 'inherit' : 'secondary'} - sx={{color: 'rgba(0, 0, 0, 0.87)'}} + color={!loadedEvent.isReturnEvent ? 'inherit' : 'primary'} + sx={{ + color: !loadedEvent.isReturnEvent + ? 'rgba(0, 0, 0, 0.87)' + : 'rgba(255, 255, 255, 0.87)', + }} > {t`event.linked.returnEvent`} ( {returnEvent?.travels?.data?.length || 0})
M frontend/containers/EventBar/useActions.tsfrontend/containers/EventBar/useActions.ts

@@ -61,11 +61,13 @@ {

label: t('menu.profile'), onClick: () => router.push('/profile'), id: 'ProfileTab', + icon: 'account_circle', }, { label: t('menu.dashboard'), onClick: () => (window.location.href = '/dashboard'), id: 'GoToDashboardTab', + icon: 'space_dashboard', }, { label: t('event.actions.share'),

@@ -74,6 +76,7 @@ share({

title: `Caroster ${event.name}`, }), id: 'ShareEvent', + icon: 'share', }, {divider: true}, ];
M frontend/containers/GenericMenu/Action.tsxfrontend/containers/GenericMenu/Action.tsx

@@ -1,18 +1,13 @@

import {isValidElement} from 'react'; -import {styled} from '@mui/material/styles'; import Divider from '@mui/material/Divider'; import Typography from '@mui/material/Typography'; import MenuItem from '@mui/material/MenuItem'; -const PREFIX = 'Action'; - -const classes = { - divider: `${PREFIX}-divider`, - textItem: `${PREFIX}-textItem`, -}; +import {Icon, ListItemIcon, ListItemText} from '@mui/material'; export type ActionType = { divider?: boolean; label: JSX.Element | string; + icon?: string; id: string; onClick?: () => void; };

@@ -23,29 +18,25 @@ }

const Action = (props: Props): JSX.Element => { const {action} = props; - const {divider, onClick, id, label, ...menuItemProps} = action; + const {divider, onClick, id, label, icon, ...menuItemProps} = action; if (divider) return <Divider variant="fullWidth" sx={{mt: 0, mb: 0}} />; else if (isValidElement(label)) return label; else if (onClick) return ( <MenuItem id={id} onClick={onClick} {...menuItemProps}> - {label} + <ListItemIcon> + <Icon baseClassName="material-icons-outlined">{icon}</Icon> + </ListItemIcon> + <ListItemText>{label}</ListItemText> </MenuItem> ); else return ( - <StyledTypography variant="body1" id={id} className={classes.textItem}> + <Typography variant="body1" id={id}> {label} - </StyledTypography> + </Typography> ); }; - -const StyledTypography = styled(Typography)(({theme}) => ({ - [`&.${classes.textItem}`]: { - margin: theme.spacing(1, 2), - '&:focus': {outline: 0}, - }, -})); export default Action;
M frontend/containers/GenericMenu/index.tsxfrontend/containers/GenericMenu/index.tsx

@@ -76,6 +76,7 @@ callbackUrl: settings?.['about_link'] || '/',

}); }, id: 'LogoutTabs', + icon: 'logout', }; const validActions = [
M frontend/containers/GenericToolbar/index.tsxfrontend/containers/GenericToolbar/index.tsx

@@ -26,9 +26,7 @@ }) => {

const router = useRouter(); const theme = useTheme(); const [anchorEl, setAnchorEl] = useState(null); - const {profile, connected} = useProfile(); - const session = useSession(); const isAuthenticated = session.status === 'authenticated';
M frontend/containers/PassengersList/Passenger.tsxfrontend/containers/PassengersList/Passenger.tsx

@@ -64,7 +64,7 @@ textOverflow: 'ellipsis',

whiteSpace: 'nowrap', }} > - {getPassengerName(passenger, canSeeFullName())} + {getPassengerName(passenger, canSeeFullName() || isUser)} </Typography> {isUser && ( <Chip
M frontend/containers/Travel/Header.tsxfrontend/containers/Travel/Header.tsx

@@ -84,7 +84,7 @@ {travel.attributes.departureTime}

</Typography> )} <Typography variant="subtitle1"> - {getTravelName(travel, canSeeFullName())} + {getTravelName(travel, canSeeFullName() || isUserTripCreator)} {isUserTripCreator && ( <Typography component="span"> <Chip
M frontend/containers/Travel/index.tsxfrontend/containers/Travel/index.tsx

@@ -78,6 +78,7 @@ <Header travel={travel} toggleEditing={toggleEditing} />

<> <Divider /> <AddPassengerButtons + travelId={travel.id} registered={registered} variant="travel" disabled={disableNewPassengers}
M frontend/layouts/EventCreation.tsxfrontend/layouts/EventCreation.tsx

@@ -1,6 +1,4 @@

-import {Paper} from '@mui/material'; import Layout from './Centered'; -import Logo from '../components/Logo'; import LanguagesIcon from '../containers/Languages/Icon'; import {useTranslation} from 'next-i18next'; import {useSession} from 'next-auth/react';

@@ -24,12 +22,14 @@ {

label: t('menu.profile'), onClick: () => router.push('/profile'), id: 'ProfileTabs', + icon: 'account_circle', }, {divider: true}, { label: t('menu.dashboard'), onClick: () => router.push('/dashboard'), id: 'SeeDashboardTabs', + icon: 'dashboard', }, ] : [

@@ -37,6 +37,7 @@ {

label: t('menu.login'), onClick: () => router.push('/auth/login'), id: 'LoginTabs', + icon: 'login', }, ];
M frontend/pages/dashboard.tsxfrontend/pages/dashboard.tsx

@@ -54,12 +54,14 @@ {

label: t('menu.profile'), onClick: () => router.push('/profile'), id: 'ProfileTabs', + icon: 'account_circle', }, {divider: true}, { label: t('menu.new_event'), onClick: () => router.push('/new'), id: 'AddEventTabs', + icon: 'add', }, ];
M frontend/pages/new/type.tsxfrontend/pages/new/type.tsx

@@ -15,13 +15,14 @@ const router = useRouter();

const theme = useTheme(); const isMobile = useMediaQuery(theme.breakpoints.down('md')); const event = useEventCreationStore(s => s.event); + const eventStoreReady = useEventCreationStore(s => s.ready); const {locale} = useLocale(); const {data: moduleData} = useModuleQuery({variables: {locale}}); const moduleConfig = moduleData?.module?.data?.attributes; useEffect(() => { - if (!event.name) router.push('/new'); - }, [event.name, router]); + if (eventStoreReady && !event.name) router.push('/new'); + }, [event.name, eventStoreReady, router]); return ( <Layout>
M frontend/stores/useEventCreationStore.tsfrontend/stores/useEventCreationStore.ts

@@ -3,6 +3,7 @@ import {persist, createJSONStorage} from 'zustand/middleware';

import {EventInput} from '../generated/graphql'; interface State { + ready: boolean; event: Partial<EventInput>; setField: (fieldName: keyof EventInput, value: unknown) => void; }

@@ -10,6 +11,7 @@

const useEventCreationStore = create<State>()( persist( (set, get) => ({ + ready: false, event: {}, setField: (field, value) => { const currentEvent = get().event;

@@ -19,6 +21,9 @@ }),

{ name: 'event-creation', storage: createJSONStorage(() => localStorage), + onRehydrateStorage: () => state => { + if (state) state.ready = true; + }, } ) );