Browse Source

add language selector

pull/9/head
Nareshkumar Rao 3 years ago
parent
commit
d1a88c046b
  1. 2
      package.json
  2. 2
      src/app/store.js
  3. 43
      src/components/LanguageSwitcher.js
  4. 21
      src/features/auth/langSlice.js
  5. 12
      src/i18n.js
  6. 3
      src/screens/HomeScreen.js
  7. 5
      src/screens/LoginScreen.js
  8. 12
      yarn.lock

2
package.json

@ -11,6 +11,7 @@
"@testing-library/react": "^10.2.1", "@testing-library/react": "^10.2.1",
"@testing-library/user-event": "^12.0.2", "@testing-library/user-event": "^12.0.2",
"axios": "^0.21.1", "axios": "^0.21.1",
"country-flag-icons": "^1.4.0",
"dotenv": "^10.0.0", "dotenv": "^10.0.0",
"framer-motion": "^4", "framer-motion": "^4",
"i18next": "^20.3.5", "i18next": "^20.3.5",
@ -18,7 +19,6 @@
"react": "^17.0.2", "react": "^17.0.2",
"react-dom": "^17.0.2", "react-dom": "^17.0.2",
"react-i18next": "^11.11.4", "react-i18next": "^11.11.4",
"react-icons": "^3.0.0",
"react-qr-reader": "^2.2.1", "react-qr-reader": "^2.2.1",
"react-redux": "^7.2.4", "react-redux": "^7.2.4",
"react-router-dom": "^5.2.0", "react-router-dom": "^5.2.0",

2
src/app/store.js

@ -1,10 +1,12 @@
import { configureStore } from '@reduxjs/toolkit'; import { configureStore } from '@reduxjs/toolkit';
import authSlice from '../features/auth/authSlice'; import authSlice from '../features/auth/authSlice';
import covidSlice from '../features/auth/covidSlice'; import covidSlice from '../features/auth/covidSlice';
import langSlice from '../features/auth/langSlice';
export const store = configureStore({ export const store = configureStore({
reducer: { reducer: {
auth: authSlice, auth: authSlice,
covid: covidSlice, covid: covidSlice,
lang: langSlice,
}, },
}); });

43
src/components/LanguageSwitcher.js

@ -0,0 +1,43 @@
import { Select } from "@chakra-ui/react";
import Flags from 'country-flag-icons/react/3x2';
import { useTranslation } from "react-i18next";
import { useDispatch } from "react-redux";
import { setLanguage } from "../features/auth/langSlice";
function LanguageSwitcher() {
const [, i18n] = useTranslation();
const dispatch = useDispatch();
const currentLangIcon = (() => {
switch (i18n.language) {
case "en":
return <Flags.GB />;
case "ms":
return <Flags.MY />;
case "zh":
return <Flags.CN />;
case "ta":
return <Flags.IN />;
default:
return <Flags.GB />;
}
})();
const handleSelectLanguage = (e) => {
const languageKey = e.target.value;
i18n.changeLanguage(languageKey);
dispatch(setLanguage(languageKey));
}
return (
<Select value={i18n.language} icon={currentLangIcon} variant="filled" onChange={handleSelectLanguage}>
<option value="en">English</option>
<option value="ms">Bahasa Melayu</option>
<option value="zh">中文</option>
<option value="ta">தமிழ்</option>
</Select>
);
}
export default LanguageSwitcher;

21
src/features/auth/langSlice.js

@ -0,0 +1,21 @@
import { createSlice } from '@reduxjs/toolkit';
import Cookies from 'js-cookie';
const initialState = {
lang: Cookies.get('lang'),
};
export const langSlice = createSlice({
name: 'lang',
initialState,
reducers: {
setLanguage: (state, action) => {
state.lang = action.payload;
Cookies.set('lang', action.payload);
},
},
});
export const { setLanguage } = langSlice.actions;
export default langSlice.reducer;

12
src/i18n.js

