This repository has been archived by the owner on Dec 2, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 31
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
28 changed files
with
699 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
import * as types from '../constants/ActionTypes' | ||
|
||
export function addTodo(text) { | ||
return { type: types.ADD_TODO, text } | ||
} | ||
|
||
export function deleteTodo(id) { | ||
return { type: types.DELETE_TODO, id } | ||
} | ||
|
||
export function editTodo(id, text) { | ||
return { type: types.EDIT_TODO, id, text } | ||
} | ||
|
||
export function completeTodo(id) { | ||
return { type: types.COMPLETE_TODO, id } | ||
} | ||
|
||
export function completeAll() { | ||
return { type: types.COMPLETE_ALL } | ||
} | ||
|
||
export function clearCompleted() { | ||
return { type: types.CLEAR_COMPLETED } | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
import React, { PropTypes, Component } from 'react' | ||
import classnames from 'classnames' | ||
import { SHOW_ALL, SHOW_COMPLETED, SHOW_ACTIVE } from '../constants/TodoFilters' | ||
|
||
const FILTER_TITLES = { | ||
[SHOW_ALL]: 'All', | ||
[SHOW_ACTIVE]: 'Active', | ||
[SHOW_COMPLETED]: 'Completed' | ||
} | ||
|
||
class Footer extends Component { | ||
renderTodoCount() { | ||
const { activeCount } = this.props | ||
const itemWord = activeCount === 1 ? 'item' : 'items' | ||
|
||
return ( | ||
<span className="todo-count"> | ||
<strong>{activeCount || 'No'}</strong> {itemWord} left | ||
</span> | ||
) | ||
} | ||
|
||
renderFilterLink(filter) { | ||
const title = FILTER_TITLES[filter] | ||
const { filter: selectedFilter, onShow } = this.props | ||
|
||
return ( | ||
<a className={classnames({ selected: filter === selectedFilter })} | ||
style={{ cursor: 'pointer' }} | ||
onClick={() => onShow(filter)}> | ||
{title} | ||
</a> | ||
) | ||
} | ||
|
||
renderClearButton() { | ||
const { completedCount, onClearCompleted } = this.props | ||
if (completedCount > 0) { | ||
return ( | ||
<button className="clear-completed" | ||
onClick={onClearCompleted} > | ||
Clear completed | ||
</button> | ||
) | ||
} | ||
} | ||
|
||
render() { | ||
return ( | ||
<footer className="footer"> | ||
{this.renderTodoCount()} | ||
<ul className="filters"> | ||
{[ SHOW_ALL, SHOW_ACTIVE, SHOW_COMPLETED ].map(filter => | ||
<li key={filter}> | ||
{this.renderFilterLink(filter)} | ||
</li> | ||
)} | ||
</ul> | ||
{this.renderClearButton()} | ||
</footer> | ||
) | ||
} | ||
} | ||
|
||
Footer.propTypes = { | ||
completedCount: PropTypes.number.isRequired, | ||
activeCount: PropTypes.number.isRequired, | ||
filter: PropTypes.string.isRequired, | ||
onClearCompleted: PropTypes.func.isRequired, | ||
onShow: PropTypes.func.isRequired | ||
} | ||
|
||
export default Footer |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import React, { PropTypes, Component } from 'react' | ||
import TodoTextInput from './TodoTextInput' | ||
|
||
class Header extends Component { | ||
handleSave(text) { | ||
if (text.length !== 0) { | ||
this.props.addTodo(text) | ||
} | ||
} | ||
|
||
render() { | ||
return ( | ||
<header className="header"> | ||
<h1>todos</h1> | ||
<TodoTextInput newTodo | ||
onSave={this.handleSave.bind(this)} | ||
placeholder="What needs to be done?" /> | ||
</header> | ||
) | ||
} | ||
} | ||
|
||
Header.propTypes = { | ||
addTodo: PropTypes.func.isRequired | ||
} | ||
|
||
export default Header |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
import React, { Component, PropTypes } from 'react' | ||
import TodoItem from './TodoItem' | ||
import Footer from './Footer' | ||
import { SHOW_ALL, SHOW_COMPLETED, SHOW_ACTIVE } from '../constants/TodoFilters' | ||
|
||
const TODO_FILTERS = { | ||
[SHOW_ALL]: () => true, | ||
[SHOW_ACTIVE]: todo => !todo.completed, | ||
[SHOW_COMPLETED]: todo => todo.completed | ||
} | ||
|
||
class MainSection extends Component { | ||
constructor(props, context) { | ||
super(props, context) | ||
this.state = { filter: SHOW_ALL } | ||
} | ||
|
||
handleClearCompleted() { | ||
const atLeastOneCompleted = this.props.todos.some(todo => todo.completed) | ||
if (atLeastOneCompleted) { | ||
this.props.actions.clearCompleted() | ||
} | ||
} | ||
|
||
handleShow(filter) { | ||
this.setState({ filter }) | ||
} | ||
|
||
renderToggleAll(completedCount) { | ||
const { todos, actions } = this.props | ||
if (todos.length > 0) { | ||
return ( | ||
<input className="toggle-all" | ||
type="checkbox" | ||
checked={completedCount === todos.length} | ||
onChange={actions.completeAll} /> | ||
) | ||
} | ||
} | ||
|
||
renderFooter(completedCount) { | ||
const { todos } = this.props | ||
const { filter } = this.state | ||
const activeCount = todos.length - completedCount | ||
|
||
if (todos.length) { | ||
return ( | ||
<Footer completedCount={completedCount} | ||
activeCount={activeCount} | ||
filter={filter} | ||
onClearCompleted={this.handleClearCompleted.bind(this)} | ||
onShow={this.handleShow.bind(this)} /> | ||
) | ||
} | ||
} | ||
|
||
render() { | ||
const { todos, actions } = this.props | ||
const { filter } = this.state | ||
|
||
const filteredTodos = todos.filter(TODO_FILTERS[filter]) | ||
const completedCount = todos.reduce((count, todo) => | ||
todo.completed ? count + 1 : count, | ||
0 | ||
) | ||
|
||
return ( | ||
<section className="main"> | ||
{this.renderToggleAll(completedCount)} | ||
<ul className="todo-list"> | ||
{filteredTodos.map(todo => | ||
<TodoItem key={todo._id} todo={todo} {...actions} /> | ||
)} | ||
</ul> | ||
{this.renderFooter(completedCount)} | ||
</section> | ||
) | ||
} | ||
} | ||
|
||
MainSection.propTypes = { | ||
todos: PropTypes.array.isRequired, | ||
actions: PropTypes.object.isRequired | ||
} | ||
|
||
export default MainSection |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import React, { PropTypes, Component } from 'react' | ||
import classnames from 'classnames' | ||
import { SHOW_ALL, SHOW_COMPLETED, SHOW_ACTIVE } from '../constants/TodoFilters' | ||
|
||
class SyncStatus extends Component { | ||
|
||
render() { | ||
const { text } = this.props.status | ||
return ( | ||
<p style={{padding: "1em"}}> | ||
syncStatus: {text} | ||
</p> | ||
) | ||
} | ||
} | ||
|
||
export default SyncStatus |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
import React, { Component, PropTypes } from 'react' | ||
import classnames from 'classnames' | ||
import TodoTextInput from './TodoTextInput' | ||
|
||
class TodoItem extends Component { | ||
constructor(props, context) { | ||
super(props, context) | ||
this.state = { | ||
editing: false | ||
} | ||
} | ||
|
||
handleDoubleClick() { | ||
this.setState({ editing: true }) | ||
} | ||
|
||
handleSave(id, text) { | ||
if (text.length === 0) { | ||
this.props.deleteTodo(id) | ||
} else { | ||
this.props.editTodo(id, text) | ||
} | ||
this.setState({ editing: false }) | ||
} | ||
|
||
render() { | ||
const { todo, completeTodo, deleteTodo } = this.props | ||
|
||
let element | ||
if (this.state.editing) { | ||
element = ( | ||
<TodoTextInput text={todo.text} | ||
editing={this.state.editing} | ||
onSave={(text) => this.handleSave(todo._id, text)} /> | ||
) | ||
} else { | ||
element = ( | ||
<div className="view"> | ||
<input className="toggle" | ||
type="checkbox" | ||
checked={todo.completed} | ||
onChange={() => completeTodo(todo._id)} /> | ||
<label onDoubleClick={this.handleDoubleClick.bind(this)}> | ||
{todo.text} | ||
</label> | ||
<button className="destroy" | ||
onClick={() => deleteTodo(todo._id)} /> | ||
</div> | ||
) | ||
} | ||
|
||
return ( | ||
<li className={classnames({ | ||
completed: todo.completed, | ||
editing: this.state.editing | ||
})}> | ||
{element} | ||
</li> | ||
) | ||
} | ||
} | ||
|
||
TodoItem.propTypes = { | ||
todo: PropTypes.object.isRequired, | ||
editTodo: PropTypes.func.isRequired, | ||
deleteTodo: PropTypes.func.isRequired, | ||
completeTodo: PropTypes.func.isRequired | ||
} | ||
|
||
export default TodoItem |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
import React, { Component, PropTypes } from 'react' | ||
import classnames from 'classnames' | ||
|
||
class TodoTextInput extends Component { | ||
constructor(props, context) { | ||
super(props, context) | ||
this.state = { | ||
text: this.props.text || '' | ||
} | ||
} | ||
|
||
handleSubmit(e) { | ||
const text = e.target.value.trim() | ||
if (e.which === 13) { | ||
this.props.onSave(text) | ||
if (this.props.newTodo) { | ||
this.setState({ text: '' }) | ||
} | ||
} | ||
} | ||
|
||
handleChange(e) { | ||
this.setState({ text: e.target.value }) | ||
} | ||
|
||
handleBlur(e) { | ||
if (!this.props.newTodo) { | ||
this.props.onSave(e.target.value) | ||
} | ||
} | ||
|
||
render() { | ||
return ( | ||
<input className={ | ||
classnames({ | ||
edit: this.props.editing, | ||
'new-todo': this.props.newTodo | ||
})} | ||
type="text" | ||
placeholder={this.props.placeholder} | ||
autoFocus="true" | ||
value={this.state.text} | ||
onBlur={this.handleBlur.bind(this)} | ||
onChange={this.handleChange.bind(this)} | ||
onKeyDown={this.handleSubmit.bind(this)} /> | ||
) | ||
} | ||
} | ||
|
||
TodoTextInput.propTypes = { | ||
onSave: PropTypes.func.isRequired, | ||
text: PropTypes.string, | ||
placeholder: PropTypes.string, | ||
editing: PropTypes.bool, | ||
newTodo: PropTypes.bool | ||
} | ||
|
||
export default TodoTextInput |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
export const ERROR = 'ERROR' | ||
export const ADD_TODO = 'ADD_TODO' | ||
export const INSERT_TODO = 'INSERT_TODO' | ||
export const DELETE_TODO = 'DELETE_TODO' | ||
export const EDIT_TODO = 'EDIT_TODO' | ||
export const UPDATE_TODO = 'UPDATE_TODO' | ||
export const COMPLETE_TODO = 'COMPLETE_TODO' | ||
export const COMPLETE_ALL = 'COMPLETE_ALL' | ||
export const CLEAR_COMPLETED = 'CLEAR_COMPLETED' | ||
export const SET_SYNC_STATE = 'SET_SYNC_STATE' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
export const SHOW_ALL = 'show_all' | ||
export const SHOW_COMPLETED = 'show_completed' | ||
export const SHOW_ACTIVE = 'show_active' |
Oops, something went wrong.