all repos — caroster @ e70935af9e0fac5a21e2c8dd999608ce06538783

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

chore: :globe_with_meridians: Clear i18n setup
Tim Izzo tim@octree.ch
Wed, 21 Aug 2024 11:00:21 +0200
commit

e70935af9e0fac5a21e2c8dd999608ce06538783

parent

5ed83071ddb9096ff61df7bcbb763178d4445e4d

89 files changed, 289 insertions(+), 281 deletions(-)

jump to
M frontend/components/LangSelector/index.tsxfrontend/components/LangSelector/index.tsx

@@ -2,7 +2,7 @@ import FormControl from '@mui/material/FormControl';

import {Enum_Event_Lang} from '../../generated/graphql'; import Select from '@mui/material/Select'; import MenuItem from '@mui/material/MenuItem'; -import {useTranslation} from 'react-i18next'; +import {useTranslation} from 'next-i18next'; type Props = { value: Enum_Event_Lang;

@@ -26,5 +26,5 @@ <MenuItem value={'nl'}>{t`PROTECTED.languages.nl`}</MenuItem>

</Select> </FormControl> ); -}; +}; export default LangSelector;
M frontend/containers/AddPassengerButtons/index.tsxfrontend/containers/AddPassengerButtons/index.tsx

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

import Box from '@mui/material/Box'; import Button from '@mui/material/Button'; -import {useTranslation} from 'react-i18next'; +import {useTranslation} from 'next-i18next'; import usePermissions from '../../hooks/usePermissions'; interface Props {
M frontend/containers/AddToMyEventDialog/index.tsxfrontend/containers/AddToMyEventDialog/index.tsx

@@ -1,5 +1,5 @@

import {forwardRef} from 'react'; -import { styled } from '@mui/material/styles'; +import {styled} from '@mui/material/styles'; import {useRouter} from 'next/router'; import Dialog from '@mui/material/Dialog'; import DialogTitle from '@mui/material/DialogTitle';

@@ -10,25 +10,21 @@ import Icon from '@mui/material/Icon';

import Slide from '@mui/material/Slide'; import Button from '@mui/material/Button'; import IconButton from '@mui/material/IconButton'; -import {useTranslation} from 'react-i18next'; +import {useTranslation} from 'next-i18next'; import useAddToEvents from '../../hooks/useAddToEvents'; const PREFIX = 'AddToMyEventDialog'; const classes = { - close: `${PREFIX}-close` + close: `${PREFIX}-close`, }; -const StyledSlide = styled(Slide)(( - { - theme - } -) => ({ +const StyledSlide = styled(Slide)(({theme}) => ({ [`& .${classes.close}`]: { position: 'absolute', top: theme.spacing(1), right: theme.spacing(0.5), - } + }, })); const AddToMyEventDialog = ({event, open, onClose}) => {
M frontend/containers/Alerts/index.tsxfrontend/containers/Alerts/index.tsx

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

import {useReducer} from 'react'; import {Box, Container, Paper, Typography, useMediaQuery} from '@mui/material'; -import {useTranslation} from 'react-i18next'; +import {useTranslation} from 'next-i18next'; import theme from '../../theme'; import usePermissions from '../../hooks/usePermissions'; import LoginToAttend from '../LoginToAttend/LoginToAttend';

@@ -27,9 +27,9 @@

return ( <Container maxWidth="sm" sx={{mt: 11, mx: 0, px: isMobile ? 2 : 4}}> {!canSetAlert() && ( - <Box sx={{width: '480px', maxWidth: '100%', position: 'relative'}}> - <LoginToAttend title={t('event.loginToSetAlert')}/> - </Box> + <Box sx={{width: '480px', maxWidth: '100%', position: 'relative'}}> + <LoginToAttend title={t('event.loginToSetAlert')} /> + </Box> )} <Paper sx={{width: '480px', maxWidth: '100%', position: 'relative'}}> <Box p={2}>
M frontend/containers/AssignPassenger/AvailableTravel.tsxfrontend/containers/AssignPassenger/AvailableTravel.tsx

@@ -6,7 +6,7 @@ import Link from '@mui/material/Link';

import Button from '@mui/material/Button'; import Divider from '@mui/material/Divider'; import LinearProgress from '@mui/material/LinearProgress'; -import {useTranslation} from 'react-i18next'; +import {useTranslation} from 'next-i18next'; import getMapsLink from '../../lib/getMapsLink'; import {TravelEntity} from '../../generated/graphql';
M frontend/containers/AssignPassenger/index.tsxfrontend/containers/AssignPassenger/index.tsx

@@ -4,7 +4,7 @@ import List from '@mui/material/List';

import Button from '@mui/material/Button'; import Paper from '@mui/material/Paper'; import Container from '@mui/material/Container'; -import {useTranslation} from 'react-i18next'; +import {useTranslation} from 'next-i18next'; import {useRouter} from 'next/router'; import ShareEvent from '../ShareEvent'; import useToastStore from '../../stores/useToastStore';
M frontend/containers/CarosterPlusOption/index.tsxfrontend/containers/CarosterPlusOption/index.tsx

@@ -10,7 +10,7 @@ import ListItemIcon from '@mui/material//ListItemIcon';

import ListItemText from '@mui/material/ListItemText'; import ChevronRightIcon from '@mui/icons-material/ChevronRight'; import AccountCircleOutlinedIcon from '@mui/icons-material/AccountCircleOutlined'; -import {useTranslation} from 'react-i18next'; +import {useTranslation} from 'next-i18next'; import Markdown from '../../components/Markdown'; import useLocale from '../../hooks/useLocale'; import usePermissions from '../../hooks/usePermissions';
M frontend/containers/CarosterPlusSettings/index.tsxfrontend/containers/CarosterPlusSettings/index.tsx

@@ -14,7 +14,7 @@ import TextField from '@mui/material/TextField';

import IconButton from '@mui/material/IconButton'; import AccountCircleOutlinedIcon from '@mui/icons-material/AccountCircleOutlined'; import DeleteOutlineIcon from '@mui/icons-material/DeleteOutline'; -import {useTranslation} from 'react-i18next'; +import {useTranslation} from 'next-i18next'; import usePermissions from '../../hooks/usePermissions'; import useToastStore from '../../stores/useToastStore'; import FormDialog from '../FormDialog';
M frontend/containers/CreateEvent/Step1.tsxfrontend/containers/CreateEvent/Step1.tsx

@@ -8,7 +8,7 @@ import FormControlLabel from '@mui/material/FormControlLabel';

import NextLink from 'next/link'; import CardActions from '@mui/material/CardActions'; import {useTheme} from '@mui/material/styles'; -import {useTranslation} from 'react-i18next'; +import {useTranslation} from 'next-i18next'; import {useSession} from 'next-auth/react'; import useDebounce from '../../hooks/useDebounce'; import {isValidEmail} from '../../lib/formValidation';
M frontend/containers/CreateEvent/Step2.tsxfrontend/containers/CreateEvent/Step2.tsx

@@ -7,7 +7,7 @@ import Box from '@mui/material/Box';

import {useTheme} from '@mui/material/styles'; import {useRouter} from 'next/router'; import {DatePicker} from '@mui/x-date-pickers/DatePicker'; -import {useTranslation} from 'react-i18next'; +import {useTranslation} from 'next-i18next'; import useToastStore from '../../stores/useToastStore'; import PlaceInput from '../PlaceInput'; import {EventEntity, EventInput} from '../../generated/graphql';
M frontend/containers/DashboardEmpty/index.tsxfrontend/containers/DashboardEmpty/index.tsx

@@ -5,7 +5,7 @@ import CardActions from '@mui/material/CardActions';

import CardContent from '@mui/material/CardContent'; import Typography from '@mui/material/Typography'; import Button from '@mui/material/Button'; -import {useTranslation} from 'react-i18next'; +import {useTranslation} from 'next-i18next'; const DashboardEmpty = () => { const {t} = useTranslation();
M frontend/containers/DashboardEvents/EventCard.tsxfrontend/containers/DashboardEvents/EventCard.tsx

@@ -5,7 +5,7 @@ import CardActions from '@mui/material/CardActions';

import CardContent from '@mui/material/CardContent'; import Typography from '@mui/material/Typography'; import Button from '@mui/material/Button'; -import {useTranslation} from 'react-i18next'; +import {useTranslation} from 'next-i18next'; import {EventEntity} from '../../generated/graphql'; import Box from '@mui/material/Box'; import Chip from '@mui/material/Chip';

@@ -56,7 +56,8 @@ >

{t('event.fields.date')} </Typography> <Typography variant="body1" sx={{mb: 1}}> - {event.attributes.date && moment(event.attributes.date).format('DD/MM/YYYY') || + {(event.attributes.date && + moment(event.attributes.date).format('DD/MM/YYYY')) || t('event.fields.empty')} </Typography> <Typography
M frontend/containers/DashboardEvents/index.tsxfrontend/containers/DashboardEvents/index.tsx

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

-import {useTranslation} from 'react-i18next'; +import {useTranslation} from 'next-i18next'; import Box from '@mui/material/Box'; import Section from './Section'; import {EventEntity} from '../../generated/graphql';
M frontend/containers/DrawerMenu/index.tsxfrontend/containers/DrawerMenu/index.tsx

@@ -2,7 +2,7 @@ import Link from 'next/link';

import Drawer from '@mui/material/Drawer'; import Box from '@mui/material/Box'; import {useTheme} from '@mui/material/styles'; -import {useTranslation} from 'react-i18next'; +import {useTranslation} from 'next-i18next'; import {useRouter} from 'next/router'; import useProfile from '../../hooks/useProfile'; import DrawerMenuItem from './DrawerMenuItem';
M frontend/containers/DrawerNotification/CardNotification.tsxfrontend/containers/DrawerNotification/CardNotification.tsx

@@ -4,7 +4,7 @@ NotificationEntity,

useReadNotificationsMutation, } from '../../generated/graphql'; import {useRouter} from 'next/navigation'; -import {useTranslation} from 'react-i18next'; +import {useTranslation} from 'next-i18next'; import {formatDate} from './formatDate'; interface NotificationProps {
M frontend/containers/DrawerNotification/DrawerContent.tsxfrontend/containers/DrawerNotification/DrawerContent.tsx

@@ -6,7 +6,7 @@ NotificationEntity,

} from '../../generated/graphql'; import CardNotification from './CardNotification'; import DrawerHeader from './DrawerHeader'; -import {useTranslation} from 'react-i18next'; +import {useTranslation} from 'next-i18next'; interface Props { isOpen: boolean;
M frontend/containers/DrawerNotification/DrawerHeader.tsxfrontend/containers/DrawerNotification/DrawerHeader.tsx

@@ -4,7 +4,7 @@ import IconButton from '@mui/material/IconButton';

import Icon from '@mui/material/Icon'; import Typography from '@mui/material/Typography'; import Button from '@mui/material/Button'; -import {useTranslation} from 'react-i18next'; +import {useTranslation} from 'next-i18next'; import useMediaQuery from '@mui/material/useMediaQuery'; const DrawerHeader = ({onClose, markAllRead, disabled}) => {
M frontend/containers/DrawerNotification/formatDate.tsfrontend/containers/DrawerNotification/formatDate.ts

@@ -1,14 +1,14 @@

import moment from 'moment'; -import { useTranslation } from 'react-i18next'; +import {useTranslation} from 'next-i18next'; export const formatDate = (dateString: string) => { - const momentDate = moment(dateString); - const isToday = momentDate.isSame(moment(), 'day'); - const { t } = useTranslation(); + const momentDate = moment(dateString); + const isToday = momentDate.isSame(moment(), 'day'); + const {t} = useTranslation(); - if (isToday) { - return `${t('date.today')}, ${momentDate.format('hh:mm')}`; - } else { - return momentDate.format('DD/MM/YY, H:mm'); - } + if (isToday) { + return `${t('date.today')}, ${momentDate.format('hh:mm')}`; + } else { + return momentDate.format('DD/MM/YY, H:mm'); + } };
M frontend/containers/DrawerPassenger/index.tsxfrontend/containers/DrawerPassenger/index.tsx

@@ -1,10 +1,8 @@

import {Drawer, Typography, useMediaQuery, Link, Box} from '@mui/material'; -import {useTranslation} from 'react-i18next'; -import { - CountryIso2, -} from 'react-international-phone'; +import {useTranslation} from 'next-i18next'; +import {CountryIso2} from 'react-international-phone'; import DrawerPassengerHeader from './DrawerPassengerHeader'; -import { getFormatedPhoneNumber } from '../../lib/phoneNumbers'; +import {getFormatedPhoneNumber} from '../../lib/phoneNumbers'; interface Props { isOpen: boolean;

@@ -15,8 +13,6 @@ email: string;

phone?: string; phoneCountry?: '' | CountryIso2; } - - const DrawerPassenger = ({ isOpen,
M frontend/containers/EventBar/useActions.tsfrontend/containers/EventBar/useActions.ts

@@ -1,5 +1,5 @@

import {useRouter} from 'next/router'; -import {useTranslation} from 'react-i18next'; +import {useTranslation} from 'next-i18next'; import useProfile from '../../hooks/useProfile'; import useShare from '../../hooks/useShare'; import useEventStore from '../../stores/useEventStore';
M frontend/containers/EventMarker/EventPopup.tsxfrontend/containers/EventMarker/EventPopup.tsx

@@ -3,7 +3,7 @@ import Card from '@mui/material/Card';

import Typography from '@mui/material/Typography'; import Link from '@mui/material/Link'; import Box from '@mui/material/Box'; -import {useTranslation} from 'react-i18next'; +import {useTranslation} from 'next-i18next'; import {Popup} from 'react-leaflet'; import getMapsLink from '../../lib/getMapsLink'; import {Event} from '../../generated/graphql';
M frontend/containers/FormDialog/index.tsxfrontend/containers/FormDialog/index.tsx

@@ -1,5 +1,5 @@

import {PropsWithChildren} from 'react'; -import {useTranslation} from 'react-i18next'; +import {useTranslation} from 'next-i18next'; import Dialog from '@mui/material/Dialog'; import DialogContent from '@mui/material/DialogContent'; import DialogActions from '@mui/material/DialogActions';
M frontend/containers/GenericMenu/index.tsxfrontend/containers/GenericMenu/index.tsx

@@ -1,5 +1,5 @@

import Menu from '@mui/material/Menu'; -import {useTranslation} from 'react-i18next'; +import {useTranslation} from 'next-i18next'; import {signOut, useSession} from 'next-auth/react'; import useSettings from '../../hooks/useSettings'; import Languages from '../Languages/MenuItem';
M frontend/containers/Languages/Icon.tsxfrontend/containers/Languages/Icon.tsx

@@ -4,7 +4,7 @@ import IconButton from '@mui/material/IconButton';

import Icon from '@mui/material/Icon'; import Menu from '@mui/material/Menu'; import MenuItem from '@mui/material/MenuItem'; -import {useTranslation} from 'react-i18next'; +import {useTranslation} from 'next-i18next'; import {Enum_Userspermissionsuser_Lang as SupportedLocales} from '../../generated/graphql'; import withLanguagesSelection, { LanguageSelectionComponentProps,
M frontend/containers/Languages/MenuItem.tsxfrontend/containers/Languages/MenuItem.tsx

@@ -3,7 +3,7 @@ import MenuList from '@mui/material/MenuList';

import MenuItem from '@mui/material/MenuItem'; import Box from '@mui/material/Box'; import {useTheme} from '@mui/material/styles'; -import {useTranslation} from 'react-i18next'; +import {useTranslation} from 'next-i18next'; import {Enum_Userspermissionsuser_Lang as SupportedLocales} from '../../generated/graphql'; import withLanguagesSelection, { LanguageSelectionComponentProps,
M frontend/containers/Languages/withLanguagesSelection.tsxfrontend/containers/Languages/withLanguagesSelection.tsx

@@ -3,7 +3,7 @@ import {

useUpdateMeMutation, Enum_Userspermissionsuser_Lang as Lang, } from '../../generated/graphql'; -import {useTranslation} from 'react-i18next'; +import {useTranslation} from 'next-i18next'; import useLocale from '../../hooks/useLocale'; export interface LanguageSelectionComponentProps {
M frontend/containers/LoginGoogle/index.tsxfrontend/containers/LoginGoogle/index.tsx

@@ -2,7 +2,7 @@ import Box from '@mui/material/Box';

import Button from '@mui/material/Button'; import {useTheme} from '@mui/material/styles'; import {signIn} from 'next-auth/react'; -import {useTranslation} from 'react-i18next'; +import {useTranslation} from 'next-i18next'; const LoginGoogle = () => { const {t} = useTranslation();
M frontend/containers/LoginToAttend/LoginToAttend.tsxfrontend/containers/LoginToAttend/LoginToAttend.tsx

@@ -3,7 +3,7 @@ import Box from '@mui/material/Box';

import Button from '@mui/material/Button'; import Typography from '@mui/material/Typography'; import {useRouter} from 'next/router'; -import {useTranslation} from 'react-i18next'; +import {useTranslation} from 'next-i18next'; const LoginToAttend = ({title}) => { const {t} = useTranslation();

@@ -21,7 +21,7 @@ color="textSecondary"

> {t('event.loginToAttend.desc')} </Typography> - <Box display='flex' justifyContent='space-between' pt={2} gap={1}> + <Box display="flex" justifyContent="space-between" pt={2} gap={1}> <Link href={`/auth/login?redirectPath=${router.asPath}`} passHref
M frontend/containers/LostPassword/Success.jsfrontend/containers/LostPassword/Success.js

@@ -1,5 +1,5 @@

-import {useTranslation} from 'react-i18next'; -import { styled } from '@mui/material/styles'; +import {useTranslation} from 'next-i18next'; +import {styled} from '@mui/material/styles'; import Button from '@mui/material/Button'; import Icon from '@mui/material/Icon'; import CardContent from '@mui/material/CardContent';

@@ -13,14 +13,10 @@

const classes = { successCard: `${PREFIX}-successCard`, successIcon: `${PREFIX}-successIcon`, - actions: `${PREFIX}-actions` + actions: `${PREFIX}-actions`, }; -const StyledCard = styled(Card)(( - { - theme - } -) => ({ +const StyledCard = styled(Card)(({theme}) => ({ [`&.${classes.successCard}`]: { textAlign: 'center', },

@@ -31,12 +27,11 @@ },

[`& .${classes.actions}`]: { justifyContent: 'center', - } + }, })); const Success = ({email}) => { const {t} = useTranslation(); - return ( <StyledCard className={classes.successCard}>
M frontend/containers/LostPassword/index.jsfrontend/containers/LostPassword/index.js

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

import {useCallback, useState, useEffect} from 'react'; -import { styled } from '@mui/material/styles'; -import {useTranslation} from 'react-i18next'; +import {styled} from '@mui/material/styles'; +import {useTranslation} from 'next-i18next'; import router from 'next/router'; import TextField from '@mui/material/TextField'; import Button from '@mui/material/Button';

@@ -18,14 +18,10 @@ const PREFIX = 'LostPassword';

const classes = { loader: `${PREFIX}-loader`, - actions: `${PREFIX}-actions` + actions: `${PREFIX}-actions`, }; -const Root = styled('form')(( - { - theme - } -) => ({ +const Root = styled('form')(({theme}) => ({ [`& .${classes.loader}`]: { marginLeft: theme.spacing(4), },

@@ -33,7 +29,7 @@

[`& .${classes.actions}`]: { marginTop: theme.spacing(2), justifyContent: 'flex-end', - } + }, })); const LostPassword = () => {
M frontend/containers/MailSignUpForm/SignupActions.tsxfrontend/containers/MailSignUpForm/SignupActions.tsx

@@ -1,17 +1,17 @@

import Link from 'next/link'; -import { useTheme } from '@mui/material/styles'; +import {useTheme} from '@mui/material/styles'; import Button from '@mui/material/Button'; import CardActions from '@mui/material/CardActions'; -import {useTranslation} from 'react-i18next'; +import {useTranslation} from 'next-i18next'; const SignUpActions = () => { - const theme = useTheme() + const theme = useTheme(); const {t} = useTranslation(); - return ( - <CardActions sx={{justifyContent: 'center', - marginBottom: theme.spacing(2)}}> + <CardActions + sx={{justifyContent: 'center', marginBottom: theme.spacing(2)}} + > <Link href="/auth/login" passHref> <Button id="SignUpLogin" variant="text"> {t('signup.login')}
M frontend/containers/MailSignUpForm/index.tsxfrontend/containers/MailSignUpForm/index.tsx

@@ -9,7 +9,7 @@ import CardContent from '@mui/material/CardContent';

import Typography from '@mui/material/Typography'; import CircularProgress from '@mui/material/CircularProgress'; import {useTheme} from '@mui/material/styles'; -import {Trans, useTranslation} from 'react-i18next'; +import {Trans, useTranslation} from 'next-i18next'; import {useRouter} from 'next/router'; import useToastsStore from '../../stores/useToastStore'; import SignUpActions from './SignupActions';
M frontend/containers/NewPassengerDialog/AddPassengerCommonFields.tsxfrontend/containers/NewPassengerDialog/AddPassengerCommonFields.tsx

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

import {Fragment} from 'react'; import TextField from '@mui/material/TextField'; -import {useTranslation} from 'react-i18next'; +import {useTranslation} from 'next-i18next'; import Icon from '@mui/material/Icon'; import Box from '@mui/material/Box'; import Typography from '@mui/material/Typography';
M frontend/containers/NewPassengerDialog/AddPassengerToTravel.tsxfrontend/containers/NewPassengerDialog/AddPassengerToTravel.tsx

@@ -3,7 +3,7 @@ import Dialog from '@mui/material/Dialog';

import DialogContent from '@mui/material/DialogContent'; import DialogTitle from '@mui/material/DialogTitle'; import Icon from '@mui/material/Icon'; -import {useTranslation} from 'react-i18next'; +import {useTranslation} from 'next-i18next'; import useAddToEvents from '../../hooks/useAddToEvents'; import useEventStore from '../../stores/useEventStore'; import {TravelEntity} from '../../generated/graphql';
M frontend/containers/NewPassengerDialog/AddPassengerToWaitingList.tsxfrontend/containers/NewPassengerDialog/AddPassengerToWaitingList.tsx

@@ -6,7 +6,7 @@ import TextField from '@mui/material/TextField';

import Box from '@mui/material/Box'; import Typography from '@mui/material/Typography'; import Icon from '@mui/material/Icon'; -import {useTranslation} from 'react-i18next'; +import {useTranslation} from 'next-i18next'; import useToastStore from '../../stores/useToastStore'; import useEventStore from '../../stores/useEventStore'; import useAddToEvents from '../../hooks/useAddToEvents';
M frontend/containers/NewTravelDialog/index.tsxfrontend/containers/NewTravelDialog/index.tsx

@@ -13,7 +13,7 @@ import {Box, Divider} from '@mui/material';

import {useTheme} from '@mui/material/styles'; import {DatePicker} from '@mui/x-date-pickers/DatePicker'; import {TimePicker} from '@mui/x-date-pickers/TimePicker'; -import {useTranslation} from 'react-i18next'; +import {useTranslation} from 'next-i18next'; import PhoneInput from '../../components/PhoneInput'; import PlaceInput from '../PlaceInput'; import useEventStore from '../../stores/useEventStore';
M frontend/containers/NewTravelDialog/useActions.tsfrontend/containers/NewTravelDialog/useActions.ts

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

-import {useTranslation} from 'react-i18next'; +import {useTranslation} from 'next-i18next'; import {PureQueryOptions} from '@apollo/client/core'; import useToastsStore from '../../stores/useToastStore'; import useAddToEvents from '../../hooks/useAddToEvents';

@@ -41,7 +41,6 @@ query: FindUserVehiclesDocument,

}); } try { - await createTravelMutation({ variables: { travel: {
M frontend/containers/PassengersList/Passenger.tsxfrontend/containers/PassengersList/Passenger.tsx

@@ -9,7 +9,7 @@ Typography,

Icon, useTheme, } from '@mui/material'; -import {useTranslation} from 'react-i18next'; +import {useTranslation} from 'next-i18next'; import useProfile from '../../hooks/useProfile'; import {PassengerEntity} from '../../generated/graphql';
M frontend/containers/PlaceInput/index.tsxfrontend/containers/PlaceInput/index.tsx

@@ -4,7 +4,7 @@ import InputAdornment from '@mui/material/InputAdornment';

import PlaceOutlinedIcon from '@mui/icons-material/PlaceOutlined'; import Autocomplete from '@mui/material/Autocomplete'; import {debounce} from '@mui/material/utils'; -import {useTranslation} from 'react-i18next'; +import {useTranslation} from 'next-i18next'; import useLocale from '../../hooks/useLocale'; import getPlacesSuggestions from '../../lib/getPlacesSuggestion'; import ListItemText from '@mui/material/ListItemText';
M frontend/containers/Profile/EditPassword.tsxfrontend/containers/Profile/EditPassword.tsx

@@ -1,26 +1,22 @@

import React from 'react'; -import { styled } from '@mui/material/styles'; +import {styled} from '@mui/material/styles'; import Card from '@mui/material/Card'; import CardContent from '@mui/material/CardContent'; import CardActions from '@mui/material/CardActions'; import Button from '@mui/material/Button'; -import {useTranslation} from 'react-i18next'; +import {useTranslation} from 'next-i18next'; import TextField from '@mui/material/TextField'; const PREFIX = 'EditPassword'; const classes = { - actions: `${PREFIX}-actions` + actions: `${PREFIX}-actions`, }; -const Root = styled('form')(( - { - theme - } -) => ({ +const Root = styled('form')(({theme}) => ({ [`& .${classes.actions}`]: { justifyContent: 'flex-end', - } + }, })); const EditPassword = ({
M frontend/containers/Profile/ManagingNotificationsField.tsxfrontend/containers/Profile/ManagingNotificationsField.tsx

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

import Typography from '@mui/material/Typography'; import Box from '@mui/material/Box'; -import {useTranslation} from 'react-i18next'; +import {useTranslation} from 'next-i18next'; import ContentSwitch from './ContentSwitch'; interface Props {
M frontend/containers/Profile/StripeDashboardLink.tsxfrontend/containers/Profile/StripeDashboardLink.tsx

@@ -1,5 +1,5 @@

import {Box, Button, Typography} from '@mui/material'; -import {useTranslation} from 'react-i18next'; +import {useTranslation} from 'next-i18next'; import OpenInNewIcon from '@mui/icons-material/OpenInNew'; import useSettings from '../../hooks/useSettings'; import Link from 'next/link';
M frontend/containers/Profile/index.tsxfrontend/containers/Profile/index.tsx

@@ -5,7 +5,7 @@ import CardContent from '@mui/material/CardContent';

import CardActions from '@mui/material/CardActions'; import Button from '@mui/material/Button'; import {useTheme} from '@mui/material/styles'; -import {useTranslation} from 'react-i18next'; +import {useTranslation} from 'next-i18next'; import EditPassword from './EditPassword'; import ProfileField from './ProfileField'; import useToastStore from '../../stores/useToastStore';
M frontend/containers/RemoveDialog/index.tsxfrontend/containers/RemoveDialog/index.tsx

@@ -5,7 +5,7 @@ import DialogContent from '@mui/material/DialogContent';

import DialogContentText from '@mui/material/DialogContentText'; import Slide from '@mui/material/Slide'; import Button from '@mui/material/Button'; -import {useTranslation} from 'react-i18next'; +import {useTranslation} from 'next-i18next'; const Transition = React.forwardRef(function Transition(props, ref) { return <Slide direction="up" ref={ref} {...props} />;
M frontend/containers/ResetPassword/index.tsxfrontend/containers/ResetPassword/index.tsx

@@ -1,27 +1,23 @@

import React from 'react'; -import { styled } from '@mui/material/styles'; +import {styled} from '@mui/material/styles'; import Card from '@mui/material/Card'; import CardHeader from '@mui/material/CardHeader'; import CardContent from '@mui/material/CardContent'; import CardActions from '@mui/material/CardActions'; import Button from '@mui/material/Button'; -import {useTranslation} from 'react-i18next'; +import {useTranslation} from 'next-i18next'; import TextField from '@mui/material/TextField'; const PREFIX = 'ResetPassword'; const classes = { - actions: `${PREFIX}-actions` + actions: `${PREFIX}-actions`, }; -const StyledCard = styled(Card)(( - { - theme - } -) => ({ +const StyledCard = styled(Card)(({theme}) => ({ [`& .${classes.actions}`]: { justifyContent: 'flex-end', marginTop: theme.spacing(2), - } + }, })); const ResetPassword = ({
M frontend/containers/ShareEvent/index.tsxfrontend/containers/ShareEvent/index.tsx

@@ -1,5 +1,5 @@

import Button, {ButtonProps} from '@mui/material/Button'; -import {useTranslation} from 'react-i18next'; +import {useTranslation} from 'next-i18next'; import useShare from '../../hooks/useShare'; import Box from '@mui/material/Box';
M frontend/containers/SignInForm/index.tsxfrontend/containers/SignInForm/index.tsx

@@ -9,7 +9,7 @@ import CardActions from '@mui/material/CardActions';

import Divider from '@mui/material/Divider'; import Box from '@mui/material/Box'; import {useTheme} from '@mui/material/styles'; -import {useTranslation} from 'react-i18next'; +import {useTranslation} from 'next-i18next'; import {signIn} from 'next-auth/react'; import useAddToEvents from '../../hooks/useAddToEvents'; import LoginGoogle from '../LoginGoogle';
M frontend/containers/SupportCaroster/index.tsxfrontend/containers/SupportCaroster/index.tsx

@@ -1,5 +1,5 @@

import {Link} from '@mui/material'; -import {useTranslation} from 'react-i18next'; +import {useTranslation} from 'next-i18next'; import useSettings from '../../hooks/useSettings'; type Props = {};
M frontend/containers/Travel/Header.tsxfrontend/containers/Travel/Header.tsx

@@ -8,14 +8,14 @@ import Link from '@mui/material/Link';

import LinearProgress from '@mui/material/LinearProgress'; import Chip from '@mui/material/Chip'; import {useTheme} from '@mui/material/styles'; -import {useTranslation} from 'react-i18next'; +import {useTranslation} from 'next-i18next'; import getMapsLink from '../../lib/getMapsLink'; import useMapStore from '../../stores/useMapStore'; import usePermissions from '../../hooks/usePermissions'; import useProfile from '../../hooks/useProfile'; import DetailsLink from '../DetailsLink'; import {TravelEntity} from '../../generated/graphql'; -import { getFormatedPhoneNumber } from '../../lib/phoneNumbers'; +import {getFormatedPhoneNumber} from '../../lib/phoneNumbers'; interface Props { travel: TravelEntity;

@@ -95,7 +95,10 @@ <Typography variant="overline" sx={{color: 'GrayText'}}>

{t('travel.fields.phone')} </Typography> <Typography variant="body1" id="TravelPhone"> - {getFormatedPhoneNumber({phone: travel.attributes.phone_number, phoneCountry: travel.attributes.phoneCountry})} + {getFormatedPhoneNumber({ + phone: travel.attributes.phone_number, + phoneCountry: travel.attributes.phoneCountry, + })} </Typography> </Box> )}
M frontend/containers/Travel/HeaderEditing.tsxfrontend/containers/Travel/HeaderEditing.tsx

@@ -9,7 +9,7 @@ import {useTheme} from '@mui/material/styles';

import {DatePicker} from '@mui/x-date-pickers/DatePicker'; import {TimePicker} from '@mui/x-date-pickers/TimePicker'; import {CountryIso2} from 'react-international-phone'; -import {useTranslation} from 'react-i18next'; +import {useTranslation} from 'next-i18next'; import RemoveDialog from '../RemoveDialog'; import useActions from './useActions'; import PlaceInput from '../PlaceInput';
M frontend/containers/Travel/RemovePassengerModal.tsxfrontend/containers/Travel/RemovePassengerModal.tsx

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

-import {useTranslation} from 'react-i18next'; +import {useTranslation} from 'next-i18next'; import { Typography, Dialog,

@@ -29,7 +29,7 @@ if (IsPassengerIsUser && isCarosterPlus) {

return 'travel.removePassengerModal.plus.self.description'; } else if (isCarosterPlus) { return 'travel.removePassengerModal.plus.description'; - } else if (IsPassengerIsUser) { + } else if (IsPassengerIsUser) { return 'travel.removePassengerModal.self.description'; } else { return 'travel.removePassengerModal.description';
M frontend/containers/Travel/RequestTripModal.tsxfrontend/containers/Travel/RequestTripModal.tsx

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

-import {useTranslation} from 'react-i18next'; +import {useTranslation} from 'next-i18next'; import {TextField, Typography, Box} from '@mui/material'; import {useEffect, useState} from 'react'; import FormDialog from '../FormDialog';
M frontend/containers/Travel/useActions.tsxfrontend/containers/Travel/useActions.tsx

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

import Link from 'next/link'; import Button from '@mui/material/Button'; -import {useTranslation} from 'react-i18next'; +import {useTranslation} from 'next-i18next'; import useEventStore from '../../stores/useEventStore'; import useToastStore from '../../stores/useToastStore'; import {
M frontend/containers/TravelColumns/AddTravel.tsxfrontend/containers/TravelColumns/AddTravel.tsx

@@ -2,7 +2,7 @@ import React from 'react';

import Button from '@mui/material/Button'; import Container from '@mui/material/Container'; import {useTheme} from '@mui/material/styles'; -import {useTranslation} from 'react-i18next'; +import {useTranslation} from 'next-i18next'; interface Props { toggle: () => void;
M frontend/containers/TravelColumns/NoCar.tsxfrontend/containers/TravelColumns/NoCar.tsx

@@ -1,7 +1,7 @@

import Button from '@mui/material/Button'; import Typography from '@mui/material/Typography'; import {useTheme} from '@mui/material/styles'; -import {useTranslation} from 'react-i18next'; +import {useTranslation} from 'next-i18next'; import {useRouter} from 'next/router'; import Box from '@mui/material/Box'; import ShareEvent from '../ShareEvent';

@@ -18,7 +18,7 @@ const NoCar = ({eventName, title, isCarosterPlus, showImage}: Props) => {

const {t} = useTranslation(); const theme = useTheme(); const router = useRouter(); - const {uuid} = router.query + const {uuid} = router.query; return ( <Box my={4} mx="auto" pb={16} mt={9} maxWidth="100%" width={340}>
M frontend/containers/TravelColumns/index.tsxfrontend/containers/TravelColumns/index.tsx

@@ -2,7 +2,7 @@ import {useMemo, useState} from 'react';

import Masonry from '@mui/lab/Masonry'; import Box from '@mui/material/Box'; import moment from 'moment'; -import {useTranslation} from 'react-i18next'; +import {useTranslation} from 'next-i18next'; import {useTheme} from '@mui/material/styles'; import useEventStore from '../../stores/useEventStore'; import useToastStore from '../../stores/useToastStore';

@@ -119,7 +119,7 @@ >

<Masonry columns={{xl: 4, lg: 3, md: 2, sm: 2, xs: 1}} spacing={0}> {!canAddTravel() && ( <MasonryContainer key="no_other_travel"> - <LoginToAttend title={t('event.loginToAttend')}/> + <LoginToAttend title={t('event.loginToAttend')} /> </MasonryContainer> )} {displayedTravels?.map(travel => {
M frontend/containers/TravelMarker/TravelPopup.tsxfrontend/containers/TravelMarker/TravelPopup.tsx

@@ -5,9 +5,9 @@ import Link from '@mui/material/Link';

import Box from '@mui/material/Box'; import {TravelEntity} from '../../generated/graphql'; import {Popup} from 'react-leaflet'; -import {useTranslation} from 'react-i18next'; +import {useTranslation} from 'next-i18next'; import getMapsLink from '../../lib/getMapsLink'; -import { getFormatedPhoneNumber } from '../../lib/phoneNumbers'; +import {getFormatedPhoneNumber} from '../../lib/phoneNumbers'; interface Props { travel: TravelEntity;

@@ -33,7 +33,10 @@ <Typography variant="overline" color="GrayText">

{t('travel.fields.phone')} </Typography> <Typography variant="body1"> - {getFormatedPhoneNumber({phone: travel.attributes.phone_number, phoneCountry: travel.attributes.phoneCountry})} + {getFormatedPhoneNumber({ + phone: travel.attributes.phone_number, + phoneCountry: travel.attributes.phoneCountry, + })} </Typography> </Box> )}
M frontend/containers/VehicleChoiceDialog/VehicleItem.tsxfrontend/containers/VehicleChoiceDialog/VehicleItem.tsx

@@ -2,7 +2,7 @@ import Typography from '@mui/material/Typography';

import ListItem from '@mui/material/ListItem'; import Box from '@mui/material/Box'; import Button from '@mui/material/Button'; -import {useTranslation} from 'react-i18next'; +import {useTranslation} from 'next-i18next'; import { FindUserVehiclesDocument, useDeleteVehicleMutation,
M frontend/containers/VehicleChoiceDialog/index.tsxfrontend/containers/VehicleChoiceDialog/index.tsx

@@ -9,7 +9,7 @@ import List from '@mui/material/List';

import Container from '@mui/material/Container'; import Divider from '@mui/material/Divider'; import Slide from '@mui/material/Slide'; -import {useTranslation} from 'react-i18next'; +import {useTranslation} from 'next-i18next'; import VehicleItem from './VehicleItem'; import Typography from '@mui/material/Typography'; import {VehicleEntity} from '../../generated/graphql';
M frontend/containers/WaitingList/AssignButton.tsxfrontend/containers/WaitingList/AssignButton.tsx

@@ -1,7 +1,7 @@

import IconButton from '@mui/material/IconButton'; import Icon from '@mui/material/Icon'; import {useTheme} from '@mui/material/styles'; -import {useTranslation} from 'react-i18next'; +import {useTranslation} from 'next-i18next'; import ListItemSecondaryAction from '@mui/material/ListItemSecondaryAction'; interface Props {
M frontend/containers/WaitingList/index.tsxfrontend/containers/WaitingList/index.tsx

@@ -12,7 +12,7 @@ import Divider from '@mui/material/Divider';

import ListItemSecondaryAction from '@mui/material/ListItemSecondaryAction'; import CancelOutlinedIcon from '@mui/icons-material/CancelOutlined'; import {useTheme} from '@mui/material/styles'; -import {Trans, useTranslation} from 'react-i18next'; +import {Trans, useTranslation} from 'next-i18next'; import useToastStore from '../../stores/useToastStore'; import useEventStore from '../../stores/useEventStore'; import usePassengersActions from '../../hooks/usePassengersActions';
M frontend/containers/WelcomeDialog/index.tsxfrontend/containers/WelcomeDialog/index.tsx

@@ -1,5 +1,5 @@

import React from 'react'; -import { styled } from '@mui/material/styles'; +import {styled} from '@mui/material/styles'; import Dialog from '@mui/material/Dialog'; import CardMedia from '@mui/material/CardMedia'; import DialogActions from '@mui/material/DialogActions';

@@ -7,13 +7,13 @@ import DialogContent from '@mui/material/DialogContent';

import DialogContentText from '@mui/material/DialogContentText'; import Typography from '@mui/material/Typography'; import Button from '@mui/material/Button'; -import {useTranslation} from 'react-i18next'; +import {useTranslation} from 'next-i18next'; import useTourStore from '../../stores/useTourStore'; const PREFIX = 'WelcomeDialog'; const classes = { - media: `${PREFIX}-media` + media: `${PREFIX}-media`, }; const StyledDialog = styled(Dialog)({

@@ -27,11 +27,10 @@ const {t} = useTranslation();

const showWelcome = useTourStore(s => s.showWelcome); const setTour = useTourStore(s => s.setTour); - const onStartTour = () => setTour({showWelcome: false, run: true, step: 0, prev: -1}); - const onCancel = () => setTour({showWelcome: false}); + const onCancel = () => setTour({showWelcome: false}); return ( <StyledDialog open={showWelcome} fullWidth maxWidth="xs">
M frontend/hooks/useLocale.tsfrontend/hooks/useLocale.ts

@@ -4,6 +4,10 @@ import moment from 'moment';

import {setCookie} from '../lib/cookies'; import {useEffect} from 'react'; +// Import moment locales +import 'moment/locale/fr'; +import 'moment/locale/nl'; + const defaultLocale = SupportedLocales['en']; const useLocale = (): {
M frontend/hooks/useShare.tsfrontend/hooks/useShare.ts

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

-import {useTranslation} from 'react-i18next'; +import {useTranslation} from 'next-i18next'; import {Enum_Userspermissionsuser_Lang as SupportedLocales} from '../generated/graphql'; import useToastStore from '../stores/useToastStore';

@@ -22,7 +22,7 @@ const splittedUrl = url.split('/');

const localeParamIndex = splittedUrl.findIndex( member => SupportedLocales[member] ); - const urlCopy = [...splittedUrl] + const urlCopy = [...splittedUrl]; urlCopy[localeParamIndex] = FALLBACK_LANGUAGE; const withDefaultLocaleURL = urlCopy.join('/'); const isPhone = /iPhone|iPad|iPod|Android/i.test(navigator.userAgent);
A frontend/hooks/useTolgee.ts

@@ -0,0 +1,22 @@

+import i18n from 'i18next'; +import {withTolgee, Tolgee, I18nextPlugin, DevTools} from '@tolgee/i18next'; +import useLocale from './useLocale'; + +const tolgee = Tolgee() + .use(DevTools()) + .use(I18nextPlugin()) + .init({ + apiUrl: process.env.NEXT_PUBLIC_TOLGEE_API_URL || 'https://app.tolgee.io', + apiKey: process.env.NEXT_PUBLIC_TOLGEE_API_KEY, + ns: ['common'], + }); + +const useTolgee = () => { + const {locale} = useLocale(); + return withTolgee(i18n, tolgee).init({ + lng: locale, + fallbackLng: 'fr', + }); +}; + +export default useTolgee;
M frontend/layouts/Event.tsxfrontend/layouts/Event.tsx

@@ -2,7 +2,7 @@ import {PropsWithChildren, useEffect, useMemo, useState} from 'react';

import useMediaQuery from '@mui/material/useMediaQuery'; import Box from '@mui/material/Box'; import {useTheme} from '@mui/material/styles'; -import {useTranslation} from 'react-i18next'; +import {useTranslation} from 'next-i18next'; import ErrorPage from '../pages/_error'; import useEventStore from '../stores/useEventStore'; import Layout from '../layouts/Default';
D frontend/lib/i18n.ts

@@ -1,51 +0,0 @@

-import i18n from 'i18next'; -import {initReactI18next} from 'react-i18next'; -import 'moment/min/locales'; -import moment from 'moment'; -import {InContextTools} from '@tolgee/web/tools'; -import {withTolgee, Tolgee, I18nextPlugin, BackendFetch} from '@tolgee/i18next'; -import {Enum_Userspermissionsuser_Lang as SupportedLocales} from '../generated/graphql'; -import translationFr from '../locales/fr.json'; -import translationEn from '../locales/en.json'; -import translationNl from '../locales/nl.json'; - -const resources = { - en: { - translation: translationEn, - }, - fr: { - translation: translationFr, - }, - - nl: { - translation: translationNl, - }, -}; - -const tolgee = Tolgee() - .use(InContextTools()) - .use(I18nextPlugin()) - .init({ - // for development - apiUrl: process.env.NEXT_PUBLIC_TOLGEE_API_URL, - apiKey: process.env.NEXT_PUBLIC_TOLGEE_API_KEY, - ns: ['translation'], - }); - -export const initI18Next = (locale: SupportedLocales) => { - withTolgee(i18n, tolgee) - .use(initReactI18next) // passes i18n down to react-i18next - .init({ - resources, - lng: locale, - supportedLngs: ['fr', 'en', 'nl'], - fallbackLng: 'en', - defaultNS: 'translation', - interpolation: { - escapeValue: false, // react already safes from xss - }, - }); - moment.locale(i18n.language); -}; - -export default i18n;
M frontend/lib/pageUtils.tsfrontend/lib/pageUtils.ts

@@ -1,8 +1,10 @@

import {ApolloClient} from '@apollo/client'; import {getSession} from 'next-auth/react'; +import {serverSideTranslations} from 'next-i18next/serverSideTranslations'; import {ProfileDocument, SettingDocument} from '../generated/graphql'; import {initializeApollo, APOLLO_STATE_PROP_NAME} from './apolloClient'; import {getCookie, hashText} from './cookies'; +import nextI18NextConfig from '../next-i18next.config'; type ServerSideExtension = ( context: any,

@@ -21,6 +23,11 @@ const {STRAPI_URL = 'http://localhost:1337'} = process.env;

const jwt = session?.token?.jwt; const apolloClient = initializeApollo(`${STRAPI_URL}/graphql/`, jwt); + const translations = await serverSideTranslations( + context.locale, + ['common'], + nextI18NextConfig + ); try { const {

@@ -64,13 +71,14 @@ props: {

session, announcement, [APOLLO_STATE_PROP_NAME]: apolloClient.cache.extract(), + ...translations, ...extensionProps, }, }; } catch (error) { console.error(error); return { - props: {session}, + props: {session, ...translations}, }; } };
M frontend/locales/fr.jsonfrontend/locales/fr.json

@@ -198,6 +198,9 @@ "profile.password_changed": "Mot de passe mis à jour",

"profile.stripe_link.button": "Historique", "profile.stripe_link.title": "Facturation", "profile.title": "Profil", + "PROTECTED.languages.en": "English (100%)", + "PROTECTED.languages.fr": "Français (100%)", + "PROTECTED.languages.nl": "Nederlands (97%)", "signin.email": "Email", "signin.emailConfirmation": "Votre compte a bien été confirmé. Vous pouvez maintenant vous connecter.", "signin.errors.CredentialsSignin": "Vérifiez votre email et mot de passe. Si votre compte est lié à Google, merci d'utiliser l'authentification Google.",

@@ -306,4 +309,4 @@ "travel.vehicle.empty": "Vous n'avez aucun véhicule assigné. Utilisez le bouton ci-dessous pour en créer un.",

"travel.vehicle.name": "Nom du véhicule", "travel.vehicle.seats_number": "Nombre de places", "travel.vehicle.title": "Mes véhicules" -}+}
A frontend/next-i18next.config.js

@@ -0,0 +1,20 @@

+/** @type {import('next-i18next').UserConfig} */ + +const {FALLBACK_LANGUAGE = 'en'} = process.env; + +module.exports = { + i18n: { + defaultLocale: FALLBACK_LANGUAGE, + locales: [...new Set([FALLBACK_LANGUAGE, 'en', 'fr', 'nl'])], + }, + // Load same lang file for every namespaces + localePath: (locale, _namespace) => `./locales/${locale}.json`, + ns: ['common'], + localeDetection: false, + fallbackLng: ['fr'], + trailingSlash: true, + serializeConfig: false, + interpolation: { + escapeValue: false, // react already safes from xss + }, +};
M frontend/next.config.jsfrontend/next.config.js

@@ -1,4 +1,5 @@

-const {i18n} = require('./react-i18next.config'); +const {i18n} = require('./next-i18next.config'); + const { NODE_ENV, DEV_TILES_URL,
M frontend/package.jsonfrontend/package.json

@@ -11,8 +11,8 @@ "gql": "graphql-codegen --config codegen.yml"

}, "dependencies": { "@apollo/client": "^3.11.4", - "@date-io/dayjs": "2.17.0", - "@date-io/moment": "2.17.0", + "@date-io/dayjs": "3.0.0", + "@date-io/moment": "3.0.0", "@emotion/react": "^11.13.0", "@emotion/styled": "^11.13.0", "@mapbox/search-js-core": "^1.0.0-beta.22",

@@ -34,6 +34,7 @@ "marked": "^7.0.5",

"moment": "^2.30.1", "next": "^14.2.5", "next-auth": "4.24.7", + "next-i18next": "^15.3.1", "next-pwa": "^5.6.0", "react": "^18.3.1", "react-dom": "^18.3.1",
M frontend/pages/_app.tsxfrontend/pages/_app.tsx

@@ -5,18 +5,19 @@ import Head from 'next/head';

import CssBaseline from '@mui/material/CssBaseline'; import {ThemeProvider, Theme} from '@mui/material/styles'; import {AppProps} from 'next/app'; -import {I18nextProvider} from 'react-i18next'; +import {appWithTranslation} from 'next-i18next'; import {ApolloProvider} from '@apollo/client'; import {LocalizationProvider} from '@mui/x-date-pickers/LocalizationProvider'; import {AdapterMoment} from '@mui/x-date-pickers/AdapterMoment'; import {SessionProvider} from 'next-auth/react'; -import moment from 'moment'; import Metas from '../containers/Metas'; import Toasts from '../components/Toasts'; import theme from '../theme'; import useLocale from '../hooks/useLocale'; -import i18n, {initI18Next} from '../lib/i18n'; import {useApollo} from '../lib/apolloClient'; +import nextI18NextConfig from '../next-i18next.config.js'; +import moment from 'moment'; +import useTolgee from '../hooks/useTolgee'; declare module '@mui/styles/defaultTheme' { interface DefaultTheme extends Theme {}

@@ -26,6 +27,7 @@ const App = function (props: AppProps) {

const {Component, pageProps} = props; const apolloClient = useApollo(pageProps); const {locale} = useLocale(); + useTolgee(); useEffect(() => { // Remove the server-side injected CSS.

@@ -35,31 +37,27 @@ jssStyles.parentElement!.removeChild(jssStyles);

} }, []); - initI18Next(locale); - return ( - <I18nextProvider i18n={i18n}> - <ApolloProvider client={apolloClient}> - <Metas metas={pageProps.metas} /> - <ThemeProvider theme={theme}> - <LocalizationProvider - dateAdapter={AdapterMoment} - dateLibInstance={moment} - adapterLocale={locale} - > - <CssBaseline /> - <Head> - <meta - name="viewport" - content="width=device-width, initial-scale=1, maximum-scale=1" - /> - </Head> - <Component {...pageProps} /> - <Toasts /> - </LocalizationProvider> - </ThemeProvider> - </ApolloProvider> - </I18nextProvider> + <ApolloProvider client={apolloClient}> + <Metas metas={pageProps.metas} /> + <ThemeProvider theme={theme}> + <LocalizationProvider + dateAdapter={AdapterMoment} + dateLibInstance={moment} + adapterLocale={locale} + > + <CssBaseline /> + <Head> + <meta + name="viewport" + content="width=device-width, initial-scale=1, maximum-scale=1" + /> + </Head> + <Component {...pageProps} /> + <Toasts /> + </LocalizationProvider> + </ThemeProvider> + </ApolloProvider> ); };

@@ -69,4 +67,4 @@ <App {...props} />

</SessionProvider> ); -export default AppWrapper; +export default appWithTranslation(AppWrapper, nextI18NextConfig);
M frontend/pages/_error.tsxfrontend/pages/_error.tsx

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

-import {useTranslation} from 'react-i18next'; +import {useTranslation} from 'next-i18next'; import Box from '@mui/material/Box'; import Typography from '@mui/material/Typography'; import pageUtils from '../lib/pageUtils';

@@ -26,7 +26,6 @@ </Typography>

</Box> ); }; - export const getServerSideProps = pageUtils.getServerSideProps(); export default NotFoundPage;
M frontend/pages/auth/confirm/google.tsxfrontend/pages/auth/confirm/google.tsx

@@ -5,7 +5,7 @@ import FormControlLabel from '@mui/material/FormControlLabel';

import Checkbox from '@mui/material/Checkbox'; import Button from '@mui/material/Button'; import Box from '@mui/material/Box'; -import {useTranslation, Trans} from 'react-i18next'; +import {useTranslation, Trans} from 'next-i18next'; import {useState} from 'react'; import pageUtils from '../../../lib/pageUtils'; import CommonConfirm from '../../../layouts/ConfirmLayout';
M frontend/pages/auth/confirm/index.tsxfrontend/pages/auth/confirm/index.tsx

@@ -1,7 +1,7 @@

import Typography from '@mui/material/Typography'; import {useTheme} from '@mui/material/styles'; import Icon from '@mui/material/Icon'; -import {useTranslation} from 'react-i18next'; +import {useTranslation} from 'next-i18next'; import CommonConfirm from '../../../layouts/ConfirmLayout'; import pageUtils from '../../../lib/pageUtils';

@@ -17,10 +17,7 @@ </Typography>

<Typography variant="h5" align="center"> {t('confirm.title')} </Typography> - <Typography - align="center" - sx={{margin: theme.spacing(5, 0)}} - > + <Typography align="center" sx={{margin: theme.spacing(5, 0)}}> <Icon fontSize="large">mail</Icon> </Typography> <Typography
M frontend/pages/auth/login.tsxfrontend/pages/auth/login.tsx

@@ -2,7 +2,7 @@ import CardMedia from '@mui/material/CardMedia';

import Card from '@mui/material/Card'; import Typography from '@mui/material/Typography'; import {getSession} from 'next-auth/react'; -import {useTranslation} from 'react-i18next'; +import {useTranslation} from 'next-i18next'; import Layout from '../../layouts/Centered'; import Logo from '../../components/Logo'; import SignInForm from '../../containers/SignInForm';
M frontend/pages/auth/lost-password.tsxfrontend/pages/auth/lost-password.tsx

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

-import {useTranslation} from 'react-i18next'; +import {useTranslation} from 'next-i18next'; import Layout from '../../layouts/Centered'; import LostPasswordContainer from '../../containers/LostPassword'; import pageUtils from '../../lib/pageUtils';

@@ -12,7 +12,6 @@ <LostPasswordContainer />

</Layout> ); }; - export const getServerSideProps = pageUtils.getServerSideProps();
M frontend/pages/auth/register/index.tsxfrontend/pages/auth/register/index.tsx

@@ -8,7 +8,7 @@ import Divider from '@mui/material/Divider';

import Button from '@mui/material/Button'; import CardMedia from '@mui/material/CardMedia'; import {useTheme} from '@mui/material/styles'; -import {useTranslation} from 'react-i18next'; +import {useTranslation} from 'next-i18next'; import Layout from '../../../layouts/Centered'; import Logo from '../../../components/Logo'; import LanguagesIcon from '../../../containers/Languages/Icon';
M frontend/pages/auth/register/mail.tsxfrontend/pages/auth/register/mail.tsx

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

import Card from '@mui/material/Card'; import CardMedia from '@mui/material/CardMedia'; -import {useTranslation} from 'react-i18next'; +import {useTranslation} from 'next-i18next'; import Layout from '../../../layouts/Centered'; import MailSignUpForm from '../../../containers/MailSignUpForm'; import Logo from '../../../components/Logo';

@@ -19,7 +19,6 @@ </Card>

</Layout> ); }; - export const getServerSideProps = pageUtils.getServerSideProps();
M frontend/pages/auth/reset.tsxfrontend/pages/auth/reset.tsx

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

import {useState} from 'react'; import {useRouter} from 'next/router'; -import {useTranslation} from 'react-i18next'; +import {useTranslation} from 'next-i18next'; import useToastStore from '../../stores/useToastStore'; import Layout from '../../layouts/Centered'; import ResetPasswordContainer from '../../containers/ResetPassword';
M frontend/pages/dashboard.tsxfrontend/pages/dashboard.tsx

@@ -3,7 +3,7 @@ import moment from 'moment';

import Cookies from 'cookies'; import {useRouter} from 'next/router'; import {getSession} from 'next-auth/react'; -import {useTranslation} from 'react-i18next'; +import {useTranslation} from 'next-i18next'; import LayoutDefault from '../layouts/Default'; import DashboardEvents from '../containers/DashboardEvents'; import DashboardEmpty from '../containers/DashboardEmpty';
M frontend/pages/e/[uuid]/details.tsxfrontend/pages/e/[uuid]/details.tsx

@@ -13,7 +13,7 @@ import CheckCircleOutlineIcon from '@mui/icons-material/CheckCircleOutline';

import {useTheme} from '@mui/material/styles'; import {DatePicker} from '@mui/x-date-pickers/DatePicker'; import {PropsWithChildren, useState} from 'react'; -import {useTranslation} from 'react-i18next'; +import {useTranslation} from 'next-i18next'; import pageUtils from '../../../lib/pageUtils'; import DetailsLink from '../../../containers/DetailsLink'; import ShareEvent from '../../../containers/ShareEvent';
M frontend/pages/e/[uuid]/index.tsxfrontend/pages/e/[uuid]/index.tsx

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

import {useState, useReducer, PropsWithChildren} from 'react'; import Box from '@mui/material/Box'; -import {useTranslation} from 'react-i18next'; +import {useTranslation} from 'next-i18next'; import {getSession, useSession} from 'next-auth/react'; import TravelColumns from '../../../containers/TravelColumns'; import NewTravelDialog from '../../../containers/NewTravelDialog';
M frontend/pages/e/[uuid]/options.tsxfrontend/pages/e/[uuid]/options.tsx

@@ -14,7 +14,7 @@ } from '../../../generated/graphql';

import CarosterPlusOption from '../../../containers/CarosterPlusOption'; import CarosterPlusSettings from '../../../containers/CarosterPlusSettings'; import {Card, Typography} from '@mui/material'; -import {useTranslation} from 'react-i18next'; +import {useTranslation} from 'next-i18next'; interface Props { modulesSettings?: Module;
M frontend/pages/new.tsxfrontend/pages/new.tsx

@@ -1,5 +1,5 @@

import {useRouter} from 'next/router'; -import {useTranslation} from 'react-i18next'; +import {useTranslation} from 'next-i18next'; import Layout from '../layouts/Centered'; import CreateEvent from '../containers/CreateEvent'; import LanguagesIcon from '../containers/Languages/Icon';
M frontend/pages/profile.tsxfrontend/pages/profile.tsx

@@ -1,5 +1,5 @@

import {useRouter} from 'next/router'; -import {useTranslation} from 'react-i18next'; +import {useTranslation} from 'next-i18next'; import Loading from '../containers/Loading'; import Profile from '../containers/Profile'; import LayoutDefault from '../layouts/Default';

@@ -39,7 +39,7 @@ menuActions={menuActions}

goBack {...props} > - {profile && <Profile profile={profile} logout={signOut} />} + {profile && <Profile profile={profile} logout={signOut} />} </LayoutDefault> ); };
D frontend/react-i18next.config.js

@@ -1,15 +0,0 @@

-const {FALLBACK_LANGUAGE = 'en'} = process.env; - -module.exports = { - i18n: { - defaultLocale: FALLBACK_LANGUAGE, - locales: [...new Set([FALLBACK_LANGUAGE, 'en', 'fr', 'nl'])], - localeDetection: false, - }, - trailingSlash: true, - - fallbackLng: { - default: FALLBACK_LANGUAGE, - 'fr-CH': ['fr'], - }, -};
M frontend/yarn.lockfrontend/yarn.lock

@@ -1557,38 +1557,38 @@ checksum: 10c0/05c5368c13b662ee4c122c7bfbe5dc0b613416672a829f3e78bc49a357a197e0218d6e74e7c66cfcd04e15a179acab080bd3c69658c9fbefd0e1ccd950a07fc6

languageName: node linkType: hard -"@date-io/core@npm:^2.17.0": - version: 2.17.0 - resolution: "@date-io/core@npm:2.17.0" - checksum: 10c0/e56df44e9b0bc14eefad8509fef2f4a0b847ea01ad0f2cf6b7b5fce5f69120e607a90b6436e84266a2b0336b6bb986fd3f56c3f4b897db85578b9050ac6610bd +"@date-io/core@npm:^3.0.0": + version: 3.0.0 + resolution: "@date-io/core@npm:3.0.0" + checksum: 10c0/c8a725ad5729b38d3f73b7c2bf852ac18a980d6b610832db9f87eb6821e6377854112ba4b5f8510d3e3f49d5290a50dd79ae7724bbafeb146bfdfb5b4c8a13ed languageName: node linkType: hard -"@date-io/dayjs@npm:2.17.0": - version: 2.17.0 - resolution: "@date-io/dayjs@npm:2.17.0" +"@date-io/dayjs@npm:3.0.0": + version: 3.0.0 + resolution: "@date-io/dayjs@npm:3.0.0" dependencies: - "@date-io/core": "npm:^2.17.0" + "@date-io/core": "npm:^3.0.0" peerDependencies: dayjs: ^1.8.17 peerDependenciesMeta: dayjs: optional: true - checksum: 10c0/ecf92e37a1c5afae91a8e6acb580e17dcb2b32ee2a461a5302dfb05acbcd0076c819eaa2a968f6005162aba7788ffff1b8cfbe63553484b98f79e308d6bba140 + checksum: 10c0/0c445e6ca6dd2e39a359645f817258cf6f5909455c3b41172a2e6ccfaad85dbe2683b7328b46399f8edaf2ecffd3441b5b2ac869126d1e8765116e2fc6526816 languageName: node linkType: hard -"@date-io/moment@npm:2.17.0": - version: 2.17.0 - resolution: "@date-io/moment@npm:2.17.0" +"@date-io/moment@npm:3.0.0": + version: 3.0.0 + resolution: "@date-io/moment@npm:3.0.0" dependencies: - "@date-io/core": "npm:^2.17.0" + "@date-io/core": "npm:^3.0.0" peerDependencies: moment: ^2.24.0 peerDependenciesMeta: moment: optional: true - checksum: 10c0/7fb24a7155ecf6a10ebbb61db8d3f82017773b5dfd38e301786ff67b667ec9fb7ca377fe64557978249b6f53f421292a0cd84c30720496477e806f5f0cac1579 + checksum: 10c0/60dce1746510f040a84e05450069028bcc53b677f54fdc46c44ecbe9922223dab7f1c93851182fb741173fecaf9f8cac53e67222adbc30f495520006395ef038 languageName: node linkType: hard

@@ -3463,6 +3463,16 @@ checksum: 10c0/a8eb5d5cb5c48fc58c7ca3ff1e1ddf771ee07ca5043da6e4871e6757b4472e2e73b4cfef2644c38983174a4bc728c73f8da02845c28a1212f98cabd293ecae98

languageName: node linkType: hard +"@types/hoist-non-react-statics@npm:^3.3.4": + version: 3.3.5 + resolution: "@types/hoist-non-react-statics@npm:3.3.5" + dependencies: + "@types/react": "npm:*" + hoist-non-react-statics: "npm:^3.3.0" + checksum: 10c0/2a3b64bf3d9817d7830afa60ee314493c475fb09570a64e7737084cd482d2177ebdddf888ce837350bac51741278b077683facc9541f052d4bbe8487b4e3e618 + languageName: node + linkType: hard + "@types/js-yaml@npm:^4.0.0": version: 4.0.9 resolution: "@types/js-yaml@npm:4.0.9"

@@ -3911,8 +3921,8 @@ version: 0.0.0-use.local

resolution: "app@workspace:." dependencies: "@apollo/client": "npm:^3.11.4" - "@date-io/dayjs": "npm:2.17.0" - "@date-io/moment": "npm:2.17.0" + "@date-io/dayjs": "npm:3.0.0" + "@date-io/moment": "npm:3.0.0" "@emotion/react": "npm:^11.13.0" "@emotion/styled": "npm:^11.13.0" "@graphql-codegen/cli": "npm:^5.0.2"

@@ -3946,6 +3956,7 @@ marked: "npm:^7.0.5"

moment: "npm:^2.30.1" next: "npm:^14.2.5" next-auth: "npm:4.24.7" + next-i18next: "npm:^15.3.1" next-pwa: "npm:^5.6.0" react: "npm:^18.3.1" react-dom: "npm:^18.3.1"

@@ -4812,6 +4823,13 @@ resolution: "core-js-compat@npm:3.36.1"

dependencies: browserslist: "npm:^4.23.0" checksum: 10c0/70fba18a4095cd8ac04e5ba8cee251e328935859cf2851c1f67770068ea9f9fe71accb1b7de17cd3c9a28d304a4c41712bd9aa895110ebb6e3be71b666b029d1 + languageName: node + linkType: hard + +"core-js@npm:^3": + version: 3.38.1 + resolution: "core-js@npm:3.38.1" + checksum: 10c0/7df063b6f13a54e46515817ac3e235c6c598a4d3de65cd188a061fc250642be313b895fb9fb2f36e1e31890a1bb4ef61d82666a340413f540b7ce3c65689739b languageName: node linkType: hard

@@ -6335,7 +6353,7 @@ checksum: 10c0/c9f295d9d8e38fa50679281fd70d80726962256e888a76c8e72e526453da7a1832dcb427caa716c1ad5d79841d4537301b90156fa30298fefd3d68f4ea2181bb

languageName: node linkType: hard -"hoist-non-react-statics@npm:^3.3.1, hoist-non-react-statics@npm:^3.3.2": +"hoist-non-react-statics@npm:^3.3.0, hoist-non-react-statics@npm:^3.3.1, hoist-non-react-statics@npm:^3.3.2": version: 3.3.2 resolution: "hoist-non-react-statics@npm:3.3.2" dependencies:

@@ -6397,6 +6415,13 @@ checksum: 10c0/b19c3e2cd1dc426f6f893752fec08140abf79058a1b6238422e45373ed81389f02e1a2ba2ef4e9b2430d4e900a0f5ba12307de82320604e81ac1b722abd2ee62

languageName: node linkType: hard +"i18next-fs-backend@npm:^2.3.2": + version: 2.3.2 + resolution: "i18next-fs-backend@npm:2.3.2" + checksum: 10c0/5760843ade112821e4df62dffcdab769a09550bbe26264bb03babd60a122b4a1520a7ee95de228d3b932d2ac4220fc7669936026c10a729292c98cacdee8c49b + languageName: node + linkType: hard + "i18next@npm:^23.14.0": version: 23.14.0 resolution: "i18next@npm:23.14.0"

@@ -7927,6 +7952,24 @@ peerDependenciesMeta:

nodemailer: optional: true checksum: 10c0/40c5f51e02141615069d422431a4906c38f6050b29f654ecc99a92fd3c974958535eb7c5f7bbc3dfd2e5996825d7c4f20d8ca68f372e2f9aad2131701cb95b7d + languageName: node + linkType: hard + +"next-i18next@npm:^15.3.1": + version: 15.3.1 + resolution: "next-i18next@npm:15.3.1" + dependencies: + "@babel/runtime": "npm:^7.23.2" + "@types/hoist-non-react-statics": "npm:^3.3.4" + core-js: "npm:^3" + hoist-non-react-statics: "npm:^3.3.2" + i18next-fs-backend: "npm:^2.3.2" + peerDependencies: + i18next: ">= 23.7.13" + next: ">= 12.0.0" + react: ">= 17.0.2" + react-i18next: ">= 13.5.0" + checksum: 10c0/e8657760edbf345a7e047a0594f60cc2b28f66db46b9f26bbb57f5da5b30536adc4a49d640ecbb7c0c871381536496f885e9c5e34a41c8c6fd144e2fc4408435 languageName: node linkType: hard