diff options
Diffstat (limited to 'lib/itb/table/purchase-requests-table.tsx')
| -rw-r--r-- | lib/itb/table/purchase-requests-table.tsx | 229 |
1 files changed, 229 insertions, 0 deletions
diff --git a/lib/itb/table/purchase-requests-table.tsx b/lib/itb/table/purchase-requests-table.tsx new file mode 100644 index 00000000..88f27666 --- /dev/null +++ b/lib/itb/table/purchase-requests-table.tsx @@ -0,0 +1,229 @@ +// components/purchase-requests/purchase-requests-table.tsx +"use client"; + +import * as React from "react"; +import { useRouter } from "next/navigation"; +import { Button } from "@/components/ui/button"; +import { Plus, RefreshCw, FileText } from "lucide-react"; +import { DataTable } from "@/components/data-table/data-table"; +import { DataTableAdvancedToolbar } from "@/components/data-table/data-table-advanced-toolbar"; +import { useDataTable } from "@/hooks/use-data-table"; +import { getPurchaseRequestColumns } from "./purchase-request-columns"; +import { CreatePurchaseRequestDialog } from "./create-purchase-request-dialog"; +import { EditPurchaseRequestSheet } from "./edit-purchase-request-sheet"; +import { DeletePurchaseRequestDialog } from "./delete-purchase-request-dialog"; +import { ViewPurchaseRequestSheet } from "./view-purchase-request-sheet"; +// import { AttachmentsDialog } from "./attachments-dialog"; +import { ItemsDialog } from "./items-dialog"; +import type { DataTableRowAction } from "@/types/table"; +import type { PurchaseRequestView } from "@/db/schema"; +import { CreateRfqDialog } from "./create-rfq-dialog"; +import { toast } from "sonner"; + +interface PurchaseRequestsTableProps { + promises: Promise<[ + { + data: PurchaseRequestView[]; + pageCount: number; + }, + any + ]>; +} + +export function PurchaseRequestsTable({ promises }: PurchaseRequestsTableProps) { + const router = useRouter(); + const [{ data, pageCount }] = React.use(promises); + const [isCreateDialogOpen, setIsCreateDialogOpen] = React.useState(false); + const [isCreateRfqDialogOpen, setIsCreateRfqDialogOpen] = React.useState(false); + const [selectedRequestsForRfq, setSelectedRequestsForRfq] = React.useState<PurchaseRequestView[]>([]); + const [rowAction, setRowAction] = React.useState<DataTableRowAction<PurchaseRequestView> | null>(null); + + const columns = React.useMemo( + () => getPurchaseRequestColumns({ setRowAction }), + [setRowAction] + ); + + const { table } = useDataTable({ + data, + columns, + pageCount, + enablePinning: true, + enableAdvancedFilter: true, + defaultPerPage: 10, + defaultSort: [{ id: "createdAt", desc: true }], + }); + + const refreshData = () => { + router.refresh(); + }; + + // 선택된 행들 가져오기 + const selectedRows = table.getSelectedRowModel().rows + .map(row => row.original) + .filter(row => row.status === "작성중") + ; + + // 선택된 행들로 RFQ 생성 다이얼로그 열기 + const handleBulkCreateRfq = () => { + const selectedRequests = selectedRows + + if (selectedRequests.length === 0) { + toast.error("RFQ를 생성할 구매 요청을 선택해주세요"); + return; + } + + setSelectedRequestsForRfq(selectedRequests); + setIsCreateRfqDialogOpen(true); + }; + + // 개별 행 액션 처리 + React.useEffect(() => { + if (rowAction?.type === "createRfq") { + setSelectedRequestsForRfq([rowAction.row.original]); + setIsCreateRfqDialogOpen(true); + setRowAction(null); + } + }, [rowAction]); + + // RFQ 생성 성공 후 처리 + const handleRfqSuccess = () => { + table.resetRowSelection(); // 선택 초기화 + refreshData(); + }; + + return ( + <> + <DataTable table={table}> + <DataTableAdvancedToolbar + table={table} + filterFields={[ + { + id: "requestCode", + label: "요청번호", + placeholder: "PR-2025-00001" + }, + { + id: "requestTitle", + label: "요청제목", + placeholder: "요청 제목 검색" + }, + { + id: "projectName", + label: "프로젝트명", + placeholder: "프로젝트명 검색" + }, + { + id: "packageName", + label: "패키지명", + placeholder: "패키지명 검색" + }, + { + id: "status", + label: "상태", + options: [ + { label: "작성중", value: "작성중" }, + { label: "RFQ생성완료", value: "RFQ생성완료" }, + ] + }, + { + id: "engPicName", + label: "설계 담당자", + placeholder: "담당자명 검색" + }, + { + id: "purchasePicName", + label: "구매 담당자", + placeholder: "담당자명 검색" + }, + ]} + > + <div className="flex items-center gap-2"> + <Button + size="sm" + onClick={() => setIsCreateDialogOpen(true)} + > + <Plus className="mr-2 h-4 w-4" /> + 새 구매요청 + </Button> + + {/* 선택된 항목들로 RFQ 일괄 생성 버튼 */} + {selectedRows.length > 0 && ( + <Button + size="sm" + variant="secondary" + onClick={handleBulkCreateRfq} + > + <FileText className="mr-2 h-4 w-4" /> + RFQ 생성 ({selectedRows.length}개) + </Button> + )} + + <Button + variant="outline" + size="sm" + onClick={refreshData} + > + <RefreshCw className="h-4 w-4" /> + </Button> + </div> + </DataTableAdvancedToolbar> + </DataTable> + + {/* 다이얼로그들 */} + <CreatePurchaseRequestDialog + open={isCreateDialogOpen} + onOpenChange={setIsCreateDialogOpen} + onSuccess={refreshData} + /> + + {/* RFQ 생성 다이얼로그 */} + <CreateRfqDialog + requests={selectedRequestsForRfq} + open={isCreateRfqDialogOpen} + onOpenChange={(open) => { + setIsCreateRfqDialogOpen(open); + if (!open) { + setSelectedRequestsForRfq([]); + } + }} + onSuccess={handleRfqSuccess} + /> + + {rowAction?.type === "view" && ( + <ViewPurchaseRequestSheet + request={rowAction.row.original} + open={true} + onOpenChange={() => setRowAction(null)} + /> + )} + + {rowAction?.type === "update" && ( + <EditPurchaseRequestSheet + request={rowAction.row.original} + open={true} + onOpenChange={() => setRowAction(null)} + onSuccess={refreshData} + /> + )} + + {rowAction?.type === "delete" && ( + <DeletePurchaseRequestDialog + request={rowAction.row.original} + open={true} + onOpenChange={() => setRowAction(null)} + onSuccess={refreshData} + /> + )} + + {rowAction?.type === "items" && ( + <ItemsDialog + requestId={rowAction.row.original.id} + requestCode={rowAction.row.original.requestCode} + items={rowAction.row.original.items} + open={true} + onOpenChange={() => setRowAction(null)} + /> + )} + </> + ); +}
\ No newline at end of file |
