From 53ad72732f781e6c6d5ddb3776ea47aec010af8e Mon Sep 17 00:00:00 2001 From: dujinkim Date: Mon, 4 Aug 2025 09:39:21 +0000 Subject: (최겸) PQ/실사 수정 및 개발 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/pq/helper.ts | 190 +- lib/pq/pq-criteria/add-pq-dialog.tsx | 344 + lib/pq/pq-criteria/delete-pqs-dialog.tsx | 149 + lib/pq/pq-criteria/import-pq-button.tsx | 270 + lib/pq/pq-criteria/import-pq-handler.tsx | 142 + lib/pq/pq-criteria/pq-excel-template.tsx | 205 + lib/pq/pq-criteria/pq-table-column.tsx | 232 + lib/pq/pq-criteria/pq-table-toolbar-actions.tsx | 86 + lib/pq/pq-criteria/pq-table.tsx | 127 + lib/pq/pq-criteria/update-pq-sheet.tsx | 330 + .../cancel-investigation-dialog.tsx | 136 +- .../edit-investigation-dialog.tsx | 217 + .../pq-review-table-new/feature-flags-provider.tsx | 216 +- lib/pq/pq-review-table-new/pq-container.tsx | 300 +- lib/pq/pq-review-table-new/pq-filter-sheet.tsx | 1300 ++-- .../request-investigation-dialog.tsx | 667 +- lib/pq/pq-review-table-new/send-results-dialog.tsx | 279 +- lib/pq/pq-review-table-new/site-visit-dialog.tsx | 711 +++ lib/pq/pq-review-table-new/user-combobox.tsx | 242 +- .../pq-review-table-new/vendors-table-columns.tsx | 1425 +++-- .../vendors-table-toolbar-actions.tsx | 756 +-- lib/pq/pq-review-table-new/vendors-table.tsx | 772 ++- lib/pq/pq-review-table/vendors-table-columns.tsx | 4 +- lib/pq/service.ts | 6559 +++++++++++--------- lib/pq/table/add-pq-dialog.tsx | 454 -- lib/pq/table/add-pq-list-dialog.tsx | 231 + lib/pq/table/copy-pq-list-dialog.tsx | 244 + lib/pq/table/delete-pq-list-dialog.tsx | 139 + lib/pq/table/delete-pqs-dialog.tsx | 149 - lib/pq/table/import-pq-button.tsx | 270 - lib/pq/table/import-pq-handler.tsx | 145 - lib/pq/table/pq-excel-template.tsx | 205 - lib/pq/table/pq-lists-columns.tsx | 216 + lib/pq/table/pq-lists-table.tsx | 170 + lib/pq/table/pq-lists-toolbar.tsx | 61 + lib/pq/table/pq-table-column.tsx | 185 - lib/pq/table/pq-table-toolbar-actions.tsx | 87 - lib/pq/table/pq-table.tsx | 127 - lib/pq/table/update-pq-sheet.tsx | 264 - lib/pq/validations.ts | 199 +- 40 files changed, 11077 insertions(+), 7728 deletions(-) create mode 100644 lib/pq/pq-criteria/add-pq-dialog.tsx create mode 100644 lib/pq/pq-criteria/delete-pqs-dialog.tsx create mode 100644 lib/pq/pq-criteria/import-pq-button.tsx create mode 100644 lib/pq/pq-criteria/import-pq-handler.tsx create mode 100644 lib/pq/pq-criteria/pq-excel-template.tsx create mode 100644 lib/pq/pq-criteria/pq-table-column.tsx create mode 100644 lib/pq/pq-criteria/pq-table-toolbar-actions.tsx create mode 100644 lib/pq/pq-criteria/pq-table.tsx create mode 100644 lib/pq/pq-criteria/update-pq-sheet.tsx create mode 100644 lib/pq/pq-review-table-new/edit-investigation-dialog.tsx create mode 100644 lib/pq/pq-review-table-new/site-visit-dialog.tsx delete mode 100644 lib/pq/table/add-pq-dialog.tsx create mode 100644 lib/pq/table/add-pq-list-dialog.tsx create mode 100644 lib/pq/table/copy-pq-list-dialog.tsx create mode 100644 lib/pq/table/delete-pq-list-dialog.tsx delete mode 100644 lib/pq/table/delete-pqs-dialog.tsx delete mode 100644 lib/pq/table/import-pq-button.tsx delete mode 100644 lib/pq/table/import-pq-handler.tsx delete mode 100644 lib/pq/table/pq-excel-template.tsx create mode 100644 lib/pq/table/pq-lists-columns.tsx create mode 100644 lib/pq/table/pq-lists-table.tsx create mode 100644 lib/pq/table/pq-lists-toolbar.tsx delete mode 100644 lib/pq/table/pq-table-column.tsx delete mode 100644 lib/pq/table/pq-table-toolbar-actions.tsx delete mode 100644 lib/pq/table/pq-table.tsx delete mode 100644 lib/pq/table/update-pq-sheet.tsx (limited to 'lib/pq') diff --git a/lib/pq/helper.ts b/lib/pq/helper.ts index 16aed0e4..efd50714 100644 --- a/lib/pq/helper.ts +++ b/lib/pq/helper.ts @@ -1,96 +1,96 @@ -import { - vendorPQSubmissions, - vendors, - projects, - users, - vendorInvestigations -} from "@/db/schema" -import { CustomColumnMapping } from "../filter-columns" - -/** - * Helper function to create custom column mapping for PQ submissions - */ -export function createPQFilterMapping(): CustomColumnMapping { - return { - // PQ 제출 관련 - pqNumber: { table: vendorPQSubmissions, column: "pqNumber" }, - status: { table: vendorPQSubmissions, column: "status" }, - type: { table: vendorPQSubmissions, column: "type" }, - createdAt: { table: vendorPQSubmissions, column: "createdAt" }, - updatedAt: { table: vendorPQSubmissions, column: "updatedAt" }, - submittedAt: { table: vendorPQSubmissions, column: "submittedAt" }, - approvedAt: { table: vendorPQSubmissions, column: "approvedAt" }, - rejectedAt: { table: vendorPQSubmissions, column: "rejectedAt" }, - - // 협력업체 관련 - vendorName: { table: vendors, column: "vendorName" }, - vendorCode: { table: vendors, column: "vendorCode" }, - taxId: { table: vendors, column: "taxId" }, - vendorStatus: { table: vendors, column: "status" }, - - // 프로젝트 관련 - projectName: { table: projects, column: "name" }, - projectCode: { table: projects, column: "code" }, - - // 요청자 관련 - requesterName: { table: users, column: "name" }, - requesterEmail: { table: users, column: "email" }, - - // 실사 관련 - evaluationResult: { table: vendorInvestigations, column: "evaluationResult" }, - evaluationType: { table: vendorInvestigations, column: "evaluationType" }, - investigationStatus: { table: vendorInvestigations, column: "investigationStatus" }, - investigationAddress: { table: vendorInvestigations, column: "investigationAddress" }, - qmManagerId: { table: vendorInvestigations, column: "qmManagerId" }, - } -} - -/** - * PQ 관련 조인 테이블들 - */ -export function getPQJoinedTables() { - return { - vendors, - projects, - users, - vendorInvestigations, - } -} - -/** - * 직접 컬럼 참조 방식의 매핑 (더 타입 안전) - */ -export function createPQDirectColumnMapping(): CustomColumnMapping { - return { - // PQ 제출 관련 - 직접 컬럼 참조 - pqNumber: vendorPQSubmissions.pqNumber, - status: vendorPQSubmissions.status, - type: vendorPQSubmissions.type, - createdAt: vendorPQSubmissions.createdAt, - updatedAt: vendorPQSubmissions.updatedAt, - submittedAt: vendorPQSubmissions.submittedAt, - approvedAt: vendorPQSubmissions.approvedAt, - rejectedAt: vendorPQSubmissions.rejectedAt, - - // 협력업체 관련 - vendorName: vendors.vendorName, - vendorCode: vendors.vendorCode, - taxId: vendors.taxId, - vendorStatus: vendors.status, - - // 프로젝트 관련 - projectName: projects.name, - projectCode: projects.code, - - // 요청자 관련 - requesterName: users.name, - requesterEmail: users.email, - - // 실사 관련 - evaluationResult: vendorInvestigations.evaluationResult, - evaluationType: vendorInvestigations.evaluationType, - investigationStatus: vendorInvestigations.investigationStatus, - investigationAddress: vendorInvestigations.investigationAddress, - qmManagerId: vendorInvestigations.qmManagerId, - } +import { + vendorPQSubmissions, + vendors, + projects, + users, + vendorInvestigations +} from "@/db/schema" +import { CustomColumnMapping } from "../filter-columns" + +/** + * Helper function to create custom column mapping for PQ submissions + */ +export function createPQFilterMapping(): CustomColumnMapping { + return { + // PQ 제출 관련 + pqNumber: { table: vendorPQSubmissions, column: "pqNumber" }, + status: { table: vendorPQSubmissions, column: "status" }, + type: { table: vendorPQSubmissions, column: "type" }, + createdAt: { table: vendorPQSubmissions, column: "createdAt" }, + updatedAt: { table: vendorPQSubmissions, column: "updatedAt" }, + submittedAt: { table: vendorPQSubmissions, column: "submittedAt" }, + approvedAt: { table: vendorPQSubmissions, column: "approvedAt" }, + rejectedAt: { table: vendorPQSubmissions, column: "rejectedAt" }, + + // 협력업체 관련 + vendorName: { table: vendors, column: "vendorName" }, + vendorCode: { table: vendors, column: "vendorCode" }, + taxId: { table: vendors, column: "taxId" }, + vendorStatus: { table: vendors, column: "status" }, + + // 프로젝트 관련 + projectName: { table: projects, column: "name" }, + projectCode: { table: projects, column: "code" }, + + // 요청자 관련 + requesterName: { table: users, column: "name" }, + requesterEmail: { table: users, column: "email" }, + + // 실사 관련 + evaluationResult: { table: vendorInvestigations, column: "evaluationResult" }, + evaluationType: { table: vendorInvestigations, column: "evaluationType" }, + investigationStatus: { table: vendorInvestigations, column: "investigationStatus" }, + investigationAddress: { table: vendorInvestigations, column: "investigationAddress" }, + qmManagerId: { table: vendorInvestigations, column: "qmManagerId" }, + } +} + +/** + * PQ 관련 조인 테이블들 + */ +export function getPQJoinedTables() { + return { + vendors, + projects, + users, + vendorInvestigations, + } +} + +/** + * 직접 컬럼 참조 방식의 매핑 (더 타입 안전) + */ +export function createPQDirectColumnMapping(): CustomColumnMapping { + return { + // PQ 제출 관련 - 직접 컬럼 참조 + pqNumber: vendorPQSubmissions.pqNumber, + status: vendorPQSubmissions.status, + type: vendorPQSubmissions.type, + createdAt: vendorPQSubmissions.createdAt, + updatedAt: vendorPQSubmissions.updatedAt, + submittedAt: vendorPQSubmissions.submittedAt, + approvedAt: vendorPQSubmissions.approvedAt, + rejectedAt: vendorPQSubmissions.rejectedAt, + + // 협력업체 관련 + vendorName: vendors.vendorName, + vendorCode: vendors.vendorCode, + taxId: vendors.taxId, + vendorStatus: vendors.status, + + // 프로젝트 관련 + projectName: projects.name, + projectCode: projects.code, + + // 요청자 관련 + requesterName: users.name, + requesterEmail: users.email, + + // 실사 관련 + evaluationResult: vendorInvestigations.evaluationResult, + evaluationType: vendorInvestigations.evaluationType, + investigationStatus: vendorInvestigations.investigationStatus, + investigationAddress: vendorInvestigations.investigationAddress, + qmManagerId: vendorInvestigations.qmManagerId, + } } \ No newline at end of file diff --git a/lib/pq/pq-criteria/add-pq-dialog.tsx b/lib/pq/pq-criteria/add-pq-dialog.tsx new file mode 100644 index 00000000..53fe28f1 --- /dev/null +++ b/lib/pq/pq-criteria/add-pq-dialog.tsx @@ -0,0 +1,344 @@ +"use client" + +import * as React from "react" +import { useForm } from "react-hook-form" +import { zodResolver } from "@hookform/resolvers/zod" +import { z } from "zod" +import { Plus } from "lucide-react" +import { useRouter } from "next/navigation" + +import { + Dialog, + DialogTrigger, + DialogContent, + DialogHeader, + DialogTitle, + DialogDescription, + DialogFooter +} from "@/components/ui/dialog" +import { Button } from "@/components/ui/button" +import { Input } from "@/components/ui/input" +import { Textarea } from "@/components/ui/textarea" +import { + Form, + FormControl, + FormDescription, + FormField, + FormItem, + FormLabel, + FormMessage, +} from "@/components/ui/form" +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from "@/components/ui/select" + +import { useToast } from "@/hooks/use-toast" +import { createPqCriteria } from "../service" + +// PQ 생성을 위한 Zod 스키마 정의 +const createPqSchema = z.object({ + code: z.string().min(1, "Code is required"), + checkPoint: z.string().min(1, "Check point is required"), + groupName: z.string().min(1, "Group is required"), + subGroupName: z.string().min(1, "Sub group is required"), + description: z.string().optional(), + remarks: z.string().optional(), + inputFormat: z.string().default("TEXT"), + +}); + +type CreatePqFormType = z.infer; + +// 그룹 이름 옵션 +export const groupOptions = [ + "GENERAL", + "QMS", + "Warranty", + "HSE+", + "기타", +]; + +// 입력 형식 옵션 +const inputFormatOptions = [ + { value: "TEXT", label: "텍스트" }, + { value: "FILE", label: "파일" }, + { value: "EMAIL", label: "이메일" }, + { value: "PHONE", label: "전화번호" }, + { value: "NUMBER", label: "숫자" }, + { value: "TEXT_FILE", label: "텍스트 + 파일" }, +]; + +interface AddPqDialogProps { + pqListId: number; +} + +export function AddPqDialog({ pqListId }: AddPqDialogProps) { + const [open, setOpen] = React.useState(false) + const [isSubmitting, setIsSubmitting] = React.useState(false) + const router = useRouter() + const { toast } = useToast() + + // react-hook-form 설정 + const form = useForm({ + resolver: zodResolver(createPqSchema), + defaultValues: { + code: "", + checkPoint: "", + groupName: groupOptions[0], + subGroupName: "", + description: "", + remarks: "", + inputFormat: "TEXT", + + }, + }) + const formState = form.formState + + async function onSubmit(data: CreatePqFormType) { + try { + setIsSubmitting(true) + + // 서버 액션 호출 + const result = await createPqCriteria(pqListId, data) + + if (!result.success) { + toast({ + title: "오류", + description: result.message || "PQ 항목 생성에 실패했습니다", + variant: "destructive", + }) + return + } + + // 성공 시 처리 + toast({ + title: "성공", + description: result.message || "PQ 항목이 성공적으로 생성되었습니다", + }) + + // 모달 닫고 폼 리셋 + form.reset() + setOpen(false) + + // 페이지 새로고침 + router.refresh() + + } catch (error) { + console.error('Error creating PQ criteria:', error) + toast({ + title: "오류", + description: "예상치 못한 오류가 발생했습니다", + variant: "destructive", + }) + } finally { + setIsSubmitting(false) + } + } + + function handleDialogOpenChange(nextOpen: boolean) { + if (!nextOpen) { + form.reset() + } + setOpen(nextOpen) + } + + return ( + + + + + + + + PQ 항목 생성 + + 새 PQ 항목을 추가합니다. + + + +
+ +
+ {/* Group Name 필드 */} + ( + + 대분류 * + + + + )} + /> + + {/* Sub Group Name 필드 */} + ( + + 소분류 * + + + + + 세부 분류를 위한 서브 그룹명을 입력하세요 (선택사항) + + + + )} + /> + {/* Code 필드 */} + ( + + 일련번호 * + + + + + PQ 항목의 고유 코드를 입력하세요 + + + + )} + /> + {/* Check Point 필드 */} + ( + + PQ 항목 * + + + + + + )} + /> + + {/* Input Format 필드 */} + ( + + 협력업체 입력사항 * + + + + )} + /> + + {/* Description 필드 */} + ( + + 설명 + +