summaryrefslogtreecommitdiff
path: root/lib/general-check-list/table/delete-check-lists-dialog.tsx
diff options
context:
space:
mode:
authordujinkim <dujin.kim@dtsolution.co.kr>2025-06-19 09:44:28 +0000
committerdujinkim <dujin.kim@dtsolution.co.kr>2025-06-19 09:44:28 +0000
commit95bbe9c583ff841220da1267630e7b2025fc36dc (patch)
tree5e3d5bb3302530bbaa7f7abbe8c9cf8193ccbd4c /lib/general-check-list/table/delete-check-lists-dialog.tsx
parent0eb030580b5cbe5f03d570c3c9d8c519bac3b783 (diff)
(대표님) 20250619 1844 KST 작업사항
Diffstat (limited to 'lib/general-check-list/table/delete-check-lists-dialog.tsx')
-rw-r--r--lib/general-check-list/table/delete-check-lists-dialog.tsx106
1 files changed, 106 insertions, 0 deletions
diff --git a/lib/general-check-list/table/delete-check-lists-dialog.tsx b/lib/general-check-list/table/delete-check-lists-dialog.tsx
new file mode 100644
index 00000000..b4b4d648
--- /dev/null
+++ b/lib/general-check-list/table/delete-check-lists-dialog.tsx
@@ -0,0 +1,106 @@
+"use client";
+import * as React from "react";
+import { Button } from "@/components/ui/button";
+import { Dialog, DialogTrigger, DialogContent, DialogHeader, DialogTitle, DialogDescription, DialogFooter, DialogClose } from "@/components/ui/dialog";
+import { Drawer, DrawerTrigger, DrawerContent, DrawerHeader, DrawerTitle, DrawerDescription, DrawerFooter, DrawerClose } from "@/components/ui/drawer";
+import { Trash, Loader } from "lucide-react";
+import { useMediaQuery } from "@/hooks/use-media-query";
+import { deleteGeneralEvaluations } from "@/lib/general-check-list/service";
+import { toast } from "sonner";
+import { useRouter } from "next/navigation";
+
+export function DeleteEvaluationsDialog({
+ evaluations,
+ showTrigger = true,
+ onSuccess,
+ ...props
+}: {
+ evaluations: { id: number; serialNumber: string }[];
+ showTrigger?: boolean;
+ onSuccess?: () => void;
+ open?: boolean;
+ onOpenChange?: (v: boolean) => void;
+}) {
+ const [pending, startTransition] = React.useTransition();
+ const isDesktop = useMediaQuery("(min-width:640px)");
+ const router = useRouter();
+
+ const deleteText = evaluations.length === 1 ? "항목" : "항목들";
+
+ const handleDelete = () => {
+ startTransition(async () => {
+ const res = await deleteGeneralEvaluations(evaluations.map((e) => e.id));
+ if (res.success) {
+ toast.success(res.message);
+ router.refresh();
+ props.onOpenChange?.(false);
+ onSuccess?.();
+ } else {
+ toast.error(res.message);
+ }
+ });
+ };
+
+ const Content = (
+ <>
+ <DialogHeader>
+ <DialogTitle>삭제 확인</DialogTitle>
+ <DialogDescription>
+ 선택된 {evaluations.length}개의 {deleteText}을(를) 삭제합니다. 이 작업은 되돌릴 수 없습니다.
+ </DialogDescription>
+ </DialogHeader>
+ <DialogFooter className="gap-2 sm:space-x-0">
+ <DialogClose asChild>
+ <Button variant="outline">취소</Button>
+ </DialogClose>
+ <Button variant="destructive" onClick={handleDelete} disabled={pending}>
+ {pending && <Loader className="mr-2 size-4 animate-spin" />} 삭제
+ </Button>
+ </DialogFooter>
+ </>
+ );
+
+ if (isDesktop) {
+ return (
+ <Dialog {...props}>
+ {showTrigger && (
+ <DialogTrigger asChild>
+ <Button variant="outline" size="sm">
+ <Trash className="size-4 mr-2" /> 삭제({evaluations.length})
+ </Button>
+ </DialogTrigger>
+ )}
+ <DialogContent>{Content}</DialogContent>
+ </Dialog>
+ );
+ }
+
+ // Mobile Drawer
+ return (
+ <Drawer {...props}>
+ {showTrigger && (
+ <DrawerTrigger asChild>
+ <Button variant="outline" size="sm">
+ <Trash className="size-4 mr-2" /> 삭제({evaluations.length})
+ </Button>
+ </DrawerTrigger>
+ )}
+ <DrawerContent className="p-4 space-y-4">
+ <DrawerHeader>
+ <DrawerTitle>삭제 확인</DrawerTitle>
+ </DrawerHeader>
+ <DrawerDescription>
+ 선택된 {evaluations.length}개의 {deleteText}을(를) 삭제합니다. 이 작업은 되돌릴 수 없습니다.
+ </DrawerDescription>
+ <DrawerFooter className="gap-2 sm:space-x-0">
+ <DrawerClose asChild>
+ <Button variant="outline">취소</Button>
+ </DrawerClose>
+ <Button variant="destructive" onClick={handleDelete} disabled={pending}>
+ {pending && <Loader className="mr-2 size-4 animate-spin" />} 삭제
+ </Button>
+ </DrawerFooter>
+ </DrawerContent>
+ </Drawer>
+ );
+}