Files
motovaultpro/frontend/src/features/admin/catalog/catalogShared.ts
2025-11-06 16:29:11 -06:00

158 lines
4.2 KiB
TypeScript

import {
CatalogEngine,
CatalogMake,
CatalogModel,
CatalogTrim,
CatalogYear,
} from '../types/admin.types';
export type CatalogLevel = 'makes' | 'models' | 'years' | 'trims' | 'engines';
export type CatalogRow =
| CatalogMake
| CatalogModel
| CatalogYear
| CatalogTrim
| CatalogEngine;
export interface CatalogSelectionContext {
level: CatalogLevel;
make?: CatalogMake;
model?: CatalogModel;
year?: CatalogYear;
trim?: CatalogTrim;
}
export const LEVEL_LABEL: Record<CatalogLevel, string> = {
makes: 'Makes',
models: 'Models',
years: 'Years',
trims: 'Trims',
engines: 'Engines',
};
export const LEVEL_SINGULAR_LABEL: Record<CatalogLevel, string> = {
makes: 'Make',
models: 'Model',
years: 'Year',
trims: 'Trim',
engines: 'Engine',
};
export const NEXT_LEVEL: Record<CatalogLevel, CatalogLevel | null> = {
makes: 'models',
models: 'years',
years: 'trims',
trims: 'engines',
engines: null,
};
export const pluralize = (count: number, singular: string): string =>
`${count} ${singular}${count === 1 ? '' : 's'}`;
export const getCascadeSummary = (
level: CatalogLevel,
selectedItems: CatalogRow[],
modelsByMake: Map<string, CatalogModel[]>,
yearsByModel: Map<string, CatalogYear[]>,
trimsByYear: Map<string, CatalogTrim[]>,
enginesByTrim: Map<string, CatalogEngine[]>
): string => {
if (selectedItems.length === 0) {
return '';
}
if (level === 'engines') {
return 'Deleting engines will remove their configuration details.';
}
let modelCount = 0;
let yearCount = 0;
let trimCount = 0;
let engineCount = 0;
if (level === 'makes') {
selectedItems.forEach((item) => {
const make = item as CatalogMake;
const makeModels = modelsByMake.get(make.id) ?? [];
modelCount += makeModels.length;
makeModels.forEach((model) => {
const modelYears = yearsByModel.get(model.id) ?? [];
yearCount += modelYears.length;
modelYears.forEach((year) => {
const yearTrims = trimsByYear.get(year.id) ?? [];
trimCount += yearTrims.length;
yearTrims.forEach((trim) => {
const trimEngines = enginesByTrim.get(trim.id) ?? [];
engineCount += trimEngines.length;
});
});
});
});
return `Deleting ${selectedItems.length} ${LEVEL_LABEL.makes.toLowerCase()} will also remove ${pluralize(
modelCount,
'model'
)}, ${pluralize(yearCount, 'year')}, ${pluralize(
trimCount,
'trim'
)}, and ${pluralize(engineCount, 'engine')}.`;
}
if (level === 'models') {
selectedItems.forEach((item) => {
const model = item as CatalogModel;
const modelYears = yearsByModel.get(model.id) ?? [];
yearCount += modelYears.length;
modelYears.forEach((year) => {
const yearTrims = trimsByYear.get(year.id) ?? [];
trimCount += yearTrims.length;
yearTrims.forEach((trim) => {
const trimEngines = enginesByTrim.get(trim.id) ?? [];
engineCount += trimEngines.length;
});
});
});
return `Deleting ${selectedItems.length} ${LEVEL_LABEL.models.toLowerCase()} will also remove ${pluralize(
yearCount,
'year'
)}, ${pluralize(trimCount, 'trim')}, and ${pluralize(
engineCount,
'engine'
)}.`;
}
if (level === 'years') {
selectedItems.forEach((item) => {
const year = item as CatalogYear;
const yearTrims = trimsByYear.get(year.id) ?? [];
trimCount += yearTrims.length;
yearTrims.forEach((trim) => {
const trimEngines = enginesByTrim.get(trim.id) ?? [];
engineCount += trimEngines.length;
});
});
return `Deleting ${selectedItems.length} ${LEVEL_LABEL.years.toLowerCase()} will also remove ${pluralize(
trimCount,
'trim'
)} and ${pluralize(engineCount, 'engine')}.`;
}
if (level === 'trims') {
selectedItems.forEach((item) => {
const trim = item as CatalogTrim;
const trimEngines = enginesByTrim.get(trim.id) ?? [];
engineCount += trimEngines.length;
});
return `Deleting ${selectedItems.length} ${LEVEL_LABEL.trims.toLowerCase()} will also remove ${pluralize(
engineCount,
'engine'
)}.`;
}
return '';
};