1
0
Fork 0

Delete tasks

This commit is contained in:
Tomas Balsys 2024-10-26 22:12:35 +03:00
parent 3c3a5b172d
commit 7f86f64164
4 changed files with 48 additions and 37 deletions

View File

@ -2,26 +2,11 @@ import { } from 'react'
import { taskTypes, taskStatuses } from './consts'; import { taskTypes, taskStatuses } from './consts';
import { EnumSelect } from './enum-select'; import { EnumSelect } from './enum-select';
export function TaskForm({ tasks, setTasks, setExpanded }: { tasks: TodoTasks, setTasks: (t: TodoTasks) => void, setExpanded: (p: number) => void }): JSX.Element { export function TaskForm({ createTask }: { createTask: (t: Record<string, FormDataEntryValue>) => void }): JSX.Element {
return ( return (
<form className="grid grid-cols-1 gap-y-8" onSubmit={event => { <form className="grid grid-cols-1 gap-y-8" onSubmit={event => {
event.preventDefault(); event.preventDefault();
createTask(Object.fromEntries(new FormData(event.currentTarget)));
const data = Object.fromEntries(new FormData(event.currentTarget));
const newTask = {
id: tasks.reduce((max, row) => row.id > max ? row.id : max, 1) + 1,
type: data.type as TaskType,
title: data.title as string,
status: data.status as TaskStatus,
};
if (data.insert) {
setTasks([newTask, ...tasks]);
} else {
setTasks([...tasks, newTask]);
}
setExpanded(0);
}}> }}>
<div> <div>
<label htmlFor="type">Tipas</label> <label htmlFor="type">Tipas</label>
@ -46,9 +31,6 @@ export function TaskForm({ tasks, setTasks, setExpanded }: { tasks: TodoTasks, s
<label htmlFor="insert" className="ms-2">Įterpti pradžioje</label> <label htmlFor="insert" className="ms-2">Įterpti pradžioje</label>
</div> </div>
<div className="mt-2 flex items-center justify-end gap-x-6"> <div className="mt-2 flex items-center justify-end gap-x-6">
<button type="button" className="font-semibold" onClick={() => setExpanded(0)}>
Cancel
</button>
<button <button
type="submit" type="submit"
className="bg-indigo-500 rounded-lg px-3 py-2 font-semibold text-white hover:bg-indigo-600" className="bg-indigo-500 rounded-lg px-3 py-2 font-semibold text-white hover:bg-indigo-600"

View File

@ -2,7 +2,7 @@ import { useState } from 'react'
import { taskTypes, taskStatuses } from './consts'; import { taskTypes, taskStatuses } from './consts';
import { EnumSelect } from './enum-select'; import { EnumSelect } from './enum-select';
export function TaskRow({ task, updateTask }: { task: TodoTask, updateTask: (task: TodoTask) => void }): JSX.Element { export function TaskRow({ task, updateTask, deleteTask }: { task: TodoTask, updateTask: (task: TodoTask) => void, deleteTask: (id: number) => void }): JSX.Element {
const [edit, setEdit] = useState(false); const [edit, setEdit] = useState(false);
return ( return (
@ -40,23 +40,30 @@ export function TaskRow({ task, updateTask }: { task: TodoTask, updateTask: (tas
<div className="td"> <div className="td">
{edit ? <> {edit ? <>
<button type="submit" className="mr-3"> <button type="submit" className="mr-3">
<svg className="w-4 h-4 fill-white" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 490 490"> <svg className="w-5 h-5 fill-white" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 50 50">
<polygon points="452.253,28.326 197.831,394.674 29.044,256.875 0,292.469 207.253,461.674 490,54.528 "></polygon> <path d="M 25 2 C 12.317 2 2 12.317 2 25 C 2 37.683 12.317 48 25 48 C 37.683 48 48 37.683 48 25 C 48 20.44 46.660281 16.189328 44.363281 12.611328 L 42.994141 14.228516 C 44.889141 17.382516 46 21.06 46 25 C 46 36.579 36.579 46 25 46 C 13.421 46 4 36.579 4 25 C 4 13.421 13.421 4 25 4 C 30.443 4 35.393906 6.0997656 39.128906 9.5097656 L 40.4375 7.9648438 C 36.3525 4.2598437 30.935 2 25 2 z M 43.236328 7.7539062 L 23.914062 30.554688 L 15.78125 22.96875 L 14.417969 24.431641 L 24.083984 33.447266 L 44.763672 9.046875 L 43.236328 7.7539062 z"></path>
</svg> </svg>
</button> </button>
<button type="button" onClick={() => setEdit(false)}> <button type="button" onClick={event => {
<svg className="w-4 h-4 fill-white" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 490 490"> event.preventDefault()
<polygon points="456.851,0 245,212.564 33.149,0 0.708,32.337 212.669,245.004 0.708,457.678 33.149,490 245,277.443 456.851,490 489.292,457.678 277.331,245.004 489.292,32.337 "> setEdit(false)
</polygon> }}>
<svg className="w-5 h-5 fill-white" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 50 50">
<path d="M 25 2 C 12.309534 2 2 12.309534 2 25 C 2 37.690466 12.309534 48 25 48 C 37.690466 48 48 37.690466 48 25 C 48 12.309534 37.690466 2 25 2 z M 25 4 C 36.609534 4 46 13.390466 46 25 C 46 36.609534 36.609534 46 25 46 C 13.390466 46 4 36.609534 4 25 C 4 13.390466 13.390466 4 25 4 z M 32.990234 15.986328 A 1.0001 1.0001 0 0 0 32.292969 16.292969 L 25 23.585938 L 17.707031 16.292969 A 1.0001 1.0001 0 0 0 16.990234 15.990234 A 1.0001 1.0001 0 0 0 16.292969 17.707031 L 23.585938 25 L 16.292969 32.292969 A 1.0001 1.0001 0 1 0 17.707031 33.707031 L 25 26.414062 L 32.292969 33.707031 A 1.0001 1.0001 0 1 0 33.707031 32.292969 L 26.414062 25 L 33.707031 17.707031 A 1.0001 1.0001 0 0 0 32.990234 15.986328 z"></path>
</svg> </svg>
</button> </button>
</> : <> </> : <>
<button type="button" onClick={event => { <button type="button" className="mr-3" onClick={event => {
event.preventDefault() event.preventDefault()
setEdit(true) setEdit(true)
}}> }}>
<svg className="w-4 h-4 fill-white" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 30 30"> <svg className="w-5 h-5 fill-white" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" width="100" height="100" viewBox="0 0 50 50">
<path d="M 22.828125 3 C 22.316375 3 21.804562 3.1954375 21.414062 3.5859375 L 19 6 L 24 11 L 26.414062 8.5859375 C 27.195062 7.8049375 27.195062 6.5388125 26.414062 5.7578125 L 24.242188 3.5859375 C 23.851688 3.1954375 23.339875 3 22.828125 3 z M 17 8 L 5.2597656 19.740234 C 5.2597656 19.740234 6.1775313 19.658 6.5195312 20 C 6.8615312 20.342 6.58 22.58 7 23 C 7.42 23.42 9.6438906 23.124359 9.9628906 23.443359 C 10.281891 23.762359 10.259766 24.740234 10.259766 24.740234 L 22 13 L 17 8 z M 4 23 L 3.0566406 25.671875 A 1 1 0 0 0 3 26 A 1 1 0 0 0 4 27 A 1 1 0 0 0 4.328125 26.943359 A 1 1 0 0 0 4.3378906 26.939453 L 4.3632812 26.931641 A 1 1 0 0 0 4.3691406 26.927734 L 7 26 L 5.5 24.5 L 4 23 z"></path> <path d="M 43.125 2 C 41.878906 2 40.636719 2.488281 39.6875 3.4375 L 38.875 4.25 L 45.75 11.125 C 45.746094 11.128906 46.5625 10.3125 46.5625 10.3125 C 48.464844 8.410156 48.460938 5.335938 46.5625 3.4375 C 45.609375 2.488281 44.371094 2 43.125 2 Z M 37.34375 6.03125 C 37.117188 6.0625 36.90625 6.175781 36.75 6.34375 L 4.3125 38.8125 C 4.183594 38.929688 4.085938 39.082031 4.03125 39.25 L 2.03125 46.75 C 1.941406 47.09375 2.042969 47.457031 2.292969 47.707031 C 2.542969 47.957031 2.90625 48.058594 3.25 47.96875 L 10.75 45.96875 C 10.917969 45.914063 11.070313 45.816406 11.1875 45.6875 L 43.65625 13.25 C 44.054688 12.863281 44.058594 12.226563 43.671875 11.828125 C 43.285156 11.429688 42.648438 11.425781 42.25 11.8125 L 9.96875 44.09375 L 5.90625 40.03125 L 38.1875 7.75 C 38.488281 7.460938 38.578125 7.011719 38.410156 6.628906 C 38.242188 6.246094 37.855469 6.007813 37.4375 6.03125 C 37.40625 6.03125 37.375 6.03125 37.34375 6.03125 Z"></path>
</svg>
</button>
<button type="button" onClick={() => deleteTask(task.id)}>
<svg className="w-5 h-5 fill-white" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 50 50">
<path d="M 21 2 C 19.354545 2 18 3.3545455 18 5 L 18 7 L 10.154297 7 A 1.0001 1.0001 0 0 0 9.984375 6.9863281 A 1.0001 1.0001 0 0 0 9.8398438 7 L 8 7 A 1.0001 1.0001 0 1 0 8 9 L 9 9 L 9 45 C 9 46.645455 10.354545 48 12 48 L 38 48 C 39.645455 48 41 46.645455 41 45 L 41 9 L 42 9 A 1.0001 1.0001 0 1 0 42 7 L 40.167969 7 A 1.0001 1.0001 0 0 0 39.841797 7 L 32 7 L 32 5 C 32 3.3545455 30.645455 2 29 2 L 21 2 z M 21 4 L 29 4 C 29.554545 4 30 4.4454545 30 5 L 30 7 L 20 7 L 20 5 C 20 4.4454545 20.445455 4 21 4 z M 11 9 L 18.832031 9 A 1.0001 1.0001 0 0 0 19.158203 9 L 30.832031 9 A 1.0001 1.0001 0 0 0 31.158203 9 L 39 9 L 39 45 C 39 45.554545 38.554545 46 38 46 L 12 46 C 11.445455 46 11 45.554545 11 45 L 11 9 z M 18.984375 13.986328 A 1.0001 1.0001 0 0 0 18 15 L 18 40 A 1.0001 1.0001 0 1 0 20 40 L 20 15 A 1.0001 1.0001 0 0 0 18.984375 13.986328 z M 24.984375 13.986328 A 1.0001 1.0001 0 0 0 24 15 L 24 40 A 1.0001 1.0001 0 1 0 26 40 L 26 15 A 1.0001 1.0001 0 0 0 24.984375 13.986328 z M 30.984375 13.986328 A 1.0001 1.0001 0 0 0 30 15 L 30 40 A 1.0001 1.0001 0 1 0 32 40 L 32 15 A 1.0001 1.0001 0 0 0 30.984375 13.986328 z"></path>
</svg> </svg>
</button> </button>
</>} </>}

View File

@ -1,7 +1,7 @@
import { } from 'react' import { } from 'react'
import { TaskRow } from './task-row'; import { TaskRow } from './task-row';
export function TaskTable({ tasks, updateTask }: { tasks: TodoTasks, updateTask: (task: TodoTask) => void }): JSX.Element { export function TaskTable({ tasks, ...rest }: { tasks: TodoTasks, updateTask: (task: TodoTask) => void, deleteTask: (id: number) => void }): JSX.Element {
return ( return (
<div className="w-full"> <div className="w-full">
<div className="tr"> <div className="tr">
@ -10,7 +10,7 @@ export function TaskTable({ tasks, updateTask }: { tasks: TodoTasks, updateTask:
<div className="td">Statusas</div> <div className="td">Statusas</div>
<div className="td">Veiksmai</div> <div className="td">Veiksmai</div>
</div> </div>
{tasks.map(task => <TaskRow key={task.id} task={task} updateTask={updateTask} />)} {tasks.map(task => <TaskRow key={task.id} task={task} {...rest} />)}
</div> </div>
); );
} }

View File

@ -29,16 +29,38 @@ function App() {
const handleAccordion = (panel: number) => setExpanded(expanded == panel ? -1 : panel); const handleAccordion = (panel: number) => setExpanded(expanded == panel ? -1 : panel);
const createTask = (data: Record<string, FormDataEntryValue>) => {
const task = {
id: tasks.reduce((max, row) => row.id > max ? row.id : max, 1) + 1,
type: data.type as TaskType,
title: data.title as string,
status: data.status as TaskStatus,
};
if (data.insert) {
setTasks([task, ...tasks]);
} else {
setTasks([...tasks, task]);
}
setExpanded(0);
}
const updateTask = (task: TodoTask) => {
const index = tasks.findIndex(t => t.id == task.id);
setTasks([...tasks.slice(0, index), task, ...tasks.slice(index + 1)]);
};
const deleteTask = (id: number) => {
setTasks(tasks.filter(t => t.id != id));
};
return ( return (
<> <>
<AccordionItem title='Užduočių sąrašas' isOpen={expanded == 0} onClick={() => handleAccordion(0)}> <AccordionItem title='Užduočių sąrašas' isOpen={expanded == 0} onClick={() => handleAccordion(0)}>
<TaskTable tasks={tasks} updateTask={updated => { <TaskTable tasks={tasks} updateTask={updateTask} deleteTask={deleteTask} />
const index = tasks.findIndex(t => t.id == updated.id);
setTasks([...tasks.slice(0, index), updated, ...tasks.slice(index + 1)]);
}} />
</AccordionItem> </AccordionItem>
<AccordionItem title='Nauja užduotis' isOpen={expanded == 1} onClick={() => handleAccordion(1)}> <AccordionItem title='Nauja užduotis' isOpen={expanded == 1} onClick={() => handleAccordion(1)}>
<TaskForm tasks={tasks} setTasks={setTasks} setExpanded={setExpanded} /> <TaskForm createTask={createTask} />
</AccordionItem> </AccordionItem>
</> </>
) )