From ba8cd44a0ed2c613a5f2cee06bfc9bd0f61f21c7 Mon Sep 17 00:00:00 2001
From: dujinkim <dujin.kim@dtsolution.co.kr>
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<FieldServiceRateItem[]>([])
+
+  // 초기 데이터 로드
+  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 (
+    <div className="w-full">
+      <Accordion type="single" collapsible className="w-full">
+        <AccordionItem value="field-service-rate">
+          <AccordionTrigger className="hover:no-underline">
+            <div className="flex items-center gap-3 w-full">
+              <DollarSign className="w-5 h-5" />
+              <span className="font-medium">Field Service Rate</span>
+            </div>
+          </AccordionTrigger>
+          <AccordionContent>
+            <div className="space-y-6">
+              {/* 체크박스 */}
+              <div className="flex items-center gap-2">
+                <Checkbox 
+                  checked={isEnabled}
+                  disabled={isDisabled}
+                  onCheckedChange={(checked) => {
+                    if (!isDisabled) {
+                      setIsEnabled(checked as boolean)
+                    }
+                  }}
+                />
+                <span className="text-sm font-medium">Field Service Rate 활성화</span>
+              </div>
+
+              {/* Field Service Rate 테이블 */}
+              <div className="space-y-4">
+                <div className="flex items-center justify-between">
+                  <h3 className="text-lg font-medium">Field Service Rate</h3>
+                  <div className="flex gap-2">
+                    <Button
+                      type="button"
+                      variant="outline"
+                      size="sm"
+                      onClick={addFieldServiceRateRow}
+                      disabled={isDisabled || !isEnabled}
+                      className="flex items-center gap-2"
+                    >
+                      <Plus className="w-4 h-4" />
+                      행 추가
+                    </Button>
+                    <Button
+                      type="button"
+                      variant="outline"
+                      size="sm"
+                      onClick={() => {
+                        if (confirm('선택된 행들을 삭제하시겠습니까?')) {
+                          // 선택된 행들 삭제 로직 (필요시 구현)
+                        }
+                      }}
+                      disabled={isDisabled || !isEnabled}
+                      className="flex items-center gap-2"
+                    >
+                      <Trash2 className="w-4 h-4" />
+                      행 삭제
+                    </Button>
+                  </div>
+                </div>
+                
+                <div className="overflow-x-auto">
+                  <table className={`w-full border-collapse border border-gray-300 ${!isEnabled ? 'opacity-50' : ''}`}>
+                    <thead>
+                      <tr className="bg-yellow-100">
+                        <th className="border border-gray-300 p-2 w-16">No.</th>
+                        <th className="border border-gray-300 p-2 w-40">Level of Specialist</th>
+                        <th className="border border-gray-300 p-2">Description</th>
+                        <th className="border border-gray-300 p-2 w-32">Rate Currency</th>
+                        <th className="border border-gray-300 p-2 w-32">Onshore Rate</th>
+                        <th className="border border-gray-300 p-2 w-32">Offshore Rate</th>
+                        <th className="border border-gray-300 p-2 w-24">Rate Unit</th>
+                        <th className="border border-gray-300 p-2 w-32">Remark</th>
+                        <th className="border border-gray-300 p-2 w-20">Action</th>
+                      </tr>
+                    </thead>
+                    <tbody>
+                      {fieldServiceRates.map((item, index) => (
+                        <tr key={item.id} className="bg-yellow-50">
+                          <td className="border border-gray-300 p-2 text-center">{index + 1}</td>
+                          <td className="border border-gray-300 p-2">
+                            <Input
+                              value={item.levelOfSpecialist}
+                              onChange={(e) => updateFieldServiceRateData(item.id, 'levelOfSpecialist', e.target.value)}
+                              disabled={isDisabled || !isEnabled}
+                              className="border-0 bg-transparent p-0 h-auto"
+                            />
+                          </td>
+                          <td className="border border-gray-300 p-2">
+                            <Input
+                              value={item.description}
+                              onChange={(e) => updateFieldServiceRateData(item.id, 'description', e.target.value)}
+                              disabled={isDisabled || !isEnabled}
+                              className="border-0 bg-transparent p-0 h-auto"
+                            />
+                          </td>
+                          <td className="border border-gray-300 p-2">
+                            <Input
+                              value={item.rateCurrency}
+                              onChange={(e) => updateFieldServiceRateData(item.id, 'rateCurrency', e.target.value)}
+                              disabled={isDisabled || !isEnabled}
+                              className="border-0 bg-transparent p-0 h-auto"
+                            />
+                          </td>
+                          <td className="border border-gray-300 p-2">
+                            <Input
+                              value={item.onshoreRate}
+                              onChange={(e) => updateFieldServiceRateData(item.id, 'onshoreRate', e.target.value)}
+                              disabled={isDisabled || !isEnabled}
+                              className="border-0 bg-transparent p-0 h-auto"
+                            />
+                          </td>
+                          <td className="border border-gray-300 p-2">
+                            <Input
+                              value={item.offshoreRate}
+                              onChange={(e) => updateFieldServiceRateData(item.id, 'offshoreRate', e.target.value)}
+                              disabled={isDisabled || !isEnabled}
+                              className="border-0 bg-transparent p-0 h-auto"
+                            />
+                          </td>
+                          <td className="border border-gray-300 p-2">
+                            <Input
+                              value={item.rateUnit}
+                              onChange={(e) => updateFieldServiceRateData(item.id, 'rateUnit', e.target.value)}
+                              disabled={isDisabled || !isEnabled}
+                              className="border-0 bg-transparent p-0 h-auto"
+                            />
+                          </td>
+                          <td className="border border-gray-300 p-2">
+                            <Input
+                              value={item.remark}
+                              onChange={(e) => updateFieldServiceRateData(item.id, 'remark', e.target.value)}
+                              disabled={isDisabled || !isEnabled}
+                              className="border-0 bg-transparent p-0 h-auto"
+                            />
+                          </td>
+                          <td className="border border-gray-300 p-2 text-center">
+                            <Button
+                              type="button"
+                              variant="ghost"
+                              size="sm"
+                              onClick={() => removeFieldServiceRateRow(item.id)}
+                              disabled={isDisabled || !isEnabled}
+                              className="h-8 w-8 p-0 text-red-600 hover:text-red-700"
+                            >
+                              <Trash2 className="w-4 h-4" />
+                            </Button>
+                          </td>
+                        </tr>
+                      ))}
+                    </tbody>
+                  </table>
+                </div>
+
+                {/* Note 정보 */}
+                <div className="space-y-2 text-sm text-gray-600">
+                  <p><strong>Note #1:</strong> Air fare, travelling costs and hours, Visa, training, medical test and any additional applications are included.</p>
+                  <p><strong>Note #2:</strong> Accommodation, meal and local transportation are included.</p>
+                </div>
+              </div>
+
+              {/* 저장 버튼 */}
+              <div className="flex justify-end pt-4 border-t">
+                <Button 
+                  onClick={handleSaveFieldServiceRate} 
+                  disabled={isLoading || isDisabled || !isEnabled}
+                  className="flex items-center gap-2"
+                >
+                  {isLoading ? (
+                    <LoaderIcon className="w-4 h-4 animate-spin" />
+                  ) : (
+                    <Save className="w-4 h-4" />
+                  )}
+                  Field Service Rate 저장
+                </Button>
+              </div>
+            </div>
+          </AccordionContent>
+        </AccordionItem>
+      </Accordion>
+    </div>
+  )
+}
-- 
cgit v1.2.3

