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 --- .../main/create-general-contract-dialog.tsx | 156 +++++++++++++-------- 1 file changed, 99 insertions(+), 57 deletions(-) (limited to 'lib/general-contracts/main/create-general-contract-dialog.tsx') diff --git a/lib/general-contracts/main/create-general-contract-dialog.tsx b/lib/general-contracts/main/create-general-contract-dialog.tsx index 2c3fc8bc..168b8cbc 100644 --- a/lib/general-contracts/main/create-general-contract-dialog.tsx +++ b/lib/general-contracts/main/create-general-contract-dialog.tsx @@ -20,11 +20,12 @@ import { Textarea } from "@/components/ui/textarea" import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select" import { Calendar } from "@/components/ui/calendar" import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover" -import { CalendarIcon } from "lucide-react" +import { CalendarIcon, Check, ChevronsUpDown } from "lucide-react" +import { Command, CommandInput, CommandList, CommandEmpty, CommandGroup, CommandItem } from "@/components/ui/command" import { format } from "date-fns" import { ko } from "date-fns/locale" import { cn } from "@/lib/utils" -import { createContract, getVendors, getProjects } from "@/lib/general-contracts/service" +import { createContract, getVendors } from "@/lib/general-contracts/service" import { GENERAL_CONTRACT_CATEGORIES, GENERAL_CONTRACT_TYPES, @@ -39,7 +40,6 @@ interface CreateContractForm { type: string executionMethod: string vendorId: number | null - projectId: number | null startDate: Date | undefined endDate: Date | undefined validityEndDate: Date | undefined @@ -52,7 +52,8 @@ export function CreateGeneralContractDialog() { const [open, setOpen] = React.useState(false) const [isLoading, setIsLoading] = React.useState(false) const [vendors, setVendors] = React.useState>([]) - const [projects, setProjects] = React.useState>([]) + const [vendorSearchTerm, setVendorSearchTerm] = React.useState("") + const [vendorOpen, setVendorOpen] = React.useState(false) const [form, setForm] = React.useState({ contractNumber: '', @@ -61,7 +62,6 @@ export function CreateGeneralContractDialog() { type: '', executionMethod: '', vendorId: null, - projectId: null, startDate: undefined, endDate: undefined, validityEndDate: undefined, @@ -70,36 +70,54 @@ export function CreateGeneralContractDialog() { // 업체 목록 조회 React.useEffect(() => { - const fetchVendors = async () => { + const fetchData = async () => { try { const vendorList = await getVendors() + console.log('vendorList', vendorList) setVendors(vendorList) } catch (error) { - console.error('Error fetching vendors:', error) + console.error('데이터 조회 오류:', error) + toast.error('데이터를 불러오는데 실패했습니다') + setVendors([]) } } - fetchVendors() + fetchData() }, []) - // 프로젝트 목록 조회 - React.useEffect(() => { - const fetchProjects = async () => { - try { - const projectList = await getProjects() - console.log(projectList) - setProjects(projectList) - } catch (error) { - console.error('Error fetching projects:', error) - } - } - fetchProjects() - }, []) + // 협력업체 검색 필터링 + const filteredVendors = React.useMemo(() => { + if (!vendorSearchTerm.trim()) return vendors + const lowerSearch = vendorSearchTerm.toLowerCase() + return vendors.filter( + vendor => + vendor.vendorName.toLowerCase().includes(lowerSearch) || + (vendor.vendorCode && vendor.vendorCode.toLowerCase().includes(lowerSearch)) + ) + }, [vendors, vendorSearchTerm]) const handleSubmit = async () => { // 필수 필드 검증 - if (!form.name || !form.category || !form.type || !form.executionMethod || - !form.vendorId || !form.startDate || !form.endDate) { - toast.error("필수 항목을 모두 입력해주세요.") + const validationErrors: string[] = [] + + if (!form.name) validationErrors.push('계약명') + if (!form.category) validationErrors.push('계약구분') + if (!form.type) validationErrors.push('계약종류') + if (!form.executionMethod) validationErrors.push('체결방식') + if (!form.vendorId) validationErrors.push('협력업체') + + // AD, LO, OF 계약이 아닌 경우에만 계약기간 필수값 체크 + if (!['AD', 'LO', 'OF'].includes(form.type)) { + if (!form.startDate) validationErrors.push('계약시작일') + if (!form.endDate) validationErrors.push('계약종료일') + } + + // LO 계약인 경우 계약체결유효기간 필수값 체크 + if (form.type === 'LO' && !form.validityEndDate) { + validationErrors.push('유효기간') + } + + if (validationErrors.length > 0) { + toast.error(`다음 필수 항목을 입력해주세요: ${validationErrors.join(', ')}`) return } @@ -116,7 +134,6 @@ export function CreateGeneralContractDialog() { category: form.category, type: form.type, executionMethod: form.executionMethod, - projectId: form.projectId, contractSourceType: 'manual', vendorId: form.vendorId!, startDate: form.startDate!.toISOString().split('T')[0], @@ -152,7 +169,6 @@ export function CreateGeneralContractDialog() { type: '', executionMethod: '', vendorId: null, - projectId: null, startDate: undefined, endDate: undefined, validityEndDate: undefined, @@ -231,15 +247,14 @@ export function CreateGeneralContractDialog() { 'AL': '연간운송계약', 'OS': '외주용역계약', 'OW': '도급계약', - 'IS': '검사계약', 'LO': 'LOI', 'FA': 'FA', 'SC': '납품합의계약', 'OF': '클레임상계계약', 'AW': '사전작업합의', 'AD': '사전납품합의', - 'AM': '설계계약', - 'SC_SELL': '폐기물매각계약' + 'SG': '임치(물품보관)계약', + 'SR': '폐기물매각계약' } return ( @@ -268,36 +283,63 @@ export function CreateGeneralContractDialog() { -
- - -
-
- + + + + + + + + + 검색 결과가 없습니다 + + {filteredVendors.map((vendor) => ( + { + setForm(prev => ({ ...prev, vendorId: vendor.id })) + setVendorOpen(false) + setVendorSearchTerm("") + }} + > + + {vendor.vendorName} + {vendor.vendorCode && ( + ({vendor.vendorCode}) + )} + + ))} + + + + +
-- cgit v1.2.3