diff options
Diffstat (limited to 'lib/tech-vendors/possible-items')
| -rw-r--r-- | lib/tech-vendors/possible-items/possible-items-toolbar-actions.tsx | 151 |
1 files changed, 148 insertions, 3 deletions
diff --git a/lib/tech-vendors/possible-items/possible-items-toolbar-actions.tsx b/lib/tech-vendors/possible-items/possible-items-toolbar-actions.tsx index 371f88f9..bed65727 100644 --- a/lib/tech-vendors/possible-items/possible-items-toolbar-actions.tsx +++ b/lib/tech-vendors/possible-items/possible-items-toolbar-actions.tsx @@ -2,7 +2,7 @@ import * as React from "react" import type { Table } from "@tanstack/react-table" -import { Plus, Trash2, Upload, Download } from "lucide-react" +import { Plus, Trash2, Upload, Download, Users } from "lucide-react" import { toast } from "sonner" import { Button } from "@/components/ui/button" @@ -26,7 +26,14 @@ import { generatePossibleItemsImportTemplate, generatePossibleItemsErrorExcel, type PossibleItemImportData, - type PossibleItemErrorData + type PossibleItemErrorData, + // Contact Possible Import 관련 함수들 + parseContactPossibleItemsImportFile, + importContactPossibleItemsFromExcel, + generateContactPossibleItemsImportTemplate, + generateContactPossibleItemsErrorExcel, + type ContactPossibleItemImportData, + type ContactPossibleItemErrorData } from "../service" interface PossibleItemsTableToolbarActionsProps { @@ -45,7 +52,9 @@ export function PossibleItemsTableToolbarActions({ const [showDeleteAlert, setShowDeleteAlert] = React.useState(false) const [isDeleting, setIsDeleting] = React.useState(false) const [isImporting, setIsImporting] = React.useState(false) + const [isContactImporting, setIsContactImporting] = React.useState(false) const fileInputRef = React.useRef<HTMLInputElement>(null) + const contactFileInputRef = React.useRef<HTMLInputElement>(null) const selectedRows = table.getFilteredSelectedRowModel().rows @@ -163,6 +172,98 @@ export function PossibleItemsTableToolbarActions({ } } + // Contact Possible Import용 템플릿 다운로드 핸들러 + async function handleContactTemplateDownload() { + try { + const templateBlob = await generateContactPossibleItemsImportTemplate() + const url = window.URL.createObjectURL(templateBlob) + const link = document.createElement("a") + link.href = url + link.download = "담당자별_아이템매핑_템플릿.xlsx" + document.body.appendChild(link) + link.click() + document.body.removeChild(link) + window.URL.revokeObjectURL(url) + toast.success("템플릿 파일이 다운로드되었습니다") + } catch (error) { + toast.error("템플릿 다운로드 중 오류가 발생했습니다") + } + } + + // Contact Possible Import용 파일 선택 핸들러 + function handleContactFileSelect() { + contactFileInputRef.current?.click() + } + + // Contact Possible Import 핸들러 + async function handleContactFileImport(event: React.ChangeEvent<HTMLInputElement>) { + const file = event.target.files?.[0] + if (!file) return + + // 파일 타입 검증 + if (!file.name.endsWith('.xlsx') && !file.name.endsWith('.xls')) { + toast.error("Excel 파일(.xlsx 또는 .xls)만 업로드 가능합니다") + return + } + + setIsContactImporting(true) + try { + // Excel 파일 파싱 (새로운 함수 사용) + const importData: ContactPossibleItemImportData[] = await parseContactPossibleItemsImportFile(file) + + if (importData.length === 0) { + toast.error("업로드할 데이터가 없습니다") + return + } + + // 데이터 import 실행 (새로운 함수 사용) + const result = await importContactPossibleItemsFromExcel(importData) + console.log(result) + // 결과 메시지 생성 + const successMessage = `${result.successCount}개의 아이템 매핑이 성공적으로 등록되었습니다` + const failMessage = result.failedRows.length > 0 + ? `, ${result.failedRows.length}개의 매핑 등록 실패` + : "" + + toast.success(successMessage + failMessage) + + // 실패한 행이 있는 경우 에러 파일 다운로드 + if (result.failedRows.length > 0) { + const errorData: ContactPossibleItemErrorData[] = result.failedRows.map(failedRow => ({ + contactEmail: failedRow.contactEmail, + itemCode: Array.isArray(failedRow.itemCode) ? failedRow.itemCode.join(', ') : failedRow.itemCode, + error: failedRow.error, + })) + + const errorBlob = await generateContactPossibleItemsErrorExcel(errorData) + const url = window.URL.createObjectURL(errorBlob) + const link = document.createElement("a") + link.href = url + link.download = "contact_possible_items_import_에러.xlsx" + document.body.appendChild(link) + link.click() + document.body.removeChild(link) + window.URL.revokeObjectURL(url) + + toast.error("에러 내역 파일이 다운로드되었습니다") + } + + // 파일 입력 초기화 + if (contactFileInputRef.current) { + contactFileInputRef.current.value = "" + } + + // 데이터 새로고침 + onRefresh?.() + + } catch (error) { + console.error("Contact Possible Import error:", error) + toast.error(error instanceof Error ? error.message : "데이터 등록 중 오류가 발생했습니다") + } finally { + setIsContactImporting(false) + } + } + return ( <> <div className="flex items-center gap-2"> @@ -201,7 +302,42 @@ export function PossibleItemsTableToolbarActions({ </TooltipContent> </Tooltip> - {/* 숨겨진 파일 입력 */} + {/* Contact Possible Import 템플릿 버튼 */} + <Tooltip> + <TooltipTrigger asChild> + <Button + variant="outline" + size="sm" + onClick={handleContactTemplateDownload} + > + <Download className="mr-2 h-4 w-4" /> + 담당자 템플릿 + </Button> + </TooltipTrigger> + <TooltipContent> + 담당자별 아이템 매핑 템플릿 다운로드 + </TooltipContent> + </Tooltip> + + {/* Contact Possible Import 버튼 */} + <Tooltip> + <TooltipTrigger asChild> + <Button + variant="outline" + size="sm" + onClick={handleContactFileSelect} + disabled={isContactImporting} + > + <Users className="mr-2 h-4 w-4" /> + {isContactImporting ? "등록 중..." : "Contact Import"} + </Button> + </TooltipTrigger> + <TooltipContent> + 담당자별 아이템 매핑 등록 + </TooltipContent> + </Tooltip> + + {/* 숨겨진 파일 입력들 */} <input ref={fileInputRef} type="file" @@ -210,6 +346,15 @@ export function PossibleItemsTableToolbarActions({ className="hidden" /> + {/* Contact Possible Import용 숨겨진 파일 입력 */} + <input + ref={contactFileInputRef} + type="file" + accept=".xlsx,.xls" + onChange={handleContactFileImport} + className="hidden" + /> + {/* 아이템 추가 버튼 주석처리 */} <Button variant="outline" |
