From 2650b7c0bb0ea12b68a58c0439f72d61df04b2f1 Mon Sep 17 00:00:00 2001
From: dujinkim <dujin.kim@dtsolution.co.kr>
Date: Fri, 25 Jul 2025 07:51:15 +0000
Subject: (대표님) 정기평가 대상, 미들웨어 수정, nextauth 토큰 처리 개선, GTC
 등 (최겸) 기술영업
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../detail-table/quotation-history-dialog.tsx      | 163 +++++++++++++--------
 1 file changed, 101 insertions(+), 62 deletions(-)

(limited to 'lib/techsales-rfq/table/detail-table/quotation-history-dialog.tsx')

diff --git a/lib/techsales-rfq/table/detail-table/quotation-history-dialog.tsx b/lib/techsales-rfq/table/detail-table/quotation-history-dialog.tsx
index 0f5158d9..7d972b91 100644
--- a/lib/techsales-rfq/table/detail-table/quotation-history-dialog.tsx
+++ b/lib/techsales-rfq/table/detail-table/quotation-history-dialog.tsx
@@ -1,5 +1,4 @@
 "use client"
-
 import * as React from "react"
 import { useState, useEffect } from "react"
 import {
@@ -16,6 +15,8 @@ import { Skeleton } from "@/components/ui/skeleton"
 import { Clock, User, AlertCircle, Paperclip } from "lucide-react"
 import { formatDate } from "@/lib/utils"
 import { toast } from "sonner"
+import { Button } from "@/components/ui/button"
+import { updateSHIComment } from "@/lib/techsales-rfq/service";
 
 interface QuotationAttachment {
   id: number
@@ -37,7 +38,7 @@ interface QuotationSnapshot {
   totalPrice: string | null
   validUntil: Date | null
   remark: string | null
-  status: string | null
+  status: string
   quotationVersion: number | null
   submittedAt: Date | null
   acceptedAt: Date | null
@@ -93,7 +94,9 @@ function QuotationCard({
   isCurrent = false, 
   revisedBy, 
   revisedAt,
-  attachments 
+  attachments,
+  revisionId,
+  revisionNote,
 }: {
   data: QuotationSnapshot | QuotationHistoryData["current"]
   version: number
@@ -101,9 +104,36 @@ function QuotationCard({
   revisedBy?: string | null
   revisedAt?: Date
   attachments?: QuotationAttachment[]
+  revisionId?: number
+  revisionNote?: string | null
 }) {
   const statusInfo = statusConfig[data.status as keyof typeof statusConfig] || 
     { label: data.status || "알 수 없음", color: "bg-gray-100 text-gray-800" }
+  
+  const [editValue, setEditValue] = React.useState(revisionNote || "");
+  const [isSaving, setIsSaving] = React.useState(false);
+  
+  React.useEffect(() => {
+    setEditValue(revisionNote || "");
+  }, [revisionNote]);
+  
+  const handleSave = async () => {
+    if (!revisionId) return;
+    
+    setIsSaving(true);
+    try {
+      const result = await updateSHIComment(revisionId, editValue);
+      if (result.error) {
+        toast.error(result.error);
+      } else {
+        toast.success("저장 완료");
+      }
+    } catch (error) {
+      toast.error("저장 중 오류가 발생했습니다");
+    } finally {
+      setIsSaving(false);
+    }
+  };
 
   return (
     <Card className={`${isCurrent ? "border-blue-500 shadow-md" : "border-gray-200"}`}>
@@ -117,12 +147,6 @@ function QuotationCard({
             {statusInfo.label}
           </Badge>
         </div>
-        {/* {changeReason && (
-          <div className="flex items-center gap-2 text-sm text-muted-foreground">
-            <FileText className="size-4" />
-            <span>{changeReason}</span>
-          </div>
-        )} */}
       </CardHeader>
       <CardContent className="space-y-3">
         <div className="grid grid-cols-2 gap-4">
@@ -147,6 +171,21 @@ function QuotationCard({
           </div>
         )}
         
+        {revisionId && (
+  <div>
+    <p className="text-sm font-medium text-muted-foreground mt-2">SHI Comment</p>
+    <textarea
+      className="w-full min-h-[60px] p-2 border rounded bg-gray-50 text-sm"
+      value={editValue}
+      onChange={e => setEditValue(e.target.value)}
+      disabled={isSaving}
+    />
+    <Button size="sm" onClick={handleSave} disabled={isSaving} className="mt-2">
+      저장
+    </Button>
+  </div>
+)}
+        
         {/* 첨부파일 섹션 */}
         {attachments && attachments.length > 0 && (
           <div>
@@ -209,16 +248,15 @@ export function QuotationHistoryDialog({
 }: QuotationHistoryDialogProps) {
   const [data, setData] = useState<QuotationHistoryData | null>(null)
   const [isLoading, setIsLoading] = useState(false)
-
+  
   useEffect(() => {
     if (open && quotationId) {
       loadQuotationHistory()
     }
   }, [open, quotationId])
-
+  
   const loadQuotationHistory = async () => {
     if (!quotationId) return
-
     try {
       setIsLoading(true)
       const { getTechSalesVendorQuotationWithRevisions } = await import("@/lib/techsales-rfq/service")
@@ -238,14 +276,14 @@ export function QuotationHistoryDialog({
       setIsLoading(false)
     }
   }
-
+  
   const handleOpenChange = (newOpen: boolean) => {
     onOpenChange(newOpen)
     if (!newOpen) {
       setData(null) // 다이얼로그 닫을 때 데이터 초기화
     }
   }
-
+  
   return (
     <Dialog open={open} onOpenChange={handleOpenChange}>
       <DialogContent className="w-[80vw] max-h-[90vh] overflow-y-auto">
@@ -257,54 +295,55 @@ export function QuotationHistoryDialog({
         </DialogHeader>
         
         <div className="space-y-4 overflow-x-auto">
-          {isLoading ? (
-            <div className="space-y-4">
-              {[1, 2, 3].map((i) => (
-                <div key={i} className="space-y-3">
-                  <Skeleton className="h-6 w-32" />
-                  <Skeleton className="h-32 w-full" />
-                </div>
-              ))}
-            </div>
-          ) : data ? (
-            <>
-              {/* 현재 버전 */}
-              <QuotationCard
-                data={data.current}
-                version={data.current.quotationVersion || 1}
-                isCurrent={true}
-                attachments={data.current.attachments}
-              />
-              
-              {/* 이전 버전들 */}
-              {data.revisions.length > 0 ? (
-                data.revisions.map((revision) => (
-                  <QuotationCard
-                    key={revision.id}
-                    data={revision.snapshot}
-                    version={revision.version}
-                    changeReason={revision.changeReason}
-                    revisedBy={revision.revisedByName}
-                    revisedAt={revision.revisedAt}
-                    attachments={revision.attachments}
-                  />
-                ))
-              ) : (
-                <div className="text-center py-8 text-muted-foreground">
-                  <AlertCircle className="size-12 mx-auto mb-2 opacity-50" />
-                  <p>수정 이력이 없습니다.</p>
-                  <p className="text-sm">이 견적서는 아직 수정되지 않았습니다.</p>
-                </div>
-              )}
-            </>
-          ) : (
-            <div className="text-center py-8 text-muted-foreground">
-              <AlertCircle className="size-12 mx-auto mb-2 opacity-50" />
-              <p>견적서 정보를 불러올 수 없습니다.</p>
-            </div>
-          )}
-        </div>
+        {isLoading ? (
+          <div className="space-y-4">
+            {[1, 2, 3].map((i) => (
+              <div key={i} className="space-y-3">
+                <Skeleton className="h-6 w-32" />
+                <Skeleton className="h-32 w-full" />
+              </div>
+            ))}
+          </div>
+        ) : data ? (
+          <>
+            {/* 현재 버전 - SHI Comment 없이 표시 */}
+            <QuotationCard
+              data={data.current}
+              version={data.current.quotationVersion || 1}
+              isCurrent={true}
+              attachments={data.current.attachments}
+            />
+            
+            {/* 이전 버전들 (스냅샷) - SHI Comment 포함 */}
+            {data.revisions.length > 0 ? (
+              data.revisions.map((revision) => (
+                <QuotationCard
+                  key={revision.id}
+                  data={revision.snapshot}
+                  version={revision.version}
+                  revisedBy={revision.revisedByName}
+                  revisedAt={revision.revisedAt}
+                  attachments={revision.attachments}
+                  revisionId={revision.id}
+                  revisionNote={revision.revisionNote}
+                />
+              ))
+            ) : (
+              <div className="text-center py-8 text-muted-foreground">
+                <AlertCircle className="size-12 mx-auto mb-2 opacity-50" />
+                <p>수정 이력이 없습니다.</p>
+                <p className="text-sm">이 견적서는 아직 수정되지 않았습니다.</p>
+              </div>
+            )}
+          </>
+        ) : (
+          <div className="text-center py-8 text-muted-foreground">
+            <AlertCircle className="size-12 mx-auto mb-2 opacity-50" />
+            <p>견적서 정보를 불러올 수 없습니다.</p>
+          </div>
+        )}
+      </div>
       </DialogContent>
     </Dialog>
   )
-} 
\ No newline at end of file
+}
\ No newline at end of file
-- 
cgit v1.2.3

