Speedometer: Add a React + Redux TodoMVC implementation
[WebKit-https.git] / PerformanceTests / Speedometer / resources / todomvc / architecture-examples / react-redux / src / components / MainSection.js
1 import React, { Component, PropTypes } from 'react'
2 import TodoItem from './TodoItem'
3 import Footer from './Footer'
4 import { SHOW_ALL, SHOW_COMPLETED, SHOW_ACTIVE } from '../constants/TodoFilters'
5
6 const TODO_FILTERS = {
7   [SHOW_ALL]: () => true,
8   [SHOW_ACTIVE]: todo => !todo.completed,
9   [SHOW_COMPLETED]: todo => todo.completed
10 }
11
12 export default class MainSection extends Component {
13   static propTypes = {
14     todos: PropTypes.array.isRequired,
15     actions: PropTypes.object.isRequired
16   }
17
18   state = { filter: SHOW_ALL }
19
20   handleClearCompleted = () => {
21     this.props.actions.clearCompleted()
22   }
23
24   handleShow = filter => {
25     this.setState({ filter })
26   }
27
28   renderToggleAll(completedCount) {
29     const { todos, actions } = this.props
30     if (todos.length > 0) {
31       return (
32         <input className="toggle-all"
33                type="checkbox"
34                checked={completedCount === todos.length}
35                onChange={actions.completeAll} />
36       )
37     }
38   }
39
40   renderFooter(completedCount) {
41     const { todos } = this.props
42     const { filter } = this.state
43     const activeCount = todos.length - completedCount
44
45     if (todos.length) {
46       return (
47         <Footer completedCount={completedCount}
48                 activeCount={activeCount}
49                 filter={filter}
50                 onClearCompleted={this.handleClearCompleted.bind(this)}
51                 onShow={this.handleShow.bind(this)} />
52       )
53     }
54   }
55
56   render() {
57     const { todos, actions } = this.props
58     const { filter } = this.state
59
60     const filteredTodos = todos.filter(TODO_FILTERS[filter])
61     const completedCount = todos.reduce((count, todo) =>
62       todo.completed ? count + 1 : count,
63       0
64     )
65
66     return (
67       <section className="main">
68         {this.renderToggleAll(completedCount)}
69         <ul className="todo-list">
70           {filteredTodos.map(todo =>
71             <TodoItem key={todo.id} todo={todo} {...actions} />
72           )}
73         </ul>
74         {this.renderFooter(completedCount)}
75       </section>
76     )
77   }
78 }