From e9897d416b3e7327bbd4d4aef887eee37751ae82 Mon Sep 17 00:00:00 2001 From: dujinkim Date: Fri, 27 Jun 2025 01:16:20 +0000 Subject: (대표님) 20250627 오전 10시 작업사항 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../reg-eval-criteria-table-toolbar-actions.tsx | 80 ++++++++++++++++++---- 1 file changed, 65 insertions(+), 15 deletions(-) (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 index 95b2171e..b14cb22f 100644 --- a/lib/evaluation-criteria/table/reg-eval-criteria-table-toolbar-actions.tsx +++ b/lib/evaluation-criteria/table/reg-eval-criteria-table-toolbar-actions.tsx @@ -13,21 +13,21 @@ import { AlertDialogTrigger } from '@/components/ui/alert-dialog'; import { Button } from '@/components/ui/button'; -import { Download, Plus, Trash2 } from 'lucide-react'; +import { Download, Plus, Trash2, Upload } from 'lucide-react'; import { exportTableToExcel } from '@/lib/export'; -import { removeRegEvalCriteria } from '../service'; +import { importRegEvalCriteriaExcel, removeRegEvalCriteria } from '../service'; +import { toast } from 'sonner'; import { type RegEvalCriteriaView } from '@/db/schema'; import { type Table } from '@tanstack/react-table'; -import { toast } from 'sonner'; -import { useMemo, useState } from 'react'; +import { ChangeEvent, useMemo, useRef, useState } from 'react'; // ---------------------------------------------------------------------------------------------------- /* TYPES */ interface RegEvalCriteriaTableToolbarActionsProps { table: Table, - onCreateCriteria?: () => void, - onRefresh?: () => void, + onCreateCriteria: () => void, + onRefresh: () => void, } // ---------------------------------------------------------------------------------------------------- @@ -41,12 +41,10 @@ function RegEvalCriteriaTableToolbarActions(props: RegEvalCriteriaTableToolbarAc const selectedIds = useMemo(() => { return [...new Set(selectedRows.map(row => row.original.criteriaId))]; }, [selectedRows]); + const fileInputRef = useRef(null); // Function for Create New Criteria const handleCreateNew = () => { - if (!onCreateCriteria) { - return; - } onCreateCriteria(); } @@ -64,12 +62,7 @@ function RegEvalCriteriaTableToolbarActions(props: RegEvalCriteriaTableToolbarAc } table.resetRowSelection(); toast.success(`${selectedIds.length}개의 평가 기준이 삭제되었습니다.`); - - if (onRefresh) { - onRefresh(); - } else { - window.location.reload(); - } + onRefresh(); } catch (error) { console.error('Error in Deleting Regular Evaluation Critria: ', error); toast.error( @@ -82,6 +75,47 @@ function RegEvalCriteriaTableToolbarActions(props: RegEvalCriteriaTableToolbarAc } } + // Excel Import + function handleImport() { + fileInputRef.current?.click(); + }; + async function onFileChange(event: ChangeEvent) { + const file = event.target.files?.[0]; + if (!file) { + toast.error('가져올 파일을 선택해주세요.'); + return; + } + if (!file.name.endsWith('.xlsx') && !file.name.endsWith('.xls')) { + toast.error('.xlsx 또는 .xls 확장자인 Excel 파일만 업로드 가능합니다.'); + return; + } + event.target.value = ''; + + try { + const { errorFile, errorMessage, successMessage } = await importRegEvalCriteriaExcel(file); + + if (errorMessage) { + toast.error(errorMessage); + + if (errorFile) { + const url = URL.createObjectURL(errorFile); + const link = document.createElement('a'); + link.href = url; + link.download = 'errors.xlsx'; + link.click(); + URL.revokeObjectURL(url); + } + } else { + toast.success(successMessage || 'Excel 파일이 성공적으로 업로드 되었습니다.'); + } + } catch (error) { + toast.error('Excel 파일 업로드 중 오류가 발생했습니다.'); + console.error('Error in Excel File Upload: ', error); + } finally { + onRefresh(); + } + }; + // Excel Export const handleExport = () => { try { @@ -142,6 +176,22 @@ function RegEvalCriteriaTableToolbarActions(props: RegEvalCriteriaTableToolbarAc )} + +