From 02b1cf005cf3e1df64183d20ba42930eb2767a9f Mon Sep 17 00:00:00 2001
From: dujinkim <dujin.kim@dtsolution.co.kr>
Date: Thu, 21 Aug 2025 06:57:36 +0000
Subject: (대표님, 최겸) 설계메뉴추가, 작업사항 업데이트 설계메뉴 - 문서관리
 설계메뉴 - 벤더 데이터 gtc 메뉴 업데이트 정보시스템 - 메뉴리스트 및 정보
 업데이트 파일 라우트 업데이트 엑셀임포트 개선 기본계약 개선 벤더 가입과정
 변경 및 개선 벤더 기본정보 - pq 돌체 오류 수정 및 개선 벤더 로그인 과정
 이메일 오류 수정
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../template/update-basicContract-sheet.tsx        | 245 ++++-----------------
 1 file changed, 46 insertions(+), 199 deletions(-)

(limited to 'lib/basic-contract/template/update-basicContract-sheet.tsx')

diff --git a/lib/basic-contract/template/update-basicContract-sheet.tsx b/lib/basic-contract/template/update-basicContract-sheet.tsx
index 07bac31b..0236fda5 100644
--- a/lib/basic-contract/template/update-basicContract-sheet.tsx
+++ b/lib/basic-contract/template/update-basicContract-sheet.tsx
@@ -8,7 +8,6 @@ import { toast } from "sonner"
 import * as z from "zod"
 
 import { Button } from "@/components/ui/button"
