diff options
| author | dujinkim <dujin.kim@dtsolution.co.kr> | 2025-06-19 09:44:28 +0000 |
|---|---|---|
| committer | dujinkim <dujin.kim@dtsolution.co.kr> | 2025-06-19 09:44:28 +0000 |
| commit | 95bbe9c583ff841220da1267630e7b2025fc36dc (patch) | |
| tree | 5e3d5bb3302530bbaa7f7abbe8c9cf8193ccbd4c /lib/esg-check-list/table/esg-evaluation-delete-dialog.tsx | |
| parent | 0eb030580b5cbe5f03d570c3c9d8c519bac3b783 (diff) | |
(대표님) 20250619 1844 KST 작업사항
Diffstat (limited to 'lib/esg-check-list/table/esg-evaluation-delete-dialog.tsx')
| -rw-r--r-- | lib/esg-check-list/table/esg-evaluation-delete-dialog.tsx | 168 |
1 files changed, 168 insertions, 0 deletions
diff --git a/lib/esg-check-list/table/esg-evaluation-delete-dialog.tsx b/lib/esg-check-list/table/esg-evaluation-delete-dialog.tsx new file mode 100644 index 00000000..ac667483 --- /dev/null +++ b/lib/esg-check-list/table/esg-evaluation-delete-dialog.tsx @@ -0,0 +1,168 @@ +"use client" + +import { EsgEvaluationsView } from "@/db/schema" +import React from "react" +import { toast } from "sonner" +import { useTransition } from "react" +import { Button } from "@/components/ui/button" +import { + Dialog, + DialogContent, + DialogDescription, + DialogFooter, + DialogHeader, + DialogTitle, +} from "@/components/ui/dialog" +import { ScrollArea } from "@/components/ui/scroll-area" +import { Badge } from "@/components/ui/badge" + +// 서비스 함수 import +import { deleteEsgEvaluationsBatch, softDeleteEsgEvaluationsBatch } from "../service" + +interface EsgEvaluationBatchDeleteDialogProps { + open: boolean + onOpenChange: (open: boolean) => void + evaluations: EsgEvaluationsView[] + onSuccess: () => void + useSoftDelete?: boolean // 소프트 삭제 사용 여부 +} + +export function EsgEvaluationBatchDeleteDialog({ + open, + onOpenChange, + evaluations, + onSuccess, + useSoftDelete = false, +}: EsgEvaluationBatchDeleteDialogProps) { + const [isPending, startTransition] = useTransition() + + const evaluationCount = evaluations.length + const isSingle = evaluationCount === 1 + + const handleDelete = async () => { + if (evaluationCount === 0) return + + startTransition(async () => { + try { + const ids = evaluations.map((evaluation) => evaluation.id) + + let result + if (useSoftDelete) { + result = await softDeleteEsgEvaluationsBatch(ids) + } else { + result = await deleteEsgEvaluationsBatch(ids) + } + + // 성공 메시지 + if (result.failed > 0) { + toast.warning( + `${result.deleted}개 삭제 완료, ${result.failed}개 실패했습니다.` + ) + } else { + toast.success( + isSingle + ? '평가표가 삭제되었습니다.' + : `${result.deleted}개의 평가표가 삭제되었습니다.` + ) + } + + onSuccess() + onOpenChange(false) + } catch (error) { + console.error('Error deleting evaluations:', error) + toast.error( + error instanceof Error ? error.message : '삭제 중 오류가 발생했습니다.' + ) + } + }) + } + + if (evaluationCount === 0) return null + + return ( + <Dialog open={open} onOpenChange={onOpenChange}> + <DialogContent className="max-w-2xl"> + <DialogHeader> + <DialogTitle> + {isSingle ? '평가표 삭제' : `평가표 일괄 삭제 (${evaluationCount}개)`} + </DialogTitle> + <DialogDescription> + {isSingle ? ( + <> + 정말로 이 ESG 평가표를 삭제하시겠습니까? + <br /> + 이 작업은 되돌릴 수 없으며, 연관된 모든 평가항목과 답변옵션들도 함께 삭제됩니다. + </> + ) : ( + <> + 선택된 {evaluationCount}개의 ESG 평가표를 삭제하시겠습니까? + <br /> + 이 작업은 되돌릴 수 없으며, 연관된 모든 평가항목과 답변옵션들도 함께 삭제됩니다. + </> + )} + </DialogDescription> + </DialogHeader> + + {/* 삭제될 평가표 목록 */} + <div className="py-4"> + <h4 className="text-sm font-medium mb-3"> + {isSingle ? '삭제될 평가표:' : '삭제될 평가표 목록:'} + </h4> + + <ScrollArea className={evaluationCount > 5 ? "h-[200px]" : "h-auto"}> + <div className="space-y-3"> + {evaluations.map((evaluation, index) => ( + <div + key={evaluation.id} + className="p-3 border rounded-lg bg-muted/50" + > + <div className="flex items-start justify-between gap-3"> + <div className="flex-1 space-y-1"> + <div className="flex items-center gap-2"> + <Badge variant="outline" className="text-xs"> + {evaluation.serialNumber} + </Badge> + <span className="text-sm font-medium"> + {evaluation.category} + </span> + </div> + <p className="text-xs text-muted-foreground line-clamp-2"> + {evaluation.inspectionItem} + </p> + <div className="flex gap-4 text-xs text-muted-foreground"> + <span>평가항목: {evaluation.totalEvaluationItems}개</span> + <span>답변옵션: {evaluation.totalAnswerOptions}개</span> + </div> + </div> + </div> + </div> + ))} + </div> + </ScrollArea> + </div> + + <DialogFooter> + <Button + variant="outline" + onClick={() => onOpenChange(false)} + disabled={isPending} + > + 취소 + </Button> + <Button + variant="destructive" + onClick={handleDelete} + disabled={isPending} + > + {isPending + ? '삭제 중...' + : isSingle + ? '삭제' + : `${evaluationCount}개 삭제` + } + </Button> + </DialogFooter> + </DialogContent> + </Dialog> + ) +}
\ No newline at end of file |
