Webatrice: improve language dropdown (#4589)

* useLocaleSort hook, translate language dropdown

* add pt-BR translation

* fix pt-BR flag

Co-authored-by: Jeremy Letto <jeremy.letto@datasite.com>
This commit is contained in:
Jeremy Letto 2022-03-06 20:12:27 -06:00 committed by GitHub
parent 21f7dd5eba
commit 533045445a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 314 additions and 278 deletions

File diff suppressed because one or more lines are too long

View file

@ -274,6 +274,12 @@
"YE": "Yemen",
"ZM": "Zambia",
"ZW": "Zimbabwe"
},
"languages": {
"en-US": "English - US",
"fr": "French",
"nl": "Dutch",
"pt-BR": "Portuguese - Brazil"
}
}
}

View file

@ -1,29 +1,24 @@
// eslint-disable-next-line
import React, { useEffect, useState } from 'react';
import { useEffect, useState } from 'react';
import { Select, MenuItem } from '@material-ui/core';
import FormControl from '@material-ui/core/FormControl';
import InputLabel from '@material-ui/core/InputLabel';
import { useTranslation } from 'react-i18next';
import { useLocaleSort } from 'hooks';
import { Images } from 'images/Images';
import { CountryCode } from 'types';
import { countryCodes } from 'types';
import './CountryDropdown.css';
const CountryDropdown = ({ input: { onChange } }) => {
const [state, setState] = useState('');
const [sortedCountries, setSortedCountries] = useState([]);
const { t, i18n } = useTranslation();
const [value, setValue] = useState('');
const { t } = useTranslation();
useEffect(() => onChange(state), [state]);
useEffect(() => onChange(value), [value]);
useEffect(() => {
const collator = new Intl.Collator(i18n.language);
setSortedCountries(Object.keys(CountryCode).sort((a, b) =>
collator.compare(t(`Common.countries.${a}`), t(`Common.countries.${b}`))
));
}, [i18n.language]);
const translateCountry = country => t(`Common.countries.${country}`);
const sortedCountries = useLocaleSort(countryCodes, translateCountry);
return (
<FormControl variant='outlined' className='CountryDropdown'>
@ -33,9 +28,9 @@ const CountryDropdown = ({ input: { onChange } }) => {
labelId='CountryDropdown-label'
label='Country'
margin='dense'
value={state}
value={value}
fullWidth={true}
onChange={e => setState(e.target.value as string)}
onChange={e => setValue(e.target.value as string)}
>
<MenuItem value={''} key={-1}>
<div className="CountryDropdown-item">
@ -48,7 +43,7 @@ const CountryDropdown = ({ input: { onChange } }) => {
<MenuItem value={country} key={index}>
<div className="CountryDropdown-item">
<img className="CountryDropdown-item__image" src={Images.Countries[country.toLowerCase()]} />
<span className="CountryDropdown-item__label">{t(`Common.countries.${country}`)}</span>
<span className="CountryDropdown-item__label">{translateCountry(country)}</span>
</div>
</MenuItem>
))

View file

@ -6,12 +6,12 @@ import FormControl from '@material-ui/core/FormControl';
import InputLabel from '@material-ui/core/InputLabel';
import { Images } from 'images/Images';
import { Language, LanguageCountry } from 'types';
import { Language, LanguageCountry, LanguageNative } from 'types';
import './LanguageDropdown.css';
const LanguageDropdown = () => {
const { i18n } = useTranslation();
const { t, i18n } = useTranslation();
const [language, setLanguage] = useState(i18n.resolvedLanguage);
useEffect(() => {
@ -30,14 +30,20 @@ const LanguageDropdown = () => {
onChange={e => setLanguage(e.target.value as Language)}
>
{
Object.keys(LanguageCountry).map((lang) => {
Object.keys(Language).map((lang) => {
const country = LanguageCountry[lang];
return (
<MenuItem value={lang} key={lang}>
<div className="LanguageDropdown-item">
<img className="LanguageDropdown-item__image" src={Images.Countries[country]} />
<span className="LanguageDropdown-item__label">{lang}</span>
<span className="LanguageDropdown-item__label">
{LanguageNative[lang]} {
LanguageNative[lang] !== t(`Common.languages.${lang}`) && (
<>({ t(`Common.languages.${lang}`) })</>
)
}
</span>
</div>
</MenuItem>
);

View file

@ -1,4 +1,5 @@
export * from './useAutoConnect';
export * from './useFireOnce';
export * from './useDebounce';
export * from './useLocaleSort';
export * from './useReduxEffect';

View file

@ -0,0 +1,18 @@
import { useEffect, useState } from 'react';
import { useTranslation } from 'react-i18next';
export function useLocaleSort(arr: string[], valueGetter: (value: string) => string) {
const [state] = useState<string[]>(arr);
const [sorted, setSorted] = useState<string[]>([]);
const { i18n } = useTranslation();
useEffect(() => {
const collator = new Intl.Collator(i18n.language);
const sorter = (a, b) => collator.compare(valueGetter(a), valueGetter(b));
setSorted(state.sort(sorter));
}, [state, i18n.language]);
return sorted;
}

File diff suppressed because one or more lines are too long

View file

@ -17,9 +17,9 @@ i18n
.use(initReactI18next)
// for all options read: https://www.i18next.com/overview/configuration-options
.init({
fallbackLng: Language['en'],
fallbackLng: Language['en-US'],
resources: {
[Language['en']]: { translation },
[Language['en-US']]: { translation },
},
partialBundledLanguages: true,

View file

@ -1,252 +1,252 @@
export enum CountryCode {
'AF' = 'AF',
'AX' = 'AX',
'AL' = 'AL',
'DZ' = 'DZ',
'AS' = 'AS',
'AD' = 'AD',
'AO' = 'AO',
'AI' = 'AI',
'AQ' = 'AQ',
'AG' = 'AG',
'AR' = 'AR',
'AM' = 'AM',
'AW' = 'AW',
'AU' = 'AU',
'AT' = 'AT',
'AZ' = 'AZ',
'BH' = 'BH',
'BS' = 'BS',
'BD' = 'BD',
'BB' = 'BB',
'BY' = 'BY',
'BE' = 'BE',
'BZ' = 'BZ',
'BJ' = 'BJ',
'BM' = 'BM',
'BT' = 'BT',
'BO' = 'BO',
'BQ' = 'BQ',
'BA' = 'BA',
'BW' = 'BW',
'BV' = 'BV',
'BR' = 'BR',
'IO' = 'IO',
'BN' = 'BN',
'BG' = 'BG',
'BF' = 'BF',
'BI' = 'BI',
'KH' = 'KH',
'CM' = 'CM',
'CA' = 'CA',
'CV' = 'CV',
'KY' = 'KY',
'CF' = 'CF',
'TD' = 'TD',
'CL' = 'CL',
'CN' = 'CN',
'CX' = 'CX',
'CC' = 'CC',
'CO' = 'CO',
'KM' = 'KM',
'CG' = 'CG',
'CD' = 'CD',
'CK' = 'CK',
'CR' = 'CR',
'CI' = 'CI',
'HR' = 'HR',
'CU' = 'CU',
'CW' = 'CW',
'CY' = 'CY',
'CZ' = 'CZ',
'DK' = 'DK',
'DJ' = 'DJ',
'DM' = 'DM',
'DO' = 'DO',
'EC' = 'EC',
'EG' = 'EG',
'SV' = 'SV',
'GQ' = 'GQ',
'ER' = 'ER',
'EE' = 'EE',
'ET' = 'ET',
'EU' = 'EU',
'FK' = 'FK',
'FO' = 'FO',
'FJ' = 'FJ',
'FI' = 'FI',
'FR' = 'FR',
'GF' = 'GF',
'PF' = 'PF',
'TF' = 'TF',
'GA' = 'GA',
'GM' = 'GM',
'GE' = 'GE',
'DE' = 'DE',
'GH' = 'GH',
'GI' = 'GI',
'GR' = 'GR',
'GL' = 'GL',
'GD' = 'GD',
'GP' = 'GP',
'GU' = 'GU',
'GT' = 'GT',
'GG' = 'GG',
'GN' = 'GN',
'GW' = 'GW',
'GY' = 'GY',
'HT' = 'HT',
'HM' = 'HM',
'VA' = 'VA',
'HN' = 'HN',
'HK' = 'HK',
'HU' = 'HU',
'IS' = 'IS',
'IN' = 'IN',
'ID' = 'ID',
'IR' = 'IR',
'IQ' = 'IQ',
'IE' = 'IE',
'IM' = 'IM',
'IL' = 'IL',
'IT' = 'IT',
'JM' = 'JM',
'JP' = 'JP',
'JE' = 'JE',
'JO' = 'JO',
'KZ' = 'KZ',
'KE' = 'KE',
'KI' = 'KI',
'KP' = 'KP',
'KR' = 'KR',
'KW' = 'KW',
'KG' = 'KG',
'LA' = 'LA',
'LV' = 'LV',
'LB' = 'LB',
'LS' = 'LS',
'LR' = 'LR',
'LY' = 'LY',
'LI' = 'LI',
'LT' = 'LT',
'LU' = 'LU',
'MO' = 'MO',
'MK' = 'MK',
'MG' = 'MG',
'MW' = 'MW',
'MY' = 'MY',
'MV' = 'MV',
'ML' = 'ML',
'MT' = 'MT',
'MH' = 'MH',
'MQ' = 'MQ',
'MR' = 'MR',
'MU' = 'MU',
'YT' = 'YT',
'MX' = 'MX',
'FM' = 'FM',
'MD' = 'MD',
'MC' = 'MC',
'MN' = 'MN',
'ME' = 'ME',
'MS' = 'MS',
'MA' = 'MA',
'MZ' = 'MZ',
'MM' = 'MM',
'NA' = 'NA',
'NR' = 'NR',
'NP' = 'NP',
'NL' = 'NL',
'NC' = 'NC',
'NZ' = 'NZ',
'NI' = 'NI',
'NE' = 'NE',
'NG' = 'NG',
'NU' = 'NU',
'NF' = 'NF',
'MP' = 'MP',
'NO' = 'NO',
'OM' = 'OM',
'PK' = 'PK',
'PW' = 'PW',
'PS' = 'PS',
'PA' = 'PA',
'PG' = 'PG',
'PY' = 'PY',
'PE' = 'PE',
'PH' = 'PH',
'PN' = 'PN',
'PL' = 'PL',
'PT' = 'PT',
'PR' = 'PR',
'QA' = 'QA',
'RE' = 'RE',
'RO' = 'RO',
'RU' = 'RU',
'RW' = 'RW',
'BL' = 'BL',
'SH' = 'SH',
'KN' = 'KN',
'LC' = 'LC',
'MF' = 'MF',
'PM' = 'PM',
'VC' = 'VC',
'WS' = 'WS',
'SM' = 'SM',
'ST' = 'ST',
'SA' = 'SA',
'SN' = 'SN',
'RS' = 'RS',
'SC' = 'SC',
'SL' = 'SL',
'SG' = 'SG',
'SX' = 'SX',
'SK' = 'SK',
'SI' = 'SI',
'SB' = 'SB',
'SO' = 'SO',
'ZA' = 'ZA',
'GS' = 'GS',
'SS' = 'SS',
'ES' = 'ES',
'LK' = 'LK',
'SD' = 'SD',
'SR' = 'SR',
'SJ' = 'SJ',
'SZ' = 'SZ',
'SE' = 'SE',
'CH' = 'CH',
'SY' = 'SY',
'TW' = 'TW',
'TJ' = 'TJ',
'TZ' = 'TZ',
'TH' = 'TH',
'TL' = 'TL',
'TG' = 'TG',
'TK' = 'TK',
'TO' = 'TO',
'TT' = 'TT',
'TN' = 'TN',
'TR' = 'TR',
'TM' = 'TM',
'TC' = 'TC',
'TV' = 'TV',
'UG' = 'UG',
'UA' = 'UA',
'AE' = 'AE',
'GB' = 'GB',
'US' = 'US',
'UM' = 'UM',
'UY' = 'UY',
'UZ' = 'UZ',
'VU' = 'VU',
'VE' = 'VE',
'VN' = 'VN',
'VG' = 'VG',
'VI' = 'VI',
'WF' = 'WF',
'EH' = 'EH',
'YE' = 'YE',
'ZM' = 'ZM',
'ZW' = 'ZW',
};
export const countryCodes = [
'AF',
'AX',
'AL',
'DZ',
'AS',
'AD',
'AO',
'AI',
'AQ',
'AG',
'AR',
'AM',
'AW',
'AU',
'AT',
'AZ',
'BH',
'BS',
'BD',
'BB',
'BY',
'BE',
'BZ',
'BJ',
'BM',
'BT',
'BO',
'BQ',
'BA',
'BW',
'BV',
'BR',
'IO',
'BN',
'BG',
'BF',
'BI',
'KH',
'CM',
'CA',
'CV',
'KY',
'CF',
'TD',
'CL',
'CN',
'CX',
'CC',
'CO',
'KM',
'CG',
'CD',
'CK',
'CR',
'CI',
'HR',
'CU',
'CW',
'CY',
'CZ',
'DK',
'DJ',
'DM',
'DO',
'EC',
'EG',
'SV',
'GQ',
'ER',
'EE',
'ET',
'EU',
'FK',
'FO',
'FJ',
'FI',
'FR',
'GF',
'PF',
'TF',
'GA',
'GM',
'GE',
'DE',
'GH',
'GI',
'GR',
'GL',
'GD',
'GP',
'GU',
'GT',
'GG',
'GN',
'GW',
'GY',
'HT',
'HM',
'VA',
'HN',
'HK',
'HU',
'IS',
'IN',
'ID',
'IR',
'IQ',
'IE',
'IM',
'IL',
'IT',
'JM',
'JP',
'JE',
'JO',
'KZ',
'KE',
'KI',
'KP',
'KR',
'KW',
'KG',
'LA',
'LV',
'LB',
'LS',
'LR',
'LY',
'LI',
'LT',
'LU',
'MO',
'MK',
'MG',
'MW',
'MY',
'MV',
'ML',
'MT',
'MH',
'MQ',
'MR',
'MU',
'YT',
'MX',
'FM',
'MD',
'MC',
'MN',
'ME',
'MS',
'MA',
'MZ',
'MM',
'NA',
'NR',
'NP',
'NL',
'NC',
'NZ',
'NI',
'NE',
'NG',
'NU',
'NF',
'MP',
'NO',
'OM',
'PK',
'PW',
'PS',
'PA',
'PG',
'PY',
'PE',
'PH',
'PN',
'PL',
'PT',
'PR',
'QA',
'RE',
'RO',
'RU',
'RW',
'BL',
'SH',
'KN',
'LC',
'MF',
'PM',
'VC',
'WS',
'SM',
'ST',
'SA',
'SN',
'RS',
'SC',
'SL',
'SG',
'SX',
'SK',
'SI',
'SB',
'SO',
'ZA',
'GS',
'SS',
'ES',
'LK',
'SD',
'SR',
'SJ',
'SZ',
'SE',
'CH',
'SY',
'TW',
'TJ',
'TZ',
'TH',
'TL',
'TG',
'TK',
'TO',
'TT',
'TN',
'TR',
'TM',
'TC',
'TV',
'UG',
'UA',
'AE',
'GB',
'US',
'UM',
'UY',
'UZ',
'VU',
'VE',
'VN',
'VG',
'VI',
'WF',
'EH',
'YE',
'ZM',
'ZW',
];

View file

@ -1,11 +1,20 @@
export enum Language {
'en' = 'en',
'en-US' = 'en-US',
'fr' = 'fr',
'nl' = 'nl',
'pt-BR' = 'pt-BR',
}
export enum LanguageCountry {
'en' = 'us',
'en-US' = 'us',
'fr' = 'fr',
'nl' = 'nl',
'pt-BR' = 'br'
}
export enum LanguageNative {
'en-US' = 'English - US',
'fr' = 'Français',
'nl' = 'Nederlands',
'pt-BR' = 'Portugues do Brasil',
}