Files
kandev/apps/web/hooks/use-task-crud.ts
T
2026-09-06 15:19:25 +01:00

98 lines
2.8 KiB
TypeScript

"use client";
import { useCallback, useState } from "react";
import { useAppStoreApi } from "@/components/state-provider";
import { useTaskActions, type TaskActionOptions } from "@/hooks/use-task-actions";
import type { Task } from "@/components/kanban-card";
import type { KanbanState } from "@/lib/state/slices";
/**
* Custom hook that extracts task CRUD operations from the Kanban component.
* Manages dialog state and provides handlers for create, edit, delete, and archive operations.
*
* @returns Object with dialog state and task operation handlers
*/
export function useTaskCRUD() {
const [isDialogOpen, setIsDialogOpen] = useState(false);
const [editingTask, setEditingTask] = useState<Task | null>(null);
const [deletingTaskId, setDeletingTaskId] = useState<string | null>(null);
const [archivingTaskId, setArchivingTaskId] = useState<string | null>(null);
const { deleteTaskById, archiveTaskById } = useTaskActions();
const store = useAppStoreApi();
const handleCreate = useCallback(() => {
setEditingTask(null);
setIsDialogOpen(true);
}, []);
const handleEdit = useCallback((task: Task) => {
setEditingTask(task);
setIsDialogOpen(true);
}, []);
const handleDelete = useCallback(
async (task: Task, opts?: TaskActionOptions) => {
setDeletingTaskId(task.id);
try {
await deleteTaskById(task.id, opts);
// Update UI AFTER successful delete
store.getState().hydrate({
kanban: {
...store.getState().kanban,
tasks: store
.getState()
.kanban.tasks.filter((item: KanbanState["tasks"][number]) => item.id !== task.id),
},
});
} finally {
setDeletingTaskId(null);
}
},
[deleteTaskById, store],
);
const handleArchive = useCallback(
async (task: Task, opts?: TaskActionOptions) => {
setArchivingTaskId(task.id);
try {
await archiveTaskById(task.id, opts);
// Update UI AFTER successful archive - remove from kanban view
store.getState().hydrate({
kanban: {
...store.getState().kanban,
tasks: store
.getState()
.kanban.tasks.filter((item: KanbanState["tasks"][number]) => item.id !== task.id),
},
});
} finally {
setArchivingTaskId(null);
}
},
[archiveTaskById, store],
);
const handleDialogOpenChange = useCallback((open: boolean) => {
setIsDialogOpen(open);
if (!open) {
setEditingTask(null);
}
}, []);
return {
isDialogOpen,
setIsDialogOpen,
editingTask,
setEditingTask,
handleCreate,
handleEdit,
handleDelete,
handleArchive,
handleDialogOpenChange,
deletingTaskId,
archivingTaskId,
};
}