diff options
| author | dujinkim <dujin.kim@dtsolution.co.kr> | 2025-04-08 03:08:19 +0000 |
|---|---|---|
| committer | dujinkim <dujin.kim@dtsolution.co.kr> | 2025-04-08 03:08:19 +0000 |
| commit | 9ceed79cf32c896f8a998399bf1b296506b2cd4a (patch) | |
| tree | f84750fa6cac954d5e31221fc47a54c655fc06a9 /lib/rfqs/table/update-rfq-sheet.tsx | |
| parent | 230ce796836c25df26c130dbcd616ef97d12b2ec (diff) | |
로그인 및 미들웨어 처리. 구조 변경
Diffstat (limited to 'lib/rfqs/table/update-rfq-sheet.tsx')
| -rw-r--r-- | lib/rfqs/table/update-rfq-sheet.tsx | 169 |
1 files changed, 146 insertions, 23 deletions
diff --git a/lib/rfqs/table/update-rfq-sheet.tsx b/lib/rfqs/table/update-rfq-sheet.tsx index 769f25e7..22ca2c37 100644 --- a/lib/rfqs/table/update-rfq-sheet.tsx +++ b/lib/rfqs/table/update-rfq-sheet.tsx @@ -37,31 +37,127 @@ import { Input } from "@/components/ui/input" import { Rfq, RfqWithItemCount } from "@/db/schema/rfq" import { RfqType, updateRfqSchema, type UpdateRfqSchema } from "../validations" -import { modifyRfq } from "../service" +import { modifyRfq, getBudgetaryRfqs } from "../service" import { ProjectSelector } from "@/components/ProjectSelector" import { type Project } from "../service" -import { BudgetaryRfqSelector } from "./BudgetaryRfqSelector" +import { ParentRfqSelector } from "./ParentRfqSelector" interface UpdateRfqSheetProps extends React.ComponentPropsWithRef<typeof Sheet> { rfq: RfqWithItemCount | null - rfqType?: RfqType; } - -interface BudgetaryRfq { +// 부모 RFQ 정보 타입 정의 +interface ParentRfq { id: number; rfqCode: string; description: string | null; + rfqType: RfqType; + projectId: number | null; + projectCode: string | null; + projectName: string | null; } - -export function UpdateRfqSheet({ rfq,rfqType = RfqType.PURCHASE , ...props }: UpdateRfqSheetProps) { +export function UpdateRfqSheet({ rfq, ...props }: UpdateRfqSheetProps) { const [isUpdatePending, startUpdateTransition] = React.useTransition() const { data: session } = useSession() const userId = Number(session?.user?.id || 1) - const [selectedBudgetaryRfq, setSelectedBudgetaryRfq] = React.useState<BudgetaryRfq | null>(null) + const [selectedParentRfq, setSelectedParentRfq] = React.useState<ParentRfq | null>(null) + + // RFQ의 타입 가져오기 + const rfqType = rfq?.rfqType || RfqType.PURCHASE; + + // 초기 부모 RFQ ID 가져오기 + const initialParentRfqId = rfq?.parentRfqId; + + // 현재 RFQ 타입에 따라 선택 가능한 부모 RFQ 타입들 결정 + const getParentRfqTypes = (): RfqType[] => { + switch(rfqType) { + case RfqType.PURCHASE: + // PURCHASE는 BUDGETARY와 PURCHASE_BUDGETARY를 부모로 가질 수 있음 + return [RfqType.BUDGETARY, RfqType.PURCHASE_BUDGETARY]; + case RfqType.PURCHASE_BUDGETARY: + // PURCHASE_BUDGETARY는 BUDGETARY만 부모로 가질 수 있음 + return [RfqType.BUDGETARY]; + default: + return []; + } + }; + + // 부모 RFQ 타입들 + const parentRfqTypes = getParentRfqTypes(); + + // 부모 RFQ를 보여줄지 결정 + const shouldShowParentRfqSelector = rfqType === RfqType.PURCHASE || rfqType === RfqType.PURCHASE_BUDGETARY; + + // 타입에 따른 타이틀 생성 + const getTypeTitle = () => { + switch(rfqType) { + case RfqType.PURCHASE: + return "Purchase RFQ"; + case RfqType.BUDGETARY: + return "Budgetary RFQ"; + case RfqType.PURCHASE_BUDGETARY: + return "Purchase Budgetary RFQ"; + default: + return "RFQ"; + } + }; + + // 타입 설명 가져오기 + const getTypeDescription = () => { + switch(rfqType) { + case RfqType.PURCHASE: + return "실제 구매 발주 전에 가격을 요청"; + case RfqType.BUDGETARY: + return "기술영업 단계에서 입찰가 산정을 위한 견적 요청"; + case RfqType.PURCHASE_BUDGETARY: + return "프로젝트 수주 후, 공식 입찰 전 예산 책정을 위한 가격 요청"; + default: + return ""; + } + }; + // 부모 RFQ 선택기 레이블 및 설명 가져오기 + const getParentRfqSelectorLabel = () => { + if (rfqType === RfqType.PURCHASE) { + return "부모 RFQ (BUDGETARY/PURCHASE_BUDGETARY)"; + } else if (rfqType === RfqType.PURCHASE_BUDGETARY) { + return "부모 RFQ (BUDGETARY)"; + } + return "부모 RFQ"; + }; + + const getParentRfqDescription = () => { + if (rfqType === RfqType.PURCHASE) { + return "BUDGETARY 또는 PURCHASE_BUDGETARY 타입의 RFQ를 부모로 선택할 수 있습니다."; + } else if (rfqType === RfqType.PURCHASE_BUDGETARY) { + return "BUDGETARY 타입의 RFQ만 부모로 선택할 수 있습니다."; + } + return ""; + }; + + // 초기 부모 RFQ 로드 + React.useEffect(() => { + if (initialParentRfqId && shouldShowParentRfqSelector) { + const loadInitialParentRfq = async () => { + try { + const result = await getBudgetaryRfqs({ + rfqId: initialParentRfqId + }); + + if ('rfqs' in result && result.rfqs && result.rfqs.length > 0) { + setSelectedParentRfq(result.rfqs[0] as unknown as ParentRfq); + } + } catch (error) { + console.error("부모 RFQ 로드 오류:", error); + } + }; + + loadInitialParentRfq(); + } + }, [initialParentRfqId, shouldShowParentRfqSelector]); + // RHF setup const form = useForm<UpdateRfqSchema>({ resolver: zodResolver(updateRfqSchema), @@ -70,6 +166,7 @@ export function UpdateRfqSheet({ rfq,rfqType = RfqType.PURCHASE , ...props }: Up rfqCode: rfq?.rfqCode ?? "", description: rfq?.description ?? "", projectId: rfq?.projectId, // 프로젝트 ID + parentRfqId: rfq?.parentRfqId, // 부모 RFQ ID dueDate: rfq?.dueDate ?? undefined, // null을 undefined로 변환 status: rfq?.status ?? "DRAFT", createdBy: rfq?.createdBy ?? userId, @@ -77,16 +174,27 @@ export function UpdateRfqSheet({ rfq,rfqType = RfqType.PURCHASE , ...props }: Up }); // 프로젝트 선택 처리 - const handleProjectSelect = (project: Project) => { + const handleProjectSelect = (project: Project | null) => { + if (project === null) { + return; + } form.setValue("projectId", project.id); }; + // 부모 RFQ 선택 처리 + const handleParentRfqSelect = (rfq: ParentRfq | null) => { + setSelectedParentRfq(rfq); + form.setValue("parentRfqId", rfq?.id); + }; + async function onSubmit(input: UpdateRfqSchema) { startUpdateTransition(async () => { if (!rfq) return const { error } = await modifyRfq({ ...input, + rfqType: rfqType as RfqType, + }) if (error) { @@ -104,9 +212,12 @@ export function UpdateRfqSheet({ rfq,rfqType = RfqType.PURCHASE , ...props }: Up <Sheet {...props}> <SheetContent className="flex flex-col gap-6 sm:max-w-md"> <SheetHeader className="text-left"> - <SheetTitle>Update RFQ</SheetTitle> + <SheetTitle>Update {getTypeTitle()}</SheetTitle> <SheetDescription> - Update the RFQ details and save the changes + Update the {getTypeTitle()} details and save the changes + <div className="mt-1 text-xs text-muted-foreground"> + {getTypeDescription()} + </div> </SheetDescription> </SheetHeader> @@ -122,6 +233,15 @@ export function UpdateRfqSheet({ rfq,rfqType = RfqType.PURCHASE , ...props }: Up <input type="hidden" {...field} /> )} /> + + {/* Hidden rfqType field */} + {/* <FormField + control={form.control} + name="rfqType" + render={({ field }) => ( + <input type="hidden" {...field} /> + )} + /> */} {/* Project Selector - 재사용 컴포넌트 사용 */} <FormField @@ -142,31 +262,36 @@ export function UpdateRfqSheet({ rfq,rfqType = RfqType.PURCHASE , ...props }: Up )} /> - {/* Budgetary RFQ Selector - 구매용 RFQ 생성 시에만 표시 */} - {rfqType === RfqType.PURCHASE && ( + {/* Parent RFQ Selector - PURCHASE 또는 PURCHASE_BUDGETARY 타입일 때만 표시 */} + {shouldShowParentRfqSelector && ( <FormField control={form.control} name="parentRfqId" render={({ field }) => ( <FormItem> - <FormLabel>Budgetary RFQ (Optional)</FormLabel> + <FormLabel>{getParentRfqSelectorLabel()}</FormLabel> <FormControl> - <BudgetaryRfqSelector + <ParentRfqSelector selectedRfqId={field.value as number | undefined} - onRfqSelect={(rfq) => { - setSelectedBudgetaryRfq(rfq as any); - form.setValue("parentRfqId", rfq?.id); - }} - placeholder="Budgetary RFQ 선택..." + onRfqSelect={handleParentRfqSelect} + rfqType={rfqType} + parentRfqTypes={parentRfqTypes} + placeholder={ + rfqType === RfqType.PURCHASE + ? "BUDGETARY 또는 PURCHASE_BUDGETARY RFQ 선택..." + : "BUDGETARY RFQ 선택..." + } /> </FormControl> + <div className="text-xs text-muted-foreground mt-1"> + {getParentRfqDescription()} + </div> <FormMessage /> </FormItem> )} /> )} - {/* rfqCode */} <FormField control={form.control} @@ -197,8 +322,6 @@ export function UpdateRfqSheet({ rfq,rfqType = RfqType.PURCHASE , ...props }: Up )} /> - - {/* dueDate (type="date") */} <FormField control={form.control} |
