fix(catalog): filter UX and tablet layout
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:
@@ -83,6 +83,36 @@ export class SearchFacade {
|
||||
const categories = this.collectUnique(products.map(product => String(product.categoryID)).filter(Boolean));
|
||||
const subcategories = this.collectUnique(products.map(product => product.subcategoryId ?? '').filter(Boolean));
|
||||
const attributes = this.collectUnique(products.flatMap(product => (product.descriptionFields ?? []).map(field => field.key)));
|
||||
const availabilityCounts = products.reduce<Record<string, number>>((acc, product) => {
|
||||
const key = product.remainings === 'out'
|
||||
? 'out-of-stock'
|
||||
: product.remainings === 'low'
|
||||
? 'low-stock'
|
||||
: 'in-stock';
|
||||
acc[key] = (acc[key] ?? 0) + 1;
|
||||
return acc;
|
||||
}, {});
|
||||
const availabilityBase = [
|
||||
{ id: 'in-stock', label: this.translate.t('catalog.filterInStock'), value: 'in-stock', availability: 'in-stock' as const },
|
||||
{ id: 'low-stock', label: this.translate.t('catalog.filterLowStock'), value: 'low-stock', availability: 'low-stock' as const },
|
||||
{ id: 'out-of-stock', label: this.translate.t('catalog.filterOutOfStock'), value: 'out-of-stock', availability: 'out-of-stock' as const },
|
||||
];
|
||||
const availabilityOptions = availabilityBase
|
||||
.filter(option => (availabilityCounts[option.value] ?? 0) > 0)
|
||||
.map(option => ({ ...option, count: availabilityCounts[option.value] }));
|
||||
const ratingOptions = this.collectUnique(
|
||||
products
|
||||
.map(product => String(Math.max(1, Math.min(5, Math.floor(product.rating || 0)))))
|
||||
.filter(value => Number(value) > 0)
|
||||
)
|
||||
.map(value => Number(value))
|
||||
.sort((a, b) => b - a)
|
||||
.map(value => ({
|
||||
id: `rating-${value}`,
|
||||
label: this.translate.t('catalog.filterStars', { count: value }),
|
||||
value: String(value),
|
||||
rating: value,
|
||||
}));
|
||||
|
||||
const groups: FilterGroup[] = [
|
||||
{
|
||||
@@ -99,23 +129,14 @@ export class SearchFacade {
|
||||
id: 'availability',
|
||||
label: this.translate.t('catalog.filterAvailability'),
|
||||
type: 'availability',
|
||||
options: [
|
||||
{ id: 'in-stock', label: this.translate.t('catalog.filterInStock'), value: 'in-stock', availability: 'in-stock' },
|
||||
{ id: 'low-stock', label: this.translate.t('catalog.filterLowStock'), value: 'low-stock', availability: 'low-stock' },
|
||||
{ id: 'out-of-stock', label: this.translate.t('catalog.filterOutOfStock'), value: 'out-of-stock', availability: 'out-of-stock' },
|
||||
],
|
||||
options: availabilityOptions,
|
||||
enabled: enabled.has('availability'),
|
||||
},
|
||||
{
|
||||
id: 'rating',
|
||||
label: this.translate.t('catalog.filterRating'),
|
||||
type: 'rating',
|
||||
options: [5, 4, 3, 2, 1].map(value => ({
|
||||
id: `rating-${value}`,
|
||||
label: this.translate.t('catalog.filterStars', { count: value }),
|
||||
value: String(value),
|
||||
rating: value,
|
||||
})),
|
||||
options: ratingOptions,
|
||||
enabled: enabled.has('rating'),
|
||||
},
|
||||
{
|
||||
@@ -403,7 +424,12 @@ export class SearchFacade {
|
||||
}
|
||||
|
||||
private toColorHex(value: string): string {
|
||||
const normalized = value.toLowerCase();
|
||||
const normalized = value.trim().toLowerCase();
|
||||
|
||||
if (/^#([0-9a-f]{3}|[0-9a-f]{6})$/i.test(normalized)) {
|
||||
return normalized;
|
||||
}
|
||||
|
||||
const palette: Record<string, string> = {
|
||||
black: '#111111',
|
||||
white: '#ffffff',
|
||||
@@ -418,8 +444,27 @@ export class SearchFacade {
|
||||
grey: '#6b7280',
|
||||
brown: '#92400e',
|
||||
beige: '#d6c6a8',
|
||||
navy: '#1e3a8a',
|
||||
cyan: '#06b6d4',
|
||||
teal: '#0d9488',
|
||||
lime: '#65a30d',
|
||||
olive: '#4d7c0f',
|
||||
maroon: '#7f1d1d',
|
||||
silver: '#94a3b8',
|
||||
gold: '#eab308',
|
||||
};
|
||||
|
||||
return palette[normalized] ?? '#94a3b8';
|
||||
if (palette[normalized]) {
|
||||
return palette[normalized];
|
||||
}
|
||||
|
||||
const tokens = normalized.split(/[\s,\-/]+/).filter(Boolean);
|
||||
for (const token of tokens) {
|
||||
if (palette[token]) {
|
||||
return palette[token];
|
||||
}
|
||||
}
|
||||
|
||||
return '#94a3b8';
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user