Skip to content
79 changes: 78 additions & 1 deletion frontend/components/App.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,86 @@
import React from 'react'
import axios from 'axios'
import Form from './Form'
import TodoList from './TodoList'

const URL = 'http://localhost:9000/api/todos'

export default class App extends React.Component {
constructor (){
super();
this.state = {
todos: [],
error: '',
todoNameInput: '',
displayCompleted: true,
}
}

onTodoNameInputChange = evt => {
const {value} = evt.target
this.setState({...this.state, todoNameInput: value})
}

postNewTodo = () => {
axios.post(URL, {name: this.state.todoNameInput})
.then(res => {
this.setState({...this.state, todos: this.state.todos.concat(res.data.data) })
this.resetForm()
})
.catch(this.setAxiosResponseErr)
}

onTodoFormSubmit = evt => {
evt.preventDefault()
this.postNewTodo()
}
setAxiosResponseErr = (err) => this.setState({...this.state, error: err.response.data.message})
resetForm = () =>
this.setState({...this.state, todoNameInput: ''})

fetchAllTodos = () =>{
axios.get(URL)
.then(res => {
this.setState({...this.state, todos: res.data.data})
})
.catch(this.setAxiosResponseErr)
}

toggleCompleted = id => () => {
axios.patch(`${URL}/${id}`)
.then(res => {
this.setState({...this.state, todos: this.state.todos.map(td => {
if(td.id !== id) return td
return res.data.data
})})
})
.catch(this.setAxiosResponseErr)
}

toggleDisplayCompleted=() => {
this.setState({...this.state, displayCompleted: !this.state.displayCompleted})
}

componentDidMount(){
this.fetchAllTodos()
}
render() {
return null
return (
<div>
<div id='error'>Error:{this.state.error}</div>
<TodoList
todos={this.state.todos}
displayCompleted={this.state.displayCompleted}
toggleCompleted={this.toggleCompleted}
/>
<Form
onTodoFormSubmit = {this.onTodoFormSubmit}
onTodoNameInputChange = {this.onTodoNameInputChange}
toggleDisplayCompleted ={this.toggleDisplayCompleted}
displayCompleted = {this.state.displayCompleted}
todoNameInput = {this.state.todoNameInput}
/>
</div>
)
}
}
14 changes: 13 additions & 1 deletion frontend/components/Form.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,18 @@ import React from 'react'

export default class Form extends React.Component {
render() {
return null
return (
<>
<form id ='todoForm'
onSubmit ={this.props.onTodoFormSubmit}>
<input value = {this.props.todoNameInput} onChange = {this.props.onTodoNameInputChange}
type = 'text'
placeholder='Type todo'></input>
<input type = 'submit'></input>
<button onClick ={this.props.toggleDisplayCompleted}>
{this.props.displayCompleted ? 'Hide':'Show'} the completed</button>
</form>
</>
)
}
}
7 changes: 6 additions & 1 deletion frontend/components/Todo.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@ import React from 'react'

export default class Todo extends React.Component {
render() {
return null
return (
<div onClick={this.props.toggleCompleted(this.props.todo.id)}
>
{this.props.todo.name}{this.props.todo.completed ? '✔️': ''}
</div>
)
}
}
20 changes: 18 additions & 2 deletions frontend/components/TodoList.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,23 @@
import React from 'react'

import Todo from './Todo'
export default class TodoList extends React.Component {
render() {
return null
return (
<div id = 'todos'>
<h2>Todos:</h2>
{
this.props.todos.reduce((acc, td ) => {
if(this.props.displayCompleted || !td.completed) return acc.concat(
<Todo
key = {td.id}
toggleCompleted={this.props.toggleCompleted}
todo={td}
/>
)
return acc
},[])
}
</div>
)
}
}