add task check and delete

This commit is contained in:
João Geonizeli
2022-07-09 21:31:12 -03:00
parent 02955c8603
commit 916f2b3401
9 changed files with 237 additions and 9 deletions

View File

@@ -0,0 +1,67 @@
import { Add } from "@mui/icons-material";
import MoreVertIcon from "@mui/icons-material/MoreVert";
import {
Card,
CardActions,
CardContent,
CardHeader,
IconButton,
} from "@mui/material";
import useSWR from "swr";
import { useAuth } from "../../../hooks/useAuth";
import { createSWRFetcher } from "../../../utils/swrFetcher";
import { TaskListProps, TasksList } from "./TasksList";
export type APIProjectTasksList = {
data: TaskListProps["tasks"];
};
export type ProjectProps = {
id: number;
name: string;
};
export const Project = (props: ProjectProps) => {
const { token } = useAuth();
const fetcher = createSWRFetcher(token);
const { data, mutate } = useSWR<APIProjectTasksList>(
`projects/${props.id}/tasks`,
fetcher
);
const uncompletedTasks = data?.data.filter((task) => !task.finishedAt) ?? [];
const completedTasks = data?.data.filter((task) => task.finishedAt) ?? [];
return (
<Card sx={{ margin: 4 }}>
<CardHeader
action={
<IconButton aria-label="settings">
<MoreVertIcon />
</IconButton>
}
title={props.name}
/>
<CardContent>
<TasksList
projectId={props.id}
mutate={mutate}
title="To Do"
tasks={uncompletedTasks}
/>
<TasksList
projectId={props.id}
mutate={mutate}
title="Done"
tasks={completedTasks}
/>
</CardContent>
<CardActions disableSpacing>
<IconButton aria-label="add task">
<Add />
</IconButton>
</CardActions>
</Card>
);
};

View File

@@ -0,0 +1,54 @@
import { List, ListSubheader } from "@mui/material";
import { KeyedMutator } from "swr";
import { useAuth } from "../../../hooks/useAuth";
import { APIProjectTasksList } from "./Project";
import { Task, TasksListItem } from "./TasksListItem";
export type TaskListProps = {
projectId: number;
title: string;
tasks: Task[];
mutate: KeyedMutator<APIProjectTasksList>;
};
export const TasksList = ({
projectId,
title,
tasks,
mutate,
}: TaskListProps) => {
const { apiClient } = useAuth();
const handleCheck = (taskId: number) => {
apiClient(`projects/${projectId}/tasks/${taskId}/finish`).then((res) => {
mutate();
});
};
const handleDelete = (taskId: number) => {
apiClient(`projects/${projectId}/tasks/${taskId}`, {
method: "DELETE",
}).then((res) => {
mutate();
});
};
return (
<List
dense
subheader={
<ListSubheader component="div" id="nested-list-subheader">
{title}
</ListSubheader>
}
>
{tasks.map((task) => (
<TasksListItem
key={task.id}
task={task}
onCheck={handleCheck}
onDelete={handleDelete}
/>
))}
</List>
);
};

View File

@@ -0,0 +1,60 @@
import DeleteIcon from "@mui/icons-material/Delete";
import {
Checkbox,
IconButton,
ListItem,
ListItemAvatar,
ListItemText
} from "@mui/material";
import { useState } from "react";
export type Task = {
id: number;
description: string;
createdAt: Date;
finishedAt?: Date;
};
export type TasksListItemProps = {
task: Task;
onCheck: (taskId: number) => void;
onDelete: (taskId: number) => void;
};
export const TasksListItem = ({
task,
onCheck,
onDelete,
}: TasksListItemProps) => {
const finished = !!task.finishedAt;
const [isLoading, setIsLoading] = useState(false);
const handleCheck = () => {
setIsLoading(true);
onCheck(task.id);
};
const handleDelete = () => {
setIsLoading(true);
onDelete(task.id);
};
const blockInteration = finished || isLoading;
return (
<ListItem
secondaryAction={
finished ? null : (
<IconButton onClick={handleDelete} disabled={blockInteration} edge="end" aria-label="delete">
<DeleteIcon />
</IconButton>
)
}
>
<ListItemAvatar>
<Checkbox onChange={handleCheck} disabled={blockInteration} checked={blockInteration} />
</ListItemAvatar>
<ListItemText primary="Single-line item" />
</ListItem>
);
};