diff options
Diffstat (limited to 'lib/bidding/vendor/partners-bidding-list.tsx')
| -rw-r--r-- | lib/bidding/vendor/partners-bidding-list.tsx | 132 |
1 files changed, 28 insertions, 104 deletions
diff --git a/lib/bidding/vendor/partners-bidding-list.tsx b/lib/bidding/vendor/partners-bidding-list.tsx index eb38ce71..fc3cd1f2 100644 --- a/lib/bidding/vendor/partners-bidding-list.tsx +++ b/lib/bidding/vendor/partners-bidding-list.tsx @@ -5,7 +5,6 @@ import { useRouter } from 'next/navigation' import type { DataTableAdvancedFilterField, DataTableFilterField, - DataTableRowAction, } from '@/types/table' import { useDataTable } from '@/hooks/use-data-table' @@ -13,94 +12,36 @@ import { useToast } from '@/hooks/use-toast' import { DataTable } from '@/components/data-table/data-table' import { DataTableAdvancedToolbar } from '@/components/data-table/data-table-advanced-toolbar' import { getPartnersBiddingListColumns } from './partners-bidding-list-columns' -import { getBiddingListForPartners, PartnersBiddingListItem } from '../detail/service' +import { PartnersBiddingListItem } from '../detail/service' import { PartnersBiddingToolbarActions } from './partners-bidding-toolbar-actions' -import { PartnersBiddingAttendanceDialog } from './partners-bidding-attendance-dialog' -import { PartnersBiddingParticipationDialog } from './partners-bidding-participation-dialog' +import { PartnersSpecificationMeetingDialog } from './partners-bidding-attendance-dialog' import { PartnersBiddingAttachmentsDialog } from './partners-bidding-attachments-dialog' -import { setPreQuoteParticipation, getBiddingCompaniesForPartners } from '../pre-quote/service' interface PartnersBiddingListProps { companyId: number + promises: Promise<[PartnersBiddingListItem[]]> } -export function PartnersBiddingList({ companyId }: PartnersBiddingListProps) { - const [data, setData] = React.useState<PartnersBiddingListItem[]>([]) - const [pageCount, setPageCount] = React.useState<number>(1) - const [isLoading, setIsLoading] = React.useState(true) +export function PartnersBiddingList({ promises }: PartnersBiddingListProps) { + const [biddingData] = React.use(promises) const [rowAction, setRowAction] = React.useState<{ type: string; row: { original: PartnersBiddingListItem } } | null>(null) - const [isParticipationDialogOpen, setIsParticipationDialogOpen] = React.useState(false) - const [selectedBiddingForParticipation, setSelectedBiddingForParticipation] = React.useState<PartnersBiddingListItem | null>(null) - const [selectedBiddingForPreQuoteParticipation, setSelectedBiddingForPreQuoteParticipation] = React.useState<any | null>(null) + // const [selectedBiddingForSpecificationMeetingParticipation] = React.useState<PartnersBiddingListItem | null>(null) const [isAttachmentsDialogOpen, setIsAttachmentsDialogOpen] = React.useState(false) const [selectedBiddingForAttachments, setSelectedBiddingForAttachments] = React.useState<PartnersBiddingListItem | null>(null) - const router = useRouter() const { toast } = useToast() - // 데이터 새로고침 함수 - const refreshData = React.useCallback(async () => { - try { - setIsLoading(true) - const result = await getBiddingListForPartners(companyId) - setData(result) - } catch (error) { - console.error('Failed to refresh bidding list:', error) - } finally { - setIsLoading(false) - } - }, [companyId]) - - // 입찰 참여의사 결정 핸들러 - const handlePreQuoteParticipationDecision = React.useCallback(async (participate: boolean) => { - if (!selectedBiddingForPreQuoteParticipation?.biddingCompanyId) { - throw new Error('업체 정보를 찾을 수 없습니다.') - } - - const result = await setPreQuoteParticipation( - selectedBiddingForPreQuoteParticipation.biddingCompanyId, - participate - ) - - if (result.success) { - await refreshData() // 데이터 새로고침 - } else { - throw new Error(result.error) - } - }, [selectedBiddingForPreQuoteParticipation?.biddingCompanyId, refreshData]) - - // 데이터 로드 - React.useEffect(() => { - const loadData = async () => { - try { - setIsLoading(true) - const result = await getBiddingListForPartners(companyId) - setData(result) - setPageCount(1) // 클라이언트 사이드 페이징이므로 1로 설정 - } catch (error) { - console.error('Failed to load bidding list:', error) - setData([]) - } finally { - setIsLoading(false) - } - } - - loadData() - }, [companyId]) - - // rowAction 변경 감지하여 해당 페이지로 이동 또는 다이얼로그 열기 - React.useEffect(() => { + React.useEffect(() => { if (rowAction) { + const bidding = rowAction.row.original switch (rowAction.type) { case 'view': - // 본입찰 초대 여부 확인 - const bidding = rowAction.row.original // 사전견적 요청 상태에서는 상세보기 제한 if (bidding.status === 'request_for_quotation') { toast({ title: '접근 제한', - description: '사전견적 요청 상태에서는 상세보기를 이용할 수 없습니다.', + description: '사전견적 요청 상태에서는 본입찰을 이용할 수 없습니다.', variant: 'destructive', }) return @@ -116,16 +57,21 @@ export function PartnersBiddingList({ companyId }: PartnersBiddingListProps) { return } // 상세 페이지로 이동 (biddingId 사용) - router.push(`/partners/bid/${rowAction.row.original.biddingId}`) + router.push(`/partners/bid/${bidding.biddingId}`) break case 'pre-quote': // 사전견적 페이지로 이동 - router.push(`/partners/bid/${rowAction.row.original.biddingId}/pre-quote`) - break - case 'participation': - // 입찰 참여 의사 결정 다이얼로그 열기 - 상세 데이터 로드 필요 - handlePreQuoteParticipationDecision(true) - setRowAction(null) // rowAction 초기화 + // 사전견적에 초대받지 않은 벤더는 bidding status가 bidding_opened 이고 isPreQuoteParticipated이 null일 경우, 초대받지 않은 것으로 판단 + if (bidding.status === 'bidding_opened' && bidding.isPreQuoteParticipated === null) { + toast({ + title: '접근 제한', + description: '사전견적에 초대받지 않은 업체입니다.', + variant: 'destructive', + }) + return + } + + router.push(`/partners/bid/${bidding.biddingId}/pre-quote`) break case 'view-documents': // 첨부파일 다이얼로그 열기 @@ -137,7 +83,7 @@ export function PartnersBiddingList({ companyId }: PartnersBiddingListProps) { break } } - }, [rowAction, router, handlePreQuoteParticipationDecision]) + }, [rowAction, router, toast]) const columns = React.useMemo( () => getPartnersBiddingListColumns({ setRowAction }), @@ -199,9 +145,9 @@ export function PartnersBiddingList({ companyId }: PartnersBiddingListProps) { ] const { table } = useDataTable({ - data, + data: biddingData, columns, - pageCount, + pageCount: 1, filterFields, enableAdvancedFilter: true, initialState: { @@ -213,16 +159,6 @@ export function PartnersBiddingList({ companyId }: PartnersBiddingListProps) { clearOnDefault: true, }) - if (isLoading) { - return ( - <div className="flex items-center justify-center py-12"> - <div className="text-center"> - <div className="animate-spin rounded-full h-8 w-8 border-b-2 border-primary mx-auto mb-4"></div> - <p className="text-muted-foreground">입찰 목록을 불러오는 중...</p> - </div> - </div> - ) - } return ( <> @@ -232,12 +168,12 @@ export function PartnersBiddingList({ companyId }: PartnersBiddingListProps) { filterFields={advancedFilterFields} shallow={false} > - <PartnersBiddingToolbarActions table={table} companyId={companyId} onRefresh={refreshData} setRowAction={setRowAction} /> + <PartnersBiddingToolbarActions table={table} setRowAction={setRowAction} /> </DataTableAdvancedToolbar> </DataTable> - <PartnersBiddingAttendanceDialog - open={rowAction?.type === "attendance"} + <PartnersSpecificationMeetingDialog + open={rowAction?.type === "specification_meeting"} onOpenChange={() => setRowAction(null)} biddingDetail={rowAction?.row.original ? { id: rowAction.row.original.biddingId, @@ -246,23 +182,11 @@ export function PartnersBiddingList({ companyId }: PartnersBiddingListProps) { preQuoteDate: null, biddingRegistrationDate: rowAction.row.original.submissionStartDate?.toISOString() || null, evaluationDate: null, - hasSpecificationMeeting: (rowAction.row.original as any).hasSpecificationMeeting || false, // 사양설명회 여부 추가 + hasSpecificationMeeting: rowAction.row.original.hasSpecificationMeeting || false, } : null} biddingCompanyId={rowAction?.row.original?.biddingCompanyId || 0} isAttending={rowAction?.row.original?.isAttendingMeeting || null} - onSuccess={refreshData} /> -{/* - <PartnersBiddingParticipationDialog - open={isParticipationDialogOpen} - onOpenChange={setIsParticipationDialogOpen} - bidding={selectedBiddingForParticipation} - companyId={companyId} - onSuccess={() => { - refreshData() - setSelectedBiddingForParticipation(null) - }} - /> */} <PartnersBiddingAttachmentsDialog open={isAttachmentsDialogOpen} |
