summaryrefslogtreecommitdiff
path: root/lib/vendor-investigation/table/update-investigation-sheet.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'lib/vendor-investigation/table/update-investigation-sheet.tsx')
-rw-r--r--lib/vendor-investigation/table/update-investigation-sheet.tsx656
1 files changed, 377 insertions, 279 deletions
diff --git a/lib/vendor-investigation/table/update-investigation-sheet.tsx b/lib/vendor-investigation/table/update-investigation-sheet.tsx
index 69f0d9ae..29f0fa92 100644
--- a/lib/vendor-investigation/table/update-investigation-sheet.tsx
+++ b/lib/vendor-investigation/table/update-investigation-sheet.tsx
@@ -3,7 +3,7 @@
import * as React from "react"
import { zodResolver } from "@hookform/resolvers/zod"
import { useForm } from "react-hook-form"
-import { CalendarIcon, Loader } from "lucide-react"
+import { CalendarIcon, Loader, X } from "lucide-react"
import { format } from "date-fns"
import { toast } from "sonner"
@@ -49,6 +49,16 @@ import {
DropzoneDescription,
DropzoneInput
} from "@/components/ui/dropzone"
+import {
+ FileList,
+ FileListAction,
+ FileListHeader,
+ FileListIcon,
+ FileListInfo,
+ FileListItem,
+ FileListName,
+ FileListSize,
+} from "@/components/ui/file-list"
import {
updateVendorInvestigationSchema,
@@ -56,6 +66,7 @@ import {
} from "../validations"
import { updateVendorInvestigationAction, getInvestigationAttachments, deleteInvestigationAttachment } from "../service"
import { VendorInvestigationsViewWithContacts } from "@/config/vendorInvestigationsColumnsConfig"
+import prettyBytes from "pretty-bytes"
interface UpdateVendorInvestigationSheetProps
extends React.ComponentPropsWithoutRef<typeof Sheet> {
@@ -70,7 +81,7 @@ const getFileUploadConfig = (status: string) => {
enabled: false,
label: "",
description: "",
- accept: undefined, // undefined로 변경
+ accept: undefined,
maxSize: 0,
maxSizeText: ""
}
@@ -122,7 +133,7 @@ export function UpdateVendorInvestigationSheet({
evaluationScore: investigation?.evaluationScore ?? undefined,
evaluationResult: investigation?.evaluationResult ?? undefined,
investigationNotes: investigation?.investigationNotes ?? "",
- attachments: undefined, // 파일은 매번 새로 업로드
+ attachments: undefined,
},
})
@@ -142,9 +153,9 @@ export function UpdateVendorInvestigationSheet({
evaluationScore: investigation.evaluationScore ?? undefined,
evaluationResult: investigation.evaluationResult ?? undefined,
investigationNotes: investigation.investigationNotes ?? "",
- attachments: undefined, // 파일은 매번 새로 업로드
+ attachments: undefined,
})
-
+
// 기존 첨부파일 로드
loadExistingAttachments(investigation.investigationId)
}
@@ -171,32 +182,46 @@ export function UpdateVendorInvestigationSheet({
// 첨부파일 삭제 함수
const handleDeleteAttachment = async (attachmentId: number) => {
if (!investigation) return
-
+
try {
const response = await fetch(`/api/vendor-investigations/${investigation.investigationId}/attachments?attachmentId=${attachmentId}`, {
method: "DELETE",
})
-
+
if (!response.ok) {
const errorData = await response.json()
throw new Error(errorData.error || "첨부파일 삭제 실패")
}
-
+
toast.success("첨부파일이 삭제되었습니다.")
// 목록 새로고침
loadExistingAttachments(investigation.investigationId)
-
+
} catch (error) {
console.error("첨부파일 삭제 오류:", error)
toast.error(error instanceof Error ? error.message : "첨부파일 삭제 중 오류가 발생했습니다.")
}
}
+ // 선택된 파일에서 특정 파일 제거
+ const handleRemoveSelectedFile = (indexToRemove: number) => {
+ const currentFiles = form.getValues("attachments") || []
+ const updatedFiles = currentFiles.filter((_, index) => index !== indexToRemove)
+ form.setValue("attachments", updatedFiles.length > 0 ? updatedFiles : undefined)
+
+ if (updatedFiles.length === 0) {
+ toast.success("모든 선택된 파일이 제거되었습니다.")
+ } else {
+ toast.success("파일이 제거되었습니다.")
+ }
+ }
+
// 파일 업로드 섹션 렌더링
const renderFileUploadSection = () => {
const currentStatus = form.watch("investigationStatus")
+ const selectedFiles = form.watch("attachments") as File[] | undefined
const config = getFileUploadConfig(currentStatus)
-
+
if (!config.enabled) return null
return (
@@ -269,10 +294,13 @@ export function UpdateVendorInvestigationSheet({
}
})
}
-
+
if (acceptedFiles.length > 0) {
- onChange(acceptedFiles)
- toast.success(`${acceptedFiles.length}개 파일이 선택되었습니다.`)
+ // 기존 파일들과 새로 선택된 파일들을 합치기
+ const currentFiles = form.getValues("attachments") || []
+ const newFiles = [...currentFiles, ...acceptedFiles]
+ onChange(newFiles)
+ toast.success(`${acceptedFiles.length}개 파일이 추가되었습니다.`)
}
}}
accept={config.accept}
@@ -283,8 +311,8 @@ export function UpdateVendorInvestigationSheet({
<DropzoneZone>
<DropzoneUploadIcon />
<DropzoneTitle>
- {isPending || uploadingFiles
- ? "파일 업로드 중..."
+ {isPending || uploadingFiles
+ ? "파일 업로드 중..."
: "파일을 드래그하거나 클릭하여 업로드"
}
</DropzoneTitle>
@@ -299,6 +327,50 @@ export function UpdateVendorInvestigationSheet({
</FormItem>
)}
/>
+
+ {/* 선택된 파일 목록 */}
+ {selectedFiles && selectedFiles.length > 0 && (
+ <div className="space-y-2">
+ {/* <FormLabel>선택된 파일 ({selectedFiles.length}개)</FormLabel> */}
+ <FileList>
+ <FileListHeader>
+ <span className="text-sm font-medium">업로드 예정 파일 ({selectedFiles.length}개)</span>
+ </FileListHeader>
+ {selectedFiles.map((file, index) => (
+ <FileListItem
+ key={`${file.name}-${index}`}
+ className="flex items-center justify-between gap-2 px-2 py-2"
+ >
+ {/* 왼쪽 아이콘 */}
+ <FileListIcon className="shrink-0 h-4 w-4 text-muted-foreground" />
+
+ {/* 가운데 이름 + 사이즈 */}
+ <FileListInfo className="flex-1 min-w-0">
+ <FileListName className="truncate">{file.name}</FileListName>
+ <FileListSize className="text-xs text-muted-foreground shrink-0">
+ {file.size}
+ </FileListSize>
+ </FileListInfo>
+
+ {/* 오른쪽 삭제 버튼 */}
+ <FileListAction className="shrink-0">
+ <Button
+ type="button"
+ variant="ghost"
+ size="icon"
+ onClick={() => handleRemoveSelectedFile(index)}
+ disabled={isPending || uploadingFiles}
+ className="h-5 w-5 text-destructive hover:text-destructive"
+ >
+ <X className="h-4 w-4" />
+ </Button>
+ </FileListAction>
+ </FileListItem>
+
+ ))}
+ </FileList>
+ </div>
+ )}
</>
)
}
@@ -308,80 +380,87 @@ export function UpdateVendorInvestigationSheet({
const uploadPromises = files.map(async (file) => {
const formData = new FormData()
formData.append("file", file)
-
+
const response = await fetch(`/api/vendor-investigations/${investigationId}/attachments`, {
method: "POST",
body: formData,
})
-
+
if (!response.ok) {
const errorData = await response.json()
throw new Error(errorData.error || "파일 업로드 실패")
}
-
+
return await response.json()
})
-
+
return await Promise.all(uploadPromises)
}
// Submit handler
async function onSubmit(values: UpdateVendorInvestigationSchema) {
- if (!values.investigationId) return
+ console.log("onSubmit 호출됨:", values)
+
+ if (!values.investigationId) {
+ console.log("investigationId가 없음:", values.investigationId)
+ return
+ }
startTransition(async () => {
try {
+ console.log("startTransition 시작")
+
// 1) 먼저 텍스트 데이터 업데이트
const formData = new FormData()
// 필수 필드
formData.append("investigationId", String(values.investigationId))
formData.append("investigationStatus", values.investigationStatus)
-
+
// 선택적 필드들
if (values.evaluationType) {
formData.append("evaluationType", values.evaluationType)
}
-
+
if (values.investigationAddress) {
formData.append("investigationAddress", values.investigationAddress)
}
-
+
if (values.investigationMethod) {
formData.append("investigationMethod", values.investigationMethod)
}
-
+
if (values.forecastedAt) {
formData.append("forecastedAt", values.forecastedAt.toISOString())
}
-
+
if (values.requestedAt) {
formData.append("requestedAt", values.requestedAt.toISOString())
}
-
+
if (values.confirmedAt) {
formData.append("confirmedAt", values.confirmedAt.toISOString())
}
-
+
if (values.completedAt) {
formData.append("completedAt", values.completedAt.toISOString())
}
-
+
if (values.evaluationScore !== undefined) {
formData.append("evaluationScore", String(values.evaluationScore))
}
-
+
if (values.evaluationResult) {
formData.append("evaluationResult", values.evaluationResult)
}
-
+
if (values.investigationNotes) {
formData.append("investigationNotes", values.investigationNotes)
}
// 텍스트 데이터 업데이트
const { error } = await updateVendorInvestigationAction(formData)
-
+
if (error) {
toast.error(error)
return
@@ -390,14 +469,15 @@ export function UpdateVendorInvestigationSheet({
// 2) 파일이 있으면 업로드
if (values.attachments && values.attachments.length > 0) {
setUploadingFiles(true)
-
+
try {
await uploadFiles(values.attachments, values.investigationId)
toast.success(`실사 정보와 ${values.attachments.length}개 파일이 업데이트되었습니다!`)
-
+
// 첨부파일 목록 새로고침
loadExistingAttachments(values.investigationId)
} catch (fileError) {
+ console.error("파일 업로드 에러:", fileError)
toast.error(`데이터는 저장되었지만 파일 업로드 중 오류가 발생했습니다: ${fileError}`)
} finally {
setUploadingFiles(false)
@@ -408,7 +488,7 @@ export function UpdateVendorInvestigationSheet({
form.reset()
props.onOpenChange?.(false)
-
+
} catch (error) {
console.error("실사 정보 업데이트 오류:", error)
toast.error("실사 정보 업데이트 중 오류가 발생했습니다.")
@@ -416,9 +496,26 @@ export function UpdateVendorInvestigationSheet({
})
}
+ // 디버깅을 위한 버튼 클릭 핸들러
+ const handleSaveClick = async () => {
+ console.log("저장 버튼 클릭됨")
+ console.log("현재 폼 값:", form.getValues())
+ console.log("폼 에러:", form.formState.errors)
+
+ // 폼 검증 실행
+ const isValid = await form.trigger()
+ console.log("폼 검증 결과:", isValid)
+
+ if (isValid) {
+ form.handleSubmit(onSubmit)()
+ } else {
+ console.log("폼 검증 실패, 에러:", form.formState.errors)
+ }
+ }
+
return (
<Sheet {...props}>
- <SheetContent className="flex flex-col h-full sm:max-w-md">
+ <SheetContent className="flex flex-col h-full sm:max-w-xl" >
<SheetHeader className="text-left flex-shrink-0">
<SheetTitle>실사 업데이트</SheetTitle>
<SheetDescription>
@@ -433,250 +530,51 @@ export function UpdateVendorInvestigationSheet({
<form
onSubmit={form.handleSubmit(onSubmit)}
className="flex flex-col gap-4"
+ id="update-investigation-form"
>
- {/* 실사 상태 */}
- <FormField
- control={form.control}
- name="investigationStatus"
- render={({ field }) => (
- <FormItem>
- <FormLabel>실사 상태</FormLabel>
- <FormControl>
- <Select value={field.value} onValueChange={field.onChange}>
- <SelectTrigger>
- <SelectValue placeholder="상태를 선택하세요" />
- </SelectTrigger>
- <SelectContent>
- <SelectGroup>
- <SelectItem value="PLANNED">계획됨</SelectItem>
- <SelectItem value="IN_PROGRESS">진행 중</SelectItem>
- <SelectItem value="COMPLETED">완료됨</SelectItem>
- <SelectItem value="CANCELED">취소됨</SelectItem>
- </SelectGroup>
- </SelectContent>
- </Select>
- </FormControl>
- <FormMessage />
- </FormItem>
- )}
- />
-
- {/* 평가 유형 */}
- <FormField
- control={form.control}
- name="evaluationType"
- render={({ field }) => (
- <FormItem>
- <FormLabel>평가 유형</FormLabel>
- <FormControl>
- <Select value={field.value || ""} onValueChange={field.onChange}>
- <SelectTrigger>
- <SelectValue placeholder="평가 유형을 선택하세요" />
- </SelectTrigger>
- <SelectContent>
- <SelectGroup>
- <SelectItem value="SITE_AUDIT">실사의뢰평가</SelectItem>
- <SelectItem value="QM_SELF_AUDIT">QM자체평가</SelectItem>
- </SelectGroup>
- </SelectContent>
- </Select>
- </FormControl>
- <FormMessage />
- </FormItem>
- )}
- />
-
- {/* 실사 주소 */}
- <FormField
- control={form.control}
- name="investigationAddress"
- render={({ field }) => (
- <FormItem>
- <FormLabel>실사 주소</FormLabel>
- <FormControl>
- <Textarea
- placeholder="실사가 진행될 주소를 입력하세요..."
- {...field}
- className="min-h-[60px]"
- />
- </FormControl>
- <FormMessage />
- </FormItem>
- )}
- />
-
- {/* 실사 방법 */}
- <FormField
- control={form.control}
- name="investigationMethod"
- render={({ field }) => (
- <FormItem>
- <FormLabel>실사 방법</FormLabel>
- <FormControl>
- <Input placeholder="실사 방법을 입력하세요..." {...field} />
- </FormControl>
- <FormMessage />
- </FormItem>
- )}
- />
-
- {/* 실사 예정일 */}
- <FormField
- control={form.control}
- name="forecastedAt"
- render={({ field }) => (
- <FormItem className="flex flex-col">
- <FormLabel>실사 예정일</FormLabel>
- <Popover>
- <PopoverTrigger asChild>
- <FormControl>
- <Button
- variant="outline"
- className={`w-full pl-3 text-left font-normal ${!field.value && "text-muted-foreground"}`}
- >
- {field.value ? (
- format(field.value, "yyyy년 MM월 dd일")
- ) : (
- <span>날짜를 선택하세요</span>
- )}
- <CalendarIcon className="ml-auto h-4 w-4 opacity-50" />
- </Button>
- </FormControl>
- </PopoverTrigger>
- <PopoverContent className="w-auto p-0" align="start">
- <Calendar
- mode="single"
- selected={field.value}
- onSelect={field.onChange}
- initialFocus
- />
- </PopoverContent>
- </Popover>
- <FormMessage />
- </FormItem>
- )}
- />
-
- {/* 실사 확정일 */}
- <FormField
- control={form.control}
- name="confirmedAt"
- render={({ field }) => (
- <FormItem className="flex flex-col">
- <FormLabel>실사 확정일</FormLabel>
- <Popover>
- <PopoverTrigger asChild>
- <FormControl>
- <Button
- variant="outline"
- className={`w-full pl-3 text-left font-normal ${!field.value && "text-muted-foreground"}`}
- >
- {field.value ? (
- format(field.value, "yyyy년 MM월 dd일")
- ) : (
- <span>날짜를 선택하세요</span>
- )}
- <CalendarIcon className="ml-auto h-4 w-4 opacity-50" />
- </Button>
- </FormControl>
- </PopoverTrigger>
- <PopoverContent className="w-auto p-0" align="start">
- <Calendar
- mode="single"
- selected={field.value}
- onSelect={field.onChange}
- initialFocus
- />
- </PopoverContent>
- </Popover>
- <FormMessage />
- </FormItem>
- )}
- />
-
- {/* 실제 실사일 */}
- <FormField
- control={form.control}
- name="completedAt"
- render={({ field }) => (
- <FormItem className="flex flex-col">
- <FormLabel>실제 실사일</FormLabel>
- <Popover>
- <PopoverTrigger asChild>
- <FormControl>
- <Button
- variant="outline"
- className={`w-full pl-3 text-left font-normal ${!field.value && "text-muted-foreground"}`}
- >
- {field.value ? (
- format(field.value, "yyyy년 MM월 dd일")
- ) : (
- <span>날짜를 선택하세요</span>
- )}
- <CalendarIcon className="ml-auto h-4 w-4 opacity-50" />
- </Button>
- </FormControl>
- </PopoverTrigger>
- <PopoverContent className="w-auto p-0" align="start">
- <Calendar
- mode="single"
- selected={field.value}
- onSelect={field.onChange}
- initialFocus
- />
- </PopoverContent>
- </Popover>
- <FormMessage />
- </FormItem>
- )}
- />
-
- {/* 평가 점수 - 완료된 상태일 때만 표시 */}
- {form.watch("investigationStatus") === "COMPLETED" && (
+ {/* 실사 상태 */}
<FormField
control={form.control}
- name="evaluationScore"
+ name="investigationStatus"
render={({ field }) => (
<FormItem>
- <FormLabel>평가 점수</FormLabel>
+ <FormLabel>실사 상태</FormLabel>
<FormControl>
- <Input
- type="number"
- min={0}
- max={100}
- placeholder="0-100점"
- {...field}
- value={field.value || ""}
- onChange={(e) => {
- const value = e.target.value === "" ? undefined : parseInt(e.target.value, 10)
- field.onChange(value)
- }}
- />
+ <Select value={field.value} onValueChange={field.onChange}>
+ <SelectTrigger>
+ <SelectValue placeholder="상태를 선택하세요" />
+ </SelectTrigger>
+ <SelectContent>
+ <SelectGroup>
+ <SelectItem value="PLANNED">계획됨</SelectItem>
+ <SelectItem value="IN_PROGRESS">진행 중</SelectItem>
+ <SelectItem value="COMPLETED">완료됨</SelectItem>
+ <SelectItem value="CANCELED">취소됨</SelectItem>
+ </SelectGroup>
+ </SelectContent>
+ </Select>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
- )}
- {/* 평가 결과 - 완료된 상태일 때만 표시 */}
- {form.watch("investigationStatus") === "COMPLETED" && (
+ {/* 평가 유형 */}
<FormField
control={form.control}
- name="evaluationResult"
+ name="evaluationType"
render={({ field }) => (
<FormItem>
- <FormLabel>평가 결과</FormLabel>
+ <FormLabel>평가 유형</FormLabel>
<FormControl>
<Select value={field.value || ""} onValueChange={field.onChange}>
<SelectTrigger>
- <SelectValue placeholder="평가 결과를 선택하세요" />
+ <SelectValue placeholder="평가 유형을 선택하세요" />
</SelectTrigger>
<SelectContent>
<SelectGroup>
- <SelectItem value="APPROVED">승인</SelectItem>
- <SelectItem value="SUPPLEMENT">보완</SelectItem>
- <SelectItem value="REJECTED">불가</SelectItem>
+ <SelectItem value="SITE_AUDIT">실사의뢰평가</SelectItem>
+ <SelectItem value="QM_SELF_AUDIT">QM자체평가</SelectItem>
</SelectGroup>
</SelectContent>
</Select>
@@ -685,29 +583,229 @@ export function UpdateVendorInvestigationSheet({
</FormItem>
)}
/>
- )}
- {/* QM 의견 */}
- <FormField
- control={form.control}
- name="investigationNotes"
- render={({ field }) => (
- <FormItem>
- <FormLabel>QM 의견</FormLabel>
- <FormControl>
- <Textarea
- placeholder="실사에 대한 QM 의견을 입력하세요..."
- {...field}
- className="min-h-[80px]"
- />
- </FormControl>
- <FormMessage />
- </FormItem>
+ {/* 실사 주소 */}
+ <FormField
+ control={form.control}
+ name="investigationAddress"
+ render={({ field }) => (
+ <FormItem>
+ <FormLabel>실사 주소</FormLabel>
+ <FormControl>
+ <Textarea
+ placeholder="실사가 진행될 주소를 입력하세요..."
+ {...field}
+ className="min-h-[60px]"
+ />
+ </FormControl>
+ <FormMessage />
+ </FormItem>
+ )}
+ />
+
+ {/* 실사 방법 */}
+ <FormField
+ control={form.control}
+ name="investigationMethod"
+ render={({ field }) => (
+ <FormItem>
+ <FormLabel>실사 방법</FormLabel>
+ <FormControl>
+ <Input placeholder="실사 방법을 입력하세요..." {...field} />
+ </FormControl>
+ <FormMessage />
+ </FormItem>
+ )}
+ />
+
+ {/* 실사 예정일 */}
+ <FormField
+ control={form.control}
+ name="forecastedAt"
+ render={({ field }) => (
+ <FormItem className="flex flex-col">
+ <FormLabel>실사 예정일</FormLabel>
+ <Popover>
+ <PopoverTrigger asChild>
+ <FormControl>
+ <Button
+ variant="outline"
+ className={`w-full pl-3 text-left font-normal ${!field.value && "text-muted-foreground"}`}
+ >
+ {field.value ? (
+ format(field.value, "yyyy년 MM월 dd일")
+ ) : (
+ <span>날짜를 선택하세요</span>
+ )}
+ <CalendarIcon className="ml-auto h-4 w-4 opacity-50" />
+ </Button>
+ </FormControl>
+ </PopoverTrigger>
+ <PopoverContent className="w-auto p-0" align="start">
+ <Calendar
+ mode="single"
+ selected={field.value}
+ onSelect={field.onChange}
+ initialFocus
+ />
+ </PopoverContent>
+ </Popover>
+ <FormMessage />
+ </FormItem>
+ )}
+ />
+
+ {/* 실사 확정일 */}
+ <FormField
+ control={form.control}
+ name="confirmedAt"
+ render={({ field }) => (
+ <FormItem className="flex flex-col">
+ <FormLabel>실사 확정일</FormLabel>
+ <Popover>
+ <PopoverTrigger asChild>
+ <FormControl>
+ <Button
+ variant="outline"
+ className={`w-full pl-3 text-left font-normal ${!field.value && "text-muted-foreground"}`}
+ >
+ {field.value ? (
+ format(field.value, "yyyy년 MM월 dd일")
+ ) : (
+ <span>날짜를 선택하세요</span>
+ )}
+ <CalendarIcon className="ml-auto h-4 w-4 opacity-50" />
+ </Button>
+ </FormControl>
+ </PopoverTrigger>
+ <PopoverContent className="w-auto p-0" align="start">
+ <Calendar
+ mode="single"
+ selected={field.value}
+ onSelect={field.onChange}
+ initialFocus
+ />
+ </PopoverContent>
+ </Popover>
+ <FormMessage />
+ </FormItem>
+ )}
+ />
+
+ {/* 실제 실사일 */}
+ <FormField
+ control={form.control}
+ name="completedAt"
+ render={({ field }) => (
+ <FormItem className="flex flex-col">
+ <FormLabel>실제 실사일</FormLabel>
+ <Popover>
+ <PopoverTrigger asChild>
+ <FormControl>
+ <Button
+ variant="outline"
+ className={`w-full pl-3 text-left font-normal ${!field.value && "text-muted-foreground"}`}
+ >
+ {field.value ? (
+ format(field.value, "yyyy년 MM월 dd일")
+ ) : (
+ <span>날짜를 선택하세요</span>
+ )}
+ <CalendarIcon className="ml-auto h-4 w-4 opacity-50" />
+ </Button>
+ </FormControl>
+ </PopoverTrigger>
+ <PopoverContent className="w-auto p-0" align="start">
+ <Calendar
+ mode="single"
+ selected={field.value}
+ onSelect={field.onChange}
+ initialFocus
+ />
+ </PopoverContent>
+ </Popover>
+ <FormMessage />
+ </FormItem>
+ )}
+ />
+
+ {/* 평가 점수 - 완료된 상태일 때만 표시 */}
+ {form.watch("investigationStatus") === "COMPLETED" && (
+ <FormField
+ control={form.control}
+ name="evaluationScore"
+ render={({ field }) => (
+ <FormItem>
+ <FormLabel>평가 점수</FormLabel>
+ <FormControl>
+ <Input
+ type="number"
+ min={0}
+ max={100}
+ placeholder="0-100점"
+ {...field}
+ value={field.value || ""}
+ onChange={(e) => {
+ const value = e.target.value === "" ? undefined : parseInt(e.target.value, 10)
+ field.onChange(value)
+ }}
+ />
+ </FormControl>
+ <FormMessage />
+ </FormItem>
+ )}
+ />
+ )}
+
+ {/* 평가 결과 - 완료된 상태일 때만 표시 */}
+ {form.watch("investigationStatus") === "COMPLETED" && (
+ <FormField
+ control={form.control}
+ name="evaluationResult"
+ render={({ field }) => (
+ <FormItem>
+ <FormLabel>평가 결과</FormLabel>
+ <FormControl>
+ <Select value={field.value || ""} onValueChange={field.onChange}>
+ <SelectTrigger>
+ <SelectValue placeholder="평가 결과를 선택하세요" />
+ </SelectTrigger>
+ <SelectContent>
+ <SelectGroup>
+ <SelectItem value="APPROVED">승인</SelectItem>
+ <SelectItem value="SUPPLEMENT">보완</SelectItem>
+ <SelectItem value="REJECTED">불가</SelectItem>
+ </SelectGroup>
+ </SelectContent>
+ </Select>
+ </FormControl>
+ <FormMessage />
+ </FormItem>
+ )}
+ />
)}
- />
- {/* 파일 첨부 섹션 */}
- {renderFileUploadSection()}
+ {/* QM 의견 */}
+ <FormField
+ control={form.control}
+ name="investigationNotes"
+ render={({ field }) => (
+ <FormItem>
+ <FormLabel>QM 의견</FormLabel>
+ <FormControl>
+ <Textarea
+ placeholder="실사에 대한 QM 의견을 입력하세요..."
+ {...field}
+ className="min-h-[80px]"
+ />
+ </FormControl>
+ <FormMessage />
+ </FormItem>
+ )}
+ />
+
+ {/* 파일 첨부 섹션 */}
+ {renderFileUploadSection()}
</form>
</Form>
</div>
@@ -719,9 +817,9 @@ export function UpdateVendorInvestigationSheet({
취소
</Button>
</SheetClose>
- <Button
+ <Button
disabled={isPending || uploadingFiles}
- onClick={form.handleSubmit(onSubmit)}
+ onClick={handleSaveClick}
>
{(isPending || uploadingFiles) && (
<Loader className="mr-2 h-4 w-4 animate-spin" aria-hidden="true" />