Skip to content

Commit

Permalink
feat: update translations, translate countries (#111)
Browse files Browse the repository at this point in the history
* refactor: update translations, translate countries
  • Loading branch information
pyphilia authored Apr 18, 2024
1 parent 5953257 commit 4f08bf7
Show file tree
Hide file tree
Showing 14 changed files with 121 additions and 31 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
"@mui/icons-material": "5.15.15",
"@mui/lab": "5.0.0-alpha.170",
"@mui/material": "5.15.15",
"i18n-iso-countries": "7.11.0",
"leaflet": "^1.9.4",
"leaflet-easybutton": "2.4.0",
"leaflet-geosearch": "3.11.1",
Expand Down
8 changes: 8 additions & 0 deletions src/components/CountryForm/CountryForm.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,11 @@ export const TopPlacement = {
),
],
} satisfies Story;

// the popper can overflow
export const French = {
args: {
onChange: fn(),
lang: 'fr',
},
} satisfies Story;
34 changes: 31 additions & 3 deletions src/components/CountryForm/CountryForm.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,25 @@
import { Autocomplete, Popper, PopperProps, TextField } from '@mui/material';

import countriesISO from 'i18n-iso-countries';
import arTrans from 'i18n-iso-countries/langs/ar.json';
import deTrans from 'i18n-iso-countries/langs/de.json';
import enTrans from 'i18n-iso-countries/langs/en.json';
import esTrans from 'i18n-iso-countries/langs/es.json';
import frTrans from 'i18n-iso-countries/langs/fr.json';
import itTrans from 'i18n-iso-countries/langs/it.json';

import { useMapTranslation } from '@/config/i18n';

import countries from '../../data/countries.json';
import { Country } from '../../types';

countriesISO.registerLocale(enTrans);
countriesISO.registerLocale(frTrans);
countriesISO.registerLocale(arTrans);
countriesISO.registerLocale(esTrans);
countriesISO.registerLocale(deTrans);
countriesISO.registerLocale(itTrans);