@ -1,8 +1,10 @@
import i18n from 'i18next'; import i18n from 'i18next';
import Cookies from 'js-cookie';
import { initReactI18next } from 'react-i18next'; import { initReactI18next } from 'react-i18next';
import enTranslation from './locales/en/common.json'; import enTranslation from './locales/en/common.json';
import msTranslation from './locales/ms/common.json'; import msTranslation from './locales/ms/common.json';
import taTranslation from './locales/ta/common.json';
import zhTranslation from './locales/zh/common.json';
const resources = { const resources = {
en: { en: {
@ -11,11 +13,17 @@ const resources = {
ms: { ms: {
common: msTranslation, common: msTranslation,
}, },
zh: {
common: zhTranslation,
},
ta: {
common: taTranslation,
}
}; };
i18n.use(initReactI18next).init({ i18n.use(initReactI18next).init({
resources, resources,
lng: 'ms',
lng: Cookies.get('lang') ? Cookies.get('lang') : "en",
defaultNS: 'common', defaultNS: 'common',
interpolation: { interpolation: {
escapeValue: false, escapeValue: false,

3
src/screens/HomeScreen.js

@ -19,6 +19,7 @@ import { Fragment, React, useEffect, useRef, useState } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { useDispatch, useSelector } from 'react-redux'; import { useDispatch, useSelector } from 'react-redux';
import { Redirect, useHistory } from 'react-router-dom'; import { Redirect, useHistory } from 'react-router-dom';
import LanguageSwitcher from '../components/LanguageSwitcher';
import { authLogout } from '../features/auth/authSlice'; import { authLogout } from '../features/auth/authSlice';
import { setCovidPositive } from '../features/auth/covidSlice'; import { setCovidPositive } from '../features/auth/covidSlice';
@ -225,6 +226,8 @@ function Home() {
<Button colorScheme="blackAlpha" mb={6} onClick={handleLogout}> <Button colorScheme="blackAlpha" mb={6} onClick={handleLogout}>
{t('logOutButtonLabel')} {t('logOutButtonLabel')}
</Button> </Button>
<Divider mb={6} />
<LanguageSwitcher />
</Flex> </Flex>
</Flex> </Flex>
); );

5
src/screens/LoginScreen.js

@ -6,6 +6,7 @@ import { Trans } from 'react-i18next';
import { useDispatch, useSelector } from 'react-redux'; import { useDispatch, useSelector } from 'react-redux';
import { Redirect, useHistory } from 'react-router-dom'; import { Redirect, useHistory } from 'react-router-dom';
import TelegramLoginButton from 'react-telegram-login'; import TelegramLoginButton from 'react-telegram-login';
import LanguageSwitcher from '../components/LanguageSwitcher';
import { authLogin, authLogout } from '../features/auth/authSlice'; import { authLogin, authLogout } from '../features/auth/authSlice';
function Login() { function Login() {
@ -109,7 +110,7 @@ function Login() {
/> />
<Divider mb={6} mt={6} /> <Divider mb={6} mt={6} />
<Trans i18nKey="loginPrivacyNotice"> <Trans i18nKey="loginPrivacyNotice">
<Text fontSize="sm">
<Text mb={6} fontSize="sm">
<b>Privacy notes:</b> <br /> <b>Privacy notes:</b> <br />
Telegram Login allows us to verify your identity, without collecting Telegram Login allows us to verify your identity, without collecting
any of your data. Telegram does NOT give us your phone number. The any of your data. Telegram does NOT give us your phone number. The
@ -130,6 +131,8 @@ function Login() {
information is being handled securely. information is being handled securely.
</Text> </Text>
</Trans> </Trans>
<Divider mb={6} />
<LanguageSwitcher />
</Flex> </Flex>
</Flex> </Flex>
); );

12
yarn.lock

@ -4301,6 +4301,11 @@ cosmiconfig@^7.0.0:
path-type "^4.0.0" path-type "^4.0.0"
yaml "^1.10.0" yaml "^1.10.0"
country-flag-icons@^1.4.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/country-flag-icons/-/country-flag-icons-1.4.0.tgz#68a55441dbe98a7f028d4b00c1dfef3b9f83b7cd"
integrity sha512-tIeh/IZbm3G7O1ocNuEckmd1jkABkJzCPhQm+rBgJXkz1L+lKfwVY/rAy+ih06zGD4kagrZ+1eOndga09y8UHw==
create-ecdh@^4.0.0: create-ecdh@^4.0.0:
version "4.0.4" version "4.0.4"
resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.4.tgz#d6e7f4bffa66736085a0762fd3a632684dabcc4e" resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.4.tgz#d6e7f4bffa66736085a0762fd3a632684dabcc4e"
@ -9935,13 +9940,6 @@ react-i18next@^11.11.4:
"@babel/runtime" "^7.14.5" "@babel/runtime" "^7.14.5"
html-parse-stringify "^3.0.1" html-parse-stringify "^3.0.1"
react-icons@^3.0.0:
version "3.11.0"
resolved "https://registry.yarnpkg.com/react-icons/-/react-icons-3.11.0.tgz#2ca2903dfab8268ca18ebd8cc2e879921ec3b254"
integrity sha512-JRgiI/vdF6uyBgyZhVyYJUZAop95Sy4XDe/jmT3R/bKliFWpO/uZBwvSjWEdxwzec7SYbEPNPck0Kff2tUGM2Q==
dependencies:
camelcase "^5.0.0"
react-is@^16.13.1, react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.1: react-is@^16.13.1, react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.1:
version "16.13.1" version "16.13.1"
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"

Loading…
Cancel
Save