From adeca755e0b102ce953b6389f725918d0a0d86c2 Mon Sep 17 00:00:00 2001 From: Igor Kazmin Date: Wed, 13 Jun 2018 20:52:22 +0300 Subject: [PATCH] make tasks --- src/app.js | 69 ++++++++++++++++++----------- src/components/language-switcher.js | 35 +++++++++++++++ src/components/menu/index.js | 3 +- src/constants/index.js | 5 +++ src/context/language.js | 5 +++ src/i18n/dictionary.js | 15 +++++++ src/i18n/index.js | 11 +++++ src/reducer/articles.js | 4 +- 8 files changed, 118 insertions(+), 29 deletions(-) create mode 100644 src/components/language-switcher.js create mode 100644 src/context/language.js create mode 100644 src/i18n/dictionary.js create mode 100644 src/i18n/index.js diff --git a/src/app.js b/src/app.js index 3b56c13..5873a81 100644 --- a/src/app.js +++ b/src/app.js @@ -7,45 +7,60 @@ import Filters from './components/filters' import Counter from './components/counter' import Menu, { MenuItem } from './components/menu' import { Provider as UserProvider } from './context/user' +import { Provider as LanguageProvider } from './context/language' +import LanguageSwitcher from './components/language-switcher' +import t from './i18n' + +import { LANGUAGES } from './constants' class App extends Component { state = { - username: 'roma' + username: 'roma', + lang: LANGUAGES.ENGLISH } handleUserChange = (username) => this.setState({ username }) render() { return ( - -
- - Filters - Articles - Counter - Comments - - - - - - -

Add New Article

} + + + +
+ + {t('filters')} + {t('articles')} + {t('counter')} + {t('comments')} + + - - -

Some Error

} /> -

Not Found

} /> - -
-
+ + + + +

Add New Article

} + /> + + +

Some Error

} /> +

Not Found

} /> +
+
+
+ ) } + + onLangChange = (lang) => { + this.setState({ + lang + }) + } } export default App diff --git a/src/components/language-switcher.js b/src/components/language-switcher.js new file mode 100644 index 0000000..243e4b2 --- /dev/null +++ b/src/components/language-switcher.js @@ -0,0 +1,35 @@ +import React, { Component } from 'react' +import PropTypes from 'prop-types' +import { Consumer as LangConsumer } from '../context/language' + +import { LANGUAGES } from '../constants' + +class LanguageSwitcher extends Component { + static propTypes = { + onLangChange: PropTypes.func.isRequired + } + + render() { + return ( + + ) + } + + getLanguageList(activeLang) { + return Object.values(LANGUAGES).map((lang) => ( +
  • this.props.onLangChange(lang)} + style={activeLang === lang ? { color: 'red' } : null} + key={lang} + > + {lang} +
  • + )) + } +} + +export default LanguageSwitcher diff --git a/src/components/menu/index.js b/src/components/menu/index.js index ac5dfdf..ef3bcc5 100644 --- a/src/components/menu/index.js +++ b/src/components/menu/index.js @@ -1,5 +1,6 @@ import React, { Component } from 'react' import MenuItem from './menu-item' +import t from '../../i18n' class Menu extends Component { static propTypes = {} @@ -7,7 +8,7 @@ class Menu extends Component { render() { return (
    -

    Main Menu

    +

    {t('mainMenu')}

    {this.props.children}
    ) diff --git a/src/constants/index.js b/src/constants/index.js index 67a910a..7583cb3 100644 --- a/src/constants/index.js +++ b/src/constants/index.js @@ -14,3 +14,8 @@ export const LOAD_COMMENTS_FOR_PAGE = 'LOAD_COMMENTS_FOR_PAGE' export const START = '_START' export const SUCCESS = '_SUCCESS' export const FAIL = '_FAIL' + +export const LANGUAGES = { + ENGLISH: 'en', + RUSSIAN: 'ru' +} diff --git a/src/context/language.js b/src/context/language.js new file mode 100644 index 0000000..25bffa4 --- /dev/null +++ b/src/context/language.js @@ -0,0 +1,5 @@ +import { createContext } from 'react' + +const { Provider, Consumer } = createContext() + +export { Provider, Consumer } diff --git a/src/i18n/dictionary.js b/src/i18n/dictionary.js new file mode 100644 index 0000000..0c15434 --- /dev/null +++ b/src/i18n/dictionary.js @@ -0,0 +1,15 @@ +export const ru = { + mainMenu: 'Главное меню', + filters: 'Фильтры', + articles: 'Статьи', + counter: 'Счетчик', + comments: 'Комментарии' +} + +export const en = { + mainMenu: 'Main menu', + filters: 'Filters', + articles: 'Articles', + counter: 'Counters', + comments: 'Comments' +} diff --git a/src/i18n/index.js b/src/i18n/index.js new file mode 100644 index 0000000..764a8b1 --- /dev/null +++ b/src/i18n/index.js @@ -0,0 +1,11 @@ +import React from 'react' +import { Consumer } from '../context/language' +import * as dicts from './dictionary' + +export default function translate(string) { + return {(lang) => getTranslatedString(string, lang)} +} + +function getTranslatedString(string, lang) { + return dicts[lang] && dicts[lang][string] ? dicts[lang][string] : string +} diff --git a/src/reducer/articles.js b/src/reducer/articles.js index d9d9796..d620359 100644 --- a/src/reducer/articles.js +++ b/src/reducer/articles.js @@ -46,7 +46,9 @@ export default (state = new ReducerRecord(), action) => { case LOAD_ALL_ARTICLES + SUCCESS: return state - .set('entities', arrToMap(response, ArticleModel)) + .updateIn(['entities'], (entities) => + arrToMap(response, ArticleModel).mergeDeep(entities) + ) .set('loading', false) .set('loaded', true)