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

Solution #1

Open
wants to merge 21 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
Binary file added .DS_Store
Binary file not shown.
270 changes: 145 additions & 125 deletions readme.md → README.md

Large diffs are not rendered by default.

18 changes: 18 additions & 0 deletions my-react-todo/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# See https://help.github.com/ignore-files/ for more about ignoring files.

# dependencies
/node_modules

# testing
/coverage

# production
/build

# misc
.DS_Store
.env
npm-debug.log*
yarn-debug.log*
yarn-error.log*

1 change: 1 addition & 0 deletions my-react-todo/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This project was bootstrapped with [Create React App](https://github.com/facebookincubator/create-react-app).
20 changes: 20 additions & 0 deletions my-react-todo/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"name": "my-react-todo",
"version": "0.1.0",
"private": true,
"dependencies": {
"axios": "^0.16.0",
"react": "^15.4.2",
"react-dom": "^15.4.2",
"react-router": "^3.0.0"
},
"devDependencies": {
"react-scripts": "0.9.5"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject"
}
}
Binary file added my-react-todo/public/favicon.ico
Binary file not shown.
31 changes: 31 additions & 0 deletions my-react-todo/public/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
<!--
Notice the use of %PUBLIC_URL% in the tag above.
It will be replaced with the URL of the `public` folder during the build.
Only files inside the `public` folder can be referenced from the HTML.

Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>React App</title>
</head>
<body>
<div id="root"></div>
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.

You can add webfonts, meta tags, or analytics to this file.
The build step will place the bundled scripts into the <body> tag.

To begin the development, run `npm start`.
To create a production bundle, use `npm run build`.
-->
</body>
</html>
15 changes: 15 additions & 0 deletions my-react-todo/src/App.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import React, { Component } from 'react';
import Header from './components/Header'

class App extends Component {
render() {
return (
<div className="App">
<Header />
{this.props.children}
</div>
);
}
}

export default App;
41 changes: 41 additions & 0 deletions my-react-todo/src/components/CreateTodoForm.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import React, {Component} from 'react'

class CreateTodoForm extends Component {
constructor(){
super()
//sets the initial state via the constructor! that's the constructor's job :)
this.state = {
todo: ''
}
}
onInputChange(event){
this.setState({
todo: event.target.value
})
}
onFormSubmit(event){
event.preventDefault()
let todo = this.state.todo
this.props.createTodo(todo)
this.setState({
todo: ""
})
}
render(){
return (
<div className='createForm todoForm'>
<h2>Create Todo Here!</h2>
<form onSubmit={event => this.onFormSubmit(event)}>
<input
onChange={event => this.onInputChange(event)}
placeholder='Write a todo here ...'
type='text'
value={this.state.todo} />
<button type='submit'>Create Todo!</button>
</form>
</div>
)
}
}

export default CreateTodoForm
14 changes: 14 additions & 0 deletions my-react-todo/src/components/Header.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import React, {Component} from 'react'
import {Link} from 'react-router'

class Header extends Component{
render(){
return (
<header>
<h1><Link to={'/todos'}>React Todos</Link></h1>
</header>
)
}
}

export default Header
34 changes: 34 additions & 0 deletions my-react-todo/src/components/Todo.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import React, {Component} from 'react'
import TodoForm from '../components/TodoForm'

class Todo extends Component {
render(){
if (this.props.editingTodoId === this.props.todo._id){
//if we see this console.log, we know that Todo-props are being
// passed into TodosContainer, and being set as the
// TodosContainer-state, and then trickling down as props to
// the Todo component.
console.log(`${this.props.todo.body} is being edited`);
return (
<TodoForm
autoFocus={true}
onUpdateTodo={this.props.onUpdateTodo}
buttonName="Update Todo!"/>
)
}
return(
<p data-todos-index={this.props.todo._id}>
<span onClick={() => this.props.onEditTodo(this.props.todo)}>
{this.props.todo.body}
</span>
<span
className='deleteButton'
onClick={ () => this.props.onDeleteTodo(this.props.todo) }>
(X)
</span>
</p>
)
}
}

export default Todo
35 changes: 35 additions & 0 deletions my-react-todo/src/components/TodoForm.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import React, {Component} from 'react'

