summaryrefslogtreecommitdiff
path: root/lib/general-contracts_old/detail/general-contract-detail.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'lib/general-contracts_old/detail/general-contract-detail.tsx')
-rw-r--r--lib/general-contracts_old/detail/general-contract-detail.tsx186
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>
+ )
+}