summaryrefslogtreecommitdiff
path: root/lib/risk-management/table/risks-table-toolbar-actions.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'lib/risk-management/table/risks-table-toolbar-actions.tsx')
-rw-r--r--lib/risk-management/table/risks-table-toolbar-actions.tsx161
1 files changed, 161 insertions, 0 deletions
diff --git a/lib/risk-management/table/risks-table-toolbar-actions.tsx b/lib/risk-management/table/risks-table-toolbar-actions.tsx
new file mode 100644
index 00000000..2d4ba2d4
--- /dev/null
+++ b/lib/risk-management/table/risks-table-toolbar-actions.tsx
@@ -0,0 +1,161 @@
+'use client';
+
+/* IMPORT */
+import { Button } from '@/components/ui/button';
+import { ChangeEvent, useRef } from 'react';
+import { Download, FileInput, Mail, Upload } from 'lucide-react';
+import { exportTableToExcel } from '@/lib/export';
+import { generateRiskEventsTemplate, importRiskEventsExcel } from '../service';
+import { toast } from 'sonner';
+import { type DataTableRowAction } from '@/types/table';
+import { type RisksView } from '@/db/schema';
+import { type Table } from '@tanstack/react-table';
+
+// ----------------------------------------------------------------------------------------------------
+
+/* TYPES */
+interface RisksTableToolbarActionsProps {
+ table: Table<RisksView>;
+ onOpenMailDialog: () => void;
+ onRefresh: () => void;
+}
+
+// ----------------------------------------------------------------------------------------------------
+
+/* RISKS TABLE TOOLBAR ACTIONS COMPONENT */
+function RisksTableToolbarActions(props: RisksTableToolbarActionsProps) {
+ const { table, onOpenMailDialog, onRefresh } = props;
+ const selectedRows = table.getFilteredSelectedRowModel().rows;
+ const hasSelection = selectedRows.length > 0;
+ const fileInputRef = useRef<HTMLInputElement>(null);
+
+ // EXCEL IMPORT
+ function handleImport() {
+ fileInputRef.current?.click();
+ };
+ async function onFileChange(event: ChangeEvent<HTMLInputElement>) {
+ 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 importRiskEventsExcel(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 = async () => {
+ try {
+ exportTableToExcel(table, {
+ filename: '협력업체_리스크_관리',
+ excludeColumns: ['id', 'actions'],
+ });
+ toast.success('Excel 파일이 다운로드되었어요.');
+ } catch (error) {
+ console.error('Error in Exporting to Excel: ', error);
+ toast.error('Excel 파일 내보내기 중 오류가 발생했어요.');
+ }
+ };
+
+ // EXCEL TEMPLATE DOWNLOAD
+ const handleTemplateDownload = async () => {
+ try {
+ const buffer = await generateRiskEventsTemplate();
+ const blob = new Blob([buffer], {
+ type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
+ });
+ const url = URL.createObjectURL(blob);
+ const link = document.createElement('a');
+ link.href = url;
+ link.download = "협력업체_리스크_템플릿.xlsx";
+ link.click();
+ URL.revokeObjectURL(url);
+ toast.success('템플릿 파일이 다운로드되었어요.');
+ } catch (error) {
+ console.error('Error in Template Download: ', error);
+ toast.error('템플릿 다운로드 중 오류가 발생했어요.');
+ }
+ };
+
+ return (
+ <div className="flex items-center gap-2">
+ <Button
+ size="sm"
+ className="gap-2"
+ onClick={onOpenMailDialog}
+ disabled={!hasSelection}
+ >
+ <Mail className="size-4" aria-hidden="true" />
+ <span className="hidden sm:inline">
+ 메일 발송
+ </span>
+ </Button>
+ <Button
+ variant="outline"
+ size="sm"
+ className="gap-2"
+ onClick={handleImport}
+ >
+ <Upload className="size-4" aria-hidden="true" />
+ <span className="hidden sm:inline">Import</span>
+ </Button>
+ <input
+ ref={fileInputRef}
+ type="file"
+ accept=".xlsx,.xls"
+ className="hidden"
+ onChange={onFileChange}
+ />
+ <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>
+ <Button
+ variant="outline"
+ size="sm"
+ onClick={handleTemplateDownload}
+ className="gap-2"
+ >
+ <FileInput className="size-4" aria-hidden="true" />
+ <span className="hidden sm:inline">Template</span>
+ </Button>
+ </div>
+ );
+}
+
+// ----------------------------------------------------------------------------------------------------
+
+/* EXPORT */
+export default RisksTableToolbarActions; \ No newline at end of file