From 44b74ff4170090673b6eeacd8c528e0abf47b7aa Mon Sep 17 00:00:00 2001
From: joonhoekim <26rote@gmail.com>
Date: Mon, 1 Dec 2025 19:52:06 +0900
Subject: (김준회) deprecated code 정리
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../vendor-response/quotation-editor.tsx           | 955 ---------------------
 1 file changed, 955 deletions(-)
 delete mode 100644 lib/procurement-rfqs/vendor-response/quotation-editor.tsx

(limited to 'lib/procurement-rfqs/vendor-response/quotation-editor.tsx')

diff --git a/lib/procurement-rfqs/vendor-response/quotation-editor.tsx b/lib/procurement-rfqs/vendor-response/quotation-editor.tsx
deleted file mode 100644
index 66bb2613..00000000
--- a/lib/procurement-rfqs/vendor-response/quotation-editor.tsx
+++ /dev/null
@@ -1,955 +0,0 @@
-"use client"
-
-import * as React from "react"
-import { useState, useEffect, useMemo } from "react"
-import { useForm } from "react-hook-form"
-import { zodResolver } from "@hookform/resolvers/zod"
-import * as z from "zod"
-import { format } from "date-fns"
-import { toast } from "sonner"
-import { MessageSquare, Paperclip } from "lucide-react"
-
-import { Button } from "@/components/ui/button"
-import {
-  Form,
-  FormControl,
-  FormDescription,
-  FormField,
-  FormItem,
-  FormLabel,
-  FormMessage,
-} from "@/components/ui/form"
-import { Input } from "@/components/ui/input"
-import { Textarea } from "@/components/ui/textarea"
-import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"
-import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from "@/components/ui/card"
-import { Badge } from "@/components/ui/badge"
-import { Separator } from "@/components/ui/separator"
-import { ScrollArea } from "@/components/ui/scroll-area"
-import { DatePicker } from "@/components/ui/date-picker"
-import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"
-import { ClientDataTable } from "@/components/client-data-table/data-table"
-import { Skeleton } from "@/components/ui/skeleton"
-
-import { formatCurrency, formatDate } from "@/lib/utils"
-import { QuotationItemEditor } from "./quotation-item-editor"
-import {
-  submitVendorQuotation,
-  updateVendorQuotation,
-  fetchCurrencies,
-  fetchPaymentTerms,
-  fetchIncoterms,
-  fetchBuyerVendorComments,
-  Comment
-} from "../services"
-import { BuyerCommunicationDrawer } from "./buyer-communication-drawer"
-
-// 견적서 폼 스키마
-const quotationFormSchema = z.object({
-  quotationVersion: z.number().min(1),
-  // 필수값 표시됨
-  currency: z.string().min(1, "통화를 선택해주세요"),
-  // 필수값 표시됨
-  validUntil: z.date({
-    required_error: "견적 유효기간을 선택해주세요",
-    invalid_type_error: "유효한 날짜를 선택해주세요",
-  }),
-  // 필수값 표시됨
-  estimatedDeliveryDate: z.date({
-    required_error: "예상 납품일을 선택해주세요",
-    invalid_type_error: "유효한 날짜를 선택해주세요",
-  }),
-  // 필수값 표시됨
-  paymentTermsCode: z.string({
-    required_error: "지불 조건을 선택해주세요",
-  }).min(1, "지불 조건을 선택해주세요"),
-  // 필수값 표시됨
-  incotermsCode: z.string({
-    required_error: "인코텀즈를 선택해주세요",
-  }).min(1, "인코텀즈를 선택해주세요"),
-  // 필수값 아님
-  incotermsDetail: z.string().optional(),
-  // 필수값 아님
-  remark: z.string().optional(),
-})
-
-type QuotationFormValues = z.infer<typeof quotationFormSchema>
-
-// 데이터 타입 정의
-interface Currency {
-  code: string
-  name: string
-}
-
-interface PaymentTerm {
-  code: string
-  description: string
-}
-
-interface Incoterm {
-  code: string
-  description: string
-}
-
-// 이 컴포넌트에 전달되는 견적서 데이터 타입
-interface VendorQuotation {
-  id: number
-  rfqId: number
-  vendorId: number
-  quotationCode: string | null
-  quotationVersion: number | null
-  totalItemsCount:  number | null
-  subTotal: string| null
-  taxTotal: string| null
-  discountTotal: string| null
-  totalPrice: string| null
-  currency: string| null
-  validUntil: Date | null
-  estimatedDeliveryDate: Date | null
-  paymentTermsCode: string | null
-  incotermsCode: string | null
-  incotermsDetail: string | null
-  status: "Draft" | "Submitted" | "Revised" | "Rejected" | "Accepted"
-  remark: string | null
-  rejectionReason: string | null
-  submittedAt: Date | null
-  acceptedAt: Date | null
-  createdAt: Date
-  updatedAt: Date
-  rfq: {
-    id: number
-    rfqCode: string| null
-    dueDate: Date | null
-    status: string| null
-    // 기타 필요한 정보
-  }
-  vendor: {
-    id: number
-    vendorName: string
-    vendorCode: string| null
-    // 기타 필요한 정보
-  }
-  items: QuotationItem[]
-}
-
-// 견적 아이템 타입
-interface QuotationItem {
-  id: number
-  quotationId: number
-  prItemId: number
-  materialCode: string | null
-  materialDescription: string | null
-  quantity: number
-  uom: string | null
-  unitPrice: number
-  totalPrice: number
-  currency: string
-  vendorMaterialCode: string | null
-  vendorMaterialDescription: string | null
-  deliveryDate: Date | null
-  leadTimeInDays: number | null
-  taxRate: number | null
-  taxAmount: number | null
-  discountRate: number | null
-  discountAmount: number | null
-  remark: string | null
-  isAlternative: boolean
-  isRecommended: boolean
-  createdAt: Date
-  updatedAt: Date
-  prItem?: {
-    id: number
-    materialCode: string | null
-    materialDescription: string | null
-    // 기타 필요한 정보
-  }
-}
-
-// 견적서 편집 컴포넌트 프롭스
-interface VendorQuotationEditorProps {
-  quotation: VendorQuotation
-}
-
-export default function VendorQuotationEditor({ quotation }: VendorQuotationEditorProps) {
-
-
-  console.log(quotation)
-  
-  const [activeTab, setActiveTab] = useState("items")
-  const [isSubmitting, setIsSubmitting] = useState(false)
-  const [isSaving, setIsSaving] = useState(false)
-  const [items, setItems] = useState<QuotationItem[]>(quotation.items || [])
-
-  // 서버에서 가져온 데이터 상태
-  const [currencies, setCurrencies] = useState<Currency[]>([])
-  const [paymentTerms, setPaymentTerms] = useState<PaymentTerm[]>([])
-  const [incoterms, setIncoterms] = useState<Incoterm[]>([])
-
-  // 데이터 로딩 상태
-  const [loadingCurrencies, setLoadingCurrencies] = useState(true)
-  const [loadingPaymentTerms, setLoadingPaymentTerms] = useState(true)
-  const [loadingIncoterms, setLoadingIncoterms] = useState(true)
-
-  // 커뮤니케이션 드로어 상태
-  const [communicationDrawerOpen, setCommunicationDrawerOpen] = useState(false)
-
-  const [comments, setComments] = useState<Comment[]>([]);
-  const [unreadCount, setUnreadCount] = useState(0);
-  const [loadingComments, setLoadingComments] = useState(false);
-
-  // 컴포넌트 마운트 시 메시지 미리 로드
-  useEffect(() => {
-    if (quotation) {
-      loadCommunicationData();
-    }
-  }, [quotation]);
-
-  // 메시지 데이터 로드 함수
-  const loadCommunicationData = async () => {
-    try {
-      setLoadingComments(true);
-      const commentsData = await fetchBuyerVendorComments(quotation.rfqId, quotation.vendorId);
-      setComments(commentsData);
-
-      // 읽지 않은 메시지 수 계산
-      const unread = commentsData.filter(
-        comment => !comment.isVendorComment && !comment.isRead
-      ).length;
-      setUnreadCount(unread);
-    } catch (error) {
-      console.error("메시지 데이터 로드 오류:", error);
-    } finally {
-      setLoadingComments(false);
-    }
-  };
-
-  // 커뮤니케이션 드로어가 닫힐 때 데이터 새로고침
-  const handleCommunicationDrawerChange = (open: boolean) => {
-    setCommunicationDrawerOpen(open);
-    if (!open) {
-      loadCommunicationData(); // 드로어가 닫힐 때 데이터 새로고침
-    }
-  };
-
-  // 버튼 비활성화
-  const isBeforeDueDate = () => {
-    if (!quotation.rfq.dueDate) {
-      // dueDate가 null인 경우 기본적으로 수정 불가능하도록 설정 (false 반환)
-      return false;
-    }
-
-    const now = new Date();
-    const dueDate = new Date(quotation.rfq.dueDate);
-    return now < dueDate;
-  };
-  // 수정된 isDisabled 조건
-  const isDisabled = (quotation.status === "Accepted") ||
-    ((quotation.status === "Submitted" || quotation.status === "Revised") &&
-      !isBeforeDueDate());
-
-
-  // 견적서 총합 계산
-  const totals = useMemo(() => {
-    const subTotal = items.reduce((sum, item) => sum + Number(item.totalPrice), 0)
-    const taxTotal = items.reduce((sum, item) => sum + (Number(item.taxAmount) || 0), 0)
-    const discountTotal = items.reduce((sum, item) => sum + (Number(item.discountAmount) || 0), 0)
-    const totalPrice = subTotal + taxTotal - discountTotal
-
-    return {
-      subTotal,
-      taxTotal,
-      discountTotal,
-      totalPrice
-    }
-  }, [items])
-
-  // 폼 설정
-  const form = useForm<QuotationFormValues>({
-    resolver: zodResolver(quotationFormSchema),
-    defaultValues: {
-      quotationVersion: quotation.quotationVersion || 0,
-      currency: quotation.currency || "KRW",
-      validUntil: quotation.validUntil || undefined,
-      estimatedDeliveryDate: quotation.estimatedDeliveryDate || undefined,
-      paymentTermsCode: quotation.paymentTermsCode || "",
-      incotermsCode: quotation.incotermsCode || "",
-      incotermsDetail: quotation.incotermsDetail || "",
-      remark: quotation.remark || "",
-    },
-    mode: "onChange", // 실시간 검증 활성화
-  })
-
-  // 마운트 시 데이터 로드
-  useEffect(() => {
-    // 통화 데이터 로드
-    const loadCurrencies = async () => {
-      try {
-        setLoadingCurrencies(true)
-        const result = await fetchCurrencies()
-        if (result.success) {
-          setCurrencies(result.data)
-        } else {
-          toast.error(result.message || "통화 데이터 로드 실패")
-        }
-      } catch (error) {
-        console.error("통화 데이터 로드 오류:", error)
-        toast.error("통화 데이터를 불러오는 중 오류가 발생했습니다")
-      } finally {
-        setLoadingCurrencies(false)
-      }
-    }
-
-    // 지불 조건 데이터 로드
-    const loadPaymentTerms = async () => {
-      try {
-        setLoadingPaymentTerms(true)
-        const result = await fetchPaymentTerms()
-        if (result.success) {
-          setPaymentTerms(result.data)
-        } else {
-          toast.error(result.message || "지불 조건 데이터 로드 실패")
-        }
-      } catch (error) {
-        console.error("지불 조건 데이터 로드 오류:", error)
-        toast.error("지불 조건 데이터를 불러오는 중 오류가 발생했습니다")
-      } finally {
-        setLoadingPaymentTerms(false)
-      }
-    }
-
-    // 인코텀즈 데이터 로드
-    const loadIncoterms = async () => {
-      try {
-        setLoadingIncoterms(true)
-        const result = await fetchIncoterms()
-        if (result.success) {
-          setIncoterms(result.data)
-        } else {
-          toast.error(result.message || "인코텀즈 데이터 로드 실패")
-        }
-      } catch (error) {
-        console.error("인코텀즈 데이터 로드 오류:", error)
-        toast.error("인코텀즈 데이터를 불러오는 중 오류가 발생했습니다")
-      } finally {
-        setLoadingIncoterms(false)
-      }
-    }
-
-    // 함수 호출
-    loadCurrencies()
-    loadPaymentTerms()
-    loadIncoterms()
-  }, [])
-
-  // 견적서 저장
-  const handleSave = async () => {
-    try {
-      setIsSaving(true)
-
-      // 기본 검증 (통화는 필수)
-      const validationResult = await form.trigger(['currency']);
-      if (!validationResult) {
-        toast.warning("통화는 필수 항목입니다");
-        return;
-      }
-
-      const values = form.getValues()
-
-      const result = await updateVendorQuotation({
-        id: quotation.id,
-        ...values,
-        subTotal: totals.subTotal.toString(),
-        taxTotal: totals.taxTotal.toString(),
-        discountTotal: totals.discountTotal.toString(),
-        totalPrice: totals.totalPrice.toString(),
-        totalItemsCount: items.length,
-      })
-
-      if (result.success) {
-        toast.success("견적서가 저장되었습니다")
-
-        // 견적서 제출 준비 상태 점검
-        const formValid = await form.trigger();
-        const itemsValid = !items.some(item => item.unitPrice <= 0 || !item.deliveryDate);
-        const alternativeItemsValid = !items.some(item =>
-          item.isAlternative && (!item.vendorMaterialDescription || !item.remark)
-        );
-
-        if (formValid && itemsValid && alternativeItemsValid) {
-          toast.info("모든 필수 정보가 입력되었습니다. '견적서 제출' 버튼을 클릭하여 제출하세요.");
-        } else {
-          const missingFields = [];
-          if (!formValid) missingFields.push("견적서 기본 정보");
-          if (!itemsValid) missingFields.push("견적 항목의 단가/납품일");
-          if (!alternativeItemsValid) missingFields.push("대체품 정보");
-
-          toast.info(`제출하기 전에 다음 정보를 입력해주세요: ${missingFields.join(', ')}`);
-        }
-      } else {
-        toast.error(result.message || "견적서 저장 중 오류가 발생했습니다")
-      }
-    } catch (error) {
-      console.error("견적서 저장 오류:", error)
-      toast.error("견적서 저장 중 오류가 발생했습니다")
-    } finally {
-      setIsSaving(false)
-    }
-  }
-
-  // 견적서 제출
-  const handleSubmit = async () => {
-    try {
-      setIsSubmitting(true)
-
-      // 1. 폼 스키마 검증 (기본 정보)
-      const formValid = await form.trigger();
-      if (!formValid) {
-        const formState = form.getFieldState("validUntil");
-        const estimatedDeliveryState = form.getFieldState("estimatedDeliveryDate");
-        const paymentTermsState = form.getFieldState("paymentTermsCode");
-        const incotermsState = form.getFieldState("incotermsCode");
-
-        // 주요 필드별 오류 메시지 표시
-        if (!form.getValues("validUntil")) {
-          toast.error("견적 유효기간을 선택해주세요");
-        } else if (!form.getValues("estimatedDeliveryDate")) {
-          toast.error("예상 납품일을 선택해주세요");
-        } else if (!form.getValues("paymentTermsCode")) {
-          toast.error("지불 조건을 선택해주세요");
-        } else if (!form.getValues("incotermsCode")) {
-          toast.error("인코텀즈를 선택해주세요");
-        } else {
-          toast.error("견적서 기본 정보를 모두 입력해주세요");
-        }
-
-        // 견적 정보 탭으로 이동
-        setActiveTab("details");
-        return;
-      }
-
-      // 2. 견적 항목 검증
-      const emptyItems = items.filter(item =>
-        item.unitPrice <= 0 || !item.deliveryDate
-      );
-
-      if (emptyItems.length > 0) {
-        toast.error(`${emptyItems.length}개 항목의 단가와 납품일을 입력해주세요`);
-        setActiveTab("items");
-        return;
-      }
-
-      // 3. 대체품 정보 검증
-      const invalidAlternativeItems = items.filter(item =>
-        item.isAlternative && (!item.vendorMaterialDescription || !item.remark)
-      );
-
-      if (invalidAlternativeItems.length > 0) {
-        toast.error(`${invalidAlternativeItems.length}개의 대체품 항목에 정보를 모두 입력해주세요`);
-        setActiveTab("items");
-        return;
-      }
-
-      // 모든 검증 통과 - 제출 진행
-      const values = form.getValues();
-
-      const result = await submitVendorQuotation({
-        id: quotation.id,
-        ...values,
-        subTotal: totals.subTotal.toString(),
-        taxTotal: totals.taxTotal.toString(),
-        discountTotal: totals.discountTotal.toString(),
-        totalPrice: totals.totalPrice.toString(),
-        totalItemsCount: items.length,
-      });
-
-      if (result.success && isBeforeDueDate()) {
-        toast.success("견적서가 제출되었습니다. 마감일 전까지 수정 가능합니다.");
-
-        // 페이지 새로고침
-        window.location.reload();
-      } else {
-        toast.error(result.message || "견적서 제출 중 오류가 발생했습니다");
-      }
-    } catch (error) {
-      console.error("견적서 제출 오류:", error);
-      toast.error("견적서 제출 중 오류가 발생했습니다");
-    } finally {
-      setIsSubmitting(false);
-    }
-  }
-
-  const isSubmitReady = () => {
-    // 폼 유효성
-    const formValid = !Object.keys(form.formState.errors).length;
-
-    // 항목 유효성
-    const itemsValid = !items.some(item =>
-      item.unitPrice <= 0 || !item.deliveryDate
-    );
-
-    // 대체품 유효성
-    const alternativeItemsValid = !items.some(item =>
-      item.isAlternative && (!item.vendorMaterialDescription || !item.remark)
-    );
-
-    // 유효하지 않은 항목 또는 대체품이 있으면 제출 불가
-    return formValid && itemsValid && alternativeItemsValid;
-  }
-
-  // 아이템 업데이트 핸들러
-  const handleItemsUpdate = (updatedItems: QuotationItem[]) => {
-    setItems(updatedItems)
-  }
-
-  // 상태에 따른 배지 색상
-  const getStatusBadge = (status: string) => {
-    switch (status) {
-      case "Draft":
-        return <Badge variant="outline">초안</Badge>
-      case "Submitted":
-        return <Badge variant="default">제출됨</Badge>
-      case "Revised":
-        return <Badge variant="secondary">수정됨</Badge>
-      case "Rejected":
-        return <Badge variant="destructive">반려됨</Badge>
-      case "Accepted":
-        return <Badge variant="default">승인됨</Badge>
-      default:
-        return <Badge>{status}</Badge>
-    }
-  }
-
-  // 셀렉트 로딩 상태 표시 컴포넌트
-  const SelectSkeleton = () => (
-    <div className="flex flex-col gap-2">
-      <Skeleton className="h-4 w-[40%]" />
-      <Skeleton className="h-10 w-full" />
-    </div>
-  )
-
-  return (
-    <div className="space-y-6">
-      <div className="flex justify-between items-start">
-        <div>
-          <h1 className="text-2xl font-bold tracking-tight">견적서 작성</h1>
-          <p className="text-muted-foreground">
-            RFQ 번호: {quotation.rfq.rfqCode} | 견적서 번호: {quotation.quotationCode}
-          </p>
-          {quotation.rfq.dueDate ? (
-            <p className={`text-sm ${isBeforeDueDate() ? 'text-green-600' : 'text-red-600'}`}>
-              마감일: {formatDate(new Date(quotation.rfq.dueDate))}
-              {isBeforeDueDate()
-                ? ' (마감 전: 수정 가능)'
-                : ' (마감 됨: 수정 불가)'}
-            </p>
-          ) : (
-            <p className="text-sm text-amber-600">
-              마감일이 설정되지 않았습니다
-            </p>
-          )}
-        </div>
-        <div className="flex items-center gap-2">
-          {getStatusBadge(quotation.status)}
-          {quotation.status === "Rejected" && (
-            <div className="text-sm text-destructive">
-              <span className="font-medium">반려 사유:</span> {quotation.rejectionReason || "사유 없음"}
-            </div>
-          )}
-        </div>
-      </div>
-
-      <Tabs value={activeTab} onValueChange={setActiveTab} className="w-full">
-        <TabsList>
-          <TabsTrigger value="items">견적 항목</TabsTrigger>
-          <TabsTrigger value="details">견적 정보</TabsTrigger>
-          <TabsTrigger value="communication">커뮤니케이션</TabsTrigger>
-        </TabsList>
-
-        {/* 견적 항목 탭 */}
-        <TabsContent value="items" className="p-0 pt-4">
-          <Card>
-            <CardHeader>
-              <CardTitle>견적 항목 정보</CardTitle>
-              <CardDescription>
-                각 항목에 대한 가격, 납품일 등을 입력해주세요
-              </CardDescription>
-            </CardHeader>
-            <CardContent>
-              <QuotationItemEditor
-                items={items}
-                onItemsChange={handleItemsUpdate}
-                disabled={isDisabled}
-                currency={form.watch("currency")}
-              />
-            </CardContent>
-            <CardFooter className="flex justify-between border-t p-4">
-              <div className="space-y-1">
-                <div className="text-sm text-muted-foreground">
-                  <span className="font-medium">소계:</span> {formatCurrency(totals.subTotal, quotation.currency)}
-                </div>
-                <div className="text-sm text-muted-foreground">
-                  <span className="font-medium">세액:</span> {formatCurrency(totals.taxTotal, quotation.currency)}
-                </div>
-                <div className="text-sm text-muted-foreground">
-                  <span className="font-medium">할인액:</span> {formatCurrency(totals.discountTotal, quotation.currency)}
-                </div>
-                <div className="text-base font-bold">
-                  <span>총액:</span> {formatCurrency(totals.totalPrice, quotation.currency)}
-                </div>
-              </div>
-              <div className="flex space-x-2">
-                <Button
-                  variant="outline"
-                  onClick={handleSave}
-                  disabled={isDisabled || isSaving}
-                >
-                  {isSaving ? "저장 중..." : "저장"}
-                </Button>
-                <Button
-                  onClick={handleSubmit}
-                  disabled={isDisabled || isSubmitting || !isSubmitReady()}
-                >
-                  {isSubmitting ? "제출 중..." : "견적서 제출"}
-                </Button>
-              </div>
-            </CardFooter>
-          </Card>
-        </TabsContent>
-
-        {/* 견적 정보 탭 */}
-        <TabsContent value="details" className="p-0 pt-4">
-          <Form {...form}>
-            <form className="space-y-6">
-              <Card>
-                <CardHeader>
-                  <CardTitle>견적서 기본 정보</CardTitle>
-                  <CardDescription>
-                    견적서의 일반 정보를 입력해주세요
-                  </CardDescription>
-                </CardHeader>
-                <CardContent className="grid grid-cols-1 md:grid-cols-2 gap-6">
-                  {/* 통화 필드 */}
-                  {loadingCurrencies ? (
-                    <SelectSkeleton />
-                  ) : (
-                    <FormField
-                      control={form.control}
-                      name="currency"
-                      render={({ field }) => (
-                        <FormItem>
-                          <FormLabel className="flex items-center">
-                            통화
-                            <span className="text-destructive ml-1">*</span>
-                          </FormLabel>
-                          <Select
-                            value={field.value}
-                            onValueChange={field.onChange}
-                            disabled={isDisabled}
-                          >
-                            <FormControl>
-                              <SelectTrigger>
-                                <SelectValue placeholder="통화 선택" />
-                              </SelectTrigger>
-                            </FormControl>
-                            <SelectContent>
-                              {currencies.map((currency) => (
-                                <SelectItem key={currency.code} value={currency.code}>
-                                  {currency.code} ({currency.name})
-                                </SelectItem>
-                              ))}
-                            </SelectContent>
-                          </Select>
-                          <FormMessage />
-                        </FormItem>
-                      )}
-                    />
-                  )}
-
-                  <FormField
-                    control={form.control}
-                    name="validUntil"
-                    render={({ field }) => (
-                      <FormItem>
-                        <FormLabel className="flex items-center">
-                          견적 유효기간
-                          <span className="text-destructive ml-1">*</span> {/* 필수값 표시 */}
-                        </FormLabel>
-                        <FormControl>
-                          <DatePicker
-                            date={field.value}
-                            onSelect={field.onChange}
-                            disabled={isDisabled}
-                          />
-                        </FormControl>
-                        <FormMessage />
-                      </FormItem>
-                    )}
-                  />
-
-                  <FormField
-                    control={form.control}
-                    name="estimatedDeliveryDate"
-                    render={({ field }) => (
-                      <FormItem>
-                        <FormLabel className="flex items-center">
-                          예상 납품일
-                          <span className="text-destructive ml-1">*</span>
-                        </FormLabel>
-                        <FormControl>
-                          <DatePicker
-                            date={field.value}
-                            onSelect={field.onChange}
-                            disabled={isDisabled}
-                          />
-                        </FormControl>
-                        <FormMessage />
-                      </FormItem>
-                    )}
-                  />
-
-                  {/* 지불 조건 필드 */}
-                  {loadingPaymentTerms ? (
-                    <SelectSkeleton />
-                  ) : (
-                    <FormField
-                      control={form.control}
-                      name="paymentTermsCode"
-                      render={({ field }) => (
-                        <FormItem>
-                          <FormLabel className="flex items-center">
-                            지불 조건
-                            <span className="text-destructive ml-1">*</span>
-                          </FormLabel>
-                          <Select
-                            value={field.value || ""}
-                            onValueChange={field.onChange}
-                            disabled={isDisabled}
-                          >
-                            <FormControl>
-                              <SelectTrigger>
-                                <SelectValue placeholder="지불 조건 선택" />
-                              </SelectTrigger>
-                            </FormControl>
-                            <SelectContent>
-                              {paymentTerms.map((term) => (
-                                <SelectItem key={term.code} value={term.code}>
-                                  {term.description}
-                                </SelectItem>
-                              ))}
-                            </SelectContent>
-                          </Select>
-                          <FormMessage />
-                        </FormItem>
-                      )}
-                    />
-                  )}
-
-                  {/* 인코텀즈 필드 */}
-                  {loadingIncoterms ? (
-                    <SelectSkeleton />
-                  ) : (
-                    <FormField
-                      control={form.control}
-                      name="incotermsCode"
-                      render={({ field }) => (
-                        <FormItem>
-                          <FormLabel className="flex items-center">
-                            인코텀즈
-                            <span className="text-destructive ml-1">*</span>
-                          </FormLabel>
-                          <Select
-                            value={field.value || ""}
-                            onValueChange={field.onChange}
-                            disabled={isDisabled}
-                          >
-                            <FormControl>
-                              <SelectTrigger>
-                                <SelectValue placeholder="인코텀즈 선택" />
-                              </SelectTrigger>
-                            </FormControl>
-                            <SelectContent>
-                              {incoterms.map((term) => (
-                                <SelectItem key={term.code} value={term.code}>
-                                  {term.code} ({term.description})
-                                </SelectItem>
-                              ))}
-                            </SelectContent>
-                          </Select>
-                          <FormMessage />
-                        </FormItem>
-                      )}
-                    />
-                  )}
-
-                  <FormField
-                    control={form.control}
-                    name="incotermsDetail"
-                    render={({ field }) => (
-                      <FormItem>
-                        <FormLabel className="flex items-center">
-                          인코텀즈 상세
-                          <span className="text-destructive ml-1"></span>
-                        </FormLabel>
-                        <FormControl>
-                          <Input
-                            placeholder="인코텀즈 상세 정보 입력"
-                            {...field}
-                            value={field.value || ""}
-                            disabled={isDisabled}
-                          />
-                        </FormControl>
-                        <FormMessage />
-                      </FormItem>
-                    )}
-                  />
-
-                  <FormField
-                    control={form.control}
-                    name="remark"
-                    render={({ field }) => (
-                      <FormItem className="col-span-2">
-                        <FormLabel className="flex items-center">
-                          비고
-                          <span className="text-destructive ml-1"></span>
-                        </FormLabel>
-                        <FormControl>
-                          <Textarea
-                            placeholder="추가 정보나 특이사항을 입력해주세요"
-                            className="resize-none min-h-[100px]"
-                            {...field}
-                            value={field.value || ""}
-                            disabled={isDisabled}
-                          />
-                        </FormControl>
-                        <FormMessage />
-                      </FormItem>
-                    )}
-                  />
-                </CardContent>
-                <CardFooter className="flex justify-end">
-                  <Button
-                    variant="outline"
-                    onClick={handleSave}
-                    disabled={isDisabled || isSaving}
-                  >
-                    {isSaving ? "저장 중..." : "저장"}
-                  </Button>
-                </CardFooter>
-              </Card>
-            </form>
-          </Form>
-        </TabsContent>
-
-        {/* 커뮤니케이션 탭 */}
-        <TabsContent value="communication" className="p-0 pt-4">
-          <Card>
-            <CardHeader className="flex flex-row items-center justify-between">
-              <div>
-                <CardTitle className="flex items-center gap-2">
-                  커뮤니케이션
-                  {unreadCount > 0 && (
-                    <Badge variant="destructive" className="ml-2">
-                      새 메시지 {unreadCount}
-                    </Badge>
-                  )}
-                </CardTitle>
-                <CardDescription>
-                  구매자와의 메시지 및 첨부파일
-                </CardDescription>
-              </div>
-              <Button
-                onClick={() => setCommunicationDrawerOpen(true)}
-                variant="outline"
-                size="sm"
-              >
-                <MessageSquare className="h-4 w-4 mr-2" />
-                {unreadCount > 0 ? "새 메시지 확인" : "메시지 보내기"}
-              </Button>
-            </CardHeader>
-            <CardContent>
-              {loadingComments ? (
-                <div className="flex items-center justify-center p-8">
-                  <div className="text-center">
-                    <Skeleton className="h-4 w-32 mx-auto mb-2" />
-                    <Skeleton className="h-4 w-48 mx-auto" />
-                  </div>
-                </div>
-              ) : comments.length === 0 ? (
-                <div className="min-h-[200px] flex flex-col items-center justify-center text-center p-8">
-                  <div className="max-w-md">
-                    <div className="mx-auto bg-primary/10 rounded-full w-12 h-12 flex items-center justify-center mb-4">
-                      <MessageSquare className="h-6 w-6 text-primary" />
-                    </div>
-                    <h3 className="text-lg font-medium mb-2">아직 메시지가 없습니다</h3>
-                    <p className="text-muted-foreground mb-4">
-                      견적서에 대한 질문이나 의견이 있으신가요? 구매자와 메시지를 주고받으세요.
-                    </p>
-                    <Button
-                      onClick={() => setCommunicationDrawerOpen(true)}
-                      className="mx-auto"
-                    >
-                      메시지 보내기
-                    </Button>
-                  </div>
-                </div>
-              ) : (
-                <div className="space-y-4">
-                  {/* 최근 메시지 3개 미리보기 */}
-                  <div className="space-y-2">
-                    <h3 className="text-sm font-medium">최근 메시지</h3>
-                    <ScrollArea className="h-[250px] rounded-md border p-4">
-                      {comments.slice(-3).map(comment => (
-                        <div
-                          key={comment.id}
-                          className={`p-3 mb-3 rounded-lg ${!comment.isVendorComment && !comment.isRead
-                            ? 'bg-primary/10 border-l-4 border-primary'
-                            : 'bg-muted/50'
-                            }`}
-                        >
-                          <div className="flex justify-between items-center mb-1">
-                            <span className="text-sm font-medium">
-                              {comment.isVendorComment
-                                ? '나'
-                                : comment.userName || '구매 담당자'}
-                            </span>
-                            <span className="text-xs text-muted-foreground">
-                              {new Date(comment.createdAt).toLocaleDateString()}
-                            </span>
-                          </div>
-                          <p className="text-sm line-clamp-2">{comment.content}</p>
-                          {comment.attachments.length > 0 && (
-                            <div className="mt-1 text-xs text-muted-foreground">
-                              <Paperclip className="h-3 w-3 inline mr-1" />
-                              첨부파일 {comment.attachments.length}개
-                            </div>
-                          )}
-                        </div>
-                      ))}
-                    </ScrollArea>
-                  </div>
-
-                  <div className="flex justify-center">
-                    <Button
-                      onClick={() => setCommunicationDrawerOpen(true)}
-                      className="w-full"
-                    >
-                      전체 메시지 보기 ({comments.length}개)
-                    </Button>
-                  </div>
-                </div>
-              )}
-            </CardContent>
-          </Card>
-
-          {/* 커뮤니케이션 드로어 */}
-          <BuyerCommunicationDrawer
-            open={communicationDrawerOpen}
-            onOpenChange={handleCommunicationDrawerChange}
-            quotation={quotation}
-            onSuccess={loadCommunicationData}
-          />
-        </TabsContent>
-      </Tabs>
-    </div>
-  )
-}
\ No newline at end of file
-- 
cgit v1.2.3

