← full-stack-fastapi-template  /  frontend/src/components/Items/DeleteItem.tsx

1
import { useMutation, useQueryClient } from "@tanstack/react-query"
2
import { Trash2 } from "lucide-react"
3
import { useState } from "react"
4
import { useForm } from "react-hook-form"
5
6
import { ItemsService } from "@/client"
7
import { Button } from "@/components/ui/button"
8
import {
9
  Dialog,
10
  DialogClose,
11
  DialogContent,
12
  DialogDescription,
13
  DialogFooter,
14
  DialogHeader,
15
  DialogTitle,
16
} from "@/components/ui/dialog"
17
import { DropdownMenuItem } from "@/components/ui/dropdown-menu"
18
import { LoadingButton } from "@/components/ui/loading-button"
19
import useCustomToast from "@/hooks/useCustomToast"
20
import { handleError } from "@/utils"
21
22
interface DeleteItemProps {
23
  id: string
24
  onSuccess: () => void
25
}
26
27
const DeleteItem = ({ id, onSuccess }: DeleteItemProps) => {
28
  const [isOpen, setIsOpen] = useState(false)
29
  const queryClient = useQueryClient()
30
  const { showSuccessToast, showErrorToast } = useCustomToast()
31
  const { handleSubmit } = useForm()
32
33
  const deleteItem = async (id: string) => {
34
    await ItemsService.deleteItem({ id: id })
35
  }
36
37
  const mutation = useMutation({
38
    mutationFn: deleteItem,
39
    onSuccess: () => {
40
      showSuccessToast("The item was deleted successfully")
41
      setIsOpen(false)
42
      onSuccess()
43
    },
44
    onError: handleError.bind(showErrorToast),
45
    onSettled: () => {
46
      queryClient.invalidateQueries()
47
    },
48
  })
49
50
  const onSubmit = async () => {
51
    mutation.mutate(id)
52
  }
53
54
  return (
55
    <Dialog open={isOpen} onOpenChange={setIsOpen}>
56
      <DropdownMenuItem
57
        variant="destructive"
58
        onSelect={(e) => e.preventDefault()}
59
        onClick={() => setIsOpen(true)}
60
      >
61
        <Trash2 />
62
        Delete Item
63
      </DropdownMenuItem>
64
      <DialogContent className="sm:max-w-md">
65
        <form onSubmit={handleSubmit(onSubmit)}>
66
          <DialogHeader>
67
            <DialogTitle>Delete Item</DialogTitle>
68
            <DialogDescription>
69
              This item will be permanently deleted. Are you sure? You will not
70
              be able to undo this action.
71
            </DialogDescription>
72
          </DialogHeader>
73
74
          <DialogFooter className="mt-4">
75
            <DialogClose asChild>
76
              <Button variant="outline" disabled={mutation.isPending}>
77
                Cancel
78
              </Button>
79
            </DialogClose>
80
            <LoadingButton
81
              variant="destructive"
82
              type="submit"
83
              loading={mutation.isPending}
84
            >
85
              Delete
86
            </LoadingButton>
87
          </DialogFooter>
88
        </form>
89
      </DialogContent>
90
    </Dialog>
91
  )
92
}
93
94
export default DeleteItem
95