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 --- components/bidding/bidding-conditions-edit.tsx | 469 ------- components/bidding/bidding-info-header.tsx | 217 +-- components/bidding/bidding-round-actions.tsx | 201 +++ .../bidding/create/bidding-create-dialog.tsx | 1281 ++++++++++++++++++ .../bidding/manage/bidding-basic-info-editor.tsx | 1407 ++++++++++++++++++++ .../bidding/manage/bidding-companies-editor.tsx | 803 +++++++++++ .../manage/bidding-detail-vendor-create-dialog.tsx | 437 ++++++ components/bidding/manage/bidding-items-editor.tsx | 1143 ++++++++++++++++ .../bidding/manage/bidding-schedule-editor.tsx | 661 +++++++++ .../bidding/manage/create-pre-quote-rfq-dialog.tsx | 742 +++++++++++ components/bidding/price-adjustment-dialog.tsx | 6 +- .../selectors/cost-center/cost-center-selector.tsx | 335 +++++ .../selectors/cost-center/cost-center-service.ts | 89 ++ .../cost-center/cost-center-single-selector.tsx | 378 ++++++ components/common/selectors/cost-center/index.ts | 12 + .../selectors/gl-account/gl-account-selector.tsx | 311 +++++ .../selectors/gl-account/gl-account-service.ts | 79 ++ .../gl-account/gl-account-single-selector.tsx | 358 +++++ components/common/selectors/gl-account/index.ts | 12 + components/common/selectors/wbs-code/index.ts | 12 + .../selectors/wbs-code/wbs-code-selector.tsx | 323 +++++ .../common/selectors/wbs-code/wbs-code-service.ts | 92 ++ .../wbs-code/wbs-code-single-selector.tsx | 365 +++++ 23 files changed, 9179 insertions(+), 554 deletions(-) delete mode 100644 components/bidding/bidding-conditions-edit.tsx create mode 100644 components/bidding/bidding-round-actions.tsx create mode 100644 components/bidding/create/bidding-create-dialog.tsx create mode 100644 components/bidding/manage/bidding-basic-info-editor.tsx create mode 100644 components/bidding/manage/bidding-companies-editor.tsx create mode 100644 components/bidding/manage/bidding-detail-vendor-create-dialog.tsx create mode 100644 components/bidding/manage/bidding-items-editor.tsx create mode 100644 components/bidding/manage/bidding-schedule-editor.tsx create mode 100644 components/bidding/manage/create-pre-quote-rfq-dialog.tsx create mode 100644 components/common/selectors/cost-center/cost-center-selector.tsx create mode 100644 components/common/selectors/cost-center/cost-center-service.ts create mode 100644 components/common/selectors/cost-center/cost-center-single-selector.tsx create mode 100644 components/common/selectors/cost-center/index.ts create mode 100644 components/common/selectors/gl-account/gl-account-selector.tsx create mode 100644 components/common/selectors/gl-account/gl-account-service.ts create mode 100644 components/common/selectors/gl-account/gl-account-single-selector.tsx create mode 100644 components/common/selectors/gl-account/index.ts create mode 100644 components/common/selectors/wbs-code/index.ts create mode 100644 components/common/selectors/wbs-code/wbs-code-selector.tsx create mode 100644 components/common/selectors/wbs-code/wbs-code-service.ts create mode 100644 components/common/selectors/wbs-code/wbs-code-single-selector.tsx (limited to 'components') diff --git a/components/bidding/bidding-conditions-edit.tsx b/components/bidding/bidding-conditions-edit.tsx deleted file mode 100644 index 1017597b..00000000 --- a/components/bidding/bidding-conditions-edit.tsx +++ /dev/null @@ -1,469 +0,0 @@ -"use client" - -import * as React from "react" -import { useRouter } from "next/navigation" -import { useTransition } from "react" -import { Button } from "@/components/ui/button" -import { Input } from "@/components/ui/input" -import { Textarea } from "@/components/ui/textarea" -import { Label } from "@/components/ui/label" -import { Switch } from "@/components/ui/switch" -import { - Select, - SelectContent, - SelectItem, - SelectTrigger, - SelectValue, -} from "@/components/ui/select" -import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card" -import { Pencil, Save, X } from "lucide-react" -import { getBiddingConditions, updateBiddingConditions } from "@/lib/bidding/service" -import { getIncotermsForSelection, getPaymentTermsForSelection, getPlaceOfShippingForSelection, getPlaceOfDestinationForSelection } from "@/lib/procurement-select/service" -import { TAX_CONDITIONS, getTaxConditionName } from "@/lib/tax-conditions/types" -import { useToast } from "@/hooks/use-toast" - -interface BiddingConditionsEditProps { - biddingId: number - initialConditions?: any | null -} - -export function BiddingConditionsEdit({ biddingId, initialConditions }: BiddingConditionsEditProps) { - const router = useRouter() - const { toast } = useToast() - const [isPending, startTransition] = useTransition() - const [isEditing, setIsEditing] = React.useState(false) - - // Procurement 데이터 상태들 - const [paymentTermsOptions, setPaymentTermsOptions] = React.useState>([]) - const [incotermsOptions, setIncotermsOptions] = React.useState>([]) - const [shippingPlaces, setShippingPlaces] = React.useState>([]) - const [destinationPlaces, setDestinationPlaces] = React.useState>([]) - const [procurementLoading, setProcurementLoading] = React.useState(false) - - const [conditions, setConditions] = React.useState({ - paymentTerms: initialConditions?.paymentTerms || "", - taxConditions: initialConditions?.taxConditions || "", - incoterms: initialConditions?.incoterms || "", - contractDeliveryDate: initialConditions?.contractDeliveryDate - ? new Date(initialConditions.contractDeliveryDate).toISOString().split('T')[0] - : "", - shippingPort: initialConditions?.shippingPort || "", - destinationPort: initialConditions?.destinationPort || "", - isPriceAdjustmentApplicable: initialConditions?.isPriceAdjustmentApplicable || false, - sparePartOptions: initialConditions?.sparePartOptions || "", - }) - - - const handleSave = () => { - startTransition(async () => { - try { - const result = await updateBiddingConditions(biddingId, conditions) - - if (result.success) { - toast({ - title: "성공", - description: (result as { success: true; message: string }).message, - variant: "default", - }) - setIsEditing(false) - router.refresh() - } else { - toast({ - title: "오류", - description: (result as { success: false; error: string }).error || "입찰 조건 업데이트 중 오류가 발생했습니다.", - variant: "destructive", - }) - } - } catch (error) { - console.error('Error updating bidding conditions:', error) - toast({ - title: "오류", - description: "입찰 조건 업데이트 중 오류가 발생했습니다.", - variant: "destructive", - }) - } - }) - } - - // Procurement 데이터 로드 함수들 - const loadPaymentTerms = React.useCallback(async () => { - setProcurementLoading(true); - try { - const data = await getPaymentTermsForSelection(); - setPaymentTermsOptions(data); - } catch (error) { - console.error("Failed to load payment terms:", error); - toast({ - title: "오류", - description: "결제조건 목록을 불러오는데 실패했습니다.", - variant: "destructive", - }) - } finally { - setProcurementLoading(false); - } - }, [toast]); - - const loadIncoterms = React.useCallback(async () => { - setProcurementLoading(true); - try { - const data = await getIncotermsForSelection(); - setIncotermsOptions(data); - } catch (error) { - console.error("Failed to load incoterms:", error); - toast({ - title: "오류", - description: "운송조건 목록을 불러오는데 실패했습니다.", - variant: "destructive", - }) - } finally { - setProcurementLoading(false); - } - }, [toast]); - - const loadShippingPlaces = React.useCallback(async () => { - setProcurementLoading(true); - try { - const data = await getPlaceOfShippingForSelection(); - setShippingPlaces(data); - } catch (error) { - console.error("Failed to load shipping places:", error); - toast({ - title: "오류", - description: "선적지 목록을 불러오는데 실패했습니다.", - variant: "destructive", - }) - } finally { - setProcurementLoading(false); - } - }, [toast]); - - const loadDestinationPlaces = React.useCallback(async () => { - setProcurementLoading(true); - try { - const data = await getPlaceOfDestinationForSelection(); - setDestinationPlaces(data); - } catch (error) { - console.error("Failed to load destination places:", error); - toast({ - title: "오류", - description: "하역지 목록을 불러오는데 실패했습니다.", - variant: "destructive", - }) - } finally { - setProcurementLoading(false); - } - }, [toast]); - - // 편집 모드로 전환할 때 procurement 데이터 로드 - React.useEffect(() => { - if (isEditing) { - loadPaymentTerms(); - loadIncoterms(); - loadShippingPlaces(); - loadDestinationPlaces(); - } - }, [isEditing, loadPaymentTerms, loadIncoterms, loadShippingPlaces, loadDestinationPlaces]); - - const handleCancel = () => { - setConditions({ - paymentTerms: initialConditions?.paymentTerms || "", - taxConditions: initialConditions?.taxConditions || "", - incoterms: initialConditions?.incoterms || "", - contractDeliveryDate: initialConditions?.contractDeliveryDate - ? new Date(initialConditions.contractDeliveryDate).toISOString().split('T')[0] - : "", - shippingPort: initialConditions?.shippingPort || "", - destinationPort: initialConditions?.destinationPort || "", - isPriceAdjustmentApplicable: initialConditions?.isPriceAdjustmentApplicable || false, - sparePartOptions: initialConditions?.sparePartOptions || "", - }) - setIsEditing(false) - } - - if (!isEditing) { - return ( - - - 입찰 조건 - - - -
-
- -

