From 8e70ba35379d21d89704f1095b7fd32bf286525d Mon Sep 17 00:00:00 2001 From: joonhoekim <26rote@gmail.com> Date: Thu, 2 Oct 2025 14:08:33 +0900 Subject: (김준회) ITB 및 일반견적 선택시 구매담당자 선택을 구매그룹코드로 처리하도록 변경, 오라클 연결 불가한 경우 하드코딩된 폴백데이터 제공처리 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/rfq-last/table/create-general-rfq-dialog.tsx | 214 ++++++++--------------- 1 file changed, 70 insertions(+), 144 deletions(-) (limited to 'lib/rfq-last/table/create-general-rfq-dialog.tsx') diff --git a/lib/rfq-last/table/create-general-rfq-dialog.tsx b/lib/rfq-last/table/create-general-rfq-dialog.tsx index 1d369648..7263f20f 100644 --- a/lib/rfq-last/table/create-general-rfq-dialog.tsx +++ b/lib/rfq-last/table/create-general-rfq-dialog.tsx @@ -5,8 +5,7 @@ import { useForm, useFieldArray } from "react-hook-form" import { zodResolver } from "@hookform/resolvers/zod" import { z } from "zod" import { format } from "date-fns" -import { CalendarIcon, Plus, Loader2, Trash2, PlusCircle, Check, ChevronsUpDown } from "lucide-react" -import { useRouter } from "next/navigation" +import { CalendarIcon, Plus, Loader2, Trash2, PlusCircle } from "lucide-react" import { useSession } from "next-auth/react" import { Button } from "@/components/ui/button" @@ -42,22 +41,18 @@ import { PopoverContent, PopoverTrigger, } from "@/components/ui/popover" -import { - Command, - CommandInput, - CommandList, - CommandGroup, - CommandItem, - CommandEmpty, -} from "@/components/ui/command" import { Calendar } from "@/components/ui/calendar" import { Badge } from "@/components/ui/badge" import { cn } from "@/lib/utils" import { toast } from "sonner" import { ScrollArea } from "@/components/ui/scroll-area" import { Separator } from "@/components/ui/separator" -import { createGeneralRfqAction, getPUsersForFilter, previewGeneralRfqCode } from "../service" +import { createGeneralRfqAction, previewGeneralRfqCode } from "../service" import { ProjectSelector } from "@/components/ProjectSelector" +import { + PurchaseGroupCodeSingleSelector, + PurchaseGroupCodeWithUser +} from "@/components/common/selectors/purchase-group-code" // 아이템 스키마 const itemSchema = z.object({ @@ -90,21 +85,12 @@ interface CreateGeneralRfqDialogProps { export function CreateGeneralRfqDialog({ onSuccess }: CreateGeneralRfqDialogProps) { const [open, setOpen] = React.useState(false) const [isLoading, setIsLoading] = React.useState(false) - const [users, setUsers] = React.useState>([]) - const [isLoadingUsers, setIsLoadingUsers] = React.useState(false) - const [userPopoverOpen, setUserPopoverOpen] = React.useState(false) - const [userSearchTerm, setUserSearchTerm] = React.useState("") + const [selectedPurchaseGroupCode, setSelectedPurchaseGroupCode] = React.useState(undefined) + const [selectorOpen, setSelectorOpen] = React.useState(false) const [previewCode, setPreviewCode] = React.useState("") const [isLoadingPreview, setIsLoadingPreview] = React.useState(false) - const userOptionIdsRef = React.useRef>({}) - const router = useRouter() const { data: session } = useSession() - // 고유 ID 생성 - const buttonId = React.useMemo(() => `user-button-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`, []) - const popoverContentId = React.useMemo(() => `user-popover-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`, []) - const commandId = React.useMemo(() => `user-command-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`, []) - const userId = React.useMemo(() => { return session?.user?.id ? Number(session.user.id) : null; }, [session]); @@ -171,49 +157,24 @@ export function CreateGeneralRfqDialog({ onSuccess }: CreateGeneralRfqDialogProp return () => subscription.unsubscribe() }, [form, generatePreviewCode]) - // 사용자 목록 로드 - React.useEffect(() => { - const loadUsers = async () => { - setIsLoadingUsers(true) - try { - const userList = await getPUsersForFilter() - setUsers(userList) - } catch (error) { - console.log("사용자 목록 로드 오류:", error) - toast.error("사용자 목록을 불러오는데 실패했습니다") - } finally { - setIsLoadingUsers(false) - } - } - loadUsers() - }, []) - - // 세션 사용자 ID로 기본값 설정 - React.useEffect(() => { - if (userId && !form.getValues("picUserId")) { - form.setValue("picUserId", userId) + // 구매그룹코드 선택 핸들러 + const handlePurchaseGroupCodeSelect = React.useCallback((code: PurchaseGroupCodeWithUser) => { + setSelectedPurchaseGroupCode(code) + + // 사용자 정보가 있으면 폼에 설정 + if (code.user) { + form.setValue("picUserId", code.user.id) + } else { + // 유저 정보가 없는 경우 경고 + toast.warning( + `해당 구매그룹코드(${code.PURCHASE_GROUP_CODE})의 사번 정보의 유저가 없습니다`, + { + description: `사번: ${code.EMPLOYEE_NUMBER}`, + duration: 5000, + } + ) } - }, [userId, form]) - - // 사용자 검색 필터링 - const userOptions = React.useMemo(() => { - return users.filter((user) => - user.name.toLowerCase().includes(userSearchTerm.toLowerCase()) - ) - }, [users, userSearchTerm]) - - // 선택된 사용자 찾기 - const selectedUser = React.useMemo(() => { - const picUserId = form.watch("picUserId") - return users.find(user => user.id === picUserId) - }, [users, form.watch("picUserId")]) - - // 사용자 선택 핸들러 - const handleSelectUser = (user: { id: number; name: string }) => { - form.setValue("picUserId", user.id) - setUserPopoverOpen(false) - setUserSearchTerm("") - } + }, [form]) // 다이얼로그 열림/닫힘 처리 및 폼 리셋 const handleOpenChange = (newOpen: boolean) => { @@ -238,8 +199,7 @@ export function CreateGeneralRfqDialog({ onSuccess }: CreateGeneralRfqDialogProp }, ], }) - setUserSearchTerm("") - setUserPopoverOpen(false) + setSelectedPurchaseGroupCode(undefined) setPreviewCode("") setIsLoadingPreview(false) } @@ -463,92 +423,47 @@ export function CreateGeneralRfqDialog({ onSuccess }: CreateGeneralRfqDialogProp )} /> - {/* 구매 담당자 - 검색 가능한 셀렉터로 변경 */} + {/* 구매 담당자 - 구매그룹코드 선택기 */} ( + render={() => ( - 견적담당자 * + 견적담당자 (구매그룹코드) * - - - - - - - - { - e.stopPropagation(); // 이벤트 전파 차단 - const target = e.currentTarget; - target.scrollTop += e.deltaY; // 직접 스크롤 처리 - }} - > - 담당자를 찾을 수 없습니다. - - {userOptions.map((user, userIndex) => { - if (!userOptionIdsRef.current[user.id]) { - userOptionIdsRef.current[user.id] = - `user-${user.id}-${Date.now()}-${Math.random() - .toString(36) - .slice(2, 9)}` - } - const optionId = userOptionIdsRef.current[user.id] - - return ( - handleSelectUser(user)} - value={user.name} - className="truncate" - title={user.name} - > - {user.name} - - - ) - })} - - - - - + {!selectedPurchaseGroupCode.user && ( +
+ ⚠️ 연결된 사용자가 없습니다 +
+ )} + + ) : ( + + 구매그룹코드를 선택하세요 + + )} +
{/* RFQ 코드 미리보기 */} {previewCode && ( @@ -779,6 +694,17 @@ export function CreateGeneralRfqDialog({ onSuccess }: CreateGeneralRfqDialogProp + + {/* 구매그룹코드 선택 다이얼로그 */} + ) } \ No newline at end of file -- cgit v1.2.3