Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Homework - 3 #29

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
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
6,926 changes: 3,463 additions & 3,463 deletions package-lock.json

Large diffs are not rendered by default.

9 changes: 8 additions & 1 deletion src/ac/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { INCREMENT, DELETE_ARTICLE } from '../constants'
import { INCREMENT, DELETE_ARTICLE, SET_FILTER } from '../constants'

export function increment() {
return {
Expand All @@ -12,3 +12,10 @@ export function deleteArticle(id) {
payload: { id }
}
}

export function setFilter(filter) {
Copy link
Owner

Choose a reason for hiding this comment

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

Лучше отдельно обрабатывать селект и дату, я бы делал 2 отдельных AC

return {
type: SET_FILTER,
payload: filter
}
}
2 changes: 1 addition & 1 deletion src/components/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ class App extends Component {
<div>
<UserForm />
<Counter />
<Filters articles={[]} />
<Filters />
<ArticleList />
</div>
)
Expand Down
9 changes: 7 additions & 2 deletions src/components/article-list.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import PropTypes from 'prop-types'
import { connect } from 'react-redux'
import Article from './article'
import accordionDecorator from '../decorators/accordion'
import filterDecorator from '../decorators/filter'

export class ArticleList extends Component {
static propTypes = {
Expand Down Expand Up @@ -38,7 +39,11 @@ export class ArticleList extends Component {
}

const ArticleListWithAccordion = accordionDecorator(ArticleList)
const ArticleListWithAccordionAndFilter = accordionDecorator(
filterDecorator(ArticleList, 'articles')
)

export default connect((state) => ({
articles: state.articles
}))(ArticleListWithAccordion)
articles: state.articles,
filter: state.filter
}))(ArticleListWithAccordionAndFilter)
3 changes: 3 additions & 0 deletions src/components/article/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ class Article extends PureComponent {
<div>
<h3>
{article.title}
<div>
<i>Date: {article.date}</i>
</div>
<button onClick={this.handleClick} className="test--article__btn">
{isOpen ? 'close' : 'open'}
</button>
Expand Down
11 changes: 4 additions & 7 deletions src/components/filters/date-range.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,13 @@ import DayPicker, { DateUtils } from 'react-day-picker'
import 'react-day-picker/lib/style.css'

class DateRange extends Component {
state = {
from: null,
to: null
handleDayClick = (day) => {
const { setFilter, dateRange } = this.props
setFilter({ dateRange: DateUtils.addDayToRange(day, dateRange) })
}

handleDayClick = (day) =>
this.setState(DateUtils.addDayToRange(day, this.state))

render() {
const { from, to } = this.state
const { from, to } = this.props.dateRange
const selectedRange =
from && to && `${from.toDateString()} - ${to.toDateString()}`
return (
Expand Down
21 changes: 18 additions & 3 deletions src/components/filters/index.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,33 @@
import React, { Component } from 'react'
import DateRange from './date-range'
import SelectFilter from './select'
import { connect } from 'react-redux'
import { setFilter } from '../../ac'

class Filters extends Component {
static propTypes = {}

render() {
const { articles, setFilter, dateRange, selected } = this.props

return (
<div>
<SelectFilter articles={this.props.articles} />
<DateRange />
<SelectFilter
setFilter={setFilter}
options={articles || []}
selected={selected}
/>
<DateRange setFilter={setFilter} dateRange={dateRange} />
</div>
)
}
}

export default Filters
export default connect(
(state) => ({
selected: state.filter.selected,
dateRange: state.filter.dateRange,
articles: state.articles
}),
{ setFilter }
)(Filters)
13 changes: 7 additions & 6 deletions src/components/filters/select.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,25 @@ import React, { Component } from 'react'
import Select from 'react-select'

class SelectFilter extends Component {
state = {
selected: null
handleChange = (selected) => {
const { setFilter } = this.props
setFilter({ selected })
}

handleChange = (selected) => this.setState({ selected })

get options() {
return this.props.articles.map((article) => ({
const { options } = this.props
return options.map((article) => ({
label: article.title,
value: article.id
}))
}

render() {
const { selected } = this.props
return (
<Select
options={this.options}
value={this.state.selected}
value={selected}
onChange={this.handleChange}
isMulti
/>
Expand Down
2 changes: 2 additions & 0 deletions src/constants/index.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
export const INCREMENT = 'INCREMENT'

export const DELETE_ARTICLE = 'DELETE_ARTICLE'

export const SET_FILTER = 'SET_FILTER'
70 changes: 70 additions & 0 deletions src/decorators/filter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import React, { Component } from 'react'

const filterDecorator = (OriginalComponent, listName) =>
Copy link
Owner

Choose a reason for hiding this comment

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

Идея хорошая, но немного оверхед. Покажу как проще можно было

class FilterDecorator extends Component {
getFilteredList() {
const list = this.props[listName]
let filteredList = [...list]

const { filter } = this.props
const rangeFilter = filter.dateRange
const selectFilter = filter.selected

if (selectFilter && selectFilter.length) {
filteredList = this.toApplySelectFilter(filteredList, selectFilter)
}

if (rangeFilter) {
filteredList = this.toApplyRangeFilter(filteredList, rangeFilter)
}

return filteredList
}

toApplySelectFilter(list, selected) {
return list.filter((item) =>
selected.find((selectedItem) => selectedItem.value === item.id)
)
}

toApplyRangeFilter(list, rangeFilter) {
const { from = null, to = null } = rangeFilter

//convert to ISOString if it's not in the format
const fromInISO =
from && typeof from !== 'string' ? from.toISOString() : from
const toInISO = to && typeof to !== 'string' ? to.toISOString() : to

if (fromInISO || toInISO) {
return list.filter((item) => {
if (!item.date) return false

//convert to ISOString if it's not in the format
const itemDateInISO =
typeof item.date !== 'string' ? item.date.toISOString() : item.date

if (fromInISO && toInISO) {
return fromInISO <= itemDateInISO && itemDateInISO <= toInISO
} else {
if (fromInISO) {
return fromInISO <= itemDateInISO
}
if (toInISO) {
return itemDateInISO <= toInISO
}
}
})
}

return list
}

render() {
let filteredList = this.getFilteredList()
return (
<OriginalComponent {...{ ...this.props, [listName]: filteredList }} />
)
}
}

export default filterDecorator
21 changes: 21 additions & 0 deletions src/fixtures.js
Original file line number Diff line number Diff line change
Expand Up @@ -155,5 +155,26 @@ export default [
title: 'Lorem Ipsum dolor',
text:
'Commodo laborum sit nostrud reprehenderit cupidatat officia laboris. Ipsum minim culpa in enim. Voluptate dolor ea irure nisi incididunt enim magna.\n\nCupidatat quis cillum velit culpa tempor esse irure nostrud ea consectetur officia fugiat irure qui. Enim quis officia do in. Velit veniam ipsum consequat aliqua duis voluptate. Minim nisi ex aute ad.\n\nNisi Lorem ex tempor adipisicing labore. Quis occaecat fugiat pariatur labore culpa cillum laboris. Labore occaecat ut laborum sit ex do sit. Deserunt consectetur elit aute laboris est deserunt officia ullamco sit laboris officia aliquip. Aliqua ut sunt nostrud voluptate excepteur quis incididunt Lorem ut.'
},
{
id: '56c782fghgfc2c3268ddgb3206',
date: '2018-10-08T19:03:23.000Z',
title: 'New article 1',
text:
'Commodo laborum sit nostrud reprehenderit cupidatat officia laboris. Ipsum minim culpa in enim. Voluptate dolor ea irure nisi incididunt enim magna.\n\nCupidatat quis cillum velit culpa tempor esse irure nostrud ea consectetur officia fugiat irure qui. Enim quis officia do in. Velit veniam ipsum consequat aliqua duis voluptate. Minim nisi ex aute ad.\n\nNisi Lorem ex tempor adipisicing labore. Quis occaecat fugiat pariatur labore culpa cillum laboris. Labore occaecat ut laborum sit ex do sit. Deserunt consectetur elit aute laboris est deserunt officia ullamco sit laboris officia aliquip. Aliqua ut sunt nostrud voluptate excepteur quis incididunt Lorem ut.'
},
{
id: '56c782fghgfc2c32e68ddb3206',
date: '2018-10-08T19:03:23.000Z',
title: 'New article 2',
text:
'Commodo laborum sit nostrud reprehenderit cupidatat officia laboris. Ipsum minim culpa in enim. Voluptate dolor ea irure nisi incididunt enim magna.\n\nCupidatat quis cillum velit culpa tempor esse irure nostrud ea consectetur officia fugiat irure qui. Enim quis officia do in. Velit veniam ipsum consequat aliqua duis voluptate. Minim nisi ex aute ad.\n\nNisi Lorem ex tempor adipisicing labore. Quis occaecat fugiat pariatur labore culpa cillum laboris. Labore occaecat ut laborum sit ex do sit. Deserunt consectetur elit aute laboris est deserunt officia ullamco sit laboris officia aliquip. Aliqua ut sunt nostrud voluptate excepteur quis incididunt Lorem ut.'
},
{
id: '56c782fghgfc2c326dg8ddb3206',
date: '2018-10-08T19:03:23.000Z',
title: 'New article 3',
text:
'Commodo laborum sit nostrud reprehenderit cupidatat officia laboris. Ipsum minim culpa in enim. Voluptate dolor ea irure nisi incididunt enim magna.\n\nCupidatat quis cillum velit culpa tempor esse irure nostrud ea consectetur officia fugiat irure qui. Enim quis officia do in. Velit veniam ipsum consequat aliqua duis voluptate. Minim nisi ex aute ad.\n\nNisi Lorem ex tempor adipisicing labore. Quis occaecat fugiat pariatur labore culpa cillum laboris. Labore occaecat ut laborum sit ex do sit. Deserunt consectetur elit aute laboris est deserunt officia ullamco sit laboris officia aliquip. Aliqua ut sunt nostrud voluptate excepteur quis incididunt Lorem ut.'
}
]
16 changes: 16 additions & 0 deletions src/reducer/filter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { SET_FILTER } from '../constants'

export default (
filterState = { selected: [], dateRange: { from: null, to: null } },
action
) => {
const { type, payload } = action

switch (type) {
case SET_FILTER:
return { ...filterState, ...payload }

default:
return filterState
}
}
4 changes: 3 additions & 1 deletion src/reducer/index.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { combineReducers } from 'redux'
import counterReducer from './couter'
import articles from './articles'
import filter from './filter'

export default combineReducers({
counter: counterReducer,
articles
articles,
filter
})