2020-08-31 15:41:49 +03:00
|
|
|
import React, { useState } from 'react'
|
2020-10-15 22:02:05 +03:00
|
|
|
import { Link } from 'react-router-dom'
|
2020-08-31 15:41:49 +03:00
|
|
|
|
2021-02-06 15:41:22 +03:00
|
|
|
import Button from '@material-ui/core/Button'
|
|
|
|
import TextField from '@material-ui/core/TextField'
|
|
|
|
import Paper from '@material-ui/core/Paper'
|
|
|
|
import Table from '@material-ui/core/Table'
|
|
|
|
import TableBody from '@material-ui/core/TableBody'
|
|
|
|
import TableCell from '@material-ui/core/TableCell'
|
|
|
|
import TableRow from '@material-ui/core/TableRow'
|
|
|
|
import Checkbox from '@material-ui/core/Checkbox'
|
|
|
|
|
2020-08-31 15:41:49 +03:00
|
|
|
import { useQuery } from '@wasp/queries'
|
|
|
|
import getTasks from '@wasp/queries/getTasks.js'
|
2020-09-04 13:44:05 +03:00
|
|
|
import createTask from '@wasp/actions/createTask.js'
|
2020-09-29 11:44:27 +03:00
|
|
|
import updateTaskIsDone from '@wasp/actions/updateTaskIsDone.js'
|
2020-09-30 11:08:20 +03:00
|
|
|
import deleteCompletedTasks from '@wasp/actions/deleteCompletedTasks.js'
|
|
|
|
import toggleAllTasks from '@wasp/actions/toggleAllTasks.js'
|
2020-08-31 15:41:49 +03:00
|
|
|
|
|
|
|
const Todo = (props) => {
|
2020-10-15 22:02:05 +03:00
|
|
|
const { data: tasks, isError, error: tasksError } = useQuery(getTasks)
|
2020-08-31 15:41:49 +03:00
|
|
|
|
2020-10-15 22:02:05 +03:00
|
|
|
const isThereAnyTask = () => tasks?.length > 0
|
2020-08-31 15:41:49 +03:00
|
|
|
|
2020-10-15 22:02:05 +03:00
|
|
|
const TasksError = (props) => {
|
|
|
|
return 'Error during fetching tasks: ' + (tasksError?.message || '')
|
|
|
|
}
|
2020-08-31 15:41:49 +03:00
|
|
|
|
2020-10-15 22:02:05 +03:00
|
|
|
return (
|
|
|
|
<div className='todos'>
|
|
|
|
<div className='todos__container'>
|
|
|
|
<h1> Todos </h1>
|
2020-08-31 15:41:49 +03:00
|
|
|
|
2020-10-15 22:02:05 +03:00
|
|
|
<div className='todos__toggleAndInput'>
|
|
|
|
<ToggleAllTasksButton disabled={!isThereAnyTask()} />
|
|
|
|
<NewTaskForm />
|
|
|
|
</div>
|
2020-02-05 13:47:58 +03:00
|
|
|
|
2020-10-15 22:02:05 +03:00
|
|
|
{isError && <TasksError />}
|
2020-10-19 15:45:54 +03:00
|
|
|
|
2020-10-15 22:02:05 +03:00
|
|
|
{isThereAnyTask() && (
|
|
|
|
<>
|
|
|
|
<Tasks tasks={tasks} />
|
2020-08-31 15:41:49 +03:00
|
|
|
|
2020-10-15 22:02:05 +03:00
|
|
|
<Footer tasks={tasks} />
|
|
|
|
</>
|
|
|
|
)}
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
const Footer = (props) => {
|
|
|
|
const numCompletedTasks = props.tasks.filter(t => t.isDone).length
|
|
|
|
const numUncompletedTasks = props.tasks.filter(t => !t.isDone).length
|
|
|
|
|
|
|
|
const handleDeleteCompletedTasks = async () => {
|
2020-08-31 15:41:49 +03:00
|
|
|
try {
|
2020-10-15 22:02:05 +03:00
|
|
|
await deleteCompletedTasks()
|
2020-08-31 15:41:49 +03:00
|
|
|
} catch (err) {
|
|
|
|
console.log(err)
|
|
|
|
window.alert('Error:' + err.message)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-10-15 22:02:05 +03:00
|
|
|
return (
|
|
|
|
<div className='todos__footer'>
|
|
|
|
<div className='todos__footer__itemsLeft'>
|
|
|
|
{numUncompletedTasks} items left
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div className='todos__footer__clearCompleted'>
|
2021-02-06 15:41:22 +03:00
|
|
|
<Button
|
2020-10-15 22:02:05 +03:00
|
|
|
className={numCompletedTasks > 0 ? '' : 'hidden'}
|
2021-02-06 15:41:22 +03:00
|
|
|
variant="contained" color="secondary"
|
2020-10-15 22:02:05 +03:00
|
|
|
onClick={handleDeleteCompletedTasks}
|
|
|
|
>
|
|
|
|
Delete completed
|
2021-02-06 15:41:22 +03:00
|
|
|
</Button>
|
2020-10-15 22:02:05 +03:00
|
|
|
</div>
|
2020-08-31 15:41:49 +03:00
|
|
|
</div>
|
2020-10-15 22:02:05 +03:00
|
|
|
)
|
|
|
|
}
|
2020-08-31 15:41:49 +03:00
|
|
|
|
2020-10-15 22:02:05 +03:00
|
|
|
const Tasks = (props) => {
|
|
|
|
return (
|
|
|
|
<div>
|
2021-02-06 15:41:22 +03:00
|
|
|
<Paper>
|
|
|
|
<Table size="small">
|
|
|
|
<TableBody>
|
|
|
|
{props.tasks.map((task, idx) => <Task task={task} key={idx} />)}
|
|
|
|
</TableBody>
|
|
|
|
</Table>
|
|
|
|
</Paper>
|
|
|
|
|
2020-10-15 22:02:05 +03:00
|
|
|
</div>
|
|
|
|
)
|
|
|
|
}
|
2020-08-31 15:41:49 +03:00
|
|
|
|
2020-10-15 22:02:05 +03:00
|
|
|
const Task = (props) => {
|
2020-09-29 11:44:27 +03:00
|
|
|
const handleTaskIsDoneChange = async (event) => {
|
|
|
|
const taskId = parseInt(event.target.id)
|
|
|
|
const newIsDoneVal = event.target.checked
|
|
|
|
|
|
|
|
try {
|
|
|
|
await updateTaskIsDone({ taskId, newIsDoneVal })
|
|
|
|
} catch (err) {
|
|
|
|
console.log(err)
|
|
|
|
window.alert('Error:' + err.message)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-10-15 22:02:05 +03:00
|
|
|
return (
|
2021-02-06 15:41:22 +03:00
|
|
|
<TableRow>
|
|
|
|
<TableCell>
|
|
|
|
<Checkbox
|
|
|
|
id={props.task.id}
|
|
|
|
checked={props.task.isDone}
|
|
|
|
onChange={handleTaskIsDoneChange}
|
|
|
|
color="default"
|
|
|
|
/>
|
|
|
|
</TableCell>
|
|
|
|
<TableCell>
|
|
|
|
<Link to={`/task/${props.task.id}`}> {props.task.description} </Link>
|
|
|
|
</TableCell>
|
|
|
|
</TableRow>
|
2020-10-15 22:02:05 +03:00
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
const NewTaskForm = (props) => {
|
|
|
|
const defaultDescription = ''
|
|
|
|
const [description, setDescription] = useState(defaultDescription)
|
|
|
|
|
|
|
|
const createNewTask = async (description) => {
|
|
|
|
const task = { isDone: false, description }
|
|
|
|
await createTask(task)
|
2020-08-31 15:41:49 +03:00
|
|
|
}
|
|
|
|
|
2020-10-15 22:02:05 +03:00
|
|
|
const handleNewTaskSubmit = async (event) => {
|
|
|
|
event.preventDefault()
|
2020-09-30 11:08:20 +03:00
|
|
|
try {
|
2020-10-15 22:02:05 +03:00
|
|
|
await createNewTask(description)
|
|
|
|
setDescription(defaultDescription)
|
2020-09-30 11:08:20 +03:00
|
|
|
} catch (err) {
|
|
|
|
console.log(err)
|
|
|
|
window.alert('Error:' + err.message)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-10-15 22:02:05 +03:00
|
|
|
return (
|
|
|
|
<form onSubmit={handleNewTaskSubmit}>
|
2021-02-06 15:41:22 +03:00
|
|
|
<TextField
|
|
|
|
className="todos__newTaskForm__input"
|
|
|
|
placeholder="Enter task"
|
2020-10-15 22:02:05 +03:00
|
|
|
value={description}
|
|
|
|
onChange={e => setDescription(e.target.value)}
|
|
|
|
/>
|
2021-11-08 16:19:15 +03:00
|
|
|
<Button
|
2021-02-06 15:41:22 +03:00
|
|
|
variant="contained" color="primary" type='submit'
|
|
|
|
>
|
|
|
|
Create new task
|
|
|
|
</Button>
|
2020-10-15 22:02:05 +03:00
|
|
|
</form>
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
const ToggleAllTasksButton = (props) => {
|
2020-09-30 11:08:20 +03:00
|
|
|
const handleToggleAllTasks = async () => {
|
|
|
|
try {
|
|
|
|
await toggleAllTasks()
|
|
|
|
} catch (err) {
|
|
|
|
console.log(err)
|
|
|
|
window.alert('Error:' + err.message)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-08-31 15:41:49 +03:00
|
|
|
return (
|
2021-02-06 15:41:22 +03:00
|
|
|
<Button
|
|
|
|
variant="contained" color="primary"
|
2020-10-15 22:02:05 +03:00
|
|
|
disabled={props.disabled}
|
|
|
|
onClick={handleToggleAllTasks}
|
|
|
|
>
|
|
|
|
✓
|
2021-02-06 15:41:22 +03:00
|
|
|
</Button>
|
2020-08-31 15:41:49 +03:00
|
|
|
)
|
2020-01-21 21:34:59 +03:00
|
|
|
}
|
2020-02-14 14:30:16 +03:00
|
|
|
|
2020-08-31 15:41:49 +03:00
|
|
|
export default Todo
|