-import { Checkbox } from "@/components/ui/checkbox"
 import { Switch } from "@/components/ui/switch"
 import {
   Form,
@@ -19,14 +18,6 @@ import {
   FormMessage,
   FormDescription,
 } from "@/components/ui/form"
-import {
-  Select,
-  SelectContent,
-  SelectGroup,
-  SelectItem,
-  SelectTrigger,
-  SelectValue,
-} from "@/components/ui/select"
 import {
   Sheet,
   SheetClose,
@@ -45,45 +36,14 @@ import {
   DropzoneInput
 } from "@/components/ui/dropzone"
 import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"
-import { Separator } from "@/components/ui/separator"
 import { Badge } from "@/components/ui/badge"
 import { updateTemplate } from "../service"
 import { BasicContractTemplate } from "@/db/schema"
-import { BUSINESS_UNITS, scopeHelpers } from "@/config/basicContractColumnsConfig"
-
-// 템플릿 이름 옵션 정의
-const TEMPLATE_NAME_OPTIONS = [
-  "준법서약 (한글)",
-  "준법서약 (영문)",
-  "기술자료 요구서",
-  "비밀유지 계약서",
-  "표준하도급기본 계약서",
-  "GTC",
-  "안전보건관리 약정서",
-  "동반성장",
-  "윤리규범 준수 서약서",
-  "기술자료 동의서",
-  "내국신용장 미개설 합의서",
-  "직납자재 하도급대급등 연동제 의향서"
-] as const;
+import { scopeHelpers } from "@/config/basicContractColumnsConfig"
 
-// 업데이트 템플릿 스키마 정의 (리비전 필드 제거, 워드파일만 허용)
+// 업데이트 템플릿 스키마 정의 (파일 업데이트 중심)
 export const updateTemplateSchema = z.object({
-  templateName: z.enum(TEMPLATE_NAME_OPTIONS, {
-    required_error: "템플릿 이름을 선택해주세요.",
-  }),
   legalReviewRequired: z.boolean(),
-
-  // 적용 범위
-  shipBuildingApplicable: z.boolean(),
-  windApplicable: z.boolean(),
-  pcApplicable: z.boolean(),
-  nbApplicable: z.boolean(),
-  rcApplicable: z.boolean(),
-  gyApplicable: z.boolean(),
-  sysApplicable: z.boolean(),
-  infraApplicable: z.boolean(),
-
   file: z
     .instanceof(File, { message: "파일을 업로드해주세요." })
     .refine((file) => file.size <= 100 * 1024 * 1024, {
@@ -96,15 +56,6 @@ export const updateTemplateSchema = z.object({
       { message: "워드 파일(.doc, .docx)만 업로드 가능합니다." }
     )
     .optional(),
-}).refine((data) => {
-  // 적어도 하나의 적용 범위는 선택되어야 함
-  const hasAnyScope = BUSINESS_UNITS.some(unit =>
-    data[unit.key as keyof typeof data] as boolean
-  );
-  return hasAnyScope;
-}, {
-  message: "적어도 하나의 적용 범위를 선택해야 합니다.",
-  path: ["shipBuildingApplicable"],
 });
 
 export type UpdateTemplateSchema = z.infer<typeof updateTemplateSchema>
@@ -122,16 +73,7 @@ export function UpdateTemplateSheet({ template, onSuccess, ...props }: UpdateTem
   const form = useForm<UpdateTemplateSchema>({
     resolver: zodResolver(updateTemplateSchema),
     defaultValues: {
-      templateName: template?.templateName as typeof TEMPLATE_NAME_OPTIONS[number] ?? "준법서약 (한글)",
       legalReviewRequired: template?.legalReviewRequired ?? false,
-      shipBuildingApplicable: template?.shipBuildingApplicable ?? false,
-      windApplicable: template?.windApplicable ?? false,
-      pcApplicable: template?.pcApplicable ?? false,
-      nbApplicable: template?.nbApplicable ?? false,
-      rcApplicable: template?.rcApplicable ?? false,
-      gyApplicable: template?.gyApplicable ?? false,
-      sysApplicable: template?.sysApplicable ?? false,
-      infraApplicable: template?.infraApplicable ?? false,
     },
     mode: "onChange"
   })
@@ -145,52 +87,23 @@ export function UpdateTemplateSheet({ template, onSuccess, ...props }: UpdateTem
     }
   };
 
-  // 모든 적용 범위 선택/해제
-  const handleSelectAllScopes = (checked: boolean | "indeterminate") => {
-    const value = checked === true;
-    BUSINESS_UNITS.forEach(unit => {
-      form.setValue(unit.key as keyof UpdateTemplateSchema, value);
-    });
-  };
-
   // 템플릿 변경 시 폼 값 업데이트
   React.useEffect(() => {
     if (template) {
       form.reset({
-        templateName: template.templateName as typeof TEMPLATE_NAME_OPTIONS[number],
         legalReviewRequired: template.legalReviewRequired ?? false,
-        shipBuildingApplicable: template.shipBuildingApplicable ?? false,
-        windApplicable: template.windApplicable ?? false,
-        pcApplicable: template.pcApplicable ?? false,
-        nbApplicable: template.nbApplicable ?? false,
-        rcApplicable: template.rcApplicable ?? false,
-        gyApplicable: template.gyApplicable ?? false,
-        sysApplicable: template.sysApplicable ?? false,
-        infraApplicable: template.infraApplicable ?? false,
       });
     }
   }, [template, form]);
 
-  // 현재 선택된 적용 범위 수
-  const selectedScopesCount = BUSINESS_UNITS.filter(unit =>
-    form.watch(unit.key as keyof UpdateTemplateSchema)
-  ).length;
-
   function onSubmit(input: UpdateTemplateSchema) {
     startUpdateTransition(async () => {
       if (!template) return
 
       // FormData 객체 생성하여 파일과 데이터를 함께 전송
       const formData = new FormData();
-      formData.append("templateName", input.templateName);
       formData.append("legalReviewRequired", input.legalReviewRequired.toString());
 
-      // 적용 범위 추가
-      BUSINESS_UNITS.forEach(unit => {
-        const value = input[unit.key as keyof UpdateTemplateSchema] as boolean;
-        formData.append(unit.key, value.toString());
-      });
-
       if (input.file) {
         formData.append("file", input.file);
       }
@@ -221,24 +134,14 @@ export function UpdateTemplateSheet({ template, onSuccess, ...props }: UpdateTem
 
   if (!template) return null;
 
-  const scopeSelected = BUSINESS_UNITS.some(
-    (unit) => form.watch(unit.key as keyof UpdateTemplateSchema)
-  );
-
-  const isDisabled =
-    isUpdatePending ||
-    !form.watch("templateName") ||
-    !scopeSelected;
-
   return (
     <Sheet {...props}>
-      <SheetContent className="sm:max-w-[600px] h-[100vh] flex flex-col p-0">
+      <SheetContent className="sm:max-w-[500px] h-[100vh] flex flex-col p-0">
         {/* 고정된 헤더 */}
         <SheetHeader className="p-6 pb-4 border-b">
           <SheetTitle>템플릿 업데이트</SheetTitle>
           <SheetDescription>
-            템플릿 정보를 수정하고 변경사항을 저장하세요
-            <span className="text-red-500 mt-1 block text-sm">* 표시된 항목은 필수 입력사항입니다.</span>
+            템플릿 파일을 업데이트하고 설정을 변경하세요
           </SheetDescription>
         </SheetHeader>
 
@@ -249,51 +152,49 @@ export function UpdateTemplateSheet({ template, onSuccess, ...props }: UpdateTem
               onSubmit={form.handleSubmit(onSubmit)}
               className="space-y-6 py-4"
             >
-              {/* 기본 정보 */}
+              {/* 템플릿 정보 표시 */}
               <Card>
                 <CardHeader>
-                  <CardTitle className="text-lg">기본 정보</CardTitle>
+                  <CardTitle className="text-lg">템플릿 정보</CardTitle>
                   <CardDescription>
-                    현재 리비전: <Badge variant="outline">v{template.revision}</Badge>
-                    <br />
-                    현재 적용 범위: {scopeHelpers.getScopeDisplayText(template)}
+                    현재 템플릿의 기본 정보입니다
                   </CardDescription>
                 </CardHeader>
                 <CardContent className="space-y-4">
                   <div className="grid grid-cols-1 gap-4">
-                    <FormField
-                      control={form.control}
-                      name="templateName"
-                      render={({ field }) => (
-                        <FormItem>
-                          <FormLabel>
-                            템플릿 이름 <span className="text-red-500">*</span>
-                          </FormLabel>
-                          <Select onValueChange={field.onChange} defaultValue={field.value}>
-                            <FormControl>
-                              <SelectTrigger>
-                                <SelectValue placeholder="템플릿 이름을 선택하세요" />
-                              </SelectTrigger>
-                            </FormControl>
-                            <SelectContent>
-                              <SelectGroup>
-                                {TEMPLATE_NAME_OPTIONS.map((option) => (
-                                  <SelectItem key={option} value={option}>
-                                    {option}
-                                  </SelectItem>
-                                ))}
-                              </SelectGroup>
-                            </SelectContent>
-                          </Select>
-                          <FormDescription>
-                            미리 정의된 템플릿 중에서 선택
-                          </FormDescription>
-                          <FormMessage />
-                        </FormItem>
-                      )}
-                    />
+                    <div className="space-y-2">
+                      <label className="text-sm font-medium">템플릿 이름</label>
+                      <div className="px-3 py-2 border rounded-md bg-gray-50">
+                        {template.templateName}
+                      </div>
+                    </div>
+                    
+                    <div className="space-y-2">
+                      <label className="text-sm font-medium">현재 리비전</label>
+                      <div className="px-3 py-2 border rounded-md bg-gray-50">
+                        <Badge variant="outline">v{template.revision}</Badge>
+                      </div>
+                    </div>
+                     
+                    <div className="space-y-2">
+                      <label className="text-sm font-medium">현재 파일</label>
+                      <div className="px-3 py-2 border rounded-md bg-gray-50">
+                        {template.fileName}
+                      </div>
+                    </div>
                   </div>
+                </CardContent>
+              </Card>
 
+              {/* 설정 */}
+              <Card>
+                <CardHeader>
+                  <CardTitle className="text-lg">설정</CardTitle>
+                  <CardDescription>
+                    템플릿 관련 설정을 변경할 수 있습니다
+                  </CardDescription>
+                </CardHeader>
+                <CardContent>
                   <FormField
                     control={form.control}
                     name="legalReviewRequired"
@@ -317,69 +218,12 @@ export function UpdateTemplateSheet({ template, onSuccess, ...props }: UpdateTem
                 </CardContent>
               </Card>
 
-              {/* 적용 범위 */}
-              <Card>
-                <CardHeader>
-                  <CardTitle className="text-lg">
-                    적용 범위 <span className="text-red-500">*</span>
-                  </CardTitle>
-                  <CardDescription>
-                    이 템플릿이 적용될 사업부를 선택하세요. ({selectedScopesCount}개 선택됨)
-                  </CardDescription>
-                </CardHeader>
-                <CardContent className="space-y-4">
-                  <div className="flex items-center space-x-2">
-                    <Checkbox
-                      id="select-all"
-                      checked={selectedScopesCount === BUSINESS_UNITS.length}
-                      onCheckedChange={handleSelectAllScopes}
-                    />
-                    <label htmlFor="select-all" className="text-sm font-medium">
-                      전체 선택
-                    </label>
-                  </div>
-
-                  <Separator />
-
-                  <div className="grid grid-cols-2 md:grid-cols-4 gap-4">
-                    {BUSINESS_UNITS.map((unit) => (
-                      <FormField
-                        key={unit.key}
-                        control={form.control}
-                        name={unit.key as keyof UpdateTemplateSchema}
-                        render={({ field }) => (
-                          <FormItem className="flex flex-row items-start space-x-3 space-y-0">
-                            <FormControl>
-                              <Checkbox
-                                checked={field.value as boolean}
-                                onCheckedChange={field.onChange}
-                              />
-                            </FormControl>
-                            <div className="space-y-1 leading-none">
-                              <FormLabel className="text-sm font-normal">
-                                {unit.label}
-                              </FormLabel>
-                            </div>
-                          </FormItem>
-                        )}
-                      />
-                    ))}
-                  </div>
-
-                  {form.formState.errors.shipBuildingApplicable && (
-                    <p className="text-sm text-destructive">
-                      {form.formState.errors.shipBuildingApplicable.message}
-                    </p>
-                  )}
-                </CardContent>
-              </Card>
-
               {/* 파일 업데이트 */}
               <Card>
                 <CardHeader>
                   <CardTitle className="text-lg">파일 업데이트</CardTitle>
                   <CardDescription>
-                    현재 파일: {template.fileName}
+                    새로운 템플릿 파일을 업로드하세요
                   </CardDescription>
                 </CardHeader>
                 <CardContent>
@@ -388,7 +232,7 @@ export function UpdateTemplateSheet({ template, onSuccess, ...props }: UpdateTem
                     name="file"
                     render={() => (
                       <FormItem>
-                        <FormLabel>템플릿 파일 (선택사항)</FormLabel>
+                        <FormLabel>새 템플릿 파일 (선택사항)</FormLabel>
                         <FormControl>
                           <Dropzone
                             onDrop={handleFileChange}
@@ -402,7 +246,7 @@ export function UpdateTemplateSheet({ template, onSuccess, ...props }: UpdateTem
                               <DropzoneTitle>
                                 {selectedFile
                                   ? selectedFile.name
-                                  : "새 워드 파일을 드래그하세요 (선택사항)"}
+                                  : "새 워드 파일을 드래그하세요"}
                               </DropzoneTitle>
                               <DropzoneDescription>
                                 {selectedFile
@@ -413,6 +257,9 @@ export function UpdateTemplateSheet({ template, onSuccess, ...props }: UpdateTem
                             </DropzoneZone>
                           </Dropzone>
                         </FormControl>
+                        <FormDescription>
+                          파일을 업로드하지 않으면 기존 파일이 유지됩니다
+                        </FormDescription>
                         <FormMessage />
                       </FormItem>
                     )}
@@ -433,12 +280,12 @@ export function UpdateTemplateSheet({ template, onSuccess, ...props }: UpdateTem
           <Button
             type="button"
             onClick={form.handleSubmit(onSubmit)}
-            disabled={isDisabled}
+            disabled={isUpdatePending}
           >
             {isUpdatePending && (
               <Loader className="mr-2 size-4 animate-spin" aria-hidden="true" />
             )}
-            저장
+            업데이트
           </Button>
         </SheetFooter>
       </SheetContent>
-- 
cgit v1.2.3

