From ecaccdbcf51773abd0ac080c47d7bce67961e2dc Mon Sep 17 00:00:00 2001 From: SovannarithHayGH <163391427+SovannarithHayGH@users.noreply.github.com> Date: Wed, 9 Oct 2024 22:12:56 +1100 Subject: [PATCH 1/2] Fixing the size of the progress bar and newline task edit. --- frontend/src/api/taskAPI.tsx | 38 ++++++++++--------- .../src/components/kanbans/kanban-display.tsx | 2 +- .../components/kanbans/kanban-task-detail.tsx | 6 +-- 3 files changed, 24 insertions(+), 22 deletions(-) diff --git a/frontend/src/api/taskAPI.tsx b/frontend/src/api/taskAPI.tsx index 0b28d94..ff4a7ba 100644 --- a/frontend/src/api/taskAPI.tsx +++ b/frontend/src/api/taskAPI.tsx @@ -21,6 +21,25 @@ export default class TaskAPI { return response.data as KanbanTask; } + static createTaskObservable( + boardId: number, + taskData: Partial + ): Observable { + return from(TaskAPI.createTask(boardId)).pipe( + switchMap((task) => { + return from(TaskAPI.updateTask(boardId, task.id, taskData)).pipe( + catchError((error) => { + throw new TaskApiError( + `Error creating task with boardId ${boardId}`, + task, + error + ); + }) + ); + }) + ); + } + static async deleteTask(boardId: number, taskId: number): Promise { const token = localStorage.getItem("token"); @@ -58,24 +77,7 @@ export default class TaskAPI { return response.data as KanbanTask; } - static createTaskObservable( - boardId: number, - taskData: Partial - ): Observable { - return from(TaskAPI.createTask(boardId)).pipe( - switchMap((task) => { - return from(TaskAPI.updateTask(boardId, task.id, taskData)).pipe( - catchError((error) => { - throw new TaskApiError( - `Error creating task with boardId ${boardId}`, - task, - error - ); - }) - ); - }) - ); - } + static updateTaskObservable( boardId: number, diff --git a/frontend/src/components/kanbans/kanban-display.tsx b/frontend/src/components/kanbans/kanban-display.tsx index 4eb74e4..254a9a1 100644 --- a/frontend/src/components/kanbans/kanban-display.tsx +++ b/frontend/src/components/kanbans/kanban-display.tsx @@ -240,7 +240,7 @@ function ProgressBar({ progress }: { progress: number }) { background: "#ddd", borderRadius: "4px", width: "100%", - height: "10px", + height: "30px", marginTop: "5px", }} > diff --git a/frontend/src/components/kanbans/kanban-task-detail.tsx b/frontend/src/components/kanbans/kanban-task-detail.tsx index 2b97cb4..24caff4 100644 --- a/frontend/src/components/kanbans/kanban-task-detail.tsx +++ b/frontend/src/components/kanbans/kanban-task-detail.tsx @@ -160,7 +160,7 @@ const DetailedTaskView = ({ name="urgency" value={updatedTask.urgency} onChange={handleInputChange} - className="p-2 rounded text-black" + className="block w-full p-2 rounded text-black mt-1" > @@ -183,7 +183,7 @@ const DetailedTaskView = ({ name="dueDate" value={updatedTask.dueDate} onChange={handleInputChange} - className="p-2 rounded text-black" + className="block w-full p-2 rounded text-black mt-1" /> ) : ( {task.dueDate} @@ -266,7 +266,7 @@ const DetailedTaskView = ({ name="taskCategory" value={updatedTask.taskCategory} onChange={handleInputChange} - className="p-2 rounded text-black" + className="block w-full p-2 rounded text-black mt-1" > From 682b737b8f47e6a7c1ec57efc5eb58e81efa1be3 Mon Sep 17 00:00:00 2001 From: SovannarithHayGH <163391427+SovannarithHayGH@users.noreply.github.com> Date: Thu, 10 Oct 2024 20:26:16 +1100 Subject: [PATCH 2/2] Notification popup when task completed successfully. --- .../components/forms/notification-popup.tsx | 45 +++++++++++++++++++ .../src/components/kanbans/kanban-display.tsx | 29 +++++++++++- 2 files changed, 73 insertions(+), 1 deletion(-) create mode 100644 frontend/src/components/forms/notification-popup.tsx diff --git a/frontend/src/components/forms/notification-popup.tsx b/frontend/src/components/forms/notification-popup.tsx new file mode 100644 index 0000000..ba92f60 --- /dev/null +++ b/frontend/src/components/forms/notification-popup.tsx @@ -0,0 +1,45 @@ +import { useEffect } from "react"; + +type NotificationType = "success" | "error" | "info" | undefined; + +interface NotificationPopupProps { + message: string; + isVisible: boolean; + onClose: () => void; + type?: NotificationType; +} + + + +const NotificationPopup = ({ + message, + isVisible, + onClose, + type = "info", +}: NotificationPopupProps) => { + useEffect(() => { + if (isVisible) { + const timer = setTimeout(onClose, 3000); // 1 second auto-close + return () => clearTimeout(timer); + } + }, [isVisible, onClose]); + + if (!isVisible) return null; + + const typeStyles = { + success: "bg-green-500 text-white", + error: "bg-red-500 text-white", + info: "bg-blue-500 text-white", + }; + + return ( +
+ {message} +
+ ); +}; + +export default NotificationPopup; diff --git a/frontend/src/components/kanbans/kanban-display.tsx b/frontend/src/components/kanbans/kanban-display.tsx index 254a9a1..e07b96d 100644 --- a/frontend/src/components/kanbans/kanban-display.tsx +++ b/frontend/src/components/kanbans/kanban-display.tsx @@ -8,7 +8,7 @@ import { kanbanColumns } from "../../utilities/kanban-category-mapping"; import { Droppable, DragDropContext } from "react-beautiful-dnd"; import UserAPI from "../../api/userAPI"; import ConfirmationModal from "../forms/confirmation-form"; - +import NotificationPopup from "../forms/notification-popup"; export default function KanbanDisplay({ kanban, setKanban, @@ -23,6 +23,12 @@ export default function KanbanDisplay({ const [isConfirmModalOpen, setIsConfirmModalOpen] = useState(false); const [taskToDelete, setTaskToDelete] = useState(null); const [addTaskError, setAddTaskError] = useState(null); + const [notification, setNotification] = useState<{ message: string; isVisible: boolean; type: "success" | "error" | "info" }>({ + message: "", + isVisible: false, + type: "info" + }); + useEffect(() => { const subscription = UserAPI.getUserObservable().subscribe({ @@ -39,6 +45,12 @@ export default function KanbanDisplay({ }; }, []); + + const showNotification = (message: string, type: "success" | "error" | "info" = "info") => { + setNotification({ message, isVisible: true, type }); + setTimeout(() => setNotification({ message: "", isVisible: false, type }), 3000); + }; + const handleDeleteTask = (taskId: number) => { setTaskToDelete(taskId); setIsConfirmModalOpen(true); @@ -54,9 +66,11 @@ export default function KanbanDisplay({ }); setSelectedTask(null); setIsConfirmModalOpen(false); + showNotification("Task deleted successfully", "success"); }) .catch((error) => { console.error("Error deleting task:", error); + }); } }; @@ -105,6 +119,7 @@ export default function KanbanDisplay({ next: (task) => { console.log("Task created:", task); setIsTaskModalOpen(false); + showNotification("Task created successfully", "success"); }, error: (error) => { setAddTaskError(error.error.response.data); @@ -138,6 +153,7 @@ export default function KanbanDisplay({ next: (updatedTask) => { console.log("Task updated:", updatedTask); setKanban({ ...kanban, tasks: updatedTasks }); + showNotification("Task updated successfully", "success"); }, error: (error) => { console.error("Error updating task:", error); @@ -145,8 +161,18 @@ export default function KanbanDisplay({ }); }; + return ( +
+ {/* Notification Popup */} + setNotification({ ...notification, isVisible: false })} + type={notification.type || "info"} + /> +

{kanban.name} @@ -168,6 +194,7 @@ export default function KanbanDisplay({

+