1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
|
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<any>().withDefault([
{ id: "createdAt", desc: true },
]),
// 기본 필터들
evaluationYear: parseAsInteger.withDefault(new Date().getFullYear()),
division: parseAsString.withDefault(""),
status: parseAsString.withDefault(""),
domesticForeign: parseAsString.withDefault(""),
materialType: parseAsString.withDefault(""),
consensusStatus: parseAsString.withDefault(""),
// 고급 필터
filters: getFiltersStateParser().withDefault([]),
joinOperator: parseAsStringEnum(["and", "or"]).withDefault("and"),
// 베이직 필터 (커스텀 필터 패널용)
basicFilters: getFiltersStateParser().withDefault([]),
basicJoinOperator: parseAsStringEnum(["and", "or"]).withDefault("and"),
// 검색
search: parseAsString.withDefault(""),
});
// ============= 타입 정의 =============
export type GetEvaluationTargetsSchema = Awaited<
ReturnType<typeof searchParamsEvaluationTargetsCache.parse>
>;
// ============= 필터 옵션 상수들 =============
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: "벌크" },
{ value: "EQUIPMENT_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 getDefaultSearchParams(): GetEvaluationTargetsSchema {
return {
flags: [],
page: 1,
perPage: 10,
sort: [{ id: "createdAt", desc: true }],
evaluationYear: getDefaultEvaluationYear(),
division: "",
status: "",
domesticForeign: "",
materialType: "",
consensusStatus: "",
filters: [],
joinOperator: "and",
basicFilters: [],
basicJoinOperator: "and",
search: "",
};
}
// ============= 편의 함수들 =============
// 상태별 라벨 반환
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;
}
|