diff options
Diffstat (limited to 'lib/techsales-rfq/vendor-response/table/vendor-quotations-table.tsx')
| -rw-r--r-- | lib/techsales-rfq/vendor-response/table/vendor-quotations-table.tsx | 56 |
1 files changed, 33 insertions, 23 deletions
diff --git a/lib/techsales-rfq/vendor-response/table/vendor-quotations-table.tsx b/lib/techsales-rfq/vendor-response/table/vendor-quotations-table.tsx index e98d6bdc..55dcad92 100644 --- a/lib/techsales-rfq/vendor-response/table/vendor-quotations-table.tsx +++ b/lib/techsales-rfq/vendor-response/table/vendor-quotations-table.tsx @@ -11,6 +11,7 @@ import { TechSalesVendorQuotations, TECH_SALES_QUOTATION_STATUSES, TECH_SALES_QU import { useRouter } from "next/navigation" import { getColumns } from "./vendor-quotations-table-columns" import { TechSalesRfqAttachmentsSheet, ExistingTechSalesAttachment } from "../../table/tech-sales-rfq-attachments-sheet" +import { RfqItemsViewDialog } from "../../table/rfq-items-view-dialog" import { getTechSalesRfqAttachments, getVendorQuotations } from "@/lib/techsales-rfq/service" import { toast } from "sonner" import { Skeleton } from "@/components/ui/skeleton" @@ -23,14 +24,16 @@ interface QuotationWithRfqCode extends TechSalesVendorQuotations { itemName?: string | null; projNm?: string | null; quotationCode?: string | null; - quotationVersion?: number | null; + rejectionReason?: string | null; acceptedAt?: Date | null; attachmentCount?: number; + itemCount?: number; } interface VendorQuotationsTableProps { vendorId: string; + rfqType?: "SHIP" | "TOP" | "HULL"; } // 로딩 스켈레톤 컴포넌트 @@ -92,22 +95,9 @@ function TableLoadingSkeleton() { ) } -// 중앙 로딩 인디케이터 컴포넌트 -function CenterLoadingIndicator() { - return ( - <div className="flex flex-col items-center justify-center py-12 space-y-4"> - <div className="relative"> - <div className="w-12 h-12 border-4 border-gray-200 border-t-blue-600 rounded-full animate-spin"></div> - </div> - <div className="text-center space-y-1"> - <p className="text-sm font-medium text-gray-900">데이터를 불러오는 중...</p> - <p className="text-xs text-gray-500">잠시만 기다려주세요.</p> - </div> - </div> - ) -} -export function VendorQuotationsTable({ vendorId }: VendorQuotationsTableProps) { + +export function VendorQuotationsTable({ vendorId, rfqType }: VendorQuotationsTableProps) { const searchParams = useSearchParams() const router = useRouter() @@ -116,6 +106,10 @@ export function VendorQuotationsTable({ vendorId }: VendorQuotationsTableProps) const [selectedRfqForAttachments, setSelectedRfqForAttachments] = React.useState<{ id: number; rfqCode: string | null; status: string } | null>(null) const [attachmentsDefault, setAttachmentsDefault] = React.useState<ExistingTechSalesAttachment[]>([]) + // 아이템 다이얼로그 상태 + const [itemsDialogOpen, setItemsDialogOpen] = React.useState(false) + const [selectedRfqForItems, setSelectedRfqForItems] = React.useState<{ id: number; rfqCode?: string; status?: string; rfqType?: "SHIP" | "TOP" | "HULL"; } | null>(null) + // 데이터 로딩 상태 const [data, setData] = React.useState<QuotationWithRfqCode[]>([]) const [pageCount, setPageCount] = React.useState(0) @@ -158,6 +152,7 @@ export function VendorQuotationsTable({ vendorId }: VendorQuotationsTableProps) search: initialSettings.search, from: initialSettings.from, to: initialSettings.to, + rfqType: rfqType, }, vendorId) console.log('🔍 [VendorQuotationsTable] 데이터 로드 결과:', { @@ -176,7 +171,7 @@ export function VendorQuotationsTable({ vendorId }: VendorQuotationsTableProps) setIsLoading(false) setIsInitialLoad(false) } - }, [vendorId, initialSettings]) + }, [vendorId, initialSettings, rfqType]) // URL 파라미터 변경 감지 및 데이터 재로드 (초기 로드 포함) React.useEffect(() => { @@ -192,8 +187,9 @@ export function VendorQuotationsTable({ vendorId }: VendorQuotationsTableProps) searchParams?.get('search'), searchParams?.get('from'), searchParams?.get('to'), - // vendorId 변경도 감지 - vendorId + // vendorId와 rfqType 변경도 감지 + vendorId, + rfqType ]) // 데이터 안정성을 위한 메모이제이션 @@ -246,12 +242,19 @@ export function VendorQuotationsTable({ vendorId }: VendorQuotationsTableProps) toast.error("첨부파일 조회 중 오류가 발생했습니다.") } }, [data]) + + // 아이템 다이얼로그 열기 함수 + const openItemsDialog = React.useCallback((rfq: { id: number; rfqCode?: string; status?: string; rfqType?: "SHIP" | "TOP" | "HULL"; }) => { + setSelectedRfqForItems(rfq) + setItemsDialogOpen(true) + }, []) // 테이블 컬럼 정의 const columns = React.useMemo(() => getColumns({ router, openAttachmentsSheet, - }), [router, openAttachmentsSheet]) + openItemsDialog, + }), [router, openAttachmentsSheet, openItemsDialog]) // 필터 필드 const filterFields = React.useMemo<DataTableFilterField<QuotationWithRfqCode>[]>(() => [ @@ -270,8 +273,8 @@ export function VendorQuotationsTable({ vendorId }: VendorQuotationsTableProps) }, { id: "materialCode", - label: "자재 코드", - placeholder: "자재 코드 검색...", + label: "자재 그룹", + placeholder: "자재 그룹 검색...", } ], []) @@ -284,7 +287,7 @@ export function VendorQuotationsTable({ vendorId }: VendorQuotationsTableProps) }, { id: "materialCode", - label: "자재 코드", + label: "자재 그룹", type: "text", }, { @@ -383,6 +386,13 @@ export function VendorQuotationsTable({ vendorId }: VendorQuotationsTableProps) onAttachmentsUpdated={() => {}} // 읽기 전용이므로 빈 함수 readOnly={true} // 벤더 쪽에서는 항상 읽기 전용 /> + + {/* 아이템 보기 다이얼로그 */} + <RfqItemsViewDialog + open={itemsDialogOpen} + onOpenChange={setItemsDialogOpen} + rfq={selectedRfqForItems} + /> </div> ); }
\ No newline at end of file |
