diff options
| author | dujinkim <dujin.kim@dtsolution.co.kr> | 2025-11-07 08:39:04 +0000 |
|---|---|---|
| committer | dujinkim <dujin.kim@dtsolution.co.kr> | 2025-11-07 08:39:04 +0000 |
| commit | ba8cd44a0ed2c613a5f2cee06bfc9bd0f61f21c7 (patch) | |
| tree | 7fb626c184a1fa48b28bf83571dadca2306bd1b5 /lib/general-contracts/detail/general-contract-offset-details.tsx | |
| parent | b0fe980376fcf1a19ff4b90851ca8b01f378fdc0 (diff) | |
(최겸) 입찰/견적 수정사항
Diffstat (limited to 'lib/general-contracts/detail/general-contract-offset-details.tsx')
| -rw-r--r-- | lib/general-contracts/detail/general-contract-offset-details.tsx | 314 |
1 files changed, 0 insertions, 314 deletions
diff --git a/lib/general-contracts/detail/general-contract-offset-details.tsx b/lib/general-contracts/detail/general-contract-offset-details.tsx deleted file mode 100644 index af4f2ef2..00000000 --- a/lib/general-contracts/detail/general-contract-offset-details.tsx +++ /dev/null @@ -1,314 +0,0 @@ -'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 { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'
-import { Plus, Trash2, Save, LoaderIcon, RotateCcw } from 'lucide-react'
-import { getOffsetDetails, updateOffsetDetails } from '../service'
-import { toast } from 'sonner'
-
-interface OffsetDetailsProps {
- contractId: number
- contractType?: string
-}
-
-interface OffsetDetailItem {
- id: string
- project: string
- poNumber: string
- poItemDescription: string
- offsetReason: string
- contractCurrency: string
- contractAmount: string
- offsetDate: string
- remark: string
-}
-
-export function OffsetDetails({ contractId }: OffsetDetailsProps) {
- const session = useSession()
- const [isLoading, setIsLoading] = useState(false)
- const [isEnabled, setIsEnabled] = useState(true)
-
- // 특정 계약종류를 제외한 일반계약은 Default로 표시
- const isDisabled = false
-
- const [offsetDetails, setOffsetDetails] = useState<OffsetDetailItem[]>([])
-
- // 회입/상계사유 옵션
- const offsetReasonOptions = [
- '판매자 사양불만족',
- '납기지연',
- '품질불량',
- '계약조건변경',
- '기타'
- ]
-
- // 초기 데이터 로드
- useEffect(() => {
- const loadOffsetDetails = async () => {
- try {
- const data = await getOffsetDetails(contractId)
- if (data && data.enabled !== undefined) {
- setIsEnabled(data.enabled)
- setOffsetDetails(data.offsetDetails || [])
- } else {
- }
- } catch (error) {
- console.error('회입/상계내역 데이터 로드 실패:', error)
- toast.error('회입/상계내역 데이터를 불러오는데 실패했습니다.')
- }
- }
-
- loadOffsetDetails()
- }, [contractId])
-
- const addOffsetDetailRow = () => {
- const newRow: OffsetDetailItem = {
- id: Date.now().toString(),
- project: '',
- poNumber: '',
- poItemDescription: '',
- offsetReason: '',
- contractCurrency: 'KRW',
- contractAmount: '',
- offsetDate: '',
- remark: ''
- }
- setOffsetDetails([...offsetDetails, newRow])
- }
-
- const removeOffsetDetailRow = (id: string) => {
- setOffsetDetails(offsetDetails.filter(item => item.id !== id))
- }
-
- const updateOffsetDetailData = (id: string, field: keyof OffsetDetailItem, value: string) => {
- setOffsetDetails(prev =>
- prev.map(item =>
- item.id === id ? { ...item, [field]: value } : item
- )
- )
- }
-
- const handleSaveOffsetDetails = async () => {
- if (!session.data?.user?.id) {
- toast.error('로그인이 필요합니다.')
- return
- }
-
- setIsLoading(true)
- try {
- const offsetDetailsData = {
- enabled: isEnabled,
- offsetDetails: offsetDetails
- }
-
- await updateOffsetDetails(contractId, offsetDetailsData, Number(session.data.user.id))
- toast.success('회입/상계내역이 성공적으로 저장되었습니다.')
- } catch (error) {
- console.error('회입/상계내역 저장 실패:', error)
- toast.error('회입/상계내역 저장에 실패했습니다.')
- } finally {
- setIsLoading(false)
- }
- }
-
- return (
- <div className="w-full">
- <Accordion type="single" collapsible className="w-full">
- <AccordionItem value="offset-details">
- <AccordionTrigger className="hover:no-underline">
- <div className="flex items-center gap-3 w-full">
- <RotateCcw className="w-5 h-5" />
- <span className="font-medium">회입/상계내역</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">회입/상계내역 활성화</span>
- </div>
-
- {/* 회입/상계내역 테이블 */}
- <div className="space-y-4">
- <div className="flex items-center justify-between">
- <h3 className="text-lg font-medium">회입/상계내역</h3>
- <div className="flex gap-2">
- <Button
- type="button"
- variant="outline"
- size="sm"
- onClick={addOffsetDetailRow}
- 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-32">프로젝트</th>
- <th className="border border-gray-300 p-2 w-40">발주번호</th>
- <th className="border border-gray-300 p-2">발주품목(Description)</th>
- <th className="border border-gray-300 p-2 w-40">회입/상계사유</th>
- <th className="border border-gray-300 p-2 w-32">계약통화</th>
- <th className="border border-gray-300 p-2 w-32">계약금액</th>
- <th className="border border-gray-300 p-2 w-32">회입/상계일</th>
- <th className="border border-gray-300 p-2">비고</th>
- <th className="border border-gray-300 p-2 w-20">Action</th>
- </tr>
- </thead>
- <tbody>
- {offsetDetails.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.project}
- onChange={(e) => updateOffsetDetailData(item.id, 'project', 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.poNumber}
- onChange={(e) => updateOffsetDetailData(item.id, 'poNumber', 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.poItemDescription}
- onChange={(e) => updateOffsetDetailData(item.id, 'poItemDescription', e.target.value)}
- disabled={isDisabled || !isEnabled}
- className="border-0 bg-transparent p-0 h-auto"
- />
- </td>
- <td className="border border-gray-300 p-2">
- <Select
- value={item.offsetReason}
- onValueChange={(value) => updateOffsetDetailData(item.id, 'offsetReason', value)}
- disabled={isDisabled || !isEnabled}
- >
- <SelectTrigger className="border-0 bg-transparent p-0 h-auto">
- <SelectValue placeholder="선택하세요" />
- </SelectTrigger>
- <SelectContent>
- {offsetReasonOptions.map((option) => (
- <SelectItem key={option} value={option}>
- {option}
- </SelectItem>
- ))}
- </SelectContent>
- </Select>
- </td>
- <td className="border border-gray-300 p-2">
- <Input
- value={item.contractCurrency}
- onChange={(e) => updateOffsetDetailData(item.id, 'contractCurrency', 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.contractAmount}
- onChange={(e) => updateOffsetDetailData(item.id, 'contractAmount', 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
- type="date"
- value={item.offsetDate}
- onChange={(e) => updateOffsetDetailData(item.id, 'offsetDate', 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) => updateOffsetDetailData(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={() => removeOffsetDetailRow(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>
- </div>
-
- {/* 저장 버튼 */}
- <div className="flex justify-end pt-4 border-t">
- <Button
- onClick={handleSaveOffsetDetails}
- 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>
- )
-}
|