const CustomPopper = ({
placement = 'auto',
}: {
Expand All @@ -25,29 +42,40 @@ export type CountryFormProps = {
label?: string;
placement?: PopperProps['placement'];
initialValue?: string;
lang?: string;
};

const CountryForm = ({
onChange,
label = 'Select a country',
placement = 'auto',
initialValue,
lang = 'en',
}: CountryFormProps): JSX.Element => {
const { t } = useMapTranslation();

const handleOnChange = (_event: any, newValue: Country | null) => {
if (newValue) {
onChange?.(newValue);
}
};

const translatedCountries = countries
.map((c) => ({
...c,
name: countriesISO.getName(c.alpha2, lang) ?? c.name,
}))
.sort((a, b) => a.name.localeCompare(b.name));

return (
<div style={{ position: 'relative' }}>
<Autocomplete
autoSelect
onChange={handleOnChange as any}
disablePortal
defaultValue={countries.find((c) => c.alpha2 === initialValue)}
options={countries}
getOptionKey={(o) => o.name}
options={translatedCountries}
getOptionKey={(o) => o.alpha2}
getOptionLabel={(o) => o.name}
sx={{ minWidth: 250 }}
// set custom popper to force placement
Expand Down Expand Up @@ -78,7 +106,7 @@ const CountryForm = ({
...params.InputProps,
sx: { borderRadius: '15px' },
}}
label={label}
label={t(label)}
/>
)}
/>
Expand Down
22 changes: 22 additions & 0 deletions src/components/Map.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -439,3 +439,25 @@ export const MapSignOutMobile = {
],
// cannot play inside an iframe
} satisfies Story;

export const MapFrench = {
args: {
itemId: 'd5a1c73d-cd4d-4f20-8a91-3c689ee87ea4',
viewItem: () => ({}) as any,
currentMember: MemberFactory({ extra: { lang: 'fr' } }),
useDeleteItemGeolocation: () => ({}) as any,
useItemsInMap: () => ({ data: [] }) as any,
useAddressFromGeolocation: () => ({ data: 'address' }) as any,
usePostItem: () => ({}) as any,
useRecycleItems: () => ({}) as any,
useSuggestionsForAddress: MOCK_USE_SUGGESTIONS as any,
},
decorators: [
(Story) => (
<div style={{ margin: 'auto', width: '95vw', height: '95vh' }}>
<Story />
</div>
),
],
// cannot play inside an iframe
} satisfies Story;
5 changes: 4 additions & 1 deletion src/components/common/LoggedOutWarning.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@ import { useEffect, useState } from 'react';

import { Alert } from '@mui/material';

import { useMapTranslation } from '@/config/i18n';

import { useQueryClientContext } from '../context/QueryClientContext';

const LoggedOutWarning = (): JSX.Element | null => {
const { t } = useMapTranslation();
const [open, setOpen] = useState(false);
const { currentMember } = useQueryClientContext();

Expand Down Expand Up @@ -35,7 +38,7 @@ const LoggedOutWarning = (): JSX.Element | null => {
severity="warning"
onClose={onClose}
>
Some functionalities are disabled for logged out users.
{t('Some functionalities are disabled for logged out users.')}
</Alert>
);
};
Expand Down
20 changes: 13 additions & 7 deletions src/components/map/AddItemButton.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { FormEvent, useState } from 'react';
import { useTranslation } from 'react-i18next';

import AddLocationAltIcon from '@mui/icons-material/AddLocationAlt';
import {
Expand All @@ -15,6 +14,9 @@ import {
} from '@mui/material';

import { ItemGeolocation, ItemType } from '@graasp/sdk';
import { COMMON } from '@graasp/translations';

import { useCommonTranslation, useMapTranslation } from '@/config/i18n';

import { useQueryClientContext } from '../context/QueryClientContext';

Expand All @@ -28,8 +30,9 @@ const AddItemButton = ({ location }: Props): JSX.Element | null => {
usePostItem,
itemId: parentId,
} = useQueryClientContext();
const { t: commonT } = useCommonTranslation();
const { mutate: postItem } = usePostItem();
const { t } = useTranslation();
const { t } = useMapTranslation();
const [open, setOpen] = useState(false);

const handleSubmit = async (e: FormEvent<HTMLFormElement>) => {
Expand Down Expand Up @@ -58,15 +61,15 @@ const AddItemButton = ({ location }: Props): JSX.Element | null => {
return (
<>
<CssBaseline />
<Tooltip title={t('Add a new folder at this location')}>
<Tooltip title={t('Add a new item at this location')}>
<IconButton onClick={handleAddItem}>
<AddLocationAltIcon />
</IconButton>
</Tooltip>
{/* fallback form to add an item */}
{!handleAddOnClick && (
<Dialog open={open}>
<DialogTitle>{t('Add a new folder at this location')}</DialogTitle>
<DialogTitle>{t('Add a new item at this location')}</DialogTitle>
<form onSubmit={handleSubmit}>
<DialogContent>
<TextField
Expand All @@ -77,12 +80,13 @@ const AddItemButton = ({ location }: Props): JSX.Element | null => {
fullWidth
name="name"
variant="standard"
required
/>
<TextField
autoFocus
margin="dense"
id="description"
label={t('Description (optional)')}
label={t('Description')}
fullWidth
name="description"
variant="standard"
Expand All @@ -92,9 +96,11 @@ const AddItemButton = ({ location }: Props): JSX.Element | null => {
</DialogContent>
<DialogActions>
<Button autoFocus onClick={() => setOpen(false)}>
{t('Cancel')}
{commonT(COMMON.CANCEL_BUTTON)}
</Button>
<Button type="submit" variant="contained">
{commonT(COMMON.SAVE_BUTTON)}
</Button>
<Button type="submit">{t('Save')}</Button>
</DialogActions>
</form>
</Dialog>
Expand Down
8 changes: 7 additions & 1 deletion src/components/map/CountryContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import { useMap } from 'react-leaflet';

import { Paper } from '@mui/material';

import i18n from '@/config/i18n';

import { Country } from '../../types';
import CountryForm from '../CountryForm/CountryForm';

Expand Down Expand Up @@ -42,7 +44,11 @@ const CountryContent = ({
borderRadius: 15,
}}
>
<CountryForm onChange={onChange} />
<CountryForm
onChange={onChange}
placement="bottom"
lang={i18n.language}
/>
</Paper>
</div>
);
Expand Down
5 changes: 3 additions & 2 deletions src/components/map/CurrentLocationMarker.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import { useTranslation } from 'react-i18next';
import { Marker, Popup } from 'react-leaflet';

import { useMapTranslation } from '@/config/i18n';

import { currentLocationMarker } from '../icons/icons';

const CurrentLocationMarker = ({
position,
}: {
position?: { lat: number; lng: number };
}): JSX.Element | null => {
const { t } = useTranslation();
const { t } = useMapTranslation();

if (!position) {
return null;
Expand Down
6 changes: 3 additions & 3 deletions src/components/map/CurrentMarkerPopupContent.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { useTranslation } from 'react-i18next';

import { Skeleton } from '@mui/material';

import { ItemGeolocation } from '@graasp/sdk';

import { useMapTranslation } from '@/config/i18n';

import { useQueryClientContext } from '../context/QueryClientContext';
import AddItemButton from './AddItemButton';

Expand All @@ -14,7 +14,7 @@ const CurrentMarkerPopupContent = ({
open: boolean;
point: Pick<ItemGeolocation, 'lat' | 'lng'>;
}): JSX.Element => {
const { t } = useTranslation();
const { t } = useMapTranslation();
const { useAddressFromGeolocation, currentMember } = useQueryClientContext();
const { data: address, isLoading } = useAddressFromGeolocation(point, {
enabled: Boolean(currentMember) && open,
Expand Down
7 changes: 1 addition & 6 deletions src/components/map/ItemsMarkers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,7 @@ const ItemsMarkers = ({
// color of clusters is defined by number of markers grouped together
return (
<FeatureGroup ref={groupRef}>
<MarkerClusterGroup
chunkedLoading
// hide polygon area
spiderLegPolylineOptions={{ opacity: 0 }}
icon
>
<MarkerClusterGroup chunkedLoading showCoverageOnHover={false}>
{itemGeolocations?.map((geoloc) => (
<Marker
key={geoloc.id}
Expand Down
6 changes: 3 additions & 3 deletions src/components/topbar/Search.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { useTranslation } from 'react-i18next';

import { Autocomplete, TextField } from '@mui/material';

import { useMapTranslation } from '@/config/i18n';

import { useQueryClientContext } from '../context/QueryClientContext';

const Search = ({
Expand All @@ -14,7 +14,7 @@ const Search = ({
onChange: (newTags: string[]) => void;
}): JSX.Element => {
const { currentMember } = useQueryClientContext();
const { t } = useTranslation();
const { t } = useMapTranslation();

const onChangeTags = (_e: unknown, newValue: string[]) => {
onChange(newValue);
Expand Down
5 changes: 3 additions & 2 deletions src/langs/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@
"Keywords": "Keywords",
"Filters": "Filters",
"My Location": "My Location",
"Description (optional)": "Description (optional)",
"Description": "Description",
"Name": "Name",
"Add a new folder at this location": "Add a new folder at this location",
"This location does not match a specific address.": "This location does not match a specific address."
"This location does not match a specific address.": "This location does not match a specific address.",
"Select a country": "Select a country"
}
8 changes: 5 additions & 3 deletions src/langs/fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,10 @@
"Keywords": "Mots-clés",
"Filters": "Filtres",
"My Location": "Ma position",
"Description (optional)": "description (facultatif)",
"Description": "Description",
"Name": "Nom",
"Add a new folder at this location": "Ajouter un nouveau dossier à cette adresse",
"This location does not match a specific address.": "Cet emplacement ne correspond pas à une adresse spécifique."
"Add a new item at this location": "Ajouter un nouvel élément à cette adresse",
"This location does not match a specific address.": "Cet emplacement ne correspond pas à une adresse spécifique.",
"Select a country": "Choisir un pays",
"Some functionalities are disabled for logged out users.": "Certaines fonctionnalités sont désactivées car vous n'êtes pas enregistré."
}
17 changes: 17 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2410,6 +2410,7 @@ __metadata:
eslint-plugin-react-refresh: "npm:^0.4.5"
eslint-plugin-storybook: "npm:0.8.0"
http-server: "npm:14.1.1"
i18n-iso-countries: "npm:7.11.0"
leaflet: "npm:^1.9.4"
leaflet-easybutton: "npm:2.4.0"
leaflet-geosearch: "npm:3.11.1"
Expand Down Expand Up @@ -8272,6 +8273,13 @@ __metadata:
languageName: node
linkType: hard

"diacritics@npm:1.3.0":
version: 1.3.0
resolution: "diacritics@npm:1.3.0"
checksum: 10/c5a7d6843a3569f1c5aaf643d2e01aaaf695dd369d0f7868300a1c637b91157fe89cf78aa2e87224042d7f4fc87ab39d20aadb7e006c25e0a7c6a2ef92972e74
languageName: node
linkType: hard

"diff-sequences@npm:^28.1.1":
version: 28.1.1
resolution: "diff-sequences@npm:28.1.1"
Expand Down Expand Up @@ -10629,6 +10637,15 @@ __metadata:
languageName: node
linkType: hard

"i18n-iso-countries@npm:7.11.0":
version: 7.11.0
resolution: "i18n-iso-countries@npm:7.11.0"
dependencies:
diacritics: "npm:1.3.0"
checksum: 10/30f5ab51b58599854130f41d42bd51aa99027917711cd307984dee45684c2c4c3493ff39241ed5b89feca1d49d5e3f9b247f6b2c32c8768224b7975149eaa049
languageName: node
linkType: hard

"i18next@npm:23.7.16":
version: 23.7.16
resolution: "i18next@npm:23.7.16"
Expand Down

0 comments on commit 4f08bf7

Please sign in to comment.