diff options
| author | dujinkim <dujin.kim@dtsolution.co.kr> | 2025-04-02 09:54:08 +0000 |
|---|---|---|
| committer | dujinkim <dujin.kim@dtsolution.co.kr> | 2025-04-02 09:54:08 +0000 |
| commit | dfdfae3018f8499240f48d28ce634f4a5c56e006 (patch) | |
| tree | 4493b172c061fa5bf4e94c083788110eb1507f6d /lib/pq/table/add-pq-dialog.tsx | |
| parent | 21a72eeddc74cf775e2a76e2c569de970bd62a7f (diff) | |
벤더 코멘트 처리
Diffstat (limited to 'lib/pq/table/add-pq-dialog.tsx')
| -rw-r--r-- | lib/pq/table/add-pq-dialog.tsx | 431 |
1 files changed, 293 insertions, 138 deletions
diff --git a/lib/pq/table/add-pq-dialog.tsx b/lib/pq/table/add-pq-dialog.tsx index 8164dbaf..1f374cd0 100644 --- a/lib/pq/table/add-pq-dialog.tsx +++ b/lib/pq/table/add-pq-dialog.tsx @@ -27,8 +27,12 @@ import { SelectTrigger, SelectValue, } from "@/components/ui/select" +import { Checkbox } from "@/components/ui/checkbox" import { useToast } from "@/hooks/use-toast" import { createPq, invalidatePqCache } from "../service" +import { ProjectSelector } from "@/components/ProjectSelector" +import { type Project } from "@/lib/rfqs/service" +import { ScrollArea } from "@/components/ui/scroll-area" // PQ 생성을 위한 Zod 스키마 정의 const createPqSchema = z.object({ @@ -36,10 +40,15 @@ const createPqSchema = z.object({ checkPoint: z.string().min(1, "Check point is required"), groupName: z.string().min(1, "Group is required"), description: z.string().optional(), - remarks: z.string().optional() + remarks: z.string().optional(), + // 프로젝트별 PQ 여부 체크박스 + isProjectSpecific: z.boolean().default(false), + // 프로젝트 관련 추가 필드는 isProjectSpecific가 true일 때만 필수 + contractInfo: z.string().optional(), + additionalRequirement: z.string().optional(), }); -type CreatePqInputType = z.infer<typeof createPqSchema>; +type CreatePqFormType = z.infer<typeof createPqSchema>; // 그룹 이름 옵션 const groupOptions = [ @@ -54,36 +63,71 @@ const descriptionExample = `Address : Tel. / Fax : e-mail :`; -export function AddPqDialog() { +interface AddPqDialogProps { + currentProjectId?: number | null; // 현재 선택된 프로젝트 ID (옵션) +} + +export function AddPqDialog({ currentProjectId }: AddPqDialogProps) { const [open, setOpen] = React.useState(false) const [isSubmitting, setIsSubmitting] = React.useState(false) + const [selectedProject, setSelectedProject] = React.useState<Project | null>(null) const router = useRouter() const { toast } = useToast() // react-hook-form 설정 - const form = useForm<CreatePqInputType>({ + const form = useForm<CreatePqFormType>({ resolver: zodResolver(createPqSchema), defaultValues: { code: "", checkPoint: "", groupName: groupOptions[0], description: "", - remarks: "" + remarks: "", + isProjectSpecific: !!currentProjectId, // 현재 프로젝트 ID가 있으면 기본값 true + contractInfo: "", + additionalRequirement: "", }, }) + // 프로젝트별 PQ 여부 상태 감시 + const isProjectSpecific = form.watch("isProjectSpecific") + + // 현재 프로젝트 ID가 있으면 선택된 프로젝트 설정 + React.useEffect(() => { + if (currentProjectId) { + form.setValue("isProjectSpecific", true) + } + }, [currentProjectId, form]) + // 예시 텍스트를 description 필드에 채우는 함수 const fillExampleText = () => { form.setValue("description", descriptionExample); }; - async function onSubmit(data: CreatePqInputType) { + async function onSubmit(data: CreatePqFormType) { try { setIsSubmitting(true) - + + // 서버 액션 호출용 데이터 준비 + const submitData = { + ...data, + projectId: data.isProjectSpecific ? selectedProject?.id || currentProjectId : null, + } + + // 프로젝트별 PQ인데 프로젝트가 선택되지 않은 경우 검증 + if (data.isProjectSpecific && !submitData.projectId) { + toast({ + title: "Error", + description: "Please select a project", + variant: "destructive", + }) + setIsSubmitting(false) + return + } + // 서버 액션 호출 - const result = await createPq(data) - + const result = await createPq(submitData) + if (!result.success) { toast({ title: "Error", @@ -94,20 +138,21 @@ export function AddPqDialog() { } await invalidatePqCache(); - + // 성공 시 처리 toast({ title: "Success", - description: "PQ criteria created successfully", + description: result.message || "PQ criteria created successfully", }) - + // 모달 닫고 폼 리셋 form.reset() + setSelectedProject(null) setOpen(false) - + // 페이지 새로고침 router.refresh() - + } catch (error) { console.error('Error creating PQ criteria:', error) toast({ @@ -123,10 +168,24 @@ export function AddPqDialog() { function handleDialogOpenChange(nextOpen: boolean) { if (!nextOpen) { form.reset() + setSelectedProject(null) } setOpen(nextOpen) } + // 프로젝트 선택 핸들러 + const handleProjectSelect = (project: Project | null) => { + // project가 null인 경우 선택 해제를 의미 + if (project === null) { + setSelectedProject(null); + // 필요한 경우 추가 처리 + return; + } + + // 기존 처리 - 프로젝트가 선택된 경우 + setSelectedProject(project); + } + return ( <Dialog open={open} onOpenChange={handleDialogOpenChange}> {/* 모달을 열기 위한 버튼 */} @@ -137,7 +196,7 @@ export function AddPqDialog() { </Button> </DialogTrigger> - <DialogContent className="sm:max-w-[550px]"> + <DialogContent className="sm:max-w-[600px]"> <DialogHeader> <DialogTitle>Create New PQ Criteria</DialogTitle> <DialogDescription> @@ -147,145 +206,241 @@ export function AddPqDialog() { {/* shadcn/ui Form을 이용해 react-hook-form과 연결 */} <Form {...form}> - <form onSubmit={form.handleSubmit(onSubmit)} className="space-y-4 py-2"> - {/* Code 필드 */} - <FormField - control={form.control} - name="code" - render={({ field }) => ( - <FormItem> - <FormLabel>Code <span className="text-destructive">*</span></FormLabel> - <FormControl> - <Input - placeholder="예: 1-1, A.2.3" - {...field} - /> - </FormControl> - <FormDescription> - PQ 항목의 고유 코드를 입력하세요 (예: "1-1", "A.2.3") - </FormDescription> - <FormMessage /> - </FormItem> - )} - /> - - {/* Check Point 필드 */} - <FormField - control={form.control} - name="checkPoint" - render={({ field }) => ( - <FormItem> - <FormLabel>Check Point <span className="text-destructive">*</span></FormLabel> - <FormControl> - <Input - placeholder="검증 항목을 입력하세요" - {...field} - /> - </FormControl> - <FormMessage /> - </FormItem> - )} - /> - - {/* Group Name 필드 (Select) */} - <FormField - control={form.control} - name="groupName" - render={({ field }) => ( - <FormItem> - <FormLabel>Group <span className="text-destructive">*</span></FormLabel> - <Select - onValueChange={field.onChange} - defaultValue={field.value} - value={field.value} - > + <form onSubmit={form.handleSubmit(onSubmit)} className="space-y-4 py-2 flex flex-col"> + {/* 프로젝트별 PQ 여부 체크박스 */} + + <div className="flex-1 overflow-auto px-4 space-y-4"> + <FormField + control={form.control} + name="isProjectSpecific" + render={({ field }) => ( + <FormItem className="flex flex-row items-start space-x-3 space-y-0 rounded-md border p-4"> <FormControl> - <SelectTrigger> - <SelectValue placeholder="그룹을 선택하세요" /> - </SelectTrigger> + <Checkbox + checked={field.value} + onCheckedChange={field.onChange} + /> </FormControl> - <SelectContent> - {groupOptions.map((group) => ( - <SelectItem key={group} value={group}> - {group} - </SelectItem> - ))} - </SelectContent> - </Select> + <div className="space-y-1 leading-none"> + <FormLabel>프로젝트별 PQ 생성</FormLabel> + <FormDescription> + 특정 프로젝트에만 적용되는 PQ 항목을 생성합니다 + </FormDescription> + </div> + </FormItem> + )} + /> + + {/* 프로젝트 선택 필드 (프로젝트별 PQ 선택 시에만 표시) */} + {isProjectSpecific && ( + <div className="space-y-2"> + <FormLabel>Project <span className="text-destructive">*</span></FormLabel> + <ProjectSelector + selectedProjectId={currentProjectId || selectedProject?.id} + onProjectSelect={handleProjectSelect} + placeholder="프로젝트를 선택하세요" + /> <FormDescription> - PQ 항목의 분류 그룹을 선택하세요 + PQ 항목을 적용할 프로젝트를 선택하세요 </FormDescription> - <FormMessage /> - </FormItem> + </div> )} - /> - - {/* Description 필드 - 예시 템플릿 버튼 추가 */} - <FormField - control={form.control} - name="description" - render={({ field }) => ( - <FormItem> - <div className="flex items-center justify-between"> - <FormLabel>Description</FormLabel> - <Button - type="button" - variant="outline" - size="sm" - onClick={fillExampleText} - > - 예시 채우기 - </Button> - </div> - <FormControl> - <Textarea - placeholder={`줄바꿈을 포함한 상세 설명을 입력하세요\n예:\n${descriptionExample}`} - className="min-h-[120px] font-mono" - {...field} - value={field.value || ""} + + <div className="flex-1 overflow-auto px-2 py-2 space-y-4" style={{maxHeight:420}}> + + + {/* Code 필드 */} + <FormField + control={form.control} + name="code" + render={({ field }) => ( + <FormItem> + <FormLabel>Code <span className="text-destructive">*</span></FormLabel> + <FormControl> + <Input + placeholder="예: 1-1, A.2.3" + {...field} + /> + </FormControl> + <FormDescription> + PQ 항목의 고유 코드를 입력하세요 (예: "1-1", "A.2.3") + </FormDescription> + <FormMessage /> + </FormItem> + )} + /> + + {/* Check Point 필드 */} + <FormField + control={form.control} + name="checkPoint" + render={({ field }) => ( + <FormItem> + <FormLabel>Check Point <span className="text-destructive">*</span></FormLabel> + <FormControl> + <Input + placeholder="검증 항목을 입력하세요" + {...field} + /> + </FormControl> + <FormMessage /> + </FormItem> + )} + /> + + {/* Group Name 필드 (Select) */} + <FormField + control={form.control} + name="groupName" + render={({ field }) => ( + <FormItem> + <FormLabel>Group <span className="text-destructive">*</span></FormLabel> + <Select + onValueChange={field.onChange} + defaultValue={field.value} + value={field.value} + > + <FormControl> + <SelectTrigger> + <SelectValue placeholder="그룹을 선택하세요" /> + </SelectTrigger> + </FormControl> + <SelectContent> + {groupOptions.map((group) => ( + <SelectItem key={group} value={group}> + {group} + </SelectItem> + ))} + </SelectContent> + </Select> + <FormDescription> + PQ 항목의 분류 그룹을 선택하세요 + </FormDescription> + <FormMessage /> + </FormItem> + )} + /> + + {/* Description 필드 - 예시 템플릿 버튼 추가 */} + <FormField + control={form.control} + name="description" + render={({ field }) => ( + <FormItem> + <div className="flex items-center justify-between"> + <FormLabel>Description</FormLabel> + <Button + type="button" + variant="outline" + size="sm" + onClick={fillExampleText} + > + 예시 채우기 + </Button> + </div> + <FormControl> + <Textarea + placeholder={`줄바꿈을 포함한 상세 설명을 입력하세요\n예:\n${descriptionExample}`} + className="min-h-[120px] font-mono" + {...field} + value={field.value || ""} + /> + </FormControl> + <FormDescription> + 줄바꿈이 필요한 경우 Enter 키를 누르세요. 입력한 대로 저장됩니다. + </FormDescription> + <FormMessage /> + </FormItem> + )} + /> + + {/* Remarks 필드 */} + <FormField + control={form.control} + name="remarks" + render={({ field }) => ( + <FormItem> + <FormLabel>Remarks</FormLabel> + <FormControl> + <Textarea + placeholder="비고 사항을 입력하세요" + className="min-h-[80px]" + {...field} + value={field.value || ""} + /> + </FormControl> + <FormMessage /> + </FormItem> + )} + /> + + {/* 프로젝트별 PQ일 경우 추가 필드 */} + {isProjectSpecific && ( + <> + {/* 계약 정보 필드 */} + <FormField + control={form.control} + name="contractInfo" + render={({ field }) => ( + <FormItem> + <FormLabel>Contract Info</FormLabel> + <FormControl> + <Textarea + placeholder="계약 관련 정보를 입력하세요" + className="min-h-[80px]" + {...field} + value={field.value || ""} + /> + </FormControl> + <FormDescription> + 해당 프로젝트의 계약 관련 특이사항 + </FormDescription> + <FormMessage /> + </FormItem> + )} /> - </FormControl> - <FormDescription> - 줄바꿈이 필요한 경우 Enter 키를 누르세요. 입력한 대로 저장됩니다. - </FormDescription> - <FormMessage /> - </FormItem> - )} - /> - - {/* Remarks 필드 */} - <FormField - control={form.control} - name="remarks" - render={({ field }) => ( - <FormItem> - <FormLabel>Remarks</FormLabel> - <FormControl> - <Textarea - placeholder="비고 사항을 입력하세요" - className="min-h-[80px]" - {...field} - value={field.value || ""} + + {/* 추가 요구사항 필드 */} + <FormField + control={form.control} + name="additionalRequirement" + render={({ field }) => ( + <FormItem> + <FormLabel>Additional Requirements</FormLabel> + <FormControl> + <Textarea + placeholder="추가 요구사항을 입력하세요" + className="min-h-[80px]" + {...field} + value={field.value || ""} + /> + </FormControl> + <FormDescription> + 프로젝트별 추가 요구사항 + </FormDescription> + <FormMessage /> + </FormItem> + )} /> - </FormControl> - <FormMessage /> - </FormItem> - )} - /> + </> + )} + </div> + </div> <DialogFooter> <Button type="button" variant="outline" onClick={() => { - form.reset(); - setOpen(false); - }} + form.reset(); + setSelectedProject(null); + setOpen(false); + }} > Cancel </Button> - <Button - type="submit" + <Button + type="submit" disabled={isSubmitting} > {isSubmitting ? "Creating..." : "Create"} |
