diff options
Diffstat (limited to 'lib/vendor-rfq-response/vendor-cbe-table/cbe-table.tsx')
| -rw-r--r-- | lib/vendor-rfq-response/vendor-cbe-table/cbe-table.tsx | 272 |
1 files changed, 0 insertions, 272 deletions
diff --git a/lib/vendor-rfq-response/vendor-cbe-table/cbe-table.tsx b/lib/vendor-rfq-response/vendor-cbe-table/cbe-table.tsx deleted file mode 100644 index 8477f550..00000000 --- a/lib/vendor-rfq-response/vendor-cbe-table/cbe-table.tsx +++ /dev/null @@ -1,272 +0,0 @@ -"use client" - -import * as React from "react" -import { useRouter } from "next/navigation" -import type { - DataTableAdvancedFilterField, - DataTableFilterField, - DataTableRowAction, -} from "@/types/table" - -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 "./cbe-table-columns" -import { - fetchRfqAttachmentsbyCommentId, - getCBEbyVendorId, - getFileFromRfqAttachmentsbyid, - fetchCbeFiles -} from "../../rfqs/service" -import { useSession } from "next-auth/react" -import { CbeComment, CommentSheet } from "./comments-sheet" -import { VendorWithCbeFields } from "@/config/vendorCbeColumnsConfig" -import { toast } from "sonner" -import { RfqDeailDialog } from "./rfq-detail-dialog" -import { CommercialResponseSheet } from "./respond-cbe-sheet" - -interface VendorsTableProps { - promises: Promise< - [ - Awaited<ReturnType<typeof getCBEbyVendorId>>, - ] - > -} - -export function CbeVendorTable({ promises }: VendorsTableProps) { - const { data: session } = useSession() - const userVendorId = session?.user?.companyId - const userId = Number(session?.user?.id) - // Suspense로 받아온 데이터 - const [{ data, pageCount }] = React.use(promises) - const [rowAction, setRowAction] = React.useState<DataTableRowAction<VendorWithCbeFields> | null>(null) - const [selectedCbeId, setSelectedCbeId] = React.useState<number | null>(null) - - // 개별 협력업체별 로딩 상태를 관리하는 맵 - const [loadingVendors, setLoadingVendors] = React.useState<Record<string, boolean>>({}) - - const router = useRouter() - - // 코멘트 관련 상태 - const [initialComments, setInitialComments] = React.useState<CbeComment[]>([]) - const [commentSheetOpen, setCommentSheetOpen] = React.useState(false) - const [selectedRfqIdForComments, setSelectedRfqIdForComments] = React.useState<number | null>(null) - - // 상업 응답 관련 상태 - const [commercialResponseSheetOpen, setCommercialResponseSheetOpen] = React.useState(false) - const [selectedResponseId, setSelectedResponseId] = React.useState<number | null>(null) - const [selectedRfq, setSelectedRfq] = React.useState<VendorWithCbeFields | null>(null) - - // RFQ 상세 관련 상태 - const [rfqDetailDialogOpen, setRfqDetailDialogOpen] = React.useState(false) - const [selectedRfqId, setSelectedRfqId] = React.useState<number | null>(null) - const [selectedRfqDetail, setSelectedRfqDetail] = React.useState<VendorWithCbeFields | null>(null) - - React.useEffect(() => { - if (rowAction?.type === "comments") { - // rowAction가 새로 세팅된 뒤 여기서 openCommentSheet 실행 - openCommentSheet(Number(rowAction.row.original.responseId)) - } - }, [rowAction]) - - async function openCommentSheet(responseId: number) { - setInitialComments([]) - - const comments = rowAction?.row.original.comments - const rfqId = rowAction?.row.original.rfqId - - if (comments && comments.length > 0) { - const commentWithAttachments: CbeComment[] = await Promise.all( - comments.map(async (c) => { - // 서버 액션을 사용하여 코멘트 첨부 파일 가져오기 - const attachments = await fetchRfqAttachmentsbyCommentId(c.id) - - return { - ...c, - commentedBy: userId, // DB나 API 응답에 있다고 가정 - attachments, - } - }) - ) - - setInitialComments(commentWithAttachments) - } - - if(rfqId) { - setSelectedRfqIdForComments(rfqId) - } - setSelectedCbeId(responseId) - setCommentSheetOpen(true) - } - - // 상업 응답 시트 열기 - function openCommercialResponseSheet(responseId: number, rfq: VendorWithCbeFields) { - setSelectedResponseId(responseId) - setSelectedRfq(rfq) - setCommercialResponseSheetOpen(true) - } - - // RFQ 상세 대화상자 열기 - function openRfqDetailDialog(rfqId: number, rfq: VendorWithCbeFields) { - setSelectedRfqId(rfqId) - setSelectedRfqDetail(rfq) - setRfqDetailDialogOpen(true) - } - - const handleDownloadCbeFiles = React.useCallback( - async (vendorId: number, rfqId: number) => { - // 고유 키 생성: vendorId_rfqId - const rowKey = `${vendorId}_${rfqId}` - - // 해당 협력업체의 로딩 상태만 true로 설정 - setLoadingVendors(prev => ({ - ...prev, - [rowKey]: true - })) - - try { - const { files, error } = await fetchCbeFiles(vendorId, rfqId); - if (error) { - toast.error(error); - return; - } - if (files.length === 0) { - toast.warning("다운로드할 CBE 파일이 없습니다"); - return; - } - // 순차적으로 파일 다운로드 - for (const file of files) { - await downloadFile(file.id); - } - toast.success(`${files.length}개의 CBE 파일이 다운로드되었습니다`); - } catch (error) { - toast.error("CBE 파일을 다운로드하는 데 실패했습니다"); - console.error(error); - } finally { - // 해당 협력업체의 로딩 상태만 false로 되돌림 - setLoadingVendors(prev => ({ - ...prev, - [rowKey]: false - })) - } - }, - [] - ); - - const downloadFile = React.useCallback(async (fileId: number) => { - try { - const { file, error } = await getFileFromRfqAttachmentsbyid(fileId); - if (error || !file) { - throw new Error(error || "파일 정보를 가져오는 데 실패했습니다"); - } - - const link = document.createElement("a"); - link.href = `/api/rfq-download?path=${encodeURIComponent(file.filePath)}`; - link.download = file.fileName; - document.body.appendChild(link); - link.click(); - document.body.removeChild(link); - - return true; - } catch (error) { - console.error(error); - return false; - } - }, []); - - // 응답 성공 후 데이터 갱신 - const handleResponseSuccess = React.useCallback(() => { - // 필요한 경우 데이터 다시 가져오기 - router.refresh() - }, [router]); - - // getColumns() 호출 시 필요한 핸들러들 주입 - const columns = React.useMemo( - () => getColumns({ - setRowAction, - router, - openCommentSheet, - handleDownloadCbeFiles, - loadingVendors, - openVendorContactsDialog: openRfqDetailDialog, - openCommercialResponseSheet, - }), - [ - setRowAction, - router, - openCommentSheet, - handleDownloadCbeFiles, - loadingVendors, - openRfqDetailDialog, - openCommercialResponseSheet - ] - ); - - // 필터 필드 정의 - const filterFields: DataTableFilterField<VendorWithCbeFields>[] = [] - const advancedFilterFields: DataTableAdvancedFilterField<VendorWithCbeFields>[] = [ - - ] - - const { table } = useDataTable({ - data, - columns, - pageCount, - filterFields, - enablePinning: true, - enableAdvancedFilter: true, - initialState: { - sorting: [{ id: "respondedAt", desc: true }], - columnPinning: { right: ["respond", "comments"] }, // respond 컬럼을 오른쪽에 고정 - }, - getRowId: (originalRow) => String(originalRow.responseId), - shallow: false, - clearOnDefault: true, - }) - - return ( - <> - <DataTable table={table}> - <DataTableAdvancedToolbar - table={table} - filterFields={advancedFilterFields} - shallow={false} - /> - </DataTable> - - {/* 코멘트 시트 */} - {commentSheetOpen && selectedRfqIdForComments && selectedCbeId !== null && ( - <CommentSheet - open={commentSheetOpen} - onOpenChange={setCommentSheetOpen} - rfqId={selectedRfqIdForComments} - initialComments={initialComments} - vendorId={userVendorId || 0} - currentUserId={userId || 0} - cbeId={selectedCbeId} - /> - )} - - {/* 상업 응답 시트 */} - {commercialResponseSheetOpen && selectedResponseId !== null && selectedRfq && ( - <CommercialResponseSheet - open={commercialResponseSheetOpen} - onOpenChange={setCommercialResponseSheetOpen} - responseId={selectedResponseId} - rfq={selectedRfq} - onSuccess={handleResponseSuccess} - /> - )} - - {/* RFQ 상세 대화상자 */} - {rfqDetailDialogOpen && selectedRfqId !== null && ( - <RfqDeailDialog - isOpen={rfqDetailDialogOpen} - onOpenChange={setRfqDetailDialogOpen} - rfqId={selectedRfqId} - rfq={selectedRfqDetail} - /> - )} - </> - ) -}
\ No newline at end of file |
