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
8 changes: 8 additions & 0 deletions .babelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"presets": ["es2015", "react"],
"env": {
"development": {
"presets": ["react-hmre"]
}
}
}
8 changes: 8 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
.idea
/*.env
node_modules
public/
dist/
static/
npm-debug.log
libs/
51 changes: 0 additions & 51 deletions README.md

This file was deleted.

226 changes: 226 additions & 0 deletions actions/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,226 @@
import * as types from '../constants/ActionTypes'
import fetch from 'isomorphic-fetch'
// require('es6-promise').polyfill();

// export function addTodo(text) {
// return {type: types.ADD_TODO, text}
// }

export function verticalStart(target) {
return {
type: types.VERTICAL_STARTED,
verticalSwipe: {
state: true,
target
}
}
}

export function verticalMove(target, offset) {
return {
type: types.VERTICAL_MOVED,
verticalSwipe: {
state: true,
target,
offset: offset[0]
}
}
}

export function verticalStop(target, offset) {
return {
type: types.VERTICAL_STOPPED,
verticalSwipe: {
state: false,
target,
offset: offset[0]
}
}
}

export function horizontalStart(target) {
return {
type: types.HORIZONTAL_STARTED,
horizontalSwipe: {
state: true,
target
}
}
}

export function horizontalMove(target, offset) {
return {
type: types.HORIZONTAL_MOVED,
horizontalSwipe: {
state: true,
target,
offset: offset[0]
}
}
}

export function horizontalStop(target, offset) {
return {
type: types.HORIZONTAL_STOPPED,
horizontalSwipe: {
state: false,
target,
offset: offset[0]
}
}
}

export function tap(target) {
return {
type: types.TAPPED,
tap: {
target
}
}
}

export function todoAdded(json) {
return {
type: types.TODO_ADDED,
status: json.status,
todo: json.userTodo
}
}

export function addTodo(text) {
return dispatch => {
return fetch('/api/todos', {
credentials: 'same-origin',
method: 'post',
headers: {
"Content-type": "application/x-www-form-urlencoded; charset=UTF-8"
},
body: `text=${text}`
})
.then(function (response) {
return response.json();
})
.then(json => {
dispatch(todoAdded(json));
})
}
}

// export function deleteTodo(id) {
// return {type: types.DELETE_TODO, id}
// }

export function todoDeleted(json) {
return {
type: types.TODO_DELETED,
status: json.status,
todo: json.userTodo
}
}

export function deleteTodo(id) {
return dispatch => {
return fetch(`/api/todos/${id}`, {
credentials: 'same-origin',
method: 'delete'
})
.then(function (response) {
return response.json();
})
.then(json => {
dispatch(todoDeleted(json));
})
}
}

// export function editTodo(id, text) {
// return {type: types.EDIT_TODO, id, text}
// }

export function todoEdited(json) {
return {
type: types.TODO_EDITED,
status: json.status,
todo: json.userTodo
}
}

export function editTodo(id, text) {
return dispatch => {
return fetch(`/api/todos/${id}`, {
credentials: 'same-origin',
method: 'put',
headers: {
"Content-type": "application/x-www-form-urlencoded; charset=UTF-8"
},
mode: 'cors',
body: `text=${text}`
})
.then(function (response) {
return response.json();
})
.then(json => {
dispatch(todoEdited(json));
})
}
}

// export function invalidateReddit(reddit) {
// return {
// type: INVALIDATE_REDDIT,
// reddit
// }
// }

function requestTodos() {
return {
type: types.REQUEST_TODOS
}
}

function receiveTodos(json) {
return {
type: types.RECEIVE_TODOS,
status: json.status, // ok | failed
todos: json.userTodo,
receivedAt: Date.now()
}
}

export function fetchTodos() {
return dispatch => {
dispatch(requestTodos());
return fetch(`/api/todos/`, {
credentials: 'same-origin'
})
.then(response => {
return response.json();
})
.then(json => {
console.log(json);
return json;
})
.then(json => {
dispatch(receiveTodos(json));
})
}
}

// function shouldFetchTodos(state) {
// const posts = state.postsByReddit[reddit];
// if (!posts) {
// return true
// }
// if (posts.isFetching) {
// return false
// }
// return posts.didInvalidate
// }
//
// export function fetchTodosIfNeeded() {
// return (dispatch, getState) => {
// if (shouldFetchTodos(getState())) {
// return dispatch(fetchTodos())
// }
// }
// }
28 changes: 28 additions & 0 deletions components/Footer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import React, {PropTypes, Component} from 'react'
import TodoTextInput from './TodoTextInput'
import classnames from 'classnames'

class Footer extends Component {
handleSave(text) {
if (text.length !== 0) {
this.props.addTodo(text);
}
}
render() {
return (
<footer className="todo-app__footer">
<TodoTextInput
newTodo
onSave={this.handleSave.bind(this)}
placeholder="What needs to be done?"
/>
</footer>
)
}
}

Footer.propTypes = {
addTodo: PropTypes.func.isRequired
};

export default Footer
12 changes: 12 additions & 0 deletions components/Header.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import React, {PropTypes, Component} from 'react'

class Header extends Component {
render() {
return (
<header className="todo-app__header">
<h1>Todo App</h1>
</header>
)
}
}
export default Header
28 changes: 28 additions & 0 deletions components/MainSection.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import React, {Component, PropTypes} from 'react'
import TodoItem from './TodoItem'

class MainSection extends Component {
constructor(props, context) {
super(props, context);
}

render() {
const {todos, swipe, actions} = this.props;

return (
<section className="todo-app">
{todos.map(todo =>
<TodoItem key={todo.id} todo={todo} swipe={swipe} {...actions} />
)}
</section>
)
}
}

MainSection.propTypes = {
todos: PropTypes.array.isRequired,
swipe: PropTypes.object.isRequired,
actions: PropTypes.object.isRequired
};

export default MainSection
Loading