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
76 changes: 51 additions & 25 deletions src/components/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,42 +6,68 @@ import Filters from './filters'
import Counter from './counter'
import CommentsPage from './routes/comments-page'
import Menu, { MenuItem } from './menu'
import Language from './language'
import { Provider as UserProvider } from '../contexts/user'
import {
Provider as LocalizationProvider,
dictionary
} from '../contexts/localization'

class App extends Component {
state = {
user: 'roma'
user: 'roma',
localization: dictionary.ru,
lang: 'ru'
}

setUser = (user) => this.setState({ user })

setLang = (lang) => {
this.setState((state) => ({
...state,
Copy link
Owner

Choose a reason for hiding this comment

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

это лишнее

localization: dictionary[lang],
lang
}))
}

render() {
return (
<UserProvider value={this.state.user}>
<div>
<Menu>
<MenuItem link="/articles" children="Articles" />
<MenuItem link="/filters">Filters</MenuItem>
<MenuItem link="/counter">Counter</MenuItem>
<MenuItem link="/comments">Comments</MenuItem>
</Menu>
<UserForm value={this.state.user} onChange={this.setUser} />
<LocalizationProvider value={this.state.localization}>
<UserProvider value={this.state.user}>
<div>
<Menu>
<MenuItem link="/articles" children="Articles" />
<MenuItem link="/filters">Filters</MenuItem>
<MenuItem link="/counter">Counter</MenuItem>
<MenuItem link="/comments">Comments</MenuItem>
</Menu>
<UserForm value={this.state.user} onChange={this.setUser} />
<Language onChange={this.setLang} lang={this.state.lang} />

<Switch>
<Redirect from="/" exact to="/articles" />
<Route path="/counter" component={Counter} exact />
<Route path="/comments" component={CommentsPage} />
<Route path="/filters" component={Filters} />
<Route
path="/articles/new"
render={() => <h1>New Article Page</h1>}
/>
<Route path="/articles" component={ArticlesPage} />
<Route path="/error" render={() => <h1>Error Page</h1>} />
<Route path="*" render={() => <h1>Not Found Page</h1>} />
</Switch>
</div>
</UserProvider>
<Switch>
<Redirect from="/" exact to="/articles" />
<Route path="/counter" component={Counter} exact />
<Route path="/comments" component={CommentsPage} />
<Route path="/filters" component={Filters} />
<Route
path="/articles/new"
render={() => (
<h1>{this.state.localization.new_article_page}</h1>
)}
/>
<Route path="/articles" component={ArticlesPage} />
<Route
path="/error"
render={() => <h1>{this.state.localization.error_page}</h1>}
/>
<Route
path="*"
render={() => <h1>{this.state.localization.not_found_page}</h1>}
/>
</Switch>
</div>
</UserProvider>
</LocalizationProvider>
)
}
}
Expand Down
16 changes: 14 additions & 2 deletions src/components/article/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { deleteArticle, loadArticleById } from '../../ac'
import './style.css'
import Loader from '../common/loader'
import { articleSelector } from '../../selectors'
import { Consumer as LocalizationConsumer } from '../../contexts/localization'

