From 37f55540833c2d5894513eca9fc8f7c6233fc2d2 Mon Sep 17 00:00:00 2001 From: dujinkim Date: Thu, 29 May 2025 05:17:13 +0000 Subject: (대표님) 0529 14시 16분 변경사항 저장 (Vendor Data, Docu) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../vendor-tbe-table/tbe-table.tsx | 191 +++++++++++++++++++++ 1 file changed, 191 insertions(+) create mode 100644 lib/tech-vendor-rfq-response/vendor-tbe-table/tbe-table.tsx (limited to 'lib/tech-vendor-rfq-response/vendor-tbe-table/tbe-table.tsx') diff --git a/lib/tech-vendor-rfq-response/vendor-tbe-table/tbe-table.tsx b/lib/tech-vendor-rfq-response/vendor-tbe-table/tbe-table.tsx new file mode 100644 index 00000000..2de2dd11 --- /dev/null +++ b/lib/tech-vendor-rfq-response/vendor-tbe-table/tbe-table.tsx @@ -0,0 +1,191 @@ +"use client" + +import * as React from "react" +import { useRouter } from "next/navigation" +import type { + DataTableAdvancedFilterField, + DataTableFilterField, + DataTableRowAction, +} from "@/types/table" +import { toast } from "sonner" +import { useDataTable } from "@/hooks/use-data-table" +import { DataTable } from "@/components/data-table/data-table" +import { DataTableAdvancedToolbar } from "@/components/data-table/data-table-advanced-toolbar" +import { getColumns } from "./tbe-table-columns" +import { fetchRfqAttachmentsbyCommentId, getTBEforVendor } from "../../rfqs-tech/service" +import { CommentSheet, TbeComment } from "./comments-sheet" +import { TbeVendorFields } from "@/config/vendorTbeColumnsConfig" +import { useTbeFileHandlers } from "./tbeFileHandler" +import { useSession } from "next-auth/react" +import { RfqDeailDialog } from "./rfq-detail-dialog" + +interface VendorsTableProps { + promises: Promise< + [ + Awaited>, + ] + > +} + +export function TbeVendorTable({ promises }: VendorsTableProps) { + const { data: session } = useSession() + const userVendorId = session?.user?.companyId + const userId = Number(session?.user?.id) + console.log("userVendorId", userVendorId) + console.log("userId", userId) + // Suspense로 받아온 데이터 + const [{ data, pageCount }] = React.use(promises) + const [rowAction, setRowAction] = React.useState | null>(null) + + + // router 획득 + const router = useRouter() + + const [initialComments, setInitialComments] = React.useState([]) + const [isLoadingComments, setIsLoadingComments] = React.useState(false) + + const [commentSheetOpen, setCommentSheetOpen] = React.useState(false) + const [selectedRfqIdForComments, setSelectedRfqIdForComments] = React.useState(0) + const [isRfqDetailDialogOpen, setIsRfqDetailDialogOpen] = React.useState(false) + + const [selectedRfqId, setSelectedRfqId] = React.useState(null) + const [selectedRfq, setSelectedRfq] = React.useState(null) + + const openVendorContactsDialog = (rfqId: number, rfq: TbeVendorFields) => { + setSelectedRfqId(rfqId) + setSelectedRfq(rfq) + setIsRfqDetailDialogOpen(true) + } + + // TBE 파일 핸들러 훅 사용 + const { + handleDownloadTbeTemplate, + handleUploadTbeResponse, + UploadDialog, + } = useTbeFileHandlers() + + React.useEffect(() => { + if (rowAction?.type === "comments") { + // rowAction가 새로 세팅된 뒤 여기서 openCommentSheet 실행 + openCommentSheet(Number(rowAction.row.original.tbeId)) + } + }, [rowAction]) + + async function openCommentSheet(tbeId: number) { + setInitialComments([]) + setIsLoadingComments(true) + + const comments = rowAction?.row.original.comments?.filter(c => c.evaluationId === tbeId) + + try { + if (comments && comments.length > 0) { + const commentWithAttachments: TbeComment[] = await Promise.all( + comments.map(async (c) => { + // 서버 액션을 사용하여 코멘트 첨부 파일 가져오기 + const attachments = await fetchRfqAttachmentsbyCommentId(c.id) + + return { + ...c, + commentedBy: userId, // DB나 API 응답에 있다고 가정 + attachments, + } + }) + ) + + setInitialComments(commentWithAttachments) + } + + setSelectedRfqIdForComments(rowAction?.row.original.rfqId ?? null) + setCommentSheetOpen(true) + + } catch (error) { + console.error("Error loading comments:", error) + toast.error("Failed to load comments") + } finally { + // End loading regardless of success/failure + setIsLoadingComments(false) + } +} + + // getColumns() 호출 시, 필요한 모든 핸들러 함수 주입 + const columns = React.useMemo( + () => getColumns({ + setRowAction, + router, + openCommentSheet, + handleDownloadTbeTemplate, + handleUploadTbeResponse, + openVendorContactsDialog + }), + [setRowAction, router, openCommentSheet, handleDownloadTbeTemplate, handleUploadTbeResponse, openVendorContactsDialog] + ) + + const filterFields: DataTableFilterField[] = [] + + const advancedFilterFields: DataTableAdvancedFilterField[] = [ + { id: "rfqCode", label: "RFQ Code", type: "text" }, + { id: "projectCode", label: "Project Code", type: "text" }, + { id: "projectName", label: "Project Name", type: "text" }, + { id: "rfqCode", label: "RFQ Code", type: "text" }, + { id: "tbeResult", label: "TBE Result", type: "text" }, + { id: "tbeNote", label: "TBE Note", type: "text" }, + { id: "rfqCode", label: "RFQ Code", type: "text" }, + { id: "hasResponse", label: "Response?", type: "boolean" }, + { id: "rfqVendorUpdated", label: "Updated at", type: "date" }, + { id: "dueDate", label: "Project Name", type: "date" }, + + ] + + const { table } = useDataTable({ + data, + columns, + pageCount, + filterFields, + enablePinning: true, + enableAdvancedFilter: true, + initialState: { + sorting: [{ id: "rfqVendorUpdated", desc: true }], + columnPinning: { right: ["comments", "tbeDocuments"] }, // tbeDocuments 컬럼을 우측에 고정 + }, + getRowId: (originalRow) => String(originalRow.rfqId), + shallow: false, + clearOnDefault: true, + }) + + return ( + <> + + + + + {/* 코멘트 시트 */} + {commentSheetOpen && selectedRfqIdForComments && ( + + )} + + + + {/* TBE 파일 다이얼로그 */} + + + ) +} \ No newline at end of file -- cgit v1.2.3