Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 16 additions & 6 deletions src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import ArticlesPage from './components/routes/articles'
import UserForm from './components/user-form'
import Filters from './components/filters'
import Counter from './components/counter'
import LangProvider from './provider/LangProvider'
import 'react-select/dist/react-select.css'
import CommentsPage from './components/routes/comments-page'

Expand All @@ -18,7 +19,8 @@ class App extends Component {
}

state = {
username: ''
username: '',
language: 'ru'
}

getChildContext() {
Expand All @@ -27,10 +29,19 @@ class App extends Component {
}
}

changeLanguage = (language) => (ev) => {
this.setState({language})
ev.preventDefault()
}

handleUserChange = username => this.setState({ username })

render() {
console.log('---', 'rendering App')
return (
<div>
<LangProvider language = {this.state.language}>
<a href="#" onClick={this.changeLanguage('ru')}>Rus</a>
<br />
<a href="#" onClick={this.changeLanguage('en')}>Eng</a>
<UserForm value = {this.state.username} onChange = {this.handleUserChange}/>
<ul>
<li><NavLink to = "/counter" activeStyle = {{ color: 'red' }}>counter</NavLink></li>
Expand All @@ -48,11 +59,10 @@ class App extends Component {
<Route path = "/error" render = {() => <h1>Error page</h1>} />
<Route path = "*" render = {() => <h1>Not Found Page</h1>} />
</Switch>
</div>
</LangProvider>
)
}

handleUserChange = username => this.setState({ username })
}

export default App
export default App
12 changes: 8 additions & 4 deletions src/components/article/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ class Article extends Component {
error: null
}

static contextTypes = {
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

тут и в других местах: лучше сделай декоратор либо компонент-обертку для локализации, чтоб не обращатся каждый раз к контексту, иначе потом тяжело будет что-либо поменять

dictionary: PropTypes.object
}

componentDidCatch(error) {
console.log('---', error)
this.setState({ error })
Expand All @@ -24,10 +28,10 @@ class Article extends Component {
}

render() {
console.log('---', 'rendering Article')
if (this.state.error) return <h2>{this.state.error.message}</h2>

const { isOpen, article, onButtonClick } = this.props
const { dictionary } = this.context
if (!article) return null

return (
Expand All @@ -38,10 +42,10 @@ class Article extends Component {
className = "test__article--button"
onClick={() => onButtonClick(article.id)}
>
{isOpen ? 'close' : 'open'}
{isOpen ? dictionary['close'] : dictionary['open']}
</button>
<button onClick = {this.handleDelete}>
delete me
{dictionary['delete me']}
</button>
</h2>
<CSSTransition
Expand Down Expand Up @@ -89,4 +93,4 @@ Article.propTypes = {

export default connect((state, props) => ({
article: articleSelector(state, props)
}), { deleteArticle, loadArticleById }, null, { pure: false })(Article)
}), { deleteArticle, loadArticleById }, null, { pure: false })(Article)
14 changes: 9 additions & 5 deletions src/components/comment-list/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ class CommentList extends Component {
static contextTypes = {
store: PropTypes.object,
router: PropTypes.object,
user: PropTypes.string
user: PropTypes.string,
dictionary: PropTypes.object
}

componentWillReceiveProps({ isOpen, article, loadArticleComments }) {
Expand All @@ -35,8 +36,9 @@ class CommentList extends Component {

render() {
const {isOpen, toggleOpen} = this.props
console.log('---', 'rendering CommentList')
const text = isOpen ? 'hide comments' : 'show comments'
const {dictionary} = this.context

const text = isOpen ? dictionary['hide comments'] : dictionary['show comments']
return (
<div>
<button onClick={toggleOpen} className="test__comment-list--btn">{text}</button>
Expand All @@ -53,6 +55,8 @@ class CommentList extends Component {

getBody() {
const {article: { comments, id, commentsLoading, commentsLoaded }, isOpen} = this.props
const {dictionary} = this.context

if (!isOpen) return null
if (commentsLoading) return <Loader />
if (!commentsLoaded) return null
Expand All @@ -63,7 +67,7 @@ class CommentList extends Component {
{
comments.length
? this.getComments()
: <h3 className="test__comment-list--empty">No comments yet</h3>
: <h3 className="test__comment-list--empty">{dictionary['No comments yet']}</h3>
}
<CommentForm articleId = {id} />
</div>
Expand All @@ -85,4 +89,4 @@ class CommentList extends Component {
}


export default connect(null, { loadArticleComments }, null, { pure: false })(toggleOpen(CommentList))
export default connect(null, { loadArticleComments }, null, { pure: false })(toggleOpen(CommentList))
8 changes: 6 additions & 2 deletions src/components/counter.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,16 @@ class Counter extends Component {
count: PropTypes.number
};

static contextTypes = {
dictionary: PropTypes.object
}

render() {
return (
<div>
<h3>
{this.props.count}
<button onClick = {this.handleIncrement}>increment</button>
<button onClick = {this.handleIncrement}>{this.context.dictionary.increment}</button>
</h3>
</div>
)
Expand All @@ -29,4 +33,4 @@ const mapStateToProps = state => ({
count: state.counter
})

export default connect(mapStateToProps)(Counter)
export default connect(mapStateToProps)(Counter)
23 changes: 15 additions & 8 deletions src/components/loader.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
import React from 'react'
import React, { Component } from 'react'
import PropTypes from 'prop-types'

function Loader() {
return (
<h2>Loading...</h2>
)
}
class Loader extends Component {

static propTypes = {}

static contextTypes = {
dictionary: PropTypes.object
}

Loader.propTypes = {
render() {
return (
<h2>{this.context.dictionary['Loading']}</h2>
)
}
}

export default Loader
export default Loader
23 changes: 23 additions & 0 deletions src/dictionary.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
export const en = {
'increment': 'increment',
'delete me': 'delete me',
'show comments': 'show comments',
'hide comments': 'hide comments',
'No comments yet': 'No comments yet',
'Loading': 'Loading...',
'close': 'close',
'open': 'open'
}

export const ru = {
'increment': 'увеличить',
'delete me': 'удалить статью',
'show comments': 'показать комментарии',
'hide comments': 'скрыть комментарии',
'Loading': 'Загрузка...',
'No comments yet': 'Пока нет комментариев',
'close': 'закрыть',
'open': 'открыть',
}

export default { ru, en }
29 changes: 29 additions & 0 deletions src/provider/LangProvider.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import React, { Component } from 'react';
import propTypes from 'prop-types'
import dictionaryObject from '../dictionary'

class LangProvider extends Component{

static propTypes = {
language: propTypes.string
}

static childContextTypes = {
dictionary: propTypes.object
}

getChildContext() {
return {
dictionary: dictionaryObject[this.props.language]
}
}

render() {
return (
<div>{this.props.children}</div>
)
}

}

export default LangProvider
4 changes: 2 additions & 2 deletions src/reducer/articles.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ export default (articles = new ReducerState(), action) => {

case LOAD_ALL_ARTICLES + SUCCESS:
return articles
.set('entities', arrToMap(response, ArticleRecord))
.update('entities', entities => arrToMap(response, ArticleRecord).merge(entities))
.set('loading', false)
.set('loaded', true)

Expand All @@ -62,4 +62,4 @@ export default (articles = new ReducerState(), action) => {
default:
return articles
}
}
}