class Article extends PureComponent {
static propTypes = {
Expand Down Expand Up @@ -41,7 +42,13 @@ class Article extends PureComponent {
<div>
<h3>
{article.title}
<button onClick={this.handleDeleteClick}>delete me</button>
<LocalizationConsumer>
{(localization) => (
<button onClick={this.handleDeleteClick}>
{localization.delete_me}
</button>
)}
</LocalizationConsumer>
</h3>
<CSSTransition
transitionAppear
Expand All @@ -64,7 +71,12 @@ class Article extends PureComponent {
get body() {
const { isOpen, article } = this.props
if (!isOpen) return null
if (this.state.error) return <h3>Error</h3>
if (this.state.error)
return (
<LocalizationConsumer>
{(localization) => <h3>{localization.error}</h3>}
</LocalizationConsumer>
)
if (article.loading) return <Loader />

return (
Expand Down
19 changes: 16 additions & 3 deletions src/components/comment-form/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React, { Component } from 'react'
import { connect } from 'react-redux'
import { addComment } from '../../ac'
import './style.css'
import { Consumer as LocalizationConsumer } from '../../contexts/localization'

class CommentForm extends Component {
static propTypes = {}
Expand All @@ -14,19 +15,31 @@ class CommentForm extends Component {
render() {
return (
<form onSubmit={this.handleSubmit}>
user:{' '}
<LocalizationConsumer>
{(localization) => <label>{localization.user}: </label>}
</LocalizationConsumer>
<input
value={this.state.user}
onChange={this.handleChange('user')}
className={this.getClassName('user')}
/>
comment:{' '}
<LocalizationConsumer>
{(localization) => <label>{localization.comment}: </label>}
</LocalizationConsumer>
<input
value={this.state.text}
onChange={this.handleChange('text')}
className={this.getClassName('text')}
/>
<input type="submit" value="submit" disabled={!this.isValidForm()} />
<LocalizationConsumer>
{(localization) => (
<input
type="submit"
value={localization.publish}
disabled={!this.isValidForm()}
/>
)}
</LocalizationConsumer>
</form>
)
}
Expand Down
30 changes: 24 additions & 6 deletions src/components/comment-list/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { loadArticleComments } from '../../ac'
import './style.css'
import Loader from '../common/loader'
import { Consumer as UserConsumer } from '../../contexts/user'
import { Consumer as LocalizationConsumer } from '../../contexts/localization'

class CommentList extends Component {
static propTypes = {
Expand Down Expand Up @@ -37,12 +38,15 @@ class CommentList extends Component {

render() {
const { isOpen, toggleOpen } = this.props
const text = isOpen ? 'hide comments' : 'show comments'
return (
<div>
<button onClick={toggleOpen} className="test__comment-list--btn">
{text}
</button>
<LocalizationConsumer>
{(localization) => (
<button onClick={toggleOpen} className="test__comment-list--btn">
{isOpen ? localization.hide_comments : localization.show_comments}
</button>
)}
</LocalizationConsumer>
<CSSTransition
transitionName="comments"
transitionEnterTimeout={500}
Expand All @@ -66,12 +70,26 @@ class CommentList extends Component {
return (
<div className="test__comment-list--body">
<UserConsumer>
{(username) => <h3>Username: {username}</h3>}
{(username) => (
<LocalizationConsumer>
{(localization) => (
<h3>
{localization.username}: {username}
</h3>
)}
</LocalizationConsumer>
)}
</UserConsumer>
{comments.length ? (
this.comments
) : (
<h3 className="test__comment-list--empty">No comments yet</h3>
<LocalizationConsumer>
{(localization) => (
<h3 className="test__comment-list--empty">
{localization.no_comments_yet}
</h3>
)}
</LocalizationConsumer>
)}
<CommentForm articleId={id} />
</div>
Expand Down
14 changes: 11 additions & 3 deletions src/components/comment.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,20 @@ import React from 'react'
import PropTypes from 'prop-types'
import { connect } from 'react-redux'
import { createCommentSelector } from '../selectors'
import { Consumer as LocalizationConsumer } from '../contexts/localization'

function Comment({ comment }) {
return (
<div>
{comment.text} <b>by {comment.user}</b>
</div>
<LocalizationConsumer>
{(localization) => (
<div>
{comment.text}{' '}
<b>
{localization.by} {comment.user}
</b>
</div>
)}
</LocalizationConsumer>
)
}

Expand Down
7 changes: 6 additions & 1 deletion src/components/common/loader.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
import React from 'react'
import { Consumer as LocalizationConsumer } from '../../contexts/localization'

function Loader() {
return <h3>Loading...</h3>
return (
<LocalizationConsumer>
{(localization) => <h3>{localization.loading}</h3>}
</LocalizationConsumer>
)
}

Loader.propTypes = {}
Expand Down
7 changes: 6 additions & 1 deletion src/components/counter.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React, { Component } from 'react'
import PropTypes from 'prop-types'
import { connect } from 'react-redux'
import { increment } from '../ac'
import { Consumer as LocalizationConsumer } from '../contexts/localization'

class Counter extends Component {
static propTypes = {
Expand All @@ -13,7 +14,11 @@ class Counter extends Component {
return (
<div>
<h2>{this.props.count}</h2>
<button onClick={this.handleClick}>increment</button>
<LocalizationConsumer>
{(localization) => (
<button onClick={this.handleClick}>{localization.increment}</button>
)}
</LocalizationConsumer>
</div>
)
}
Expand Down
18 changes: 12 additions & 6 deletions src/components/filters/select.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import Select from 'react-select'
import { connect } from 'react-redux'
import { changeSelection } from '../../ac'
import { articleListSelector, selectionSelector } from '../../selectors'
import { Consumer as LocalizationConsumer } from '../../contexts/localization'

class SelectFilter extends Component {
static propTypes = {
Expand All @@ -23,12 +24,17 @@ class SelectFilter extends Component {

render() {
return (
<Select
options={this.options}
value={this.props.selected}
onChange={this.handleChange}
isMulti
/>
<LocalizationConsumer>
{(localization) => (
<Select
options={this.options}
value={this.props.selected}
onChange={this.handleChange}
isMulti
placeholder={localization.select_placeholder}
/>
)}
</LocalizationConsumer>
)
}
}
Expand Down
30 changes: 30 additions & 0 deletions src/components/language.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import React, { Component } from 'react'

export default class Language extends Component {
render() {
return (
<div>
<div onChange={this.handleChange.bind(this)}>
<input
type="radio"
value="ru"
name="lang"
checked={this.props.lang === 'ru'}
/>{' '}
RU
<input
type="radio"
value="en"
name="lang"
checked={this.props.lang === 'en'}
/>{' '}
EN
</div>
</div>
)
}

handleChange = (event) => {
this.props.onChange(event.target.value)
}
}
5 changes: 4 additions & 1 deletion src/components/menu/index.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
import React, { Component } from 'react'
import MenuItem from './menu-item'
import { Consumer as LocalizationConsumer } from '../../contexts/localization'

class Menu extends Component {
static propTypes = {}

render() {
return (
<div>
<h2>Main Menu</h2>
<LocalizationConsumer>
{(localization) => <h2>{localization.main_menu}</h2>}
</LocalizationConsumer>
<nav>{this.props.children}</nav>
</div>
)
Expand Down
8 changes: 7 additions & 1 deletion src/components/routes/articles-page.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React, { Component, Fragment } from 'react'
import ArticleList from '../article-list'
import { Route } from 'react-router-dom'
import Article from '../article'
import { Consumer as LocalizationConsumer } from '../../contexts/localization'

class ArticlesPage extends Component {
static propTypes = {}
Expand All @@ -21,7 +22,12 @@ class ArticlesPage extends Component {
getArticle = ({ match }) => {
console.log('---', 'article match: ', match)

if (!match) return <h1>Please Select An Article</h1>
if (!match)
return (
<LocalizationConsumer>
{(localization) => <h1>{localization.please_select_an_article}</h1>}
</LocalizationConsumer>
)

const { id } = match.params
return <Article id={id} key={id} isOpen />
Expand Down
Loading