Skip to content

Commit a94ecd7

Browse files
committed
feat: add delete confirmation dialog to CommentItem component
- Implemented a confirmation dialog for deleting comments to enhance user experience and prevent accidental deletions. - Refactored the delete comment logic to manage loading state and handle API calls more effectively. - Updated the dropdown menu to trigger the dialog instead of directly deleting the comment.
1 parent 6b7d3a4 commit a94ecd7

File tree

1 file changed

+41
-12
lines changed

1 file changed

+41
-12
lines changed

apps/app/src/components/comments/CommentItem.tsx

Lines changed: 41 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,14 @@ import { useCommentActions } from '@/hooks/use-comments-api';
55
import { Avatar, AvatarFallback, AvatarImage } from '@comp/ui/avatar';
66
import { Button } from '@comp/ui/button';
77
import { Card, CardContent } from '@comp/ui/card';
8+
import {
9+
Dialog,
10+
DialogContent,
11+
DialogDescription,
12+
DialogFooter,
13+
DialogHeader,
14+
DialogTitle,
15+
} from '@comp/ui/dialog';
816
import {
917
DropdownMenu,
1018
DropdownMenuContent,
@@ -54,6 +62,8 @@ interface CommentItemProps {
5462
export function CommentItem({ comment, refreshComments }: CommentItemProps) {
5563
const [isEditing, setIsEditing] = useState(false);
5664
const [editedContent, setEditedContent] = useState(comment.content);
65+
const [isDeleteOpen, setIsDeleteOpen] = useState(false);
66+
const [isDeleting, setIsDeleting] = useState(false);
5767

5868
// Use API hooks instead of server actions
5969
const { updateComment, deleteComment } = useCommentActions();
@@ -93,17 +103,17 @@ export function CommentItem({ comment, refreshComments }: CommentItemProps) {
93103
};
94104

95105
const handleDeleteComment = async () => {
96-
if (window.confirm('Are you sure you want to delete this comment?')) {
97-
try {
98-
// Use API hook directly instead of server action
99-
await deleteComment(comment.id);
100-
101-
toast.success('Comment deleted successfully.');
102-
refreshComments();
103-
} catch (error) {
104-
toast.error('Failed to delete comment.');
105-
console.error('Delete comment error:', error);
106-
}
106+
setIsDeleting(true);
107+
try {
108+
await deleteComment(comment.id);
109+
toast.success('Comment deleted successfully.');
110+
refreshComments();
111+
setIsDeleteOpen(false);
112+
} catch (error) {
113+
toast.error('Failed to delete comment.');
114+
console.error('Delete comment error:', error);
115+
} finally {
116+
setIsDeleting(false);
107117
}
108118
};
109119

@@ -171,7 +181,7 @@ export function CommentItem({ comment, refreshComments }: CommentItemProps) {
171181
</DropdownMenuItem>
172182
<DropdownMenuItem
173183
className="text-destructive focus:text-destructive focus:bg-destructive/10"
174-
onSelect={handleDeleteComment}
184+
onSelect={() => setIsDeleteOpen(true)}
175185
>
176186
<Trash2 className="mr-2 h-3.5 w-3.5" />
177187
Delete
@@ -229,6 +239,25 @@ export function CommentItem({ comment, refreshComments }: CommentItemProps) {
229239
</div>
230240
</div>
231241
</CardContent>
242+
{/* Delete confirmation dialog */}
243+
<Dialog open={isDeleteOpen} onOpenChange={(open) => !open && setIsDeleteOpen(false)}>
244+
<DialogContent className="sm:max-w-[420px]">
245+
<DialogHeader>
246+
<DialogTitle>Delete Comment</DialogTitle>
247+
<DialogDescription>
248+
Are you sure you want to delete this comment? This cannot be undone.
249+
</DialogDescription>
250+
</DialogHeader>
251+
<DialogFooter className="gap-2">
252+
<Button variant="outline" onClick={() => setIsDeleteOpen(false)} disabled={isDeleting}>
253+
Cancel
254+
</Button>
255+
<Button variant="destructive" onClick={handleDeleteComment} disabled={isDeleting}>
256+
{isDeleting ? 'Deleting…' : 'Delete'}
257+
</Button>
258+
</DialogFooter>
259+
</DialogContent>
260+
</Dialog>
232261
</Card>
233262
);
234263
}

0 commit comments

Comments
 (0)