From b5aa0c58b61efaad6f513bf4ddf96d8fe74c82fd Mon Sep 17 00:00:00 2001 From: Nastia Piven Date: Sun, 15 Sep 2024 18:37:26 +0200 Subject: [PATCH] feat: implement edit Task title --- client/src/api/entries.ts | 6 ++-- client/src/api/tasks.ts | 27 ++++++++++++++++-- client/src/components/Task.tsx | 41 +++++++++++++++++++++++----- client/src/hooks/useMonthEntries.ts | 4 +++ server/src/api/entries.ts | 2 +- server/src/api/tasks.ts | 4 +++ server/src/controllers/updateTask.ts | 31 +++++++++++++++++++++ 7 files changed, 102 insertions(+), 13 deletions(-) create mode 100644 server/src/controllers/updateTask.ts diff --git a/client/src/api/entries.ts b/client/src/api/entries.ts index aaf5e9d..b31194c 100644 --- a/client/src/api/entries.ts +++ b/client/src/api/entries.ts @@ -10,12 +10,12 @@ type UpdateResponse = { // Update entry status export async function updateEntryStatus( - entryId: mongoose.Types.ObjectId | undefined, + entryId: mongoose.Types.ObjectId, status: Status, ) { try { const response: AxiosResponse = await axios.patch( - `${BASE_URL}/entries/update/${entryId}`, + `${BASE_URL}/entries/${entryId}`, { status, }, @@ -34,7 +34,7 @@ export async function updateEntryStatus( // Get month entries by task ID export async function getMonthEntriesByTaskId( userId: string, - taskId: mongoose.Types.ObjectId | undefined, + taskId: mongoose.Types.ObjectId, year: number, month: number, ) { diff --git a/client/src/api/tasks.ts b/client/src/api/tasks.ts index 0c26a4c..74083ed 100644 --- a/client/src/api/tasks.ts +++ b/client/src/api/tasks.ts @@ -4,7 +4,7 @@ import mongoose from "mongoose"; import { BASE_URL, handleRequestError } from "~/utils"; import { ITask } from "~/~/models/Task"; -type DeleteResponse = { +type MessageResponse = { message: string; }; @@ -50,13 +50,36 @@ export async function createTask(userId: string, title: string) { } } +// Update title +export async function updateTaskTitle( + taskId: mongoose.Types.ObjectId, + newTitle: string, +) { + try { + const response: AxiosResponse = await axios.patch( + `${BASE_URL}/tasks/${taskId}`, + { + newTitle, + }, + ); + + const data = response.data; + + return data; + } catch (err) { + if (err instanceof Error) { + handleRequestError(err); + } + } +} + // Delete export async function deleteTaskById( userId: string, taskId: mongoose.Types.ObjectId, ) { try { - const response: AxiosResponse = await axios.delete( + const response: AxiosResponse = await axios.delete( `${BASE_URL}/tasks/${userId}/${taskId}`, ); diff --git a/client/src/components/Task.tsx b/client/src/components/Task.tsx index e7f0b60..44c04fd 100644 --- a/client/src/components/Task.tsx +++ b/client/src/components/Task.tsx @@ -4,8 +4,9 @@ import { Button } from "./ui/Button"; import { Entry } from "./Entry"; import { useAppContext, useMonthEntries } from "~/hooks"; -import { getDaysInMonth } from "~/utils"; -import { deleteTaskById } from "~/api/tasks"; +import { cn, getDaysInMonth } from "~/utils"; +import { deleteTaskById, updateTaskTitle } from "~/api/tasks"; +import { useState } from "react"; interface TaskListItemProps { taskId: mongoose.Types.ObjectId; @@ -19,6 +20,9 @@ export function Task(props: TaskListItemProps) { const { taskId, title, year, month } = props; + const [newTaskTitle, setNewTaskTitle] = useState(title); + const [editMode, setEditMode] = useState(false); + const { data: entries, isLoading, @@ -28,17 +32,36 @@ export function Task(props: TaskListItemProps) { const daysInMonth = getDaysInMonth(month, year); const invalidEntries = entries ? daysInMonth - entries?.length : 0; + // Delete async function handleDeleteTask() { - if (!taskId) { - return; + if (taskId) { + await deleteTaskById(userId, taskId); } + } - await deleteTaskById(userId, taskId); + // Edit title + async function handleEditTitle() { + if (taskId) { + await updateTaskTitle(taskId, newTaskTitle); + } + + setEditMode(false); } return (
-
{title}
+
+ setNewTaskTitle(e.target.value)} + onFocus={() => setEditMode(true)} + onBlur={handleEditTitle} + /> +
{/* Entries */}
@@ -51,7 +74,11 @@ export function Task(props: TaskListItemProps) { {entries && entries.map((entry) => ( - + ))}
diff --git a/client/src/hooks/useMonthEntries.ts b/client/src/hooks/useMonthEntries.ts index 26e9ced..8079062 100644 --- a/client/src/hooks/useMonthEntries.ts +++ b/client/src/hooks/useMonthEntries.ts @@ -23,6 +23,10 @@ export function useMonthEntries(props: IUseEntriesProps) { setIsLoading(true); setError(false); + if (!taskId) { + return; + } + try { const entries = await getMonthEntriesByTaskId( userId, diff --git a/server/src/api/entries.ts b/server/src/api/entries.ts index be1339a..90614a3 100644 --- a/server/src/api/entries.ts +++ b/server/src/api/entries.ts @@ -10,6 +10,6 @@ router.route("/day/:userId").get(getUserEntriesByDay); router.route("/:userId/:taskId").get(getMonthEntriesByTaskId); // Update -router.route("/update/:entryId").patch(updateEntryStatus); +router.route("/:entryId").patch(updateEntryStatus); export { router as entriesRouter }; diff --git a/server/src/api/tasks.ts b/server/src/api/tasks.ts index 8073466..af3cbd4 100644 --- a/server/src/api/tasks.ts +++ b/server/src/api/tasks.ts @@ -3,6 +3,7 @@ import express from "express"; import { createTask } from "../controllers/createTask.js"; import { getTasksByUserId } from "../controllers/getTasks.js"; import { deleteTaskById } from "../controllers/deleteTask.js"; +import { updateTask } from "../controllers/updateTask.js"; const router = express.Router(); @@ -12,6 +13,9 @@ router.route("/:userId").get(getTasksByUserId); // Create router.route("/").post(createTask); +// Update +router.route("/:taskId").patch(updateTask); + // Delete router.route("/:userId/:taskId").delete(deleteTaskById); diff --git a/server/src/controllers/updateTask.ts b/server/src/controllers/updateTask.ts new file mode 100644 index 0000000..2e160ee --- /dev/null +++ b/server/src/controllers/updateTask.ts @@ -0,0 +1,31 @@ +import { Request, Response } from "express"; + +import { Task } from "../models/Task.js"; + +// Update status +export async function updateTask(req: Request, res: Response) { + const { taskId } = req.params; + const { newTitle } = req.body; + + if (!newTitle) { + return res.status(500).json({ + message: "Some parameters are missing: newTitle.", + }); + } + + try { + await Task.updateOne({ _id: taskId }, { $set: { title: newTitle } }).exec(); + + return res.status(201).json({ + message: "Task title successfully updated.", + }); + } catch (err) { + if (err instanceof Error) { + console.log("🔴 Error:", err.message); + + return res.status(500).json({ + message: "Failed to update Task title.", + }); + } + } +}