import { useMutation } from "@tanstack/react-query"; import type { AxiosError } from "axios"; import { Download, FileText, Loader2, Upload } from "lucide-react"; import * as React from "react"; import { toast } from "sonner"; import { Button } from "../../../components/ui/button"; import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger, } from "../../../components/ui/dialog"; import { importOrgChart } from "../../../lib/adminApi"; import { t } from "../../../lib/i18n"; interface OrgChartUploadModalProps { tenantId: string; onSuccess?: () => void; } export function OrgChartUploadModal({ tenantId, onSuccess, }: OrgChartUploadModalProps) { const [open, setOpen] = React.useState(false); const [file, setFile] = React.useState(null); const fileInputRef = React.useRef(null); const mutation = useMutation({ mutationFn: (file: File) => importOrgChart(tenantId, file), onSuccess: () => { toast.success( t( "msg.admin.org.import_success", "조직도가 성공적으로 업로드되었습니다.", ), ); setOpen(false); onSuccess?.(); }, onError: (error: AxiosError<{ error?: string }>) => { toast.error(t("msg.admin.org.import_error", "조직도 업로드 실패"), { description: error.response?.data?.error || error.message, }); }, }); const handleFileChange = (e: React.ChangeEvent) => { const selectedFile = e.target.files?.[0]; if (selectedFile) { setFile(selectedFile); } }; const handleUpload = () => { if (file) { mutation.mutate(file); } }; const downloadTemplate = () => { const headers = "email,name,organization,position,jobtitle,is_owner"; const example = `ceo@example.com,홍길동,경영진,대표이사,경영총괄,true cto@example.com,이몽룡,기술부문,이사,기술총괄,true user1@example.com,성춘향,기술부문/개발팀,팀원,프론트엔드 개발,false`; const blob = new Blob( [ `${headers} ${example}`, ], { type: "text/csv" }, ); const url = URL.createObjectURL(blob); const a = document.createElement("a"); a.href = url; a.download = "org_chart_template.csv"; a.click(); URL.revokeObjectURL(url); }; return ( {t("ui.admin.org.import_title", "조직도 일괄 등록")} {t( "msg.admin.org.import_description", "CSV 파일을 업로드하여 조직 계층과 멤버를 한 번에 구성합니다.", )}
{file && (
{file.name}
{(file.size / 1024).toFixed(1)} KB
)}
); }