"use client"; import { useMemo, useState } from "react"; import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; import { toast } from "sonner"; import { Button, Card, CardContent, Dialog, Drawer, Input, PageHeader, Select } from "@/components/ds"; import { useMe } from "@/hooks/useMe"; import { useCurrentHub } from "@/modules/workspace/hooks/useCurrentHub"; import { workspaceApi } from "@/modules/workspace/services/workspace-api"; import { KANBAN_COLUMNS, TASK_STATUS, displayPerson, formatDay } from "@/modules/workspace/labels"; import { StatusChip } from "@/modules/workspace/components/StatusChip"; import { IdentityUserSelect } from "@/modules/workspace/components/IdentityUserSelect"; import { CommentThread } from "@/modules/workspace/components/CommentThread"; import { WorkspaceEmptyState, WorkspacePageError, WorkspacePageLoader } from "@/modules/workspace/pages/shared"; import type { WorkspaceRecord } from "@/modules/workspace/types"; export const WorkspaceTasks = function WorkspaceTasksPage() { const queryClient = useQueryClient(); const { me } = useMe(); const { tenantId, hubId, loading } = useCurrentHub(); const [open, setOpen] = useState(false); const [title, setTitle] = useState(""); const [projectId, setProjectId] = useState(""); const [assignee, setAssignee] = useState(""); const [dueDate, setDueDate] = useState(""); const [mineOnly, setMineOnly] = useState(false); const [selected, setSelected] = useState(null); const [labels, setLabels] = useState(""); const projects = useQuery({ queryKey: ["workspace", tenantId, "projects", hubId], queryFn: () => workspaceApi.projects.list(tenantId!, { work_hub_id: hubId || undefined }), enabled: !!tenantId && !!hubId, }); const tasks = useQuery({ queryKey: ["workspace", tenantId, "tasks", hubId, mineOnly], queryFn: () => workspaceApi.tasks.list(tenantId!, { work_hub_id: hubId || undefined, assignee_user_id: mineOnly && me?.user_id ? me.user_id : undefined, }), enabled: !!tenantId && !!hubId, }); const create = useMutation({ mutationFn: () => workspaceApi.tasks.create(tenantId!, { project_id: projectId, title, assignee_user_id: assignee || undefined, due_date: dueDate || undefined, labels: labels ? labels.split(",").map((item) => item.trim()).filter(Boolean) : [], }), onSuccess: () => { toast.success("وظیفه ایجاد شد"); setOpen(false); setTitle(""); void queryClient.invalidateQueries({ queryKey: ["workspace", tenantId, "tasks"] }); }, onError: (err) => toast.error(err instanceof Error ? err.message : "ایجاد وظیفه ناموفق بود"), }); const move = useMutation({ mutationFn: ({ id, status }: { id: string; status: string }) => workspaceApi.tasks.update(tenantId!, id, { status }), onSuccess: () => { toast.success("وضعیت وظیفه ذخیره شد"); void queryClient.invalidateQueries({ queryKey: ["workspace", tenantId, "tasks"] }); }, onError: (err) => toast.error(err instanceof Error ? err.message : "تغییر وضعیت مجاز نیست"), }); const grouped = useMemo(() => { const map: Record = {}; for (const column of KANBAN_COLUMNS) map[column.id] = []; for (const task of tasks.data ?? []) { const status = String(task.status || "backlog"); if (!map[status]) map[status] = []; map[status].push(task); } return map; }, [tasks.data]); if (!tenantId || loading || tasks.isLoading) return ; if (!hubId) return ; if (tasks.error) return tasks.refetch()} />; return (
} /> {(tasks.data ?? []).length === 0 ? ( setOpen(true)}>ایجاد وظیفه} /> ) : (
{KANBAN_COLUMNS.map((column) => (
event.preventDefault()} onDrop={(event) => { const id = event.dataTransfer.getData("text/task-id"); if (id) move.mutate({ id, status: column.id }); }} >

{column.label}

{(grouped[column.id] ?? []).map((task) => ( event.dataTransfer.setData("text/task-id", String(task.id))} className="cursor-grab" onClick={() => setSelected(task)} >

{String(task.title || "وظیفه")}

{displayPerson(String(task.assignee_user_id || ""))}
{task.due_date ? (

مهلت {formatDay(String(task.due_date))}

) : null}
))}
))}
)} setOpen(false)} title="وظیفه جدید">
setTitle(event.target.value)} placeholder="عنوان وظیفه" /> setDueDate(event.target.value)} /> setLabels(event.target.value)} placeholder="برچسب‌ها با ویرگول" />
setSelected(null)} title={String(selected?.title || "وظیفه")}> {selected && hubId ? (
{ void workspaceApi.tasks.update(tenantId!, String(selected.id), { assignee_user_id: id }).then(() => { toast.success("مسئول ذخیره شد"); void queryClient.invalidateQueries({ queryKey: ["workspace", tenantId, "tasks"] }); }); }} emptyLabel="مسئول" /> { void workspaceApi.tasks.update(tenantId!, String(selected.id), { due_date: event.target.value }).then(() => { toast.success("مهلت ذخیره شد"); void queryClient.invalidateQueries({ queryKey: ["workspace", tenantId, "tasks"] }); }); }} />
) : null}
); }; export default WorkspaceTasks;