Improved task structure

This commit is contained in:
2025-11-10 21:05:08 +01:00
parent 086f470ebe
commit 6bf91af1f8
2 changed files with 68 additions and 70 deletions
+67 -70
View File
@@ -18,59 +18,53 @@ const id = (prefix = "t") =>
`${prefix}_${Math.random().toString(36).slice(2, 9)}`; `${prefix}_${Math.random().toString(36).slice(2, 9)}`;
export default function BoardView() { export default function BoardView() {
const [columns, setColumns] = useState<Record<string, Task[]>>({ const [tasks, setTasks] = useState<Task[]>([]);
todo: [],
inprogress: [],
done: [],
});
useEffect(() => { useEffect(() => {
setColumns({ setTasks([
todo: [ { id: id(), title: "Buy groceries", status: "todo" },
{ id: id(), title: "Buy groceries" }, { id: id(), title: "Plan sprint", status: "todo" },
{ id: id(), title: "Plan sprint" }, {
], id: id(),
inprogress: [ title: "Build header",
{ description: "A simple description",
id: id(), tags: [
title: "Build header", { name: "Website", color: "pink" },
description: "A simple description", { name: "Development", color: "blue" },
tags: [ { name: "API", color: "green" },
{ name: "Website", color: "pink" }, { name: "App", color: "purple" },
{ name: "Development", color: "blue" }, { name: "Rust", color: "orange" },
{ name: "API", color: "green" }, ],
{ name: "App", color: "purple" }, status: "inprogress",
{ name: "Rust", color: "orange" }, },
], ]);
},
],
done: [],
});
}, []); }, []);
function onDragEnd(result: any) { function onDragEnd(result: any) {
const { source, destination } = result; const { draggableId, source, destination } = result;
if (!destination) return; if (!destination) return;
const sourceCol = source.droppableId; setTasks((tasks) => {
const destCol = destination.droppableId; const taskIndex = tasks.findIndex((task) => task.id === draggableId);
const task = tasks[taskIndex];
tasks.splice(taskIndex, 1);
if (sourceCol === destCol) { const destinationGroupStartIndex = tasks.findIndex(
const items = Array.from(columns[sourceCol]); (t) => t.status === destination.droppableId
const [moved] = items.splice(source.index, 1); );
items.splice(destination.index, 0, moved);
setColumns({ ...columns, [sourceCol]: items }); const insertIndex =
} else { destinationGroupStartIndex === -1
const sourceItems = Array.from(columns[sourceCol]); ? tasks.length
const destItems = Array.from(columns[destCol]); : destinationGroupStartIndex + destination.index;
const [moved] = sourceItems.splice(source.index, 1);
destItems.splice(destination.index, 0, moved); tasks.splice(insertIndex, 0, {
setColumns({ ...task,
...columns, status: destination.droppableId,
[sourceCol]: sourceItems,
[destCol]: destItems,
}); });
}
return tasks;
});
} }
return ( return (
@@ -93,11 +87,12 @@ export default function BoardView() {
className="ml-auto" className="ml-auto"
variant="outline" variant="outline"
onClick={() => { onClick={() => {
const t: Task = { id: id(), title: "New task" }; const t: Task = {
setColumns((c) => ({ id: id(),
...c, title: "New task",
[colKey]: [...c[colKey], t], status: colKey,
})); };
setTasks((c) => [...c, t]);
}} }}
> >
<PlusIcon /> <PlusIcon />
@@ -106,28 +101,30 @@ export default function BoardView() {
</CardHeader> </CardHeader>
<CardContent> <CardContent>
<div className="flex flex-col gap-3"> <div className="flex flex-col gap-3">
{columns[colKey].map((task, index) => ( {tasks
<Draggable .filter((task) => task.status === colKey)
key={task.id} .map((task, index) => (
draggableId={task.id} <Draggable
index={index} key={task.id}
> draggableId={task.id}
{(provided) => ( index={index}
<BoardTask >
setTask={(t) => {(provided) => (
setColumns((cols) => { <BoardTask
cols[colKey][index] = t; setTask={(t) =>
return cols; setTasks((cols) =>
}) cols.map((c) => (c.id === t.id ? t : c))
} )
provided={provided} }
task={task} provided={provided}
/> task={task}
)} />
</Draggable> )}
))} </Draggable>
))}
{provided.placeholder} {provided.placeholder}
{columns[colKey].length === 0 && ( {tasks.filter((task) => task.status === colKey).length ===
0 && (
<p className="text-sm text-muted-foreground"> <p className="text-sm text-muted-foreground">
No tasks No tasks
</p> </p>
+1
View File
@@ -3,6 +3,7 @@ import { Color } from "./ui/color";
export type Task = { export type Task = {
id: string; id: string;
title: string; title: string;
status: string;
description?: string; description?: string;
tags?: { name: string; color: Color }[]; tags?: { name: string; color: Color }[];
}; };