summaryrefslogtreecommitdiff
path: root/lib/pq/table/add-pq-dialog.tsx
diff options
context:
space:
mode:
authordujinkim <dujin.kim@dtsolution.co.kr>2025-04-02 09:54:08 +0000
committerdujinkim <dujin.kim@dtsolution.co.kr>2025-04-02 09:54:08 +0000
commitdfdfae3018f8499240f48d28ce634f4a5c56e006 (patch)
tree4493b172c061fa5bf4e94c083788110eb1507f6d /lib/pq/table/add-pq-dialog.tsx
parent21a72eeddc74cf775e2a76e2c569de970bd62a7f (diff)
벤더 코멘트 처리
Diffstat (limited to 'lib/pq/table/add-pq-dialog.tsx')
-rw-r--r--lib/pq/table/add-pq-dialog.tsx431
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"}