From ba8cd44a0ed2c613a5f2cee06bfc9bd0f61f21c7 Mon Sep 17 00:00:00 2001 From: dujinkim Date: Fri, 7 Nov 2025 08:39:04 +0000 Subject: (최겸) 입찰/견적 수정사항 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../detail/general-contract-yard-entry-info.tsx | 232 +++++++++++++++++++++ 1 file changed, 232 insertions(+) create mode 100644 lib/general-contracts/detail/general-contract-yard-entry-info.tsx (limited to 'lib/general-contracts/detail/general-contract-yard-entry-info.tsx') diff --git a/lib/general-contracts/detail/general-contract-yard-entry-info.tsx b/lib/general-contracts/detail/general-contract-yard-entry-info.tsx new file mode 100644 index 00000000..1fb1e310 --- /dev/null +++ b/lib/general-contracts/detail/general-contract-yard-entry-info.tsx @@ -0,0 +1,232 @@ +'use client' + +import React, { useState, useEffect } from 'react' +import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card' +import { Input } from '@/components/ui/input' +import { Label } from '@/components/ui/label' +import { Button } from '@/components/ui/button' +import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select' +import { Save, LoaderIcon } from 'lucide-react' +import { toast } from 'sonner' +import { useSession } from 'next-auth/react' +import { getProjects, getYardEntryInfo, saveYardEntryInfo } from '../service' + +interface YardEntryInfo { + projectId: number | null + projectCode: string + projectName: string + managerName: string + managerDepartment: string + rehandlingContractor: string +} + +interface ContractYardEntryInfoProps { + contractId: number + readOnly?: boolean +} + +export function ContractYardEntryInfo({ contractId, readOnly = false }: ContractYardEntryInfoProps) { + const session = useSession() + const userId = session.data?.user?.id ? Number(session.data.user.id) : null + const [isLoading, setIsLoading] = useState(false) + const [isSaving, setIsSaving] = useState(false) + const [projects, setProjects] = useState>([]) + const [formData, setFormData] = useState({ + projectId: null, + projectCode: '', + projectName: '', + managerName: '', + managerDepartment: '', + rehandlingContractor: '' + }) + + // 프로젝트 목록 로드 + useEffect(() => { + const loadProjects = async () => { + try { + const projectList = await getProjects() + setProjects(projectList) + } catch (error) { + console.error('Error loading projects:', error) + } + } + loadProjects() + }, []) + + // 데이터 로드 + useEffect(() => { + const loadYardEntryInfo = async () => { + setIsLoading(true) + try { + const data = await getYardEntryInfo(contractId) + if (data) { + setFormData(data) + } + } catch (error) { + console.error('Error loading yard entry info:', error) + toast.error('사외업체 야드투입 정보를 불러오는 중 오류가 발생했습니다.') + } finally { + setIsLoading(false) + } + } + + if (contractId) { + loadYardEntryInfo() + } + }, [contractId]) + + // 저장 + const handleSave = async () => { + if (!userId) { + toast.error('사용자 정보를 찾을 수 없습니다.') + return + } + + // 유효성 검사 + if (!formData.projectId) { + toast.error('프로젝트를 선택해주세요.') + return + } + + setIsSaving(true) + try { + await saveYardEntryInfo(contractId, formData, userId) + toast.success('사외업체 야드투입 정보가 저장되었습니다.') + } catch (error) { + console.error('Error saving yard entry info:', error) + toast.error('사외업체 야드투입 정보 저장 중 오류가 발생했습니다.') + } finally { + setIsSaving(false) + } + } + + const selectedProject = projects.find(p => p.id === formData.projectId) + + if (isLoading) { + return ( + + + 사외업체 야드투입 정보 + + +
+ + 로딩 중... +
+
+
+ ) + } + + return ( + + +
+ 사외업체 야드투입 정보 + {!readOnly && ( + + )} +
+
+ +
+ {/* 프로젝트 */} +
+ + {readOnly ? ( +
+ {selectedProject ? `${selectedProject.code} - ${selectedProject.name}` : '-'} +
+ ) : ( + + )} +
+ + {/* 관리담당자 */} +
+ + {readOnly ? ( +
{formData.managerName || '-'}
+ ) : ( + setFormData(prev => ({ ...prev, managerName: e.target.value }))} + placeholder="관리담당자 입력" + /> + )} +
+ + {/* 관리부서 */} +
+ + {readOnly ? ( +
{formData.managerDepartment || '-'}
+ ) : ( + setFormData(prev => ({ ...prev, managerDepartment: e.target.value }))} + placeholder="관리부서 입력" + /> + )} +
+ + {/* 재하도협력사 */} +
+ + {readOnly ? ( +
{formData.rehandlingContractor || '-'}
+ ) : ( + setFormData(prev => ({ ...prev, rehandlingContractor: e.target.value }))} + placeholder="재하도협력사 입력" + /> + )} +
+
+
+
+ ) +} + -- cgit v1.2.3