diff options
Diffstat (limited to 'lib/tech-vendor-candidates/validations.ts')
| -rw-r--r-- | lib/tech-vendor-candidates/validations.ts | 148 |
1 files changed, 148 insertions, 0 deletions
diff --git a/lib/tech-vendor-candidates/validations.ts b/lib/tech-vendor-candidates/validations.ts new file mode 100644 index 00000000..d2ef4d53 --- /dev/null +++ b/lib/tech-vendor-candidates/validations.ts @@ -0,0 +1,148 @@ +import { techVendorCandidatesWithVendorInfo } from "@/db/schema/techVendors" +import { + createSearchParamsCache, + parseAsArrayOf, + parseAsInteger, + parseAsString, + parseAsStringEnum, +} from "nuqs/server" +import * as z from "zod" +import { getFiltersStateParser, getSortingStateParser } from "@/lib/parsers" + +export const searchParamsTechCandidateCache = createSearchParamsCache({ + // Common flags + flags: parseAsArrayOf(z.enum(["advancedTable", "floatingBar"])).withDefault([]), + from: parseAsString.withDefault(""), + to: parseAsString.withDefault(""), + // Paging + page: parseAsInteger.withDefault(1), + perPage: parseAsInteger.withDefault(10), + + // Sorting - adjusting for vendorInvestigationsView + sort: getSortingStateParser<typeof techVendorCandidatesWithVendorInfo.$inferSelect>().withDefault([ + { id: "createdAt", desc: true }, + ]), + + // Advanced filter + filters: getFiltersStateParser().withDefault([]), + joinOperator: parseAsStringEnum(["and", "or"]).withDefault("and"), + + // Global search + search: parseAsString.withDefault(""), + + // ----------------------------------------------------------------- + // Fields specific to vendor investigations + // ----------------------------------------------------------------- + + // investigationStatus: PLANNED, IN_PROGRESS, COMPLETED, CANCELED + status: parseAsStringEnum(["COLLECTED", "INVITED", "DISCARDED"]), + + // In case you also want to filter by vendorName, vendorCode, etc. + companyName: parseAsString.withDefault(""), + contactEmail: parseAsString.withDefault(""), + contactPhone: parseAsString.withDefault(""), + country: parseAsString.withDefault(""), + source: parseAsString.withDefault(""), + + +}) + +// Finally, export the type you can use in your server action: +export type GetTechVendorsCandidateSchema = Awaited<ReturnType<typeof searchParamsTechCandidateCache.parse>> + + +// Updated version of the updateVendorCandidateSchema +export const updateVendorCandidateSchema = z.object({ + id: z.number(), + // 필수 필드 + companyName: z.string().min(1, "회사명은 필수입니다").max(255), + // null을 명시적으로 처리 + contactEmail: z.union([ + z.string().email("유효한 이메일 형식이 아닙니다").max(255), + z.literal(''), + z.null() + ]).optional().transform(val => val === null ? '' : val), + contactPhone: z.union([z.string().max(50), z.literal(''), z.null()]).optional() + .transform(val => val === null ? '' : val), + country: z.union([z.string().max(100), z.literal(''), z.null()]).optional() + .transform(val => val === null ? '' : val), + // 필수 필드 + source: z.string().min(1, "출처는 필수입니다").max(100), + address: z.union([z.string(), z.literal(''), z.null()]).optional() + .transform(val => val === null ? '' : val), + taxId: z.union([z.string(), z.literal(''), z.null()]).optional() + .transform(val => val === null ? '' : val), + // 필수 필드 + items: z.string().min(1, "항목은 필수입니다"), + remark: z.union([z.string(), z.literal(''), z.null()]).optional() + .transform(val => val === null ? '' : val), + status: z.enum(["COLLECTED", "INVITED", "DISCARDED"]), + updatedAt: z.date().optional().default(() => new Date()), +});; + +// Create schema for vendor candidates +export const createVendorCandidateSchema = z.object({ + companyName: z.string().min(1, "회사명은 필수입니다").max(255), + // contactEmail을 필수값으로 변경 + contactEmail: z.string().min(1, "이메일은 필수입니다").email("유효한 이메일 형식이 아닙니다").max(255), + contactPhone: z.string().max(50).optional(), + country: z.string().max(100).optional(), + source: z.string().min(1, "출처는 필수입니다").max(100), + address: z.string().optional(), + taxId: z.string().optional(), + items: z.string().min(1, "항목은 필수입니다"), + remark: z.string().optional(), + vendorId: z.number().optional(), + status: z.enum(["COLLECTED", "INVITED", "DISCARDED"]).default("COLLECTED"), +}); + +// Export types for both schemas +export type UpdateVendorCandidateSchema = z.infer<typeof updateVendorCandidateSchema>; +export type CreateVendorCandidateSchema = z.infer<typeof createVendorCandidateSchema>; + + +export const removeCandidatesSchema = z.object({ + ids: z.array(z.number()).min(1, "At least one candidate ID must be provided"), +}); + +export type RemoveCandidatesInput = z.infer<typeof removeCandidatesSchema>; + +// 기술영업 벤더 후보 생성 스키마 +export const createTechVendorCandidateSchema = z.object({ + companyName: z.string().min(1, "Company name is required"), + contactEmail: z.string().email("Invalid email").optional(), + contactPhone: z.string().optional(), + taxId: z.string().optional(), + address: z.string().optional(), + country: z.string().optional(), + source: z.string().optional(), + status: z.enum(["COLLECTED", "INVITED", "DISCARDED"]).default("COLLECTED"), + remark: z.string().optional(), + items: z.string().min(1, "Items are required"), + vendorId: z.number().optional(), +}); + +// 기술영업 벤더 후보 업데이트 스키마 +export const updateTechVendorCandidateSchema = z.object({ + id: z.number(), + companyName: z.string().min(1, "Company name is required").optional(), + contactEmail: z.string().email("Invalid email").optional(), + contactPhone: z.string().optional(), + taxId: z.string().optional(), + address: z.string().optional(), + country: z.string().optional(), + source: z.string().optional(), + status: z.enum(["COLLECTED", "INVITED", "DISCARDED"]).optional(), + remark: z.string().optional(), + items: z.string().optional(), + vendorId: z.number().optional(), +}); + +// 기술영업 벤더 후보 삭제 스키마 +export const removeTechCandidatesSchema = z.object({ + ids: z.array(z.number()).min(1, "At least one ID is required"), +}); + +export type CreateTechVendorCandidateSchema = z.infer<typeof createTechVendorCandidateSchema> +export type UpdateTechVendorCandidateSchema = z.infer<typeof updateTechVendorCandidateSchema> +export type RemoveTechCandidatesInput = z.infer<typeof removeTechCandidatesSchema>
\ No newline at end of file |
