summaryrefslogtreecommitdiff
path: root/lib/general-contracts_old/detail/general-contract-communication-channel.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'lib/general-contracts_old/detail/general-contract-communication-channel.tsx')
-rw-r--r--lib/general-contracts_old/detail/general-contract-communication-channel.tsx362
1 files changed, 362 insertions, 0 deletions
diff --git a/lib/general-contracts_old/detail/general-contract-communication-channel.tsx b/lib/general-contracts_old/detail/general-contract-communication-channel.tsx
new file mode 100644
index 00000000..f5cd79b2
--- /dev/null
+++ b/lib/general-contracts_old/detail/general-contract-communication-channel.tsx
@@ -0,0 +1,362 @@
+'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, MessageSquare } from 'lucide-react'
+import { updateCommunicationChannel, getCommunicationChannel } from '../service'
+import { toast } from 'sonner'
+
+interface CommunicationChannelProps {
+ contractType?: string
+ contractId: number
+}
+
+interface Representative {
+ id: string
+ position: string
+ name: string
+ telNo: string
+ email: string
+ isActive: boolean
+}
+
+export function CommunicationChannel({ contractId }: CommunicationChannelProps) {
+ const session = useSession()
+ const [isLoading, setIsLoading] = useState(false)
+ const [isEnabled, setIsEnabled] = useState(true)
+
+ // 일단 모든 계약종류에서 활성화
+ const isDisabled = false
+
+ const [contractorReps, setContractorReps] = useState<Representative[]>([])
+ const [supplierReps, setSupplierReps] = useState<Representative[]>([])
+
+ // 초기 데이터 로드
+ useEffect(() => {
+ const loadCommunicationChannel = async () => {
+ try {
+ const data = await getCommunicationChannel(contractId)
+ if (data && data.enabled !== undefined) {
+ setIsEnabled(data.enabled)
+ setContractorReps(data.contractorRepresentatives || [])
+ setSupplierReps(data.supplierRepresentatives || [])
+ }
+ } catch (error) {
+ console.error('Error loading communication channel:', error)
+
+ }
+ }
+
+ loadCommunicationChannel()
+ }, [contractId])
+
+ const addContractorRow = () => {
+ const newId = (contractorReps.length + 1).toString()
+ setContractorReps([...contractorReps, {
+ id: newId,
+ position: '',
+ name: '',
+ telNo: '',
+ email: '',
+ isActive: false
+ }])
+ }
+
+ const removeContractorRow = () => {
+ const selectedRows = contractorReps.filter(rep => rep.isActive)
+ if (selectedRows.length > 0) {
+ setContractorReps(contractorReps.filter(rep => !rep.isActive))
+ }
+ }
+
+ const addSupplierRow = () => {
+ const newId = (supplierReps.length + 1).toString()
+ setSupplierReps([...supplierReps, {
+ id: newId,
+ position: '',
+ name: '',
+ telNo: '',
+ email: '',
+ isActive: false
+ }])
+ }
+
+ const removeSupplierRow = () => {
+ const selectedRows = supplierReps.filter(rep => rep.isActive)
+ if (selectedRows.length > 0) {
+ setSupplierReps(supplierReps.filter(rep => !rep.isActive))
+ }
+ }
+
+ const updateContractorRep = (id: string, field: keyof Representative, value: string | boolean) => {
+ setContractorReps(contractorReps.map(rep =>
+ rep.id === id ? { ...rep, [field]: value } : rep
+ ))
+ }
+
+ const updateSupplierRep = (id: string, field: keyof Representative, value: string | boolean) => {
+ setSupplierReps(supplierReps.map(rep =>
+ rep.id === id ? { ...rep, [field]: value } : rep
+ ))
+ }
+
+ const handleSaveCommunicationChannel = async () => {
+ const userId = session.data?.user?.id ? Number(session.data.user.id) : null
+
+ if (!userId) {
+ toast.error('사용자 정보를 찾을 수 없습니다.')
+ return
+ }
+
+ try {
+ setIsLoading(true)
+
+ const communicationData = {
+ enabled: isEnabled,
+ contractorRepresentatives: contractorReps,
+ supplierRepresentatives: supplierReps
+ }
+
+ await updateCommunicationChannel(contractId, communicationData, userId)
+ toast.success('커뮤니케이션 채널이 저장되었습니다.')
+ } catch (error) {
+ console.error('Error saving communication channel:', error)
+ toast.error('커뮤니케이션 채널 저장에 실패했습니다.')
+ } finally {
+ setIsLoading(false)
+ }
+ }
+
+ return (
+ <div className="w-full">
+ <Accordion type="single" collapsible className="w-full">
+ {/* Communication Channel 활성화 */}
+ <AccordionItem value="communication-channel">
+ <AccordionTrigger className="hover:no-underline">
+ <div className="flex items-center gap-3 w-full">
+ <MessageSquare className="w-5 h-5" />
+ <span className="font-medium">Communication Channel</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">Communication Channel 활성화</span>
+ </div>
+
+ {/* Table 1: The Contractor's Representatives */}
+ <div className="space-y-4">
+ <div className="flex items-center justify-between">
+ <h3 className="text-lg font-medium">Table 1: The Contractor &apos;s Representatives</h3>
+ <div className="flex gap-2">
+ <Button
+ type="button"
+ variant="outline"
+ size="sm"
+ onClick={addContractorRow}
+ disabled={isDisabled || !isEnabled}
+ >
+ <Plus className="w-4 h-4 mr-1" />
+ 행 추가
+ </Button>
+ <Button
+ type="button"
+ variant="outline"
+ size="sm"
+ onClick={removeContractorRow}
+ disabled={isDisabled || !isEnabled}
+ >
+ <Trash2 className="w-4 h-4 mr-1" />
+ 행 삭제
+ </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-12"></th>
+ <th className="border border-gray-300 p-2 w-16">No.</th>
+ <th className="border border-gray-300 p-2">Position</th>
+ <th className="border border-gray-300 p-2">Name</th>
+ <th className="border border-gray-300 p-2">Tel. No.</th>
+ <th className="border border-gray-300 p-2">Email</th>
+ </tr>
+ </thead>
+ <tbody>
+ {contractorReps.map((rep) => (
+ <tr key={rep.id} className="bg-yellow-50">
+ <td className="border border-gray-300 p-2 text-center">
+ <Checkbox
+ checked={rep.isActive}
+ onCheckedChange={(checked) => updateContractorRep(rep.id, 'isActive', checked as boolean)}
+ disabled={isDisabled || !isEnabled}
+ />
+ </td>
+ <td className="border border-gray-300 p-2 text-center">{rep.id}</td>
+ <td className="border border-gray-300 p-2">
+ <Input
+ value={rep.position}
+ onChange={(e) => updateContractorRep(rep.id, 'position', 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={rep.name}
+ onChange={(e) => updateContractorRep(rep.id, 'name', 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={rep.telNo}
+ onChange={(e) => updateContractorRep(rep.id, 'telNo', 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={rep.email}
+ onChange={(e) => updateContractorRep(rep.id, 'email', e.target.value)}
+ disabled={isDisabled || !isEnabled}
+ className="border-0 bg-transparent p-0 h-auto"
+ />
+ </td>
+ </tr>
+ ))}
+ </tbody>
+ </table>
+ </div>
+ </div>
+
+ {/* Table 2: The Supplier's Representatives */}
+ <div className="space-y-4">
+ <div className="flex items-center justify-between">
+ <h3 className="text-lg font-medium">Table 2: The Supplier &apos;s Representatives</h3>
+ <div className="flex gap-2">
+ <Button
+ type="button"
+ variant="outline"
+ size="sm"
+ onClick={addSupplierRow}
+ disabled={isDisabled || !isEnabled}
+ >
+ <Plus className="w-4 h-4 mr-1" />
+ 행 추가
+ </Button>
+ <Button
+ type="button"
+ variant="outline"
+ size="sm"
+ onClick={removeSupplierRow}
+ disabled={isDisabled || !isEnabled}
+ >
+ <Trash2 className="w-4 h-4 mr-1" />
+ 행 삭제
+ </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-12"></th>
+ <th className="border border-gray-300 p-2 w-16">No.</th>
+ <th className="border border-gray-300 p-2">Position</th>
+ <th className="border border-gray-300 p-2">Name</th>
+ <th className="border border-gray-300 p-2">Tel. No.</th>
+ <th className="border border-gray-300 p-2">Email</th>
+ </tr>
+ </thead>
+ <tbody>
+ {supplierReps.map((rep) => (
+ <tr key={rep.id} className="bg-yellow-50">
+ <td className="border border-gray-300 p-2 text-center">
+ <Checkbox
+ checked={rep.isActive}
+ onCheckedChange={(checked) => updateSupplierRep(rep.id, 'isActive', checked as boolean)}
+ disabled={isDisabled || !isEnabled}
+ />
+ </td>
+ <td className="border border-gray-300 p-2 text-center">{rep.id}</td>
+ <td className="border border-gray-300 p-2">
+ <Input
+ value={rep.position}
+ onChange={(e) => updateSupplierRep(rep.id, 'position', 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={rep.name}
+ onChange={(e) => updateSupplierRep(rep.id, 'name', 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={rep.telNo}
+ onChange={(e) => updateSupplierRep(rep.id, 'telNo', 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={rep.email}
+ onChange={(e) => updateSupplierRep(rep.id, 'email', 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={handleSaveCommunicationChannel}
+ 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" />
+ )}
+ 커뮤니케이션 채널 저장
+ </Button>
+ </div>
+ </div>
+ </AccordionContent>
+ </AccordionItem>
+ </Accordion>
+ </div>
+ )
+}