- {conditions.paymentTerms - ? paymentTermsOptions.find(opt => opt.code === conditions.paymentTerms)?.code || conditions.paymentTerms - : "미설정" - } -

-
-
- -

- {conditions.taxConditions - ? getTaxConditionName(conditions.taxConditions) - : "미설정" - } -

-
-
- -

- {conditions.incoterms - ? incotermsOptions.find(opt => opt.code === conditions.incoterms)?.code || conditions.incoterms - : "미설정" - } -

-
-
- -

- {conditions.contractDeliveryDate - ? new Date(conditions.contractDeliveryDate).toLocaleDateString('ko-KR') - : "미설정" - } -

-
-
- -

{conditions.shippingPort || "미설정"}

-
-
- -

{conditions.destinationPort || "미설정"}

-
-
- -

{conditions.isPriceAdjustmentApplicable ? "적용 가능" : "적용 불가"}

-
-
- -

{conditions.sparePartOptions}

-
- -
-
-
- ) - } - - return ( - - - 입찰 조건 수정 -
- - -
-
- -
-
- - -
- -
- - -
- -
- - -
- -
- - setConditions(prev => ({ - ...prev, - contractDeliveryDate: e.target.value - }))} - /> -
- -
- - -
- -
- - -
-
- -
- setConditions(prev => ({ - ...prev, - isPriceAdjustmentApplicable: checked - }))} - /> - -
- -
- -