summaryrefslogtreecommitdiff
path: root/lib/general-contracts_old/detail/general-contract-location.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'lib/general-contracts_old/detail/general-contract-location.tsx')
-rw-r--r--lib/general-contracts_old/detail/general-contract-location.tsx480
1 files changed, 480 insertions, 0 deletions
diff --git a/lib/general-contracts_old/detail/general-contract-location.tsx b/lib/general-contracts_old/detail/general-contract-location.tsx
new file mode 100644
index 00000000..5b388895
--- /dev/null
+++ b/lib/general-contracts_old/detail/general-contract-location.tsx
@@ -0,0 +1,480 @@
+'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 { Save, LoaderIcon, MapPin } from 'lucide-react'
+import { updateLocation, getLocation } from '../service'
+import { toast } from 'sonner'
+
+interface LocationProps {
+ contractType?: string
+ contractId: number
+}
+
+interface LocationData {
+ country: {
+ projectManager: string
+ engineering: string
+ procurement: string
+ fabrication: string
+ assembly: string
+ test: string
+ shippingExw: string
+ shippingFob: string
+ remark: string
+ }
+ location: {
+ projectManager: string
+ engineering: string
+ procurement: string
+ fabrication: string
+ assembly: string
+ test: string
+ shippingExw: string
+ shippingFob: string
+ remark: string
+ }
+ subContractor: {
+ projectManager: string
+ engineering: string
+ procurement: string
+ fabrication: string
+ assembly: string
+ test: string
+ shippingExw: string
+ shippingFob: string
+ remark: string
+ }
+}
+
+export function Location({ contractId }: LocationProps) {
+ const session = useSession()
+ const [isLoading, setIsLoading] = useState(false)
+ const [isEnabled, setIsEnabled] = useState(true)
+ const [locationData, setLocationData] = useState<LocationData>({
+ country: {
+ projectManager: '',
+ engineering: '',
+ procurement: '',
+ fabrication: '',
+ assembly: '',
+ test: '',
+ shippingExw: '',
+ shippingFob: '',
+ remark: ''
+ },
+ location: {
+ projectManager: '',
+ engineering: '',
+ procurement: '',
+ fabrication: '',
+ assembly: '',
+ test: '',
+ shippingExw: '',
+ shippingFob: '',
+ remark: ''
+ },
+ subContractor: {
+ projectManager: '',
+ engineering: '',
+ procurement: '',
+ fabrication: '',
+ assembly: '',
+ test: '',
+ shippingExw: '',
+ shippingFob: '',
+ remark: ''
+ }
+ })
+
+ // 특정 계약종류를 제외한 일반계약은 Default로 표시
+ const isDisabled = false // 일단 모든 계약종류에서 활성화
+
+ // 초기 데이터 로드
+ useEffect(() => {
+ const loadLocationData = async () => {
+ try {
+ const data = await getLocation(contractId)
+ if (data && data.locations) {
+ setLocationData(data.locations)
+ setIsEnabled(data.enabled || true)
+ } else {
+ // 기본 데이터는 이미 useState에서 설정됨
+ }
+ } catch (error) {
+ console.error('Error loading location data:', error)
+ // 기본 데이터는 이미 useState에서 설정됨
+ }
+ }
+
+ loadLocationData()
+ }, [contractId])
+
+ const updateLocationData = (rowType: keyof LocationData, field: keyof LocationData['country'], value: string) => {
+ setLocationData(prev => ({
+ ...prev,
+ [rowType]: {
+ ...prev[rowType],
+ [field]: value
+ }
+ }))
+ }
+
+ const handleSaveLocation = async () => {
+ const userId = session.data?.user?.id ? Number(session.data.user.id) : null
+
+ if (!userId) {
+ toast.error('사용자 정보를 찾을 수 없습니다.')
+ return
+ }
+
+ try {
+ setIsLoading(true)
+
+ const locationDataToSave = {
+ enabled: isEnabled,
+ locations: locationData
+ }
+
+ await updateLocation(contractId, locationDataToSave, userId)
+ toast.success('Location 정보가 저장되었습니다.')
+ } catch (error) {
+ console.error('Error saving location:', error)
+ toast.error('Location 정보 저장에 실패했습니다.')
+ } finally {
+ setIsLoading(false)
+ }
+ }
+
+ return (
+ <div className="w-full">
+ <Accordion type="single" collapsible className="w-full">
+ <AccordionItem value="location">
+ <AccordionTrigger className="hover:no-underline">
+ <div className="flex items-center gap-3 w-full">
+ <MapPin className="w-5 h-5" />
+ <span className="font-medium">Location</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">Location 활성화</span>
+ </div>
+
+ {/* Location 테이블 */}
+ <div className="space-y-4">
+ <h3 className="text-lg font-medium">Location</h3>
+
+ <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">Activity</th>
+ <th className="border border-gray-300 p-2">Project Manager</th>
+ <th className="border border-gray-300 p-2">Engineering</th>
+ <th className="border border-gray-300 p-2">Procurement</th>
+ <th className="border border-gray-300 p-2">Fabrication</th>
+ <th className="border border-gray-300 p-2">Assembly</th>
+ <th className="border border-gray-300 p-2">Test (FAT)</th>
+ <th className="border border-gray-300 p-2">Shipping (EXW)</th>
+ <th className="border border-gray-300 p-2">Shipping (FOB)</th>
+ <th className="border border-gray-300 p-2">Remark</th>
+ </tr>
+ </thead>
+ <tbody>
+ {/* Country Row */}
+ <tr className="bg-yellow-50">
+ <td className="border border-gray-300 p-2 font-medium">Country</td>
+ <td className="border border-gray-300 p-2">
+ <Input
+ value={locationData?.country?.projectManager || ''}
+ onChange={(e) => updateLocationData('country', 'projectManager', e.target.value)}
+ disabled={isDisabled || !isEnabled}
+ className="border-0 bg-transparent p-0 h-auto"
+ placeholder="국가"
+ />
+ </td>
+ <td className="border border-gray-300 p-2">
+ <Input
+ value={locationData?.country?.engineering || ''}
+ onChange={(e) => updateLocationData('country', 'engineering', e.target.value)}
+ disabled={isDisabled || !isEnabled}
+ className="border-0 bg-transparent p-0 h-auto"
+ placeholder="국가"
+ />
+ </td>
+ <td className="border border-gray-300 p-2">
+ <Input
+ value={locationData?.country.procurement}
+ onChange={(e) => updateLocationData('country', 'procurement', e.target.value)}
+ disabled={isDisabled || !isEnabled}
+ className="border-0 bg-transparent p-0 h-auto"
+ placeholder="국가"
+ />
+ </td>
+ <td className="border border-gray-300 p-2">
+ <Input
+ value={locationData?.country.fabrication}
+ onChange={(e) => updateLocationData('country', 'fabrication', e.target.value)}
+ disabled={isDisabled || !isEnabled}
+ className="border-0 bg-transparent p-0 h-auto"
+ placeholder="국가"
+ />
+ </td>
+ <td className="border border-gray-300 p-2">
+ <Input
+ value={locationData?.country.assembly}
+ onChange={(e) => updateLocationData('country', 'assembly', e.target.value)}
+ disabled={isDisabled || !isEnabled}
+ className="border-0 bg-transparent p-0 h-auto"
+ placeholder="국가"
+ />
+ </td>
+ <td className="border border-gray-300 p-2">
+ <Input
+ value={locationData?.country.test}
+ onChange={(e) => updateLocationData('country', 'test', e.target.value)}
+ disabled={isDisabled || !isEnabled}
+ className="border-0 bg-transparent p-0 h-auto"
+ placeholder="국가"
+ />
+ </td>
+ <td className="border border-gray-300 p-2">
+ <Input
+ value={locationData?.country.shippingExw}
+ onChange={(e) => updateLocationData('country', 'shippingExw', e.target.value)}
+ disabled={isDisabled || !isEnabled}
+ className="border-0 bg-transparent p-0 h-auto"
+ placeholder="국가"
+ />
+ </td>
+ <td className="border border-gray-300 p-2">
+ <Input
+ value={locationData?.country.shippingFob}
+ onChange={(e) => updateLocationData('country', 'shippingFob', e.target.value)}
+ disabled={isDisabled || !isEnabled}
+ className="border-0 bg-transparent p-0 h-auto"
+ placeholder="국가"
+ />
+ </td>
+ <td className="border border-gray-300 p-2">
+ <Input
+ value={locationData?.country.remark}
+ onChange={(e) => updateLocationData('country', 'remark', e.target.value)}
+ disabled={isDisabled || !isEnabled}
+ className="border-0 bg-transparent p-0 h-auto"
+ />
+ </td>
+ </tr>
+
+ {/* Location (City) Row */}
+ <tr className="bg-yellow-50">
+ <td className="border border-gray-300 p-2 font-medium">Location (City)</td>
+ <td className="border border-gray-300 p-2">
+ <Input
+ value={locationData?.location.projectManager}
+ onChange={(e) => updateLocationData('location', 'projectManager', e.target.value)}
+ disabled={isDisabled || !isEnabled}
+ className="border-0 bg-transparent p-0 h-auto"
+ placeholder="국가 내 지역"
+ />
+ </td>
+ <td className="border border-gray-300 p-2">
+ <Input
+ value={locationData?.location.engineering}
+ onChange={(e) => updateLocationData('location', 'engineering', e.target.value)}
+ disabled={isDisabled || !isEnabled}
+ className="border-0 bg-transparent p-0 h-auto"
+ placeholder="국가 내 지역"
+ />
+ </td>
+ <td className="border border-gray-300 p-2">
+ <Input
+ value={locationData?.location.procurement}
+ onChange={(e) => updateLocationData('location', 'procurement', e.target.value)}
+ disabled={isDisabled || !isEnabled}
+ className="border-0 bg-transparent p-0 h-auto"
+ placeholder="국가 내 지역"
+ />
+ </td>
+ <td className="border border-gray-300 p-2">
+ <Input
+ value={locationData?.location.fabrication}
+ onChange={(e) => updateLocationData('location', 'fabrication', e.target.value)}
+ disabled={isDisabled || !isEnabled}
+ className="border-0 bg-transparent p-0 h-auto"
+ placeholder="국가 내 지역"
+ />
+ </td>
+ <td className="border border-gray-300 p-2">
+ <Input
+ value={locationData?.location.assembly}
+ onChange={(e) => updateLocationData('location', 'assembly', e.target.value)}
+ disabled={isDisabled || !isEnabled}
+ className="border-0 bg-transparent p-0 h-auto"
+ placeholder="국가 내 지역"
+ />
+ </td>
+ <td className="border border-gray-300 p-2">
+ <Input
+ value={locationData?.location.test}
+ onChange={(e) => updateLocationData('location', 'test', e.target.value)}
+ disabled={isDisabled || !isEnabled}
+ className="border-0 bg-transparent p-0 h-auto"
+ placeholder="국가 내 지역"
+ />
+ </td>
+ <td className="border border-gray-300 p-2">
+ <Input
+ value={locationData?.location.shippingExw}
+ onChange={(e) => updateLocationData('location', 'shippingExw', e.target.value)}
+ disabled={isDisabled || !isEnabled}
+ className="border-0 bg-transparent p-0 h-auto"
+ placeholder="국가 내 지역"
+ />
+ </td>
+ <td className="border border-gray-300 p-2">
+ <Input
+ value={locationData?.location.shippingFob}
+ onChange={(e) => updateLocationData('location', 'shippingFob', e.target.value)}
+ disabled={isDisabled || !isEnabled}
+ className="border-0 bg-transparent p-0 h-auto"
+ placeholder="국가 내 지역"
+ />
+ </td>
+ <td className="border border-gray-300 p-2">
+ <Input
+ value={locationData?.location.remark}
+ onChange={(e) => updateLocationData('location', 'remark', e.target.value)}
+ disabled={isDisabled || !isEnabled}
+ className="border-0 bg-transparent p-0 h-auto"
+ />
+ </td>
+ </tr>
+
+ {/* Sub-Contractor Row */}
+ <tr className="bg-yellow-50">
+ <td className="border border-gray-300 p-2 font-medium">Sub-Contractor<br />(where applicable)</td>
+ <td className="border border-gray-300 p-2">
+ <Input
+ value={locationData?.subContractor?.projectManager || ''}
+ onChange={(e) => updateLocationData('subContractor', 'projectManager', e.target.value)}
+ disabled={isDisabled || !isEnabled}
+ className="border-0 bg-transparent p-0 h-auto"
+ placeholder="국가 및 지역"
+ />
+ </td>
+ <td className="border border-gray-300 p-2">
+ <Input
+ value={locationData?.subContractor?.engineering || ''}
+ onChange={(e) => updateLocationData('subContractor', 'engineering', e.target.value)}
+ disabled={isDisabled || !isEnabled}
+ className="border-0 bg-transparent p-0 h-auto"
+ placeholder="국가 및 지역"
+ />
+ </td>
+ <td className="border border-gray-300 p-2">
+ <Input
+ value={locationData?.subContractor?.procurement || ''}
+ onChange={(e) => updateLocationData('subContractor', 'procurement', e.target.value)}
+ disabled={isDisabled || !isEnabled}
+ className="border-0 bg-transparent p-0 h-auto"
+ placeholder="국가 및 지역"
+ />
+ </td>
+ <td className="border border-gray-300 p-2">
+ <Input
+ value={locationData?.subContractor?.fabrication || ''}
+ onChange={(e) => updateLocationData('subContractor', 'fabrication', e.target.value)}
+ disabled={isDisabled || !isEnabled}
+ className="border-0 bg-transparent p-0 h-auto"
+ placeholder="국가 및 지역"
+ />
+ </td>
+ <td className="border border-gray-300 p-2">
+ <Input
+ value={locationData?.subContractor?.assembly || ''}
+ onChange={(e) => updateLocationData('subContractor', 'assembly', e.target.value)}
+ disabled={isDisabled || !isEnabled}
+ className="border-0 bg-transparent p-0 h-auto"
+ placeholder="국가 및 지역"
+ />
+ </td>
+ <td className="border border-gray-300 p-2">
+ <Input
+ value={locationData?.subContractor?.test || ''}
+ onChange={(e) => updateLocationData('subContractor', 'test', e.target.value)}
+ disabled={isDisabled || !isEnabled}
+ className="border-0 bg-transparent p-0 h-auto"
+ placeholder="국가 및 지역"
+ />
+ </td>
+ <td className="border border-gray-300 p-2">
+ <Input
+ value={locationData?.subContractor?.shippingExw || ''}
+ onChange={(e) => updateLocationData('subContractor', 'shippingExw', e.target.value)}
+ disabled={isDisabled || !isEnabled}
+ className="border-0 bg-transparent p-0 h-auto"
+ placeholder="국가 및 지역"
+ />
+ </td>
+ <td className="border border-gray-300 p-2">
+ <Input
+ value={locationData?.subContractor?.shippingFob || ''}
+ onChange={(e) => updateLocationData('subContractor', 'shippingFob', e.target.value)}
+ disabled={isDisabled || !isEnabled}
+ className="border-0 bg-transparent p-0 h-auto"
+ placeholder="국가 및 지역"
+ />
+ </td>
+ <td className="border border-gray-300 p-2">
+ <Input
+ value={locationData?.subContractor?.remark || ''}
+ onChange={(e) => updateLocationData('subContractor', 'remark', e.target.value)}
+ disabled={isDisabled || !isEnabled}
+ className="border-0 bg-transparent p-0 h-auto"
+ />
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+ </div>
+
+ {/* 저장 버튼 */}
+ <div className="flex justify-end pt-4 border-t">
+ <Button
+ onClick={handleSaveLocation}
+ 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" />
+ )}
+ Location 저장
+ </Button>
+ </div>
+ </div>
+ </AccordionContent>
+ </AccordionItem>
+ </Accordion>
+ </div>
+ )
+} \ No newline at end of file