// lib/rfq/validation.ts import { createSearchParamsCache, parseAsArrayOf, parseAsInteger, parseAsString, parseAsStringEnum, } from "nuqs/server"; import * as z from "zod"; import { getFiltersStateParser, getSortingStateParser } from "@/lib/parsers"; import { RfqLastAttachments } from "@/db/schema"; // RFQ 상태 옵션 export const RFQ_STATUS_OPTIONS = [ { value: "RFQ 생성", label: "RFQ 생성" }, { value: "구매담당지정", label: "구매담당지정" }, { value: "견적요청문서 확정", label: "견적요청문서 확정" }, { value: "Short List 확정", label: "Short List 확정" }, { value: "TBE 완료", label: "TBE 완료" }, { value: "RFQ 발송", label: "RFQ 발송" }, { value: "견적접수", label: "견적접수" }, { value: "최종업체선정", label: "최종업체선정" }, ]; // 시리즈 옵션 export const SERIES_OPTIONS = [ { value: "SS", label: "시리즈 통합" }, { value: "II", label: "품목 통합" }, { value: "", label: "통합 없음" }, ]; // RFQ 카테고리 (탭 구분용) export const RFQ_CATEGORY_OPTIONS = [ { value: "all", label: "전체" }, { value: "general", label: "일반견적" }, { value: "itb", label: "ITB" }, { value: "rfq", label: "RFQ" }, ]; // ============= 메인 검색 파라미터 스키마 ============= export const searchParamsRfqCache = createSearchParamsCache({ flags: parseAsArrayOf(z.enum(["advancedTable", "floatingBar"])).withDefault([]), page: parseAsInteger.withDefault(1), perPage: parseAsInteger.withDefault(10), sort: getSortingStateParser().withDefault([ { id: "createdAt", desc: true }, ]), filters: getFiltersStateParser().withDefault([]), joinOperator: parseAsStringEnum(["and", "or"]).withDefault("and"), // 검색 search: parseAsString.withDefault(""), // RFQ 카테고리 (전체/일반견적/ITB/RFQ) rfqCategory: parseAsStringEnum(["all", "general", "itb", "rfq"]).withDefault("all"), }); // ============= 타입 정의 ============= export type GetRfqsSchema = Awaited< ReturnType >; // 공통 탭 파라미터 export const searchParamsRfqTabCache = createSearchParamsCache({ tab: parseAsStringEnum(['design', 'purchase']).withDefault('design'), }) // 설계 탭 전용 파라미터 export const searchParamsRfqDesignCache = createSearchParamsCache({ design_page: parseAsInteger.withDefault(1), design_perPage: parseAsInteger.withDefault(10), design_sort: getSortingStateParser().withDefault([ { id: "createdAt", desc: true }, ]), design_search: parseAsString.withDefault(""), design_fileType: parseAsArrayOf(z.string()).withDefault([]), design_filters: getFiltersStateParser().withDefault([]), design_joinOperator: parseAsStringEnum(["and", "or"]).withDefault("and"), }) // 구매 탭 전용 파라미터 export const searchParamsRfqPurchaseCache = createSearchParamsCache({ purchase_page: parseAsInteger.withDefault(1), purchase_perPage: parseAsInteger.withDefault(10), purchase_sort: getSortingStateParser().withDefault([ { id: "createdAt", desc: true }, ]), purchase_search: parseAsString.withDefault(""), purchase_fileType: parseAsArrayOf(z.string()).withDefault([]), purchase_filters: getFiltersStateParser().withDefault([]), purchase_joinOperator: parseAsStringEnum(["and", "or"]).withDefault("and"), }) // 통합 파라미터 캐시 (모든 파라미터를 한 번에 파싱) export const searchParamsRfqAttachmentsCache = createSearchParamsCache({ // 공통 tab: parseAsStringEnum(['design', 'purchase']).withDefault('design'), flags: parseAsArrayOf(z.enum(["advancedTable", "floatingBar"])).withDefault([]), // 설계 탭 파라미터 design_page: parseAsInteger.withDefault(1), design_perPage: parseAsInteger.withDefault(10), design_sort: getSortingStateParser().withDefault([ { id: "createdAt", desc: true }, ]), design_search: parseAsString.withDefault(""), design_fileType: parseAsArrayOf(z.string()).withDefault([]), design_filters: getFiltersStateParser().withDefault([]), design_joinOperator: parseAsStringEnum(["and", "or"]).withDefault("and"), // 구매 탭 파라미터 purchase_page: parseAsInteger.withDefault(1), purchase_perPage: parseAsInteger.withDefault(10), purchase_sort: getSortingStateParser().withDefault([ { id: "createdAt", desc: true }, ]), purchase_search: parseAsString.withDefault(""), purchase_fileType: parseAsArrayOf(z.string()).withDefault([]), purchase_filters: getFiltersStateParser().withDefault([]), purchase_joinOperator: parseAsStringEnum(["and", "or"]).withDefault("and"), }) // 타입 정의 export type GetRfqLastAttachmentsSchema = { page: number perPage: number sort: Array<{ id: string; desc: boolean }> search: string fileType: string[] filters: any[] joinOperator: "and" | "or" attachmentType?: string[] } // 헬퍼 함수: prefix가 붙은 파라미터를 일반 파라미터로 변환 export function extractTabParams( allParams: Awaited>, tabPrefix: 'design' | 'purchase' ): GetRfqLastAttachmentsSchema { const prefix = `${tabPrefix}_` return { page: allParams[`${prefix}page` as keyof typeof allParams] as number, perPage: allParams[`${prefix}perPage` as keyof typeof allParams] as number, sort: allParams[`${prefix}sort` as keyof typeof allParams] as any, search: allParams[`${prefix}search` as keyof typeof allParams] as string, fileType: allParams[`${prefix}fileType` as keyof typeof allParams] as string[], filters: allParams[`${prefix}filters` as keyof typeof allParams] as any[], joinOperator: allParams[`${prefix}joinOperator` as keyof typeof allParams] as "and" | "or", } }