From 4e63d8427d26d0d1b366ddc53650e15f3481fc75 Mon Sep 17 00:00:00 2001
From: dujinkim <dujin.kim@dtsolution.co.kr>
Date: Tue, 24 Jun 2025 01:44:03 +0000
Subject: (대표님/최겸) 20250624 작업사항 10시43분
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../reg-eval-criteria-table-toolbar-actions.tsx    | 161 +++++++++++++++++++++
 1 file changed, 161 insertions(+)
 create mode 100644 lib/evaluation-criteria/table/reg-eval-criteria-table-toolbar-actions.tsx

(limited to 'lib/evaluation-criteria/table/reg-eval-criteria-table-toolbar-actions.tsx')

diff --git a/lib/evaluation-criteria/table/reg-eval-criteria-table-toolbar-actions.tsx b/lib/evaluation-criteria/table/reg-eval-criteria-table-toolbar-actions.tsx
new file mode 100644
index 00000000..95b2171e
--- /dev/null
+++ b/lib/evaluation-criteria/table/reg-eval-criteria-table-toolbar-actions.tsx
@@ -0,0 +1,161 @@
+'use client';
+
+/* IMPORT */
+import {
+  AlertDialog,
+  AlertDialogAction,
+  AlertDialogCancel,
+  AlertDialogContent,
+  AlertDialogDescription,
+  AlertDialogFooter,
+  AlertDialogHeader,
+  AlertDialogTitle,
+  AlertDialogTrigger
+} from '@/components/ui/alert-dialog';
+import { Button } from '@/components/ui/button';
+import { Download, Plus, Trash2 } from 'lucide-react';
+import { exportTableToExcel } from '@/lib/export';
+import { removeRegEvalCriteria } from '../service';
+import { type RegEvalCriteriaView } from '@/db/schema';
+import { type Table } from '@tanstack/react-table';
+import { toast } from 'sonner';
+import { useMemo, useState } from 'react';
+
+// ----------------------------------------------------------------------------------------------------
+
+/* TYPES */
+interface RegEvalCriteriaTableToolbarActionsProps {
+  table: Table<RegEvalCriteriaView>,
+  onCreateCriteria?: () => void,
+  onRefresh?: () => void,
+}
+
+// ----------------------------------------------------------------------------------------------------
+
+/* REGULAR EVALUATION CRITERIA TABLE TOOLBAR ACTIONS COMPONENT */
+function RegEvalCriteriaTableToolbarActions(props: RegEvalCriteriaTableToolbarActionsProps) {
+  const { table, onCreateCriteria, onRefresh } = props;
+  const [isDeleting, setIsDeleting] = useState<boolean>(false);
+  const selectedRows = table.getFilteredSelectedRowModel().rows;
+  const hasSelection = selectedRows.length > 0;
+  const selectedIds = useMemo(() => {
+    return [...new Set(selectedRows.map(row => row.original.criteriaId))];
+  }, [selectedRows]);
+
+  // Function for Create New Criteria
+  const handleCreateNew = () => {
+    if (!onCreateCriteria) {
+      return;
+    }
+    onCreateCriteria();
+  }
+
+  const handleDeleteSelected = async () => {
+    if (!hasSelection) {
+      return;
+    }
+    try {
+      setIsDeleting(true);
+
+      for (const selectedId of selectedIds) {
+        if (selectedId) {
+          await removeRegEvalCriteria(selectedId);
+        }
+      }
+      table.resetRowSelection();
+      toast.success(`${selectedIds.length}개의 평가 기준이 삭제되었습니다.`);
+      
+      if (onRefresh) {
+        onRefresh();
+      } else {
+        window.location.reload();
+      }
+    } catch (error) {
+      console.error('Error in Deleting Regular Evaluation Critria: ', error);
+      toast.error(
+        error instanceof Error
+          ? error.message
+          : '평가 기준 삭제 중 오류가 발생했습니다.'
+      );
+    } finally {
+      setIsDeleting(false);
+    }
+  }
+
+  // Excel Export
+  const handleExport = () => {
+    try {
+      exportTableToExcel(table, {
+        filename: 'Regular_Evaluation_Criteria',
+        excludeColumns: ['select', 'actions'],
+      });
+      toast.success('Excel 파일이 다운로드되었습니다.');
+    } catch (error) {
+      console.error('Error in Exporting to Excel: ', error);
+      toast.error('Excel 내보내기 중 오류가 발생했습니다.');
+    }
+  };
+
+  return (
+    <div className="flex items-center gap-2">
+      <Button
+        variant="default"
+        size="sm"
+        className="gap-2"
+        onClick={handleCreateNew}
+      >
+        <Plus className="size-4" aria-hidden="true" />
+        <span className="hidden sm:inline">New Criteria</span>
+      </Button>
+      {hasSelection && (
+        <AlertDialog>
+          <AlertDialogTrigger asChild>
+            <Button
+              variant="destructive"
+              size="sm"
+              className="gap-2"
+              disabled={isDeleting}
+            >
+              <Trash2 className="size-4" aria-hidden="true" />
+              <span className="hidden sm:inline">
+                선택 삭제 ({selectedIds.length})
+              </span>
+            </Button>
+          </AlertDialogTrigger>
+          <AlertDialogContent>
+            <AlertDialogHeader>
+              <AlertDialogTitle>정말 삭제하시겠습니까?</AlertDialogTitle>
+              <AlertDialogDescription>
+                선택된 {selectedIds.length}개의 협력업체 평가 기준 항목이 영구적으로 삭제됩니다. 
+                이 작업은 되돌릴 수 없으며, 연관된 평가 기준과 항목들도 함께 삭제됩니다.
+              </AlertDialogDescription>
+            </AlertDialogHeader>
+            <AlertDialogFooter>
+              <AlertDialogCancel>Cancel</AlertDialogCancel>
+              <AlertDialogAction
+                onClick={handleDeleteSelected}
+                className="bg-destructive text-destructive-foreground hover:bg-destructive/90"
+              >
+                {isDeleting ? 'Deleting...' : 'Delete'}
+              </AlertDialogAction>
+            </AlertDialogFooter>
+          </AlertDialogContent>
+        </AlertDialog>
+      )}
+      <Button
+        variant="outline"
+        size="sm"
+        onClick={handleExport}
+        className="gap-2"
+      >
+        <Download className="size-4" aria-hidden="true" />
+        <span className="hidden sm:inline">Export</span>
+      </Button>
+    </div>
+  );
+}
+
+// ----------------------------------------------------------------------------------------------------
+
+/* EXPORT */
+export default RegEvalCriteriaTableToolbarActions;
\ No newline at end of file
-- 
cgit v1.2.3

