Files
motovaultpro/frontend/src/features/admin/catalog/catalogSchemas.ts
2025-12-21 19:56:52 -06:00

152 lines
3.6 KiB
TypeScript

import { z } from 'zod';
import {
CatalogLevel,
CatalogRow,
CatalogSelectionContext,
} from './catalogShared';
import {
CatalogMake,
CatalogModel,
CatalogYear,
CatalogTrim,
CatalogEngine,
} from '../types/admin.types';
export type CatalogFormValues = {
name?: string;
makeId?: string;
modelId?: string;
year?: number;
yearId?: string;
trimId?: string;
displacement?: string;
cylinders?: number;
fuelType?: string;
};
export const makeSchema = z.object({
name: z.string().min(1, 'Name is required'),
});
export const modelSchema = z.object({
name: z.string().min(1, 'Name is required'),
makeId: z.coerce.string().min(1, 'Select a make'),
});
export const yearSchema = z.object({
modelId: z.coerce.string().min(1, 'Select a model'),
year: z
.coerce.number()
.int()
.min(1900, 'Enter a valid year')
.max(2100, 'Enter a valid year'),
});
export const trimSchema = z.object({
name: z.string().min(1, 'Name is required'),
yearId: z.coerce.string().min(1, 'Select a year'),
});
export const engineSchema = z.object({
name: z.string().min(1, 'Name is required'),
trimId: z.coerce.string().min(1, 'Select a trim'),
displacement: z.string().optional(),
cylinders: z
.preprocess(
(value) =>
value === '' || value === null || value === undefined
? undefined
: Number(value),
z
.number()
.int()
.positive('Cylinders must be positive')
.optional()
),
fuelType: z.string().optional(),
});
export const getSchemaForLevel = (level: CatalogLevel) => {
switch (level) {
case 'makes':
return makeSchema;
case 'models':
return modelSchema;
case 'years':
return yearSchema;
case 'trims':
return trimSchema;
case 'engines':
return engineSchema;
default:
return makeSchema;
}
};
export const buildDefaultValues = (
level: CatalogLevel,
mode: 'create' | 'edit',
entity: CatalogRow | undefined,
context: CatalogSelectionContext
): CatalogFormValues => {
if (mode === 'edit' && entity) {
switch (level) {
case 'makes':
return { name: (entity as CatalogMake).name };
case 'models':
return {
name: (entity as CatalogModel).name,
makeId: String((entity as CatalogModel).makeId),
};
case 'years':
return {
modelId: String((entity as CatalogYear).modelId),
year: (entity as CatalogYear).year,
};
case 'trims':
return {
name: (entity as CatalogTrim).name,
yearId: String((entity as CatalogTrim).yearId),
};
case 'engines':
return {
name: (entity as CatalogEngine).name,
trimId: String((entity as CatalogEngine).trimId),
displacement: (entity as CatalogEngine).displacement ?? undefined,
cylinders: (entity as CatalogEngine).cylinders ?? undefined,
fuelType: (entity as CatalogEngine).fuelType ?? undefined,
};
default:
return {};
}
}
switch (level) {
case 'models':
return {
name: '',
makeId: context.make?.id ? String(context.make.id) : '',
};
case 'years':
return {
modelId: context.model?.id ? String(context.model.id) : '',
year: undefined,
};
case 'trims':
return {
name: '',
yearId: context.year?.id ? String(context.year.id) : '',
};
case 'engines':
return {
name: '',
trimId: context.trim?.id ? String(context.trim.id) : '',
displacement: '',
fuelType: '',
};
case 'makes':
default:
return { name: '' };
}
};