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-field-service-rate.tsx | 288 +++++++++++++++++++++ 1 file changed, 288 insertions(+) create mode 100644 lib/general-contracts_old/detail/general-contract-field-service-rate.tsx (limited to 'lib/general-contracts_old/detail/general-contract-field-service-rate.tsx') diff --git a/lib/general-contracts_old/detail/general-contract-field-service-rate.tsx b/lib/general-contracts_old/detail/general-contract-field-service-rate.tsx new file mode 100644 index 00000000..a8158307 --- /dev/null +++ b/lib/general-contracts_old/detail/general-contract-field-service-rate.tsx @@ -0,0 +1,288 @@ +'use client' + +import React, { useState, useEffect } from 'react' +import { useSession } from 'next-auth/react' +import { Input } from '@/components/ui/input' +import { Button } from '@/components/ui/button' +import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from '@/components/ui/accordion' +import { Checkbox } from '@/components/ui/checkbox' +import { Plus, Trash2, Save, LoaderIcon, DollarSign } from 'lucide-react' +import { getFieldServiceRate, updateFieldServiceRate } from '../service' +import { toast } from 'sonner' + +interface FieldServiceRateProps { + contractId: number + contractType?: string +} + +interface FieldServiceRateItem { + id: string + levelOfSpecialist: string + description: string + rateCurrency: string + onshoreRate: string + offshoreRate: string + rateUnit: string + remark: string +} + +export function FieldServiceRate({ contractId }: FieldServiceRateProps) { + const session = useSession() + const [isLoading, setIsLoading] = useState(false) + const [isEnabled, setIsEnabled] = useState(true) + + // 특정 계약종류를 제외한 일반계약은 Default로 표시 + const isDisabled = false + + const [fieldServiceRates, setFieldServiceRates] = useState([]) + + // 초기 데이터 로드 + useEffect(() => { + const loadFieldServiceRate = async () => { + try { + const data = await getFieldServiceRate(contractId) + if (data && data.enabled !== undefined) { + setIsEnabled(data.enabled) + setFieldServiceRates(data.fieldServiceRates || []) + } else { + } + } catch (error) { + console.error('Field Service Rate 데이터 로드 실패:', error) + toast.error('Field Service Rate 데이터를 불러오는데 실패했습니다.') + } + } + + loadFieldServiceRate() + }, [contractId]) + + const addFieldServiceRateRow = () => { + const newRow: FieldServiceRateItem = { + id: Date.now().toString(), + levelOfSpecialist: '', + description: '', + rateCurrency: 'USD', + onshoreRate: '', + offshoreRate: '', + rateUnit: 'day', + remark: '' + } + setFieldServiceRates([...fieldServiceRates, newRow]) + } + + const removeFieldServiceRateRow = (id: string) => { + setFieldServiceRates(fieldServiceRates.filter(item => item.id !== id)) + } + + const updateFieldServiceRateData = (id: string, field: keyof FieldServiceRateItem, value: string) => { + setFieldServiceRates(prev => + prev.map(item => + item.id === id ? { ...item, [field]: value } : item + ) + ) + } + + const handleSaveFieldServiceRate = async () => { + if (!session.data?.user?.id) { + toast.error('로그인이 필요합니다.') + return + } + + setIsLoading(true) + try { + const fieldServiceRateData = { + enabled: isEnabled, + fieldServiceRates: fieldServiceRates + } + + await updateFieldServiceRate(contractId, fieldServiceRateData, Number(session.data.user.id)) + toast.success('Field Service Rate가 성공적으로 저장되었습니다.') + } catch (error) { + console.error('Field Service Rate 저장 실패:', error) + toast.error('Field Service Rate 저장에 실패했습니다.') + } finally { + setIsLoading(false) + } + } + + return ( +
+ + + +
+ + Field Service Rate +
+
+ +
+ {/* 체크박스 */} +
+ { + if (!isDisabled) { + setIsEnabled(checked as boolean) + } + }} + /> + Field Service Rate 활성화 +
+ + {/* Field Service Rate 테이블 */} +
+
+

Field Service Rate

+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + {fieldServiceRates.map((item, index) => ( + + + + + + + + + + + + ))} + +
No.Level of SpecialistDescriptionRate CurrencyOnshore RateOffshore RateRate UnitRemarkAction
{index + 1} + updateFieldServiceRateData(item.id, 'levelOfSpecialist', e.target.value)} + disabled={isDisabled || !isEnabled} + className="border-0 bg-transparent p-0 h-auto" + /> + + updateFieldServiceRateData(item.id, 'description', e.target.value)} + disabled={isDisabled || !isEnabled} + className="border-0 bg-transparent p-0 h-auto" + /> + + updateFieldServiceRateData(item.id, 'rateCurrency', e.target.value)} + disabled={isDisabled || !isEnabled} + className="border-0 bg-transparent p-0 h-auto" + /> + + updateFieldServiceRateData(item.id, 'onshoreRate', e.target.value)} + disabled={isDisabled || !isEnabled} + className="border-0 bg-transparent p-0 h-auto" + /> + + updateFieldServiceRateData(item.id, 'offshoreRate', e.target.value)} + disabled={isDisabled || !isEnabled} + className="border-0 bg-transparent p-0 h-auto" + /> + + updateFieldServiceRateData(item.id, 'rateUnit', e.target.value)} + disabled={isDisabled || !isEnabled} + className="border-0 bg-transparent p-0 h-auto" + /> + + updateFieldServiceRateData(item.id, 'remark', e.target.value)} + disabled={isDisabled || !isEnabled} + className="border-0 bg-transparent p-0 h-auto" + /> + + +
+
+ + {/* Note 정보 */} +
+

Note #1: Air fare, travelling costs and hours, Visa, training, medical test and any additional applications are included.

+

Note #2: Accommodation, meal and local transportation are included.

+
+
+ + {/* 저장 버튼 */} +
+ +
+
+
+
+
+
+ ) +} -- cgit v1.2.3