diff options
Diffstat (limited to 'lib/roles/table/role-table-toolbar-actions.tsx')
| -rw-r--r-- | lib/roles/table/role-table-toolbar-actions.tsx | 101 |
1 files changed, 101 insertions, 0 deletions
diff --git a/lib/roles/table/role-table-toolbar-actions.tsx b/lib/roles/table/role-table-toolbar-actions.tsx new file mode 100644 index 00000000..66e279d6 --- /dev/null +++ b/lib/roles/table/role-table-toolbar-actions.tsx @@ -0,0 +1,101 @@ +"use client" + +import * as React from "react" +import { type Table } from "@tanstack/react-table" +import { Download, Upload } from "lucide-react" +import { toast } from "sonner" + +import { exportTableToExcel } from "@/lib/export" +import { Button } from "@/components/ui/button" + +// 삭제, 추가 다이얼로그 + +// 만약 서버 액션이나 API 라우트를 이용해 업로드 처리한다면 import +import { importTasksExcel } from "@/lib/tasks/service" // 예시 +import { AddRoleDialog } from "./add-role-dialog" +import { DeleteRolesDialog } from "./delete-roles-dialog" +import { RoleView } from "@/db/schema/users" + +interface RoleTableToolbarActionsProps { + table: Table<RoleView> +} + +export function RoleTableToolbarActions({ table }: RoleTableToolbarActionsProps) { + // 파일 input을 숨기고, 버튼 클릭 시 참조해 클릭하는 방식 + const fileInputRef = React.useRef<HTMLInputElement>(null) + + // 파일이 선택되었을 때 처리 + async function onFileChange(event: React.ChangeEvent<HTMLInputElement>) { + const file = event.target.files?.[0] + if (!file) return + + // 파일 초기화 (동일 파일 재업로드 시에도 onChange가 트리거되도록) + event.target.value = "" + + // 서버 액션 or API 호출 + try { + // 예: 서버 액션 호출 + const { errorFile, errorMessage } = await importTasksExcel(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("Import success") + // 필요 시 revalidateTag("tasks") 등 + } + + } catch (err) { + toast.error("파일 업로드 중 오류가 발생했습니다.") + + } + } + + function handleImportClick() { + // 숨겨진 <input type="file" /> 요소를 클릭 + fileInputRef.current?.click() + } + + return ( + <div className="flex items-center gap-2"> + + {table.getFilteredSelectedRowModel().rows.length > 0 ? ( + <DeleteRolesDialog + roles={table + .getFilteredSelectedRowModel() + .rows.map((row) => row.original)} + onSuccess={() => table.toggleAllRowsSelected(false)} + /> + ) : null} + + <AddRoleDialog /> + + + + {/** 4) Export 버튼 */} + <Button + variant="outline" + size="sm" + onClick={() => + exportTableToExcel(table, { + filename: "roles", + excludeColumns: ["select", "actions"], + }) + } + className="gap-2" + > + <Download className="size-4" aria-hidden="true" /> + <span className="hidden sm:inline">Export</span> + </Button> + </div> + ) +}
\ No newline at end of file |