class TodoForm extends Component {
onChange(event) {
this.setState({
todo: event.target.value
})
}
onSubmit(event){
event.preventDefault()
var todo = this.state.todo
console.log("todo is", todo)
this.props.onUpdateTodo(todo)
this.setState({
todo: ""
})
}
render(){
return (
<div className='todoForm'>
<form onSubmit={e => this.onSubmit(e)}>
<input
autoFocus={this.props.autoFocus}
onChange={e => this.onChange(e)}
placeholder='Write a todo here ...'
type='text'
value={(this.state && this.state.todo) || ''} />
<button type='submit'>{this.props.buttonName}</button>
</form>
</div>
)
}
}

export default TodoForm
26 changes: 26 additions & 0 deletions my-react-todo/src/components/Todos.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import React, {Component} from 'react'
import Todo from './Todo'

class Todos extends Component {
render(){
let todos = this.props.todos.map( (todo) => {
return (
<Todo
key={todo._id}
todo={todo}
editingTodoId={this.props.editingTodoId}
onEditTodo={this.props.onEditTodo}
onDeleteTodo={this.props.onDeleteTodo}
onUpdateTodo={this.props.onUpdateTodo}
/>
)
})
return(
<div className="todos">
{todos}
</div>
)
}
}

export default Todos
10 changes: 10 additions & 0 deletions my-react-todo/src/config/routes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import React from 'react'
import {Route} from 'react-router'
import App from '../App'
import TodosContainer from '../containers/TodosContainer'

module.exports = (
<Route path='/' component={App}>
<Route path='/todos' component={TodosContainer}/>
</Route>
);
69 changes: 69 additions & 0 deletions my-react-todo/src/containers/TodosContainer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import React, {Component} from 'react'
import TodoModel from '../models/Todo'
import Todos from '../components/Todos'
import CreateTodoForm from '../components/CreateTodoForm'

class TodosContainer extends Component {
constructor() {
super()
this.state = {
todos: []
}
}
componentDidMount() {
this.fetchData()
}
fetchData() {
TodoModel.all().then((res) => {
this.setState({todos: res.data.todos, todo: ''})
})
}
createTodo(todo) {
let newTodo = {
body: todo,
completed: false
}
TodoModel.create(newTodo).then((res) => {
let todos = this.state.todos
let newTodos = todos.push(res.data)
this.setState({newTodos})
})
}
deleteTodo(todo) {
TodoModel.delete(todo).then((res) => {
let todos = this.state.todos.filter(function(todo) {
return todo._id !== res.data._id
});
this.setState({todos})
})
}
updateTodo(todoBody) {
var todoId = this.state.editingTodoId
function isUpdatedTodo(todo) {
return todo._id === todoId;
}
TodoModel.update(todoId, todoBody).then((res) => {
let todos = this.state.todos
todos.find(isUpdatedTodo).body = todoBody
this.setState({todos: todos, editingTodoId: null, editing: null})
})
}
editTodo(todo) {
this.setState({editingTodoId: todo._id})
}
render() {
return (
<div className='TodosContainer'>
<h2>This is the Todos Container</h2>
<Todos todos={this.state.todos}
editingTodoId={this.state.editingTodoId}
onEditTodo={this.editTodo.bind(this)}
onDeleteTodo={this.deleteTodo.bind(this)}
onUpdateTodo={this.updateTodo.bind(this)}/>
<CreateTodoForm createTodo={this.createTodo.bind(this)}/>
</div>
)
}
}

export default TodosContainer
52 changes: 52 additions & 0 deletions my-react-todo/src/index.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
body {
margin: 0;
padding: 0;
font-family: "Brush Script MT", cursive;
}

header, .todos {
text-align: center
}

.todosContainer {
width: 60%;
margin: auto;
}

h2 {
padding-bottom: .5em;
margin-bottom: .5em;
}

.incomplete h2{
border-bottom: 3px solid red;
}

h1, h2{
font-family: "Brush Script MT", cursive;
}

p {
font-family: "Brush Script MT", cursive;
font-size: 2em;
}

.todoForm {
clear:both;
text-align: center;
}

span.deleteButton, span.toggleButton {
padding-left: 1em;
}

.deleteButton{
color: red;
}

.createForm {
padding-top: 3em;
padding-bottom: 3em;
margin: auto;
width: 58%;
}
10 changes: 10 additions & 0 deletions my-react-todo/src/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import {Router, browserHistory} from 'react-router'
import routes from './config/routes.js'

ReactDOM.render(
<Router routes={routes} history={browserHistory}/>,
document.getElementById('root')
);
Loading