tasks as objects, separate completed tasks in view

- tasks are list of objects
- add button to complete task
- show completed tasks separatedly
- move filter from navbar to tasks component
This commit is contained in:
data 2019-06-20 15:58:56 -04:00
parent 086b6f4e5c
commit 70ee0b3570
3 changed files with 52 additions and 24 deletions

View File

@ -1,10 +1,11 @@
import React from 'react'
import { About, Tasks, Navbar } from './components'
const defaultState = { loading: true, tasks: [], search: '', newTask: '' }
const defaultState = { user: {}, loading: true, tasks: [], search: '', newTask: '' }
// hard-coded for now, but can be passed anything and set on state
const data = { user: { name: 'Scott', role: 'manager' }, component: 'tasks', tasks: ['arf', 'bruf', 'crap'] }
const data = { user: { name: 'Scott', role: 'manager' }, component: 'tasks',
tasks: [{ id: 0, desc: 'arf'}, { id:1, desc: 'bruf' }, { id: 2, desc: 'crap' }] }
class App extends React.Component {
constructor() {
@ -15,6 +16,7 @@ class App extends React.Component {
this.handleSubmit = this.handleSubmit.bind(this)
this.addTask = this.addTask.bind(this)
this.deleteTask = this.deleteTask.bind(this)
this.completeTask = this.completeTask.bind(this)
}
fetchData() {
@ -44,12 +46,18 @@ class App extends React.Component {
addTask(e) {
e.preventDefault()
this.setState( { tasks: this.state.tasks.concat(this.state.newTask), newTask: '' })
this.setState( { tasks: this.state.tasks.concat( { id: this.state.tasks.length, desc: this.state.newTask } ), newTask: '' })
}
deleteTask(task) {
this.setState( { tasks: this.state.tasks.filter(t => t !== task) })
deleteTask(id) {
this.setState( { tasks: this.state.tasks.filter(t => t.id !== id) })
}
completeTask(id) {
const otherTasks = this.state.tasks.filter(t=> t.id !== id)
const completedTask = this.state.tasks.find(t => t.id === id)
completedTask.completed = ! completedTask.completed
console.log(completedTask)
this.setState( { tasks: otherTasks.concat(completedTask) })
}
renderLoading() {
return <div>Loading...</div>
@ -60,22 +68,22 @@ class App extends React.Component {
renderAbout() {
return <About {...this.state} />
}
renderTasks(filtered) {
renderTasks(filtered, completed) {
// {...this.state} passes everything on state to the component
return <Tasks handleChange={this.handleChange} addTask={this.addTask} deleteTask={this.deleteTask} filtered={filtered} {...this.state} />
return <Tasks handleChange={this.handleChange} handleSubmit={this.handleSubmit} addTask={this.addTask} completeTask={this.completeTask} deleteTask={this.deleteTask} filtered={filtered} completed={completed} {...this.state} />
}
render() {
const filtered = this.state.tasks.filter(task => this.state.search === task.slice(0, this.state.search.length))
const completed = this.state.tasks.filter(task => task.completed === true)
const filtered = this.state.tasks.filter(task => task.completed !== true && this.state.search === task.desc.slice(0, this.state.search.length))
const renderComponent = () => this.state.loading ? this.renderLoading()
: this.state.component === 'tasks' ? this.renderTasks(filtered)
: this.state.component === 'tasks' ? this.renderTasks(filtered, completed)
: this.state.component === 'about' ? this.renderAbout()
: this.renderError()
return (<div>
<Navbar handleChange={this.handleChange} handleSubmit={this.handleSubmit} navigate={this.navigate} {...this.state} />
<Navbar handleChange={this.handleChange} navigate={this.navigate} {...this.state} />
{ renderComponent() }
</div>)
}

View File

@ -22,10 +22,6 @@ return (
<a className="nav-link disabled" href="#hi">hi</a>
</li>
</ul>
<form className="form-inline my-2 my-lg-0">
<input className="form-control mr-sm-2" type="search" value={props.search} name="search" placeholder="Filter" onChange={(e) => props.handleChange(e)} />
<button className="btn btn-outline-success my-2 my-sm-0" type="submit" onClick={(e) => props.handleSubmit(e) }>Search</button>
</form>
</div>
</nav>
)

View File

@ -3,17 +3,41 @@ import React from 'react'
function Tasks(props) {
// props are passed from App as {...this.state}
const filtered = props.filtered || []
const completed = props.completed || []
return (
<div>
<h1>{`Hello, ${props.user.name}!`}</h1>
<p>Your tasks:</p>
<ul className="list-group">{filtered.map(task =>
<li className="list-group-item" key={task} onClick={ props.editTask }>
<button className="btn btn-outline-danger" onClick={ () => props.deleteTask(task) }>X</button> {task}</li> )}</ul>
<form className="mt-2">
<button className="btn btn-dark" type="submit" onClick={ props.addTask }>Add</button>
<input className="ml-1" name="newTask" value={props.newTask} onChange={ props.handleChange } />
</form>
<h3 className="mt-4">Your open tasks</h3>
<ul className="list-group">
<li className="list-group-item">
<form className="form-inline my-2 my-lg-0 float-right">
<input className="form-control mr-sm-2" type="search" value={props.search} name="search" placeholder="Filter" onChange={(e) => props.handleChange(e)} />
<button className="btn btn-outline-secondary my-2 my-sm-0" type="submit" onClick={(e) => props.handleSubmit(e) }>Show all</button>
</form>
<form onSubmit={ props.addTask }>Add task:
<input className="ml-1" name="newTask" value={props.newTask} onChange={ props.handleChange }/>
</form>
</li>
{filtered.map(task =>
<li className="list-group-item" key={task.id} onClick={ props.editTask }>
<button className="btn btn-outline-danger mr-1" onClick={ () => props.deleteTask(task.id) }>X</button>
{task.desc}
<button className={`btn btn-${ task.completed ? "secondary" : "outline-success" } float-right`} onClick={ () => props.completeTask(task.id) }>&#10004;</button>
</li> )
}
</ul>
{ completed.length === 0 ? null : <h3 className="mt-4">Completed</h3> }
<ul className="list-group">
{completed.map(task =>
<li className="list-group-item" key={task.id} onClick={ props.editTask }>
<button className="btn btn-outline-danger mr-1" onClick={ () => props.deleteTask(task.id) }>X</button>
{task.desc}
<button className={`btn btn-${ task.completed ? "secondary" : "outline-success" } float-right`} onClick={ () => props.completeTask(task.id) }>&#10004;</button>
</li> )
}
</ul>
</div>
)
}