diff options
Diffstat (limited to 'lib/site-visit/vendor-info-view-dialog.tsx')
| -rw-r--r-- | lib/site-visit/vendor-info-view-dialog.tsx | 110 |
1 files changed, 88 insertions, 22 deletions
diff --git a/lib/site-visit/vendor-info-view-dialog.tsx b/lib/site-visit/vendor-info-view-dialog.tsx index 431069b3..48aefeb0 100644 --- a/lib/site-visit/vendor-info-view-dialog.tsx +++ b/lib/site-visit/vendor-info-view-dialog.tsx @@ -15,6 +15,7 @@ import { } from "@/components/ui/dialog"
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
import { Button } from "@/components/ui/button"
+import { Badge } from "@/components/ui/badge"
import { toast } from "sonner"
interface VendorInfo {
@@ -53,46 +54,63 @@ interface VendorInfoViewDialogProps { isOpen: boolean
onClose: () => void
siteVisitRequestId: number | null
+ investigationId?: number | null // 실사 ID 추가 - 여러 확정정보 조회용
+ isReinspection?: boolean // 재실사 모드 플래그
}
export function VendorInfoViewDialog({
isOpen,
onClose,
siteVisitRequestId,
+ investigationId,
}: VendorInfoViewDialogProps) {
const [data, setData] = React.useState<VendorInfo | null>(null)
const [attachments, setAttachments] = React.useState<Attachment[]>([])
+ const [allConfirmations, setAllConfirmations] = React.useState<any[]>([]) // 여러 확정정보
const [isLoading, setIsLoading] = React.useState(false)
// 데이터 로드
React.useEffect(() => {
- if (isOpen && siteVisitRequestId) {
- loadVendorInfo()
+ if (isOpen && (siteVisitRequestId || investigationId)) {
+ loadData()
}
- }, [isOpen, siteVisitRequestId])
+ }, [isOpen, siteVisitRequestId, investigationId])
- const loadVendorInfo = async () => {
- if (!siteVisitRequestId) return
+ const loadData = async () => {
+ if (!siteVisitRequestId && !investigationId) return
setIsLoading(true)
try {
- const { getVendorSiteVisitInfoAction } = await import("./service")
- const result = await getVendorSiteVisitInfoAction(siteVisitRequestId)
-
- if (result.success && result.data) {
- setData(result.data.vendorInfo)
- setAttachments(result.data.attachments || [])
- } else {
- toast.error("협력업체 정보를 불러올 수 없습니다.")
+ // 단일 확정정보 조회 (기존)
+ if (siteVisitRequestId) {
+ const { getVendorSiteVisitInfoAction } = await import("./service")
+ const result = await getVendorSiteVisitInfoAction(siteVisitRequestId)
+
+ if (result.success && result.data) {
+ setData(result.data.vendorInfo)
+ setAttachments(result.data.attachments || [])
+ } else {
+ toast.error("협력업체 정보를 불러올 수 없습니다.")
+ }
+ }
+
+ // 여러 확정정보 조회 (신규 - 실사 ID로 모든 siteVisitRequests 조회)
+ if (investigationId) {
+ const { getAllSiteVisitRequestsForInvestigationAction } = await import("./service")
+ const result = await getAllSiteVisitRequestsForInvestigationAction(investigationId)
+ if (result.success) {
+ setAllConfirmations(result.confirmations || [])
+ }
}
} catch (error) {
- console.error("협력업체 정보 로드 오류:", error)
- toast.error("협력업체 정보를 불러오는 중 오류가 발생했습니다.")
+ console.error("데이터 로드 오류:", error)
+ toast.error("데이터를 불러오는 중 오류가 발생했습니다.")
} finally {
setIsLoading(false)
}
}
+
return (
<Dialog open={isOpen} onOpenChange={(open) => !open && onClose()}>
<DialogContent className="max-w-4xl max-h-[90vh] overflow-y-auto">
@@ -110,10 +128,11 @@ export function VendorInfoViewDialog({ <p className="text-muted-foreground">협력업체 정보를 불러오는 중...</p>
</div>
</div>
- ) : data ? (
+ ) : (data || allConfirmations.length > 0) ? (
<div className="space-y-6">
- {/* 협력업체 정보 */}
- <Card>
+ {/* 협력업체 정보 - 단일 확정정보 조회 시에만 표시 */}
+ {data && (
+ <Card>
<CardHeader>
<CardTitle className="flex items-center gap-2">
<Building2 className="h-5 w-5" />
@@ -173,6 +192,7 @@ export function VendorInfoViewDialog({ </div>
</CardContent>
</Card>
+ )}
{/* 첨부파일 */}
{attachments.length > 0 && (
@@ -226,8 +246,54 @@ export function VendorInfoViewDialog({ </Card>
)}
+ {/* 실사 실시 확정정보 (복수 지원) */}
+ {allConfirmations.length > 0 && (
+ <div className="space-y-4">
+ <h3 className="text-lg font-semibold">실사 실시 확정정보</h3>
+ {allConfirmations.map((confirmation, index) => (
+ <Card key={confirmation.id}>
+ <CardHeader>
+ <CardTitle className="flex items-center justify-between">
+ <span className="flex items-center gap-2">
+ <Calendar className="h-5 w-5" />
+ 실사 확정정보 #{index + 1}
+ </span>
+ <Badge variant={confirmation.status === "COMPLETED" ? "default" : "secondary"}>
+ {confirmation.status === "COMPLETED" ? "완료" : "진행중"}
+ </Badge>
+ </CardTitle>
+ </CardHeader>
+ <CardContent>
+ <div className="grid grid-cols-2 gap-4 text-sm">
+ <div>
+ <span className="font-medium">실사 기간:</span> {confirmation.inspectionDuration}일
+ </div>
+ <div>
+ <span className="font-medium">요청 시작일:</span>
+ {confirmation.requestedStartDate ? formatDate(confirmation.requestedStartDate, "kr") : "미정"}
+ </div>
+ <div>
+ <span className="font-medium">요청 종료일:</span>
+ {confirmation.requestedEndDate ? formatDate(confirmation.requestedEndDate, "kr") : "미정"}
+ </div>
+ <div>
+ <span className="font-medium">생성일:</span> {formatDate(confirmation.createdAt, "kr")}
+ </div>
+ {confirmation.additionalRequests && (
+ <div className="col-span-2">
+ <span className="font-medium">추가 요청사항:</span>
+ <div className="bg-muted p-2 rounded mt-1">{confirmation.additionalRequests}</div>
+ </div>
+ )}
+ </div>
+ </CardContent>
+ </Card>
+ ))}
+ </div>
+ )}
+
{/* 기타 정보 */}
- {data.otherInfo && (
+ {data?.otherInfo && (
<Card>
<CardHeader>
<CardTitle className="flex items-center gap-2">
@@ -236,7 +302,7 @@ export function VendorInfoViewDialog({ </CardTitle>
</CardHeader>
<CardContent>
- <p className="text-sm whitespace-pre-wrap">{data.otherInfo}</p>
+ <p className="text-sm whitespace-pre-wrap">{data?.otherInfo}</p>
</CardContent>
</Card>
)}
@@ -253,8 +319,8 @@ export function VendorInfoViewDialog({ <div className="grid grid-cols-2 gap-4">
<div>
<div className="space-y-2 text-sm">
- <div><span className="font-medium">제출일:</span> {formatDate(data.submittedAt, "kr")}</div>
- <div><span className="font-medium">첨부파일:</span> {data.hasAttachments ? "있음" : "없음"}</div>
+ <div><span className="font-medium">제출일:</span> {formatDate(data?.submittedAt, "kr")}</div>
+ <div><span className="font-medium">첨부파일:</span> {data?.hasAttachments ? "있음" : "없음"}</div>
</div>
</div>
</div>
|
