From 8daa2aeee017c642d2fd171094cf5d442966eb12 Mon Sep 17 00:00:00 2001
From: dujinkim <dujin.kim@dtsolution.co.kr>
Date: Fri, 7 Nov 2025 05:05:40 +0000
Subject: (임수민) 기본계약서 서명란 변수 수정
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../template/basic-contract-template-viewer.tsx    | 117 +++++----------------
 1 file changed, 29 insertions(+), 88 deletions(-)

(limited to 'lib/basic-contract/template/basic-contract-template-viewer.tsx')

diff --git a/lib/basic-contract/template/basic-contract-template-viewer.tsx b/lib/basic-contract/template/basic-contract-template-viewer.tsx
index 52ea4153..38438d33 100644
--- a/lib/basic-contract/template/basic-contract-template-viewer.tsx
+++ b/lib/basic-contract/template/basic-contract-template-viewer.tsx
@@ -8,9 +8,8 @@ import React, {
   Dispatch,
 } from "react";
 import { WebViewerInstance } from "@pdftron/webviewer";
-import { Loader2, Target } from "lucide-react";
+import { Loader2 } from "lucide-react";
 import { toast } from "sonner";
-import { Button } from "@/components/ui/button";
 
 interface BasicContractTemplateViewerProps {
   templateId?: number;
@@ -20,58 +19,23 @@ interface BasicContractTemplateViewerProps {
   onSignatureFieldFound?: (searchText: string) => void; // 서명란 발견 시 콜백
 }
 
-// 서명란 위치 정보 인터페이스
-interface SignatureFieldLocation {
-  pageNumber: number;
-  x: number;
-  y: number;
-  searchText: string;
-}
-
-// 서명란으로 이동하는 함수
-const navigateToSignatureField = async (
-  instance: WebViewerInstance | null,
-  location: SignatureFieldLocation | null
-) => {
-  if (!instance || !location) {
-    toast.error("서명란 위치를 찾을 수 없습니다.");
-    return;
-  }
-
-  try {
-    const { documentViewer } = instance.Core;
-    
-    // 해당 페이지로 이동
-    documentViewer.setCurrentPage(location.pageNumber, true);
-    
-    // 페이지 로드 후 알림
-    setTimeout(() => {
-      toast.success(`서명란으로 이동했습니다. (페이지 ${location.pageNumber})`, {
-        description: `"${location.searchText}" 텍스트를 찾아주세요.`
-      });
-    }, 500);
-  } catch (error) {
-    console.error("서명란으로 이동 실패:", error);
-    toast.error("서명란으로 이동하는데 실패했습니다.");
-  }
-};
-
-// 서명란 텍스트 찾기 함수
+// 서명란 텍스트 찾기 함수 (변수 추가를 위해 사용) - 모든 서명란 텍스트를 찾아서 반환
 const findSignatureFieldLocation = async (
   instance: WebViewerInstance | null
-): Promise<SignatureFieldLocation | null> => {
+): Promise<string[]> => {
   if (!instance?.Core?.documentViewer) {
-    return null;
+    return [];
   }
 
   try {
     const { documentViewer } = instance.Core;
     const doc = documentViewer.getDocument();
-    if (!doc) return null;
+    if (!doc) return [];
 
     // 검색할 텍스트 목록 (협력업체와 구매자 모두)
     const searchTexts = ['협력업체_서명란', '삼성중공업_서명란'];
     const pageCount = documentViewer.getPageCount();
+    const foundTexts: string[] = [];
 
     for (const searchText of searchTexts) {
       for (let pageNumber = 1; pageNumber <= pageCount; pageNumber++) {
@@ -88,16 +52,11 @@ const findSignatureFieldLocation = async (
           const quads = await doc.getTextPosition(pageNumber, startIndex, endIndex);
           if (!quads || quads.length === 0) continue;
 
-          const q = quads[0] as any;
-          const x = Math.min(q.x1, q.x2, q.x3, q.x4);
-          const y = Math.min(q.y1, q.y2, q.y3, q.y4);
-
-          return {
-            pageNumber,
-            x,
-            y,
-            searchText
-          };
+          // 찾은 서명란 텍스트를 배열에 추가 (중복 제거)
+          if (!foundTexts.includes(searchText)) {
+            foundTexts.push(searchText);
+          }
+          break; // 해당 텍스트를 찾았으면 다음 텍스트로 이동
         } catch (error) {
           console.warn(`페이지 ${pageNumber}에서 ${searchText} 검색 실패:`, error);
           continue;
@@ -105,10 +64,10 @@ const findSignatureFieldLocation = async (
       }
     }
 
-    return null;
+    return foundTexts;
   } catch (error) {
     console.error("서명란 위치 찾기 실패:", error);
-    return null;
+    return [];
   }
 };
 
@@ -120,7 +79,6 @@ export function BasicContractTemplateViewer({
   onSignatureFieldFound,
 }: BasicContractTemplateViewerProps) {
   const [fileLoading, setFileLoading] = useState<boolean>(true);
-  const [signatureLocation, setSignatureLocation] = useState<SignatureFieldLocation | null>(null);
   const viewer = useRef<HTMLDivElement>(null);
   const initialized = useRef(false);
   const isCancelled = useRef(false);
@@ -233,23 +191,22 @@ export function BasicContractTemplateViewer({
     loadDocument(instance, filePath);
   }, [instance, filePath]);
 
-  // 문서 로드 후 서명란 위치 찾기
+  // 문서 로드 후 서명란 텍스트 찾기 (변수 추가를 위해)
   useEffect(() => {
     if (!instance) return;
 
     const { documentViewer } = instance.Core;
     
     const handleDocumentLoaded = async () => {
-      // 문서 로드 완료 후 서명란 위치 찾기
+      // 문서 로드 완료 후 서명란 텍스트 찾기
       setTimeout(async () => {
-        const location = await findSignatureFieldLocation(instance);
-        if (location) {
-          setSignatureLocation(location);
-          console.log("✅ 서명란 위치 발견:", location);
-          // 서명란 발견 시 부모 컴포넌트에 알림
-          if (onSignatureFieldFound) {
-            onSignatureFieldFound(location.searchText);
-          }
+        const foundTexts = await findSignatureFieldLocation(instance);
+        if (foundTexts.length > 0 && onSignatureFieldFound) {
+          console.log("✅ 서명란 텍스트 발견:", foundTexts);
+          // 모든 찾은 서명란 텍스트에 대해 콜백 호출
+          foundTexts.forEach(searchText => {
+            onSignatureFieldFound(searchText);
+          });
         }
       }, 2000);
     };
@@ -259,13 +216,12 @@ export function BasicContractTemplateViewer({
     // 이미 문서가 로드되어 있다면 즉시 실행
     if (documentViewer.getDocument()) {
       setTimeout(async () => {
-        const location = await findSignatureFieldLocation(instance);
-        if (location) {
-          setSignatureLocation(location);
-          // 서명란 발견 시 부모 컴포넌트에 알림
-          if (onSignatureFieldFound) {
-            onSignatureFieldFound(location.searchText);
-          }
+        const foundTexts = await findSignatureFieldLocation(instance);
+        if (foundTexts.length > 0 && onSignatureFieldFound) {
+          // 모든 찾은 서명란 텍스트에 대해 콜백 호출
+          foundTexts.forEach(searchText => {
+            onSignatureFieldFound(searchText);
+          });
         }
       }, 2000);
     }
@@ -273,7 +229,7 @@ export function BasicContractTemplateViewer({
     return () => {
       documentViewer.removeEventListener('documentLoaded', handleDocumentLoaded);
     };
-  }, [instance]);
+  }, [instance, onSignatureFieldFound]);
 
   // 한글 지원 Office 문서 로드
   const loadDocument = async (instance: WebViewerInstance, documentPath: string) => {
@@ -345,21 +301,6 @@ export function BasicContractTemplateViewer({
           contain: 'layout style paint', // CSS containment로 격리
         }}
       >
-        {/* 서명란으로 이동 버튼 - 툴바 아래에 배치 (편집 도구와 겹치지 않도록) */}
-        {signatureLocation && !fileLoading && (
-          <div className="absolute right-4 z-30" style={{ top: '70px' }}>
-            <Button
-              variant="outline"
-              size="sm"
-              className="h-7 px-2 text-xs bg-blue-50 hover:bg-blue-100 border-blue-200 shadow-sm"
-              onClick={() => navigateToSignatureField(instance, signatureLocation)}
-            >
-              <Target className="h-3 w-3 mr-1" />
-              서명란으로 이동
-            </Button>
-          </div>
-        )}
-        
         {fileLoading && (
           <div className="absolute inset-0 flex flex-col items-center justify-center bg-white bg-opacity-90 z-10">
             <Loader2 className="h-8 w-8 text-blue-500 animate-spin mb-4" />
-- 
cgit v1.2.3

