diff options
| author | dujinkim <dujin.kim@dtsolution.co.kr> | 2025-05-28 19:03:21 +0000 |
|---|---|---|
| committer | dujinkim <dujin.kim@dtsolution.co.kr> | 2025-05-28 19:03:21 +0000 |
| commit | 5036cf2908792cef45f06256e71f10920f647f49 (patch) | |
| tree | 3116e7419e872d45025d1d48e6ddaffe2ba2dd38 /lib/techsales-rfq/vendor-response/detail/project-info-tab.tsx | |
| parent | 7ae037e9c2fc0be1fe68cecb461c5e1e837cb0da (diff) | |
(김준회) 기술영업 조선 RFQ (SHI/벤더)
Diffstat (limited to 'lib/techsales-rfq/vendor-response/detail/project-info-tab.tsx')
| -rw-r--r-- | lib/techsales-rfq/vendor-response/detail/project-info-tab.tsx | 269 |
1 files changed, 269 insertions, 0 deletions
diff --git a/lib/techsales-rfq/vendor-response/detail/project-info-tab.tsx b/lib/techsales-rfq/vendor-response/detail/project-info-tab.tsx new file mode 100644 index 00000000..7ba3320d --- /dev/null +++ b/lib/techsales-rfq/vendor-response/detail/project-info-tab.tsx @@ -0,0 +1,269 @@ +"use client" + +import * as React from "react" +import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card" +import { Badge } from "@/components/ui/badge" +import { ScrollArea } from "@/components/ui/scroll-area" +import { formatDateToQuarter, formatDate } from "@/lib/utils" + +interface ProjectSnapshot { + pspid?: string + projNm?: string + projMsrm?: number + kunnr?: string + kunnrNm?: string + cls1?: string + cls1Nm?: string + ptype?: string + ptypeNm?: string + estmPm?: string + scDt?: string + klDt?: string + lcDt?: string + dlDt?: string + dockNo?: string + dockNm?: string + projNo?: string + ownerNm?: string + pspUpdatedAt?: string | Date +} + +interface SeriesSnapshot { + sersNo?: string + klDt?: string +} + +interface ProjectInfoTabProps { + quotation: { + id: number + rfq: { + id: number + rfqCode: string | null + materialCode: string | null + dueDate: Date | null + status: string | null + remark: string | null + projectSnapshot?: ProjectSnapshot | null + seriesSnapshot?: SeriesSnapshot[] | null + item?: { + id: number + itemCode: string | null + itemName: string | null + } | null + biddingProject?: { + id: number + pspid: string | null + projNm: string | null + } | null + createdByUser?: { + id: number + name: string | null + email: string | null + } | null + } | null + vendor: { + id: number + vendorName: string + vendorCode: string | null + } | null + } +} + +export function ProjectInfoTab({ quotation }: ProjectInfoTabProps) { + const rfq = quotation.rfq + const projectSnapshot = rfq?.projectSnapshot + const seriesSnapshot = rfq?.seriesSnapshot + + if (!rfq) { + return ( + <div className="flex items-center justify-center h-full"> + <div className="text-center"> + <h3 className="text-lg font-medium">RFQ 정보를 찾을 수 없습니다</h3> + <p className="text-sm text-muted-foreground mt-1"> + 연결된 RFQ 정보가 없습니다. + </p> + </div> + </div> + ) + } + + return ( + <ScrollArea className="h-full"> + <div className="space-y-6 p-1"> + {/* RFQ 기본 정보 */} + <Card> + <CardHeader> + <CardTitle className="flex items-center gap-2"> + RFQ 기본 정보 + <Badge variant="outline">{rfq.rfqCode || "미할당"}</Badge> + </CardTitle> + <CardDescription> + 요청서 기본 정보 및 자재 정보 + </CardDescription> + </CardHeader> + <CardContent className="space-y-4"> + <div className="grid grid-cols-1 md:grid-cols-2 gap-4"> + <div className="space-y-2"> + <div className="text-sm font-medium text-muted-foreground">RFQ 번호</div> + <div className="text-sm">{rfq.rfqCode || "미할당"}</div> + </div> + <div className="space-y-2"> + <div className="text-sm font-medium text-muted-foreground">자재 코드</div> + <div className="text-sm">{rfq.materialCode || "N/A"}</div> + </div> + <div className="space-y-2"> + <div className="text-sm font-medium text-muted-foreground">품목명</div> + <div className="text-sm">{rfq.item?.itemName || "N/A"}</div> + </div> + <div className="space-y-2"> + <div className="text-sm font-medium text-muted-foreground">마감일</div> + <div className="text-sm"> + {rfq.dueDate ? formatDate(rfq.dueDate) : "N/A"} + </div> + </div> + <div className="space-y-2"> + <div className="text-sm font-medium text-muted-foreground">RFQ 상태</div> + <div className="text-sm">{rfq.status || "N/A"}</div> + </div> + <div className="space-y-2"> + <div className="text-sm font-medium text-muted-foreground">담당자</div> + <div className="text-sm">{rfq.createdByUser?.name || "N/A"}</div> + </div> + </div> + {rfq.remark && ( + <div className="space-y-2"> + <div className="text-sm font-medium text-muted-foreground">비고</div> + <div className="text-sm p-3 bg-muted rounded-md">{rfq.remark}</div> + </div> + )} + </CardContent> + </Card> + + {/* 프로젝트 기본 정보 */} + {rfq.biddingProject && ( + <Card> + <CardHeader> + <CardTitle className="flex items-center gap-2"> + 프로젝트 기본 정보 + <Badge variant="outline">{rfq.biddingProject.pspid || "N/A"}</Badge> + </CardTitle> + <CardDescription> + 연결된 프로젝트의 기본 정보 + </CardDescription> + </CardHeader> + <CardContent className="space-y-4"> + <div className="grid grid-cols-1 md:grid-cols-2 gap-4"> + <div className="space-y-2"> + <div className="text-sm font-medium text-muted-foreground">프로젝트 ID</div> + <div className="text-sm">{rfq.biddingProject.pspid || "N/A"}</div> + </div> + <div className="space-y-2"> + <div className="text-sm font-medium text-muted-foreground">프로젝트명</div> + <div className="text-sm">{rfq.biddingProject.projNm || "N/A"}</div> + </div> + </div> + </CardContent> + </Card> + )} + + {/* 프로젝트 스냅샷 정보 */} + {projectSnapshot && ( + <Card> + <CardHeader> + <CardTitle>프로젝트 스냅샷</CardTitle> + <CardDescription> + RFQ 생성 시점의 프로젝트 상세 정보 + </CardDescription> + </CardHeader> + <CardContent className="space-y-4"> + <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4"> + {projectSnapshot.projNo && ( + <div className="space-y-2"> + <div className="text-sm font-medium text-muted-foreground">공사번호</div> + <div className="text-sm">{projectSnapshot.projNo}</div> + </div> + )} + {projectSnapshot.projNm && ( + <div className="space-y-2"> + <div className="text-sm font-medium text-muted-foreground">공사명</div> + <div className="text-sm">{projectSnapshot.projNm}</div> + </div> + )} + {projectSnapshot.estmPm && ( + <div className="space-y-2"> + <div className="text-sm font-medium text-muted-foreground">견적 PM</div> + <div className="text-sm">{projectSnapshot.estmPm}</div> + </div> + )} + {projectSnapshot.kunnrNm && ( + <div className="space-y-2"> + <div className="text-sm font-medium text-muted-foreground">선주</div> + <div className="text-sm">{projectSnapshot.kunnrNm}</div> + </div> + )} + {projectSnapshot.cls1Nm && ( + <div className="space-y-2"> + <div className="text-sm font-medium text-muted-foreground">선급</div> + <div className="text-sm">{projectSnapshot.cls1Nm}</div> + </div> + )} + {projectSnapshot.projMsrm && ( + <div className="space-y-2"> + <div className="text-sm font-medium text-muted-foreground">척수</div> + <div className="text-sm">{projectSnapshot.projMsrm}</div> + </div> + )} + {projectSnapshot.ptypeNm && ( + <div className="space-y-2"> + <div className="text-sm font-medium text-muted-foreground">선종</div> + <div className="text-sm">{projectSnapshot.ptypeNm}</div> + </div> + )} + </div> + </CardContent> + </Card> + )} + + {/* 시리즈 스냅샷 정보 */} + {seriesSnapshot && Array.isArray(seriesSnapshot) && seriesSnapshot.length > 0 && ( + <Card> + <CardHeader> + <CardTitle>시리즈 정보 스냅샷</CardTitle> + <CardDescription> + 프로젝트의 시리즈별 K/L 일정 정보 + </CardDescription> + </CardHeader> + <CardContent className="space-y-4"> + {seriesSnapshot.map((series: SeriesSnapshot, index: number) => ( + <div key={index} className="border rounded-lg p-4 space-y-3"> + <div className="flex items-center gap-2"> + <Badge variant="secondary">시리즈 {series.sersNo || index + 1}</Badge> + </div> + <div className="grid grid-cols-1 md:grid-cols-2 gap-4"> + {series.klDt && ( + <div className="space-y-1"> + <div className="text-xs font-medium text-muted-foreground">K/L</div> + <div className="text-sm">{formatDateToQuarter(series.klDt)}</div> + </div> + )} + </div> + </div> + ))} + </CardContent> + </Card> + )} + + {/* 정보가 없는 경우 */} + {!projectSnapshot && !seriesSnapshot && ( + <Card> + <CardContent className="text-center py-8"> + <div className="text-muted-foreground"> + 추가 프로젝트 상세정보가 없습니다. + </div> + </CardContent> + </Card> + )} + </div> + </ScrollArea> + ) +}
\ No newline at end of file |
