feat(catalog): implement sprint 10 advanced search experience
Some checks failed
Architecture Governance / architecture (push) Has been cancelled
Some checks failed
Architecture Governance / architecture (push) Has been cancelled
This commit is contained in:
86
src/app/core/products/models/catalog-experience.model.ts
Normal file
86
src/app/core/products/models/catalog-experience.model.ts
Normal file
@@ -0,0 +1,86 @@
|
||||
import { Product, ProductListResult, ProductSort } from './product-domain.model';
|
||||
|
||||
export type CatalogLayoutMode = 'grid' | 'large-grid' | 'compact-grid' | 'list';
|
||||
export type CatalogNavigationMode = 'default' | 'left-category-navigation' | 'mega-category-layout' | 'top-category-carousel';
|
||||
|
||||
export interface SearchCriteria {
|
||||
keyword?: string;
|
||||
categoryIDs?: number[];
|
||||
subcategoryIDs?: string[];
|
||||
minPrice?: number;
|
||||
maxPrice?: number;
|
||||
availability?: Array<'in-stock' | 'low-stock' | 'out-of-stock'>;
|
||||
rating?: number[];
|
||||
brand?: string[];
|
||||
discountOnly?: boolean;
|
||||
newOnly?: boolean;
|
||||
color?: string[];
|
||||
size?: string[];
|
||||
attributes?: Record<string, string[]>;
|
||||
sort?: ProductSort | 'discount';
|
||||
page?: number;
|
||||
pageSize?: number;
|
||||
}
|
||||
|
||||
export type FilterValueType = 'multi-select' | 'range' | 'toggle';
|
||||
|
||||
export interface FilterOption {
|
||||
id: string;
|
||||
label: string;
|
||||
value: string;
|
||||
count?: number;
|
||||
}
|
||||
|
||||
export interface FilterDefinition {
|
||||
id: string;
|
||||
label: string;
|
||||
type: FilterValueType;
|
||||
options?: FilterOption[];
|
||||
min?: number;
|
||||
max?: number;
|
||||
step?: number;
|
||||
enabled?: boolean;
|
||||
}
|
||||
|
||||
export interface SortDefinition {
|
||||
id: ProductSort | 'discount';
|
||||
label: string;
|
||||
enabled?: boolean;
|
||||
}
|
||||
|
||||
export interface CatalogView {
|
||||
layout: CatalogLayoutMode;
|
||||
navigationMode: CatalogNavigationMode;
|
||||
showBreadcrumbs: boolean;
|
||||
showCategoryBanner: boolean;
|
||||
showSubcategoryChips: boolean;
|
||||
showRatings: boolean;
|
||||
showDiscounts: boolean;
|
||||
showAvailability: boolean;
|
||||
}
|
||||
|
||||
export interface SearchResult {
|
||||
criteria: SearchCriteria;
|
||||
items: Product[];
|
||||
total: number;
|
||||
page: number;
|
||||
pageSize: number;
|
||||
summary: string;
|
||||
}
|
||||
|
||||
export function toSearchResult(result: ProductListResult, criteria: SearchCriteria): SearchResult {
|
||||
const pageSize = Math.max(1, criteria.pageSize ?? result.count ?? 24);
|
||||
const page = Math.max(1, criteria.page ?? Math.floor((result.skip ?? 0) / pageSize) + 1);
|
||||
const keyword = (criteria.keyword ?? '').trim();
|
||||
|
||||
return {
|
||||
criteria,
|
||||
items: result.items,
|
||||
total: result.total,
|
||||
page,
|
||||
pageSize,
|
||||
summary: keyword.length > 0
|
||||
? `Results for "${keyword}" (${result.total})`
|
||||
: `Products found: ${result.total}`
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user