Skip to content

Commit fae2466

Browse files
committed
add confirmation dialog before deleting folders
1 parent fe45e2f commit fae2466

2 files changed

Lines changed: 121 additions & 3 deletions

File tree

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
import { FC } from 'react';
2+
import { AlertTriangle } from 'lucide-react';
3+
import { Button } from '@/components/ui/button';
4+
5+
import {
6+
Dialog,
7+
DialogContent,
8+
DialogDescription,
9+
DialogFooter,
10+
DialogHeader,
11+
DialogTitle,
12+
} from '@/components/ui/dialog';
13+
14+
interface DeleteFolderDialogProps {
15+
isOpen: boolean;
16+
setIsOpen: (open: boolean) => void;
17+
onConfirm: () => void;
18+
folderPath: string;
19+
}
20+
21+
const DeleteFolderDialog: FC<DeleteFolderDialogProps> = ({
22+
isOpen,
23+
setIsOpen,
24+
onConfirm,
25+
folderPath,
26+
}) => {
27+
const handleConfirm = () => {
28+
onConfirm();
29+
setIsOpen(false);
30+
};
31+
32+
return (
33+
<Dialog open={isOpen} onOpenChange={setIsOpen}>
34+
<DialogContent className="sm:max-w-[500px]">
35+
<DialogHeader>
36+
<div className="flex items-center gap-3">
37+
<div className="flex h-10 w-10 items-center justify-center rounded-full bg-red-100 dark:bg-red-900/20">
38+
<AlertTriangle className="h-5 w-5 text-red-600 dark:text-red-400" />
39+
</div>
40+
<DialogTitle className="text-xl">Delete Folder?</DialogTitle>
41+
</div>
42+
<DialogDescription className="pt-4 text-left">
43+
<div className="space-y-3">
44+
<p className="font-medium text-foreground">
45+
You are about to remove this folder from your library:
46+
</p>
47+
<div className="rounded-md bg-muted p-3">
48+
<code className="text-sm break-all">{folderPath}</code>
49+
</div>
50+
<div className="space-y-2 text-sm">
51+
<p className="font-semibold text-yellow-700 dark:text-yellow-400">
52+
⚠️ This action will:
53+
</p>
54+
<ul className="ml-4 space-y-1 list-disc text-muted-foreground">
55+
<li>Remove the folder from your PictoPy library</li>
56+
<li>Delete all photos in this folder from the library</li>
57+
<li>Remove all face recognition data for these photos</li>
58+
<li>Delete all AI-generated tags and clusters</li>
59+
</ul>
60+
</div>
61+
<div className="rounded-md border border-green-300 bg-green-50 p-3 dark:border-green-700 dark:bg-green-900/20">
62+
<p className="text-sm font-medium text-green-800 dark:text-green-300">
63+
✓ Your actual files on disk will NOT be deleted
64+
</p>
65+
</div>
66+
</div>
67+
</DialogDescription>
68+
</DialogHeader>
69+
70+
<DialogFooter className="gap-2 sm:gap-0">
71+
<Button
72+
variant="outline"
73+
onClick={() => setIsOpen(false)}
74+
className="cursor-pointer"
75+
>
76+
Cancel
77+
</Button>
78+
<Button
79+
variant="destructive"
80+
onClick={handleConfirm}
81+
className="cursor-pointer"
82+
>
83+
Delete from Library
84+
</Button>
85+
</DialogFooter>
86+
</DialogContent>
87+
</Dialog>
88+
);
89+
};
90+
91+
export default DeleteFolderDialog;

frontend/src/pages/SettingsPage/components/FolderManagementCard.tsx

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React from 'react';
1+
import React, { useState } from 'react';
22
import { Folder, Trash2, Check } from 'lucide-react';
33

44
import { Switch } from '@/components/ui/switch';
@@ -11,6 +11,7 @@ import FolderPicker from '@/components/FolderPicker/FolderPicker';
1111
import { useFolderOperations } from '@/hooks/useFolderOperations';
1212
import { FolderDetails } from '@/types/Folder';
1313
import SettingsCard from './SettingsCard';
14+
import DeleteFolderDialog from '@/components/Dialog/DeleteFolderDialog';
1415

1516
/**
1617
* Component for managing folder operations in settings
@@ -29,6 +30,24 @@ const FolderManagementCard: React.FC = () => {
2930
(state: RootState) => state.folders.taggingStatus,
3031
);
3132

33+
// Dialog state for folder deletion confirmation
34+
const [deleteDialogOpen, setDeleteDialogOpen] = useState(false);
35+
const [folderToDelete, setFolderToDelete] = useState<FolderDetails | null>(
36+
null,
37+
);
38+
39+
const handleDeleteClick = (folder: FolderDetails) => {
40+
setFolderToDelete(folder);
41+
setDeleteDialogOpen(true);
42+
};
43+
44+
const handleConfirmDelete = () => {
45+
if (folderToDelete) {
46+
deleteFolder(folderToDelete.folder_id);
47+
setFolderToDelete(null);
48+
}
49+
};
50+
3251
return (
3352
<SettingsCard
3453
icon={Folder}
@@ -68,7 +87,7 @@ const FolderManagementCard: React.FC = () => {
6887
</div>
6988

7089
<Button
71-
onClick={() => deleteFolder(folder.folder_id)}
90+
onClick={() => handleDeleteClick(folder)}
7291
variant="outline"
7392
size="sm"
7493
className="h-8 w-8 cursor-pointer text-gray-500 hover:border-red-300 hover:text-red-600 dark:text-gray-400 dark:hover:text-red-400"
@@ -95,7 +114,7 @@ const FolderManagementCard: React.FC = () => {
95114
0) >= 100 && <Check className="h-3 w-3" />}
96115
{Math.round(
97116
taggingStatus[folder.folder_id]?.tagging_percentage ??
98-
0,
117+
0,
99118
)}
100119
%
101120
</span>
@@ -131,6 +150,14 @@ const FolderManagementCard: React.FC = () => {
131150
<div className="border-border mt-6 border-t pt-6">
132151
<FolderPicker />
133152
</div>
153+
154+
{/* Delete Folder Confirmation Dialog */}
155+
<DeleteFolderDialog
156+
isOpen={deleteDialogOpen}
157+
setIsOpen={setDeleteDialogOpen}
158+
onConfirm={handleConfirmDelete}
159+
folderPath={folderToDelete?.folder_path || ''}
160+
/>
134161
</SettingsCard>
135162
);
136163
};

0 commit comments

Comments
 (0)