TODO App wtih React (UI)

TODO app using Redux and React

by Pratik Bhattachary

HTML

<!DOCTYPE html>
<html>
  <meta name="description" content="TODO App using Redux">
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>TODO Redux</title>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/redux/4.0.0/redux.js" type="text/javascript"></script>
  <script src="https://fb.me/react-0.14.3.js"></script>
  <script src="https://fb.me/react-dom-0.14.3.js"></script>
  <script src="https://unpkg.com/expect@%3C21/umd/expect.min.js"></script>

  <body>
    <div id="root"></div>

  </body>

</html>

Babel + JSX

const todo = (state, action) => {
	switch(action.type) {
		case 'ADD_TODO': return {
			id: action.id,
			text: action.text,
			completed: false
		}
		case 'TOGGLE_TODO': 
			if (state.id === action.id)
				return Object.assign({}, state, { completed: !state.completed });
			return state;
		default: return state;
	}
};

const todos = (state = [], action) => {
	switch(action.type) {
		case 'ADD_TODO': 
			return [
				...state,
				todo(undefined, action)
			];
		case 'TOGGLE_TODO': {
			return state.map(t => todo(t, action));
		}
		default:
			return state;
	}
};

const visibilityFilter = (
	state = 'SHOW_ALL',
	action
) => {
	switch(action.type) {
		case 'SET_VISIBILITY_FILTER':
			return action.filter;
		default:
			return state;
	}
}

const { combineReducers } = Redux;
const { createStore } = Redux;
const { Component } = React;

const todoApp = combineReducers({
	todos, visibilityFilter
});

const store = createStore(todoApp);

const FilterLink = ({
	filter,
  currentFilter,
  children
}) => {
	if (filter === currentFilter) {
  	return <span>{children}</span>
  }
	return (
  	<a href='#' 
      onClick = {e => {
      	e.preventDefault();
        store.dispatch({
        	type: 'SET_VISIBILITY_FILTER',
          filter
        })
      }} >
      {children}
      </a>
  )
}

const getVisibleTodos = (
	todos,
  filter
) => {
	switch (filter) {
  	case 'SHOW_ALL':
    	return todos;
    case 'SHOW_COMPLETED':
    	return todos.filter(t => t.completed)
    case 'SHOW_ACTIVE':
    	return todos.filter(t => !t.completed)
    default:
    	return todos;
  }
}

let nextTodoId = 0;
class TodoApp extends Component {
 render() {
 const visibleTodos = getVisibleTodos(
 		this.props.todos,
    this.props.visibilityFilter
 );
 	return (
  	<div>
      <input ref={node => {
      	this.input = node;
      }} />
  	  <button onClick={() => {
      	store.dispatch({
        	type: 'ADD_TODO',
          text: this.input.value,
          id: nextTodoId++
        });
       ...