From 4e31a55b40d23d139347f139121ce63409b9502b Mon Sep 17 00:00:00 2001
From: Mary Caserio <114102750+marycaserio@users.noreply.github.com>
Date: Mon, 4 Nov 2024 15:03:50 -0600
Subject: [PATCH] feat(DeleteItem): Add deletion of goals, microgoals, and
tasks (#18)
- Refactor: Merge all deletion logic inside the hook are all merged into
single function `deleteItem`
- Feat: Add new component to enable delete goals, microgoals, and tasks
by just single click on the delete icon (with mistake handling).
- Feat: Add new common components `ConfirmationDialog`.
---------
Co-authored-by: ZL Asica <40444637+ZL-Asica@users.noreply.github.com>
---
src/components/Home/DeleteItem.jsx | 42 ++++++++++++
src/components/Home/MacroGoal.jsx | 2 +
src/components/Home/MicroGoal.jsx | 5 ++
src/components/Home/Task.jsx | 68 +++++++++++--------
.../common/ConfirmSignOutDialog.jsx | 26 -------
src/components/common/ConfirmationDialog.jsx | 43 ++++++++++++
src/components/common/Header.jsx | 14 +++-
src/hooks/useGoalsUpdater.js | 10 +--
8 files changed, 144 insertions(+), 66 deletions(-)
create mode 100644 src/components/Home/DeleteItem.jsx
delete mode 100644 src/components/common/ConfirmSignOutDialog.jsx
create mode 100644 src/components/common/ConfirmationDialog.jsx
diff --git a/src/components/Home/DeleteItem.jsx b/src/components/Home/DeleteItem.jsx
new file mode 100644
index 0000000..cc7233c
--- /dev/null
+++ b/src/components/Home/DeleteItem.jsx
@@ -0,0 +1,42 @@
+import ConfirmationDialog from '@components/common/ConfirmationDialog';
+import useGoalsUpdater from '@hooks/useGoalsUpdater';
+import DeleteIcon from '@mui/icons-material/Delete';
+import { IconButton, Tooltip } from '@mui/material';
+import { useState } from 'react';
+
+const DeleteItem = ({ goalIndex, microGoalIndex, taskIndex }) => {
+ const { deleteItem } = useGoalsUpdater();
+ const [isDialogOpen, setIsDialogOpen] = useState(false);
+
+ const handleDelete = async () => {
+ await deleteItem({ goalIndex, microGoalIndex, taskIndex });
+ setIsDialogOpen(false); // Close the dialog after deletion
+ };
+
+ return (
+ <>
+
+ setIsDialogOpen(true)}
+ sx={{ color: 'error.main' }} // Set color to indicate delete action
+ >
+
+
+
+
+ {/* Delete Confirmation Dialog */}
+ setIsDialogOpen(false)}
+ onConfirm={handleDelete}
+ title="Confirm Delete"
+ description="Are you sure you want to delete this item?"
+ confirmText="Delete"
+ />
+ >
+ );
+};
+
+export default DeleteItem;
diff --git a/src/components/Home/MacroGoal.jsx b/src/components/Home/MacroGoal.jsx
index 779201c..a43135a 100644
--- a/src/components/Home/MacroGoal.jsx
+++ b/src/components/Home/MacroGoal.jsx
@@ -1,4 +1,5 @@
import AddItem from '@components/Home/AddItem';
+import DeleteItem from '@components/Home/DeleteItem';
import MicroGoal from '@components/Home/MicroGoal';
import ProgressIndicator from '@components/Home/ProgressIndicator';
import useGoalsUpdater from '@hooks/useGoalsUpdater';
@@ -17,6 +18,7 @@ const MacroGoal = ({ macroGoal, macroGoalIndex }) => {
{macroGoal.name}
+
toggleGoalExpansion(macroGoalIndex)} size="small">
{macroGoal.expanded ? : }
diff --git a/src/components/Home/MicroGoal.jsx b/src/components/Home/MicroGoal.jsx
index 0d87b48..cf30bf8 100644
--- a/src/components/Home/MicroGoal.jsx
+++ b/src/components/Home/MicroGoal.jsx
@@ -1,4 +1,5 @@
import AddItem from '@components/Home/AddItem';
+import DeleteItem from '@components/Home/DeleteItem';
import ProgressIndicator from '@components/Home/ProgressIndicator';
import Task from '@components/Home/Task';
import useGoalsUpdater from '@hooks/useGoalsUpdater';
@@ -17,6 +18,7 @@ const MicroGoal = ({ microGoal, macroGoalIndex, microGoalIndex }) => {
{microGoal.name}
+
toggleMicroGoalExpansion(macroGoalIndex, microGoalIndex)}
size="small"
@@ -30,6 +32,9 @@ const MicroGoal = ({ microGoal, macroGoalIndex, microGoalIndex }) => {
toggleTaskCompletion(macroGoalIndex, microGoalIndex, taskIndex)}
/>
))}
diff --git a/src/components/Home/Task.jsx b/src/components/Home/Task.jsx
index aafbe9b..a827f32 100644
--- a/src/components/Home/Task.jsx
+++ b/src/components/Home/Task.jsx
@@ -1,35 +1,43 @@
+import DeleteItem from '@components/Home/DeleteItem';
import { Checkbox, ListItem, ListItemText } from '@mui/material';
-const Task = ({ task, onToggle }) => (
-
-
- {
+ return (
+
-
-);
+ >
+
+
+
+
+ );
+};
export default Task;
diff --git a/src/components/common/ConfirmSignOutDialog.jsx b/src/components/common/ConfirmSignOutDialog.jsx
deleted file mode 100644
index 244e618..0000000
--- a/src/components/common/ConfirmSignOutDialog.jsx
+++ /dev/null
@@ -1,26 +0,0 @@
-import { useUser } from '@contexts/UserContext';
-import { Button, Dialog, DialogActions, DialogTitle } from '@mui/material';
-
-const ConfirmSignOutDialog = ({ open, onClose }) => {
- const { handleSignOut } = useUser();
-
- // Function to confirm sign out
- const confirmSignOut = async () => {
- await handleSignOut();
- onClose();
- };
-
- return (
-
- );
-};
-
-export default ConfirmSignOutDialog;
diff --git a/src/components/common/ConfirmationDialog.jsx b/src/components/common/ConfirmationDialog.jsx
new file mode 100644
index 0000000..7e061c5
--- /dev/null
+++ b/src/components/common/ConfirmationDialog.jsx
@@ -0,0 +1,43 @@
+import {
+ Button,
+ Dialog,
+ DialogActions,
+ DialogContent,
+ DialogContentText,
+ DialogTitle,
+} from '@mui/material';
+
+const ConfirmationDialog = ({
+ open,
+ onClose,
+ onConfirm,
+ title,
+ description = '', // If null, no description will be shown
+ confirmText = 'Confirm',
+ cancelText = 'Cancel',
+ confirmColor = 'error', // 'primary' or 'error'
+}) => {
+ return (
+
+ );
+};
+
+export default ConfirmationDialog;
diff --git a/src/components/common/Header.jsx b/src/components/common/Header.jsx
index c39e2bf..970440e 100644
--- a/src/components/common/Header.jsx
+++ b/src/components/common/Header.jsx
@@ -1,13 +1,13 @@
+import ConfirmationDialog from '@components/common/ConfirmationDialog';
import { useUser } from '@contexts/UserContext';
import ArrowBackIcon from '@mui/icons-material/ArrowBack';
import FireIcon from '@mui/icons-material/Whatshot';
import { AppBar, Avatar, Box, Button, IconButton, Toolbar, Typography } from '@mui/material';
import { useState } from 'react';
import { useLocation, useNavigate } from 'react-router-dom';
-import ConfirmSignOutDialog from './ConfirmSignOutDialog';
const Header = () => {
- const { user, handleSignIn } = useUser();
+ const { user, handleSignIn, handleSignOut } = useUser();
const location = useLocation();
const navigate = useNavigate();
@@ -65,9 +65,17 @@ const Header = () => {
{/* Dialog for Confirm Sign Out */}
- setOpenConfirmDialog(false)}
+ onConfirm={async () => {
+ navigate('/');
+ await handleSignOut();
+ onClose();
+ }}
+ title="Confirm Sign Out"
+ description="Are you sure you want to sign out?"
+ confirmText="Sign Out"
/>
>
) : (
diff --git a/src/hooks/useGoalsUpdater.js b/src/hooks/useGoalsUpdater.js
index 6536fc0..c39fc24 100644
--- a/src/hooks/useGoalsUpdater.js
+++ b/src/hooks/useGoalsUpdater.js
@@ -64,7 +64,7 @@ const useGoalsUpdater = () => {
};
// Delete a goal, microgoal, or task
- const deleteItem = async ({ goalIndex, microGoalIndex, taskIndex }) => {
+ const deleteItem = async ({ goalIndex, microGoalIndex = undefined, taskIndex = undefined }) => {
const updatedGoals = [...user.goals];
if (taskIndex !== undefined) {
@@ -92,12 +92,8 @@ const useGoalsUpdater = () => {
addTask: (goalIndex, microGoalIndex, taskName) =>
addItem(goalIndex, microGoalIndex, { name: taskName, completed: false }, 'task'),
- // Delete a goal, microgoal, or task
- deleteGoal: (goalIndex) => deleteItem(goalIndex),
- deleteMicrogoal: (goalIndex, microGoalIndex) => deleteItem(goalIndex, microGoalIndex),
- deleteTask: (goalIndex, microGoalIndex, taskIndex) =>
- deleteItem(goalIndex, microGoalIndex, taskIndex),
-
+ // Delete
+ deleteItem,
toggleTaskCompletion,
toggleGoalExpansion: (goalIndex) => toggleExpansion(goalIndex),