summaryrefslogtreecommitdiff
path: root/lib/general-contract-template/template/general-contract-template.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'lib/general-contract-template/template/general-contract-template.tsx')
-rw-r--r--lib/general-contract-template/template/general-contract-template.tsx287
1 files changed, 287 insertions, 0 deletions
diff --git a/lib/general-contract-template/template/general-contract-template.tsx b/lib/general-contract-template/template/general-contract-template.tsx
new file mode 100644
index 00000000..f66e8cf9
--- /dev/null
+++ b/lib/general-contract-template/template/general-contract-template.tsx
@@ -0,0 +1,287 @@
+"use client";
+
+import * as React from "react";
+import { useRouter } from "next/navigation";
+import { DataTable } from "@/components/data-table/data-table";
+import { useDataTable } from "@/hooks/use-data-table";
+import { DataTableAdvancedToolbar } from "@/components/data-table/data-table-advanced-toolbar";
+import type {
+ DataTableAdvancedFilterField,
+ DataTableRowAction,
+} from "@/types/table"
+import { getContractTemplates} from "../service";
+import { getColumns } from "./general-contract-template-columns";
+import { GeneralContractTemplateToolbarActions } from "./general-contract-template-toolbar-actions";
+import { UpdateTemplateSheet } from "./update-generalContract-sheet";
+import { CreateRevisionDialog } from "./create-revision-dialog";
+import { removeTemplates } from "../service";
+import { disposeTemplates, restoreTemplates } from "../actions";
+import { toast } from "sonner";
+import { Button } from "@/components/ui/button";
+import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from "@/components/ui/dialog";
+
+import { GeneralContractTemplate } from "@/db/schema";
+
+interface ContractTemplateTableProps {
+ promises: Promise<
+ [
+ Awaited<ReturnType<typeof getContractTemplates>>,
+ ]
+ >
+}
+
+export function ContractTemplateTable({ promises }: ContractTemplateTableProps) {
+ const router = useRouter();
+ const [rowAction, setRowAction] =
+ React.useState<DataTableRowAction<GeneralContractTemplate> | null>(null)
+ const [selectedRows, setSelectedRows] = React.useState<GeneralContractTemplate[]>([])
+ const [isDeleteDialogOpen, setIsDeleteDialogOpen] = React.useState(false)
+ const [isDisposeDialogOpen, setIsDisposeDialogOpen] = React.useState(false)
+ const [isRestoreDialogOpen, setIsRestoreDialogOpen] = React.useState(false)
+ const [isCreateRevisionDialogOpen, setIsCreateRevisionDialogOpen] = React.useState(false)
+ const [{ data, pageCount }] =
+ React.use(promises)
+
+ // 컬럼 설정 - router와 setRowAction을 전달
+ const columns = React.useMemo(
+ () => getColumns({ setRowAction, router }),
+ [setRowAction, router]
+ )
+
+ // config 기반으로 필터 필드 설정
+ const advancedFilterFields: DataTableAdvancedFilterField<GeneralContractTemplate>[] = [
+ { id: "contractTemplateName", label: "계약문서명", type: "text" },
+ {
+ id: "status", label: "상태", type: "select", options: [
+ { label: "전체", value: "ALL" },
+ { label: "활성화(A)", value: "ACTIVE" },
+ { label: "비활성화(Null)", value: "INACTIVE" },
+ { label: "폐기(D)", value: "DISPOSED" },
+ ]
+ },
+ { id: "contractTemplateType", label: "계약종류", type: "text" },
+ { id: "fileName", label: "파일명", type: "text" },
+ { id: "createdAt", label: "생성일", type: "date" },
+ { id: "updatedAt", label: "수정일", type: "date" },
+ ];
+
+ const { table } = useDataTable({
+ data,
+ columns,
+ pageCount,
+ enablePinning: true,
+ enableAdvancedFilter: true,
+ initialState: {
+ sorting: [{ id: "createdAt", desc: true }],
+ columnPinning: { right: ["actions"] },
+ },
+ getRowId: (originalRow) => String(originalRow.id),
+ shallow: false,
+ clearOnDefault: true,
+ })
+
+ // 선택된 행들 추적
+ React.useEffect(() => {
+ const selectedRowModels = table.getFilteredSelectedRowModel().rows
+ const selectedData = selectedRowModels.map(row => row.original)
+ setSelectedRows(selectedData)
+ }, [table.getState().rowSelection])
+
+ // rowAction 처리
+ React.useEffect(() => {
+ if (rowAction?.type === "delete") {
+ setIsDeleteDialogOpen(true)
+ } else if (rowAction?.type === "dispose") {
+ setIsDisposeDialogOpen(true)
+ } else if (rowAction?.type === "restore") {
+ setIsRestoreDialogOpen(true)
+ } else if (rowAction?.type === "create-revision") {
+ setIsCreateRevisionDialogOpen(true)
+ }
+ }, [rowAction])
+
+ // 삭제 확인 처리
+ const handleConfirmDelete = async () => {
+ if (!rowAction?.row) return
+
+ try {
+ const result = await removeTemplates({ ids: [rowAction.row.original.id] })
+
+ if (result.error) {
+ toast.error(result.error)
+ return
+ }
+
+ toast.success("템플릿이 삭제되었습니다.")
+ setIsDeleteDialogOpen(false)
+ setRowAction(null)
+
+ // 페이지 새로고침
+ window.location.reload()
+ } catch (error) {
+ console.error('삭제 처리 오류:', error)
+ toast.error("삭제 처리 중 오류가 발생했습니다.")
+ }
+ }
+
+ // 폐기 확인 처리
+ const handleConfirmDispose = async () => {
+ if (!rowAction?.row) return
+
+ try {
+ const result = await disposeTemplates([rowAction.row.original.id])
+
+ toast.success(result.message)
+ setIsDisposeDialogOpen(false)
+ setRowAction(null)
+
+ // 페이지 새로고침
+ window.location.reload()
+ } catch (error) {
+ console.error('폐기 처리 오류:', error)
+ toast.error("폐기 처리 중 오류가 발생했습니다.")
+ }
+ }
+
+ // 복구 확인 처리
+ const handleConfirmRestore = async () => {
+ if (!rowAction?.row) return
+
+ try {
+ const result = await restoreTemplates([rowAction.row.original.id])
+
+ toast.success(result.message)
+ setIsRestoreDialogOpen(false)
+ setRowAction(null)
+
+ // 페이지 새로고침
+ window.location.reload()
+ } catch (error) {
+ console.error('복구 처리 오류:', error)
+ toast.error("복구 처리 중 오류가 발생했습니다.")
+ }
+ }
+
+ return (
+ <>
+ <DataTable table={table}>
+ <DataTableAdvancedToolbar
+ table={table}
+ filterFields={advancedFilterFields}
+ shallow={false}
+ >
+ <GeneralContractTemplateToolbarActions selectedRows={selectedRows} />
+ </DataTableAdvancedToolbar>
+ </DataTable>
+
+ <UpdateTemplateSheet
+ open={rowAction?.type === "update"}
+ onOpenChange={() => setRowAction(null)}
+ template={rowAction?.row.original ?? null}
+ />
+
+ {/* 삭제 확인 다이얼로그 */}
+ <Dialog open={isDeleteDialogOpen} onOpenChange={setIsDeleteDialogOpen}>
+ <DialogContent>
+ <DialogHeader>
+ <DialogTitle>템플릿 삭제 확인</DialogTitle>
+ <DialogDescription>
+ "{rowAction?.row?.original?.contractTemplateName}" 템플릿을 삭제하시겠습니까?
+ <br />
+ 삭제된 템플릿은 복구할 수 없습니다.
+ </DialogDescription>
+ </DialogHeader>
+ <div className="flex justify-end gap-2">
+ <Button
+ variant="outline"
+ onClick={() => {
+ setIsDeleteDialogOpen(false)
+ setRowAction(null)
+ }}
+ >
+ 취소
+ </Button>
+ <Button
+ variant="destructive"
+ onClick={handleConfirmDelete}
+ >
+ 삭제
+ </Button>
+ </div>
+ </DialogContent>
+ </Dialog>
+
+ {/* 폐기 확인 다이얼로그 */}
+ <Dialog open={isDisposeDialogOpen} onOpenChange={setIsDisposeDialogOpen}>
+ <DialogContent>
+ <DialogHeader>
+ <DialogTitle>템플릿 폐기 확인</DialogTitle>
+ <DialogDescription>
+ "{rowAction?.row?.original?.contractTemplateName}" 템플릿을 폐기하시겠습니까?
+ <br />
+ 폐기된 템플릿은 복구할 수 있습니다.
+ </DialogDescription>
+ </DialogHeader>
+ <div className="flex justify-end gap-2">
+ <Button
+ variant="outline"
+ onClick={() => {
+ setIsDisposeDialogOpen(false)
+ setRowAction(null)
+ }}
+ >
+ 취소
+ </Button>
+ <Button
+ variant="destructive"
+ onClick={handleConfirmDispose}
+ >
+ 폐기
+ </Button>
+ </div>
+ </DialogContent>
+ </Dialog>
+
+ {/* 복구 확인 다이얼로그 */}
+ <Dialog open={isRestoreDialogOpen} onOpenChange={setIsRestoreDialogOpen}>
+ <DialogContent>
+ <DialogHeader>
+ <DialogTitle>템플릿 복구 확인</DialogTitle>
+ <DialogDescription>
+ "{rowAction?.row?.original?.contractTemplateName}" 템플릿을 복구하시겠습니까?
+ <br />
+ 복구된 템플릿은 다시 사용할 수 있습니다.
+ </DialogDescription>
+ </DialogHeader>
+ <div className="flex justify-end gap-2">
+ <Button
+ variant="outline"
+ onClick={() => {
+ setIsRestoreDialogOpen(false)
+ setRowAction(null)
+ }}
+ >
+ 취소
+ </Button>
+ <Button
+ variant="default"
+ onClick={handleConfirmRestore}
+ >
+ 복구
+ </Button>
+ </div>
+ </DialogContent>
+ </Dialog>
+
+ {/* 리비전 생성 다이얼로그 */}
+ <CreateRevisionDialog
+ open={isCreateRevisionDialogOpen}
+ onOpenChange={setIsCreateRevisionDialogOpen}
+ baseTemplate={rowAction?.row?.original || null}
+ onSuccess={() => {
+ setRowAction(null)
+ }}
+ />
+ </>
+ );
+} \ No newline at end of file