diff options
Diffstat (limited to 'lib/contact-possible-items/table/delete-contact-possible-items-dialog.tsx')
| -rw-r--r-- | lib/contact-possible-items/table/delete-contact-possible-items-dialog.tsx | 111 |
1 files changed, 111 insertions, 0 deletions
diff --git a/lib/contact-possible-items/table/delete-contact-possible-items-dialog.tsx b/lib/contact-possible-items/table/delete-contact-possible-items-dialog.tsx new file mode 100644 index 00000000..7c2fc459 --- /dev/null +++ b/lib/contact-possible-items/table/delete-contact-possible-items-dialog.tsx @@ -0,0 +1,111 @@ +"use client"
+
+import * as React from "react"
+import { Loader2, Trash2Icon } from "lucide-react"
+
+import {
+ AlertDialog,
+ AlertDialogCancel,
+ AlertDialogContent,
+ AlertDialogDescription,
+ AlertDialogFooter,
+ AlertDialogHeader,
+ AlertDialogTitle,
+ AlertDialogTrigger,
+} from "@/components/ui/alert-dialog"
+import { Button } from "@/components/ui/button"
+import { toast } from "@/hooks/use-toast"
+
+import { deleteContactPossibleItems, type ContactPossibleItemDetail } from "../service"
+
+interface DeleteContactPossibleItemsDialogProps {
+ contactPossibleItems: ContactPossibleItemDetail[]
+ showTrigger?: boolean
+ trigger?: React.ReactNode
+ open?: boolean
+ onOpenChange?: (open: boolean) => void
+ onSuccess?: () => void
+}
+
+export function DeleteContactPossibleItemsDialog({
+ contactPossibleItems,
+ showTrigger = true,
+ trigger,
+ open,
+ onOpenChange,
+ onSuccess,
+}: DeleteContactPossibleItemsDialogProps) {
+ const [isDeletePending, startDeleteTransition] = React.useTransition()
+
+ function onDelete() {
+ startDeleteTransition(async () => {
+ try {
+ const ids = contactPossibleItems.map((item) => item.id)
+ const result = await deleteContactPossibleItems(ids)
+
+ if (result.success) {
+ toast({
+ title: "성공",
+ description: `${contactPossibleItems.length}개의 담당자별 아이템이 삭제되었습니다.`,
+ })
+ onSuccess?.()
+ onOpenChange?.(false)
+ } else {
+ toast({
+ title: "오류",
+ description: result.error || "담당자별 아이템 삭제에 실패했습니다.",
+ variant: "destructive",
+ })
+ }
+ } catch {
+ toast({
+ title: "오류",
+ description: "담당자별 아이템 삭제 중 오류가 발생했습니다.",
+ variant: "destructive",
+ })
+ }
+ })
+ }
+
+ const isMultiple = contactPossibleItems.length > 1
+
+ return (
+ <AlertDialog open={open} onOpenChange={onOpenChange}>
+ {showTrigger && (
+ <AlertDialogTrigger asChild>
+ {trigger ?? (
+ <Button variant="outline" size="sm">
+ <Trash2Icon className="mr-2 size-4" aria-hidden="true" />
+ 삭제 ({contactPossibleItems.length})
+ </Button>
+ )}
+ </AlertDialogTrigger>
+ )}
+ <AlertDialogContent>
+ <AlertDialogHeader>
+ <AlertDialogTitle>
+ {isMultiple
+ ? `${contactPossibleItems.length}개의 담당자별 아이템을 삭제하시겠습니까?`
+ : "담당자별 아이템을 삭제하시겠습니까?"}
+ </AlertDialogTitle>
+ <AlertDialogDescription>
+ 이 작업은 되돌릴 수 없습니다. 선택한 담당자별 아이템{isMultiple ? "들이" : "이"} 영구적으로 삭제됩니다.
+ </AlertDialogDescription>
+ </AlertDialogHeader>
+ <AlertDialogFooter>
+ <AlertDialogCancel disabled={isDeletePending}>취소</AlertDialogCancel>
+ <Button
+ variant="destructive"
+ onClick={onDelete}
+ disabled={isDeletePending}
+ >
+ {isDeletePending && (
+ <Loader2 className="mr-2 size-4 animate-spin" aria-hidden="true" />
+ )}
+ 삭제
+ </Button>
+ </AlertDialogFooter>
+ </AlertDialogContent>
+ </AlertDialog>
+ )
+}
\ No newline at end of file |
