@@ -23,7 +23,18 @@ import {
23
23
} from '@/components/ui/dialog' ;
24
24
import { useToast } from '@/hooks/use-toast' ;
25
25
import { Loader2 } from 'lucide-react' ;
26
- import { get , post } from '@/utils/api' ;
26
+ import { get , post , del } from '@/utils/api' ;
27
+ import {
28
+ AlertDialog ,
29
+ AlertDialogAction ,
30
+ AlertDialogCancel ,
31
+ AlertDialogContent ,
32
+ AlertDialogDescription ,
33
+ AlertDialogFooter ,
34
+ AlertDialogHeader ,
35
+ AlertDialogTitle ,
36
+ AlertDialogTrigger ,
37
+ } from '@/components/ui/alert-dialog' ;
27
38
28
39
interface User {
29
40
id : string ;
@@ -105,6 +116,28 @@ export default function UsersPage() {
105
116
} ,
106
117
} ) ;
107
118
119
+ const deleteUserMutation = useMutation ( {
120
+ mutationFn : async ( userId : string ) => {
121
+ const response = await del ( `/users/${ userId } ` ) ;
122
+ const data = await response . json ( ) ;
123
+ return data ;
124
+ } ,
125
+ onSuccess : ( ) => {
126
+ queryClient . invalidateQueries ( { queryKey : [ 'users' ] } ) ;
127
+ toast ( {
128
+ title : 'Success' ,
129
+ description : 'User deleted successfully' ,
130
+ } ) ;
131
+ } ,
132
+ onError : ( error : Error ) => {
133
+ toast ( {
134
+ title : 'Error' ,
135
+ description : error . message ,
136
+ variant : 'destructive' ,
137
+ } ) ;
138
+ } ,
139
+ } ) ;
140
+
108
141
const fetchUsers = useCallback ( async ( ) => {
109
142
try {
110
143
const response = await get ( '/users' ) ;
@@ -144,6 +177,10 @@ export default function UsersPage() {
144
177
} ) ;
145
178
} ;
146
179
180
+ const handleDeleteUser = ( userId : string ) => {
181
+ deleteUserMutation . mutate ( userId ) ;
182
+ } ;
183
+
147
184
return (
148
185
< div className = "space-y-4" >
149
186
< div className = "flex justify-between items-center" >
@@ -225,14 +262,49 @@ export default function UsersPage() {
225
262
</ TableCell >
226
263
< TableCell > { user . is_admin ? 'Admin' : 'User' } </ TableCell >
227
264
< TableCell >
228
- < Button
229
- variant = { user . is_admin ? "destructive" : "secondary" }
230
- size = "sm"
231
- onClick = { ( ) => handleToggleAdmin ( user . id , user . is_admin ) }
232
- disabled = { updateUserMutation . isPending }
233
- >
234
- { user . is_admin ? 'Remove Admin' : 'Make Admin' }
235
- </ Button >
265
+ < div className = "flex gap-2" >
266
+ < Button
267
+ variant = { user . is_admin ? "destructive" : "secondary" }
268
+ size = "sm"
269
+ onClick = { ( ) => handleToggleAdmin ( user . id , user . is_admin ) }
270
+ disabled = { updateUserMutation . isPending }
271
+ >
272
+ { user . is_admin ? 'Remove Admin' : 'Make Admin' }
273
+ </ Button >
274
+ < AlertDialog >
275
+ < AlertDialogTrigger asChild >
276
+ < Button variant = "destructive" size = "sm" >
277
+ Delete
278
+ </ Button >
279
+ </ AlertDialogTrigger >
280
+ < AlertDialogContent >
281
+ < AlertDialogHeader >
282
+ < AlertDialogTitle > Are you sure?</ AlertDialogTitle >
283
+ < AlertDialogDescription >
284
+ This action cannot be undone. This will permanently delete the user account
285
+ and all associated data.
286
+ </ AlertDialogDescription >
287
+ </ AlertDialogHeader >
288
+ < AlertDialogFooter >
289
+ < AlertDialogCancel > Cancel</ AlertDialogCancel >
290
+ < AlertDialogAction
291
+ onClick = { ( ) => handleDeleteUser ( user . id ) }
292
+ className = "bg-destructive text-destructive-foreground hover:bg-destructive/90"
293
+ disabled = { deleteUserMutation . isPending }
294
+ >
295
+ { deleteUserMutation . isPending ? (
296
+ < >
297
+ < Loader2 className = "mr-2 h-4 w-4 animate-spin" />
298
+ Deleting...
299
+ </ >
300
+ ) : (
301
+ 'Delete'
302
+ ) }
303
+ </ AlertDialogAction >
304
+ </ AlertDialogFooter >
305
+ </ AlertDialogContent >
306
+ </ AlertDialog >
307
+ </ div >
236
308
</ TableCell >
237
309
</ TableRow >
238
310
) ) }
0 commit comments