117 lines
3.5 KiB
TypeScript
117 lines
3.5 KiB
TypeScript
import { Edit } from "iconsax-react";
|
|
import { useState } from "react";
|
|
import { useTranslation } from "react-i18next";
|
|
import ModalConfrim from "../../../../../components/ModalConfrim";
|
|
import { toast } from "../../../../../components/Toast";
|
|
import ProgressBar from "../../../../../components/ProgressBar";
|
|
import { ErrorType } from "../../../../../helpers/types";
|
|
import { useDeleteCheckListItem, useUpdateCheckListItem } from "../../../task/hooks/useTaskData";
|
|
import type { TaskChecklistItemType } from "../../../task/types/TaskTypes";
|
|
import ChecklistItem from "./ChecklistItem";
|
|
|
|
type Props = {
|
|
taskId: string;
|
|
checkListItems?: TaskChecklistItemType[];
|
|
checkListItemCount?: number;
|
|
completedCheckListItemCount?: number;
|
|
};
|
|
|
|
const CheckLists = ({
|
|
taskId,
|
|
checkListItems = [],
|
|
checkListItemCount,
|
|
completedCheckListItemCount,
|
|
}: Props) => {
|
|
const { t } = useTranslation("global");
|
|
const updateCheckListItem = useUpdateCheckListItem();
|
|
const deleteCheckListItem = useDeleteCheckListItem();
|
|
const [deleteItemId, setDeleteItemId] = useState<string | null>(null);
|
|
|
|
const items = checkListItems.map((item) => ({
|
|
id: item.id,
|
|
title: item.title,
|
|
checked: item.isDone,
|
|
}));
|
|
|
|
const totalCount = checkListItemCount ?? items.length;
|
|
const doneCount = completedCheckListItemCount ?? items.filter((item) => item.checked).length;
|
|
const progress = totalCount > 0 ? Math.round((doneCount / totalCount) * 100) : 0;
|
|
|
|
const handleToggle = (id: string, title: string, checked: boolean) => {
|
|
updateCheckListItem.mutate(
|
|
{ id, params: { title, isDone: !checked, taskId }, taskId },
|
|
{
|
|
onError: (error: ErrorType) => {
|
|
toast(error.response?.data?.error.message[0], "error");
|
|
},
|
|
},
|
|
);
|
|
};
|
|
|
|
const handleSave = (id: string, title: string, checked: boolean) => {
|
|
updateCheckListItem.mutate(
|
|
{ id, params: { title, isDone: checked, taskId }, taskId },
|
|
{
|
|
onError: (error: ErrorType) => {
|
|
toast(error.response?.data?.error.message[0], "error");
|
|
},
|
|
},
|
|
);
|
|
};
|
|
|
|
const handleDelete = () => {
|
|
if (!deleteItemId) return;
|
|
|
|
deleteCheckListItem.mutate(
|
|
{ id: deleteItemId, taskId },
|
|
{
|
|
onSuccess: () => {
|
|
setDeleteItemId(null);
|
|
},
|
|
onError: (error: ErrorType) => {
|
|
toast(error.response?.data?.error.message[0], "error");
|
|
},
|
|
},
|
|
);
|
|
};
|
|
|
|
if (checkListItems.length === 0) return null;
|
|
|
|
return (
|
|
<div className="mt-6">
|
|
<div className="flex gap-2 items-center">
|
|
<div className="text-sm font-bold mt-px">{t("taskmanager.task_detail.checklist")}</div>
|
|
<Edit size={20} color="#0047FF" />
|
|
</div>
|
|
|
|
<div className="mt-4 flex gap-2 items-center">
|
|
<div className="text-xs shrink-0">{progress}٪</div>
|
|
<ProgressBar value={progress} />
|
|
</div>
|
|
|
|
<div className="mt-4 flex flex-col gap-2">
|
|
{items.map((item) => (
|
|
<ChecklistItem
|
|
key={item.id}
|
|
title={item.title}
|
|
checked={item.checked}
|
|
onToggle={() => handleToggle(item.id, item.title, item.checked)}
|
|
onSave={(title) => handleSave(item.id, title, item.checked)}
|
|
onDelete={() => setDeleteItemId(item.id)}
|
|
isSaving={updateCheckListItem.isPending}
|
|
/>
|
|
))}
|
|
</div>
|
|
|
|
<ModalConfrim
|
|
isOpen={deleteItemId !== null}
|
|
close={() => setDeleteItemId(null)}
|
|
onConfrim={handleDelete}
|
|
isLoading={deleteCheckListItem.isPending}
|
|
/>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default CheckLists;
|