import { createSearchParamsCache, parseAsArrayOf, parseAsInteger, parseAsString, parseAsStringEnum, } from "nuqs/server"; import * as z from "zod"; import { getFiltersStateParser, getSortingStateParser } from "@/lib/parsers"; import { Division, DomesticForeign, EvaluationTargetStatus, MaterialType, divisionMap, domesticForeignMap, vendortypeMap } from "@/types/evaluation"; // ============= 메인 검색 파라미터 스키마 ============= export const searchParamsEvaluationTargetsCache = 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(""), aggregated: z.boolean().default(false), }); // ============= 타입 정의 ============= export type GetEvaluationTargetsSchema = Awaited< ReturnType >; // ============= 필터 옵션 상수들 ============= export const EVALUATION_TARGET_FILTER_OPTIONS = { DIVISIONS: [ { value: "PLANT", label: "해양" }, { value: "SHIP", label: "조선" }, ], STATUSES: [ { value: "PENDING", label: "검토 중" }, { value: "CONFIRMED", label: "확정" }, { value: "EXCLUDED", label: "제외" }, ], DOMESTIC_FOREIGN: [ { value: "DOMESTIC", label: "내자" }, { value: "FOREIGN", label: "외자" }, ], MATERIAL_TYPES: [ { value: "EQUIPMENT", label: "장비재" }, { value: "BULK", label: "벌크" }, ], CONSENSUS_STATUS: [ { value: "true", label: "의견 일치" }, { value: "false", label: "의견 불일치" }, { value: "null", label: "검토 중" }, ], } as const; // ============= 유효성 검사 함수들 ============= export function validateEvaluationYear(year: number): boolean { const currentYear = new Date().getFullYear(); return year >= 2020 && year <= currentYear + 1; } export function validateDivision(division: string): division is Division { return ["PLANT", "SHIP"].includes(division); } export function validateStatus(status: string): status is EvaluationTargetStatus { return ["PENDING", "CONFIRMED", "EXCLUDED"].includes(status); } export function validateMaterialType(materialType: string): materialType is MaterialType { return ["EQUIPMENT", "BULK", "EQUIPMENT_BULK"].includes(materialType); } export function validateDomesticForeign(domesticForeign: string): domesticForeign is DomesticForeign { return ["DOMESTIC", "FOREIGN"].includes(domesticForeign); } // ============= 기본값 제공 함수들 ============= export function getDefaultEvaluationYear(): number { return new Date().getFullYear(); } // ============= 편의 함수들 ============= // 상태별 라벨 반환 export function getStatusLabel(status: EvaluationTargetStatus): string { const statusMap = { PENDING: "검토 중", CONFIRMED: "확정", EXCLUDED: "제외" }; return statusMap[status] || status; } // 구분별 라벨 반환 export function getDivisionLabel(division: Division): string { return divisionMap[division] || division; } // 자재구분별 라벨 반환 export function getMaterialTypeLabel(materialType: MaterialType): string { return vendortypeMap[materialType] || materialType; } // 내외자별 라벨 반환 export function getDomesticForeignLabel(domesticForeign: DomesticForeign): string { return domesticForeignMap[domesticForeign] || domesticForeign; } // ✅ 디버깅용 로그 함수 추가 export function logSearchParams(searchParams: any, source: string) { console.log(`=== ${source} - SearchParams ===`); console.log("Raw filters:", searchParams.filters); console.log("Raw joinOperator:", searchParams.joinOperator); if (typeof searchParams.filters === 'string') { try { const parsed = JSON.parse(searchParams.filters); console.log("Parsed filters:", parsed); } catch (e) { console.error("Filter parsing error:", e); } } }