diff options
Diffstat (limited to 'lib/general-contracts_old/detail/general-contract-detail.tsx')
| -rw-r--r-- | lib/general-contracts_old/detail/general-contract-detail.tsx | 186 |
1 files changed, 186 insertions, 0 deletions
diff --git a/lib/general-contracts_old/detail/general-contract-detail.tsx b/lib/general-contracts_old/detail/general-contract-detail.tsx new file mode 100644 index 00000000..8e7a7aff --- /dev/null +++ b/lib/general-contracts_old/detail/general-contract-detail.tsx @@ -0,0 +1,186 @@ +'use client' + +import { useState, useEffect } from 'react' +import { useParams } from 'next/navigation' +import Link from 'next/link' +import { getContractById, getSubcontractChecklist } from '../service' +import { GeneralContractInfoHeader } from './general-contract-info-header' +import { Alert, AlertDescription } from '@/components/ui/alert' +import { Button } from '@/components/ui/button' +import { AlertCircle, ArrowLeft } from 'lucide-react' +import { Skeleton } from '@/components/ui/skeleton' +import { ContractItemsTable } from './general-contract-items-table' +import { SubcontractChecklist } from './general-contract-subcontract-checklist' +import { ContractBasicInfo } from './general-contract-basic-info' +import { CommunicationChannel } from './general-contract-communication-channel' +import { Location } from './general-contract-location' +import { FieldServiceRate } from './general-contract-field-service-rate' +import { OffsetDetails } from './general-contract-offset-details' +import { ContractApprovalRequestDialog } from './general-contract-approval-request-dialog' + +export default function ContractDetailPage() { + const params = useParams() + const contractId = params?.id ? parseInt(params.id as string) : null + + const [contract, setContract] = useState<Record<string, unknown> | null>(null) + const [loading, setLoading] = useState(true) + const [error, setError] = useState<string | null>(null) + const [showApprovalDialog, setShowApprovalDialog] = useState(false) + const [subcontractChecklistData, setSubcontractChecklistData] = useState<any>(null) + + useEffect(() => { + const fetchContract = async () => { + try { + setLoading(true) + setError(null) + + // 계약 기본 정보 로드 + const contractData = await getContractById(contractId!) + setContract(contractData) + + // 하도급법 체크리스트 데이터 로드 + try { + const checklistData = await getSubcontractChecklist(contractId!) + if (checklistData.success && checklistData.data) { + setSubcontractChecklistData(checklistData.data) + } + } catch (checklistError) { + console.log('하도급법 체크리스트 데이터 로드 실패:', checklistError) + // 체크리스트 로드 실패는 전체 로드를 실패시키지 않음 + } + + } catch (err) { + console.error('Error fetching contract:', err) + setError('계약 정보를 불러오는 중 오류가 발생했습니다.') + } finally { + setLoading(false) + } + } + + if (contractId && !isNaN(contractId)) { + fetchContract() + } else { + setError('유효하지 않은 계약 ID입니다.') + setLoading(false) + } + }, [contractId]) + + if (loading) { + return ( + <div className="container mx-auto py-6 space-y-6"> + <Skeleton className="h-8 w-64" /> + <div className="grid gap-6"> + <div className="grid grid-cols-2 gap-4"> + <Skeleton className="h-10 w-full" /> + <Skeleton className="h-10 w-full" /> + </div> + <div className="grid grid-cols-3 gap-4"> + <Skeleton className="h-10 w-full" /> + <Skeleton className="h-10 w-full" /> + <Skeleton className="h-10 w-full" /> + </div> + <Skeleton className="h-32 w-full" /> + </div> + </div> + ) + } + + if (error) { + return ( + <div className="container mx-auto py-6"> + <Alert variant="destructive"> + <AlertCircle className="h-4 w-4" /> + <AlertDescription> + {error} + </AlertDescription> + </Alert> + </div> + ) + } + + return ( + <div className="container mx-auto py-6 space-y-6"> + + + <div className="flex items-center justify-between"> + <div> + <h1 className="text-3xl font-bold tracking-tight">계약 상세</h1> + <p className="text-muted-foreground"> + 계약번호: {contract?.contractNumber as string} (Rev.{contract?.revision as number}) + </p> + </div> + <div className="flex gap-2"> + {/* 계약승인요청 버튼 */} + <Button + onClick={() => setShowApprovalDialog(true)} + className="bg-blue-600 hover:bg-blue-700" + > + 계약승인요청 + </Button> + {/* 계약목록으로 돌아가기 버튼 */} + <Button asChild variant="outline" size="sm"> + <Link href="/evcp/general-contracts"> + <ArrowLeft className="h-4 w-4 mr-2" /> + 계약목록으로 돌아가기 + </Link> + </Button> + </div> + </div> + {/* 계약 정보 헤더 */} + {contract && <GeneralContractInfoHeader contract={contract} />} + + {/* 계약 상세 폼 */} + {contract && ( + <div className="space-y-6"> + {/* ContractBasicInfo */} + <ContractBasicInfo contractId={contract.id as number} /> + {/* 품목정보 */} + {/* {!(contract?.contractScope === '단가' || contract?.contractScope === '물량(실적)') && ( + <div className="mb-4"> + <p className="text-sm text-gray-600 mb-2"> + <strong>품목정보 입력 안내:</strong> + <br /> + 단가/물량 확정 계약의 경우 수량 및 총 계약금액은 별도로 관리됩니다. + </p> + </div> + )} */} + <ContractItemsTable + contractId={contract.id as number} + items={[]} + onItemsChange={() => {}} + onTotalAmountChange={() => {}} + availableBudget={0} + readOnly={contract?.contractScope === '단가' || contract?.contractScope === '물량(실적)'} + /> + {/* 하도급법 자율점검 체크리스트 */} + <SubcontractChecklist + contractId={contract.id as number} + onDataChange={(data) => setSubcontractChecklistData(data)} + readOnly={false} + initialData={subcontractChecklistData} + /> + {/* Communication Channel */} + <CommunicationChannel contractId={Number(contract.id)} /> + + {/* Location */} + <Location contractId={Number(contract.id)} /> + + {/* Field Service Rate */} + <FieldServiceRate contractId={Number(contract.id)} /> + + {/* Offset Details */} + <OffsetDetails contractId={Number(contract.id)} /> + </div> + )} + + {/* 계약승인요청 다이얼로그 */} + {contract && ( + <ContractApprovalRequestDialog + contract={contract} + open={showApprovalDialog} + onOpenChange={setShowApprovalDialog} + /> + )} + </div> + ) +} |
