79 lines
2.3 KiB
TypeScript
79 lines
2.3 KiB
TypeScript
import { Item } from '../models';
|
|
|
|
export function getDiscountedPrice(item: Item): number {
|
|
return item.price * (1 - (item.discount || 0) / 100);
|
|
}
|
|
|
|
export function getMainImage(item: Item): string {
|
|
// Support both backOffice format (imgs: string[]) and legacy (photos: Photo[])
|
|
if (item.imgs && item.imgs.length > 0) {
|
|
return item.imgs[0];
|
|
}
|
|
return item.photos?.[0]?.url || '/assets/images/placeholder.svg';
|
|
}
|
|
|
|
export function getAllImages(item: Item): string[] {
|
|
if (item.imgs && item.imgs.length > 0) {
|
|
return item.imgs;
|
|
}
|
|
return item.photos?.map(p => p.url) || [];
|
|
}
|
|
|
|
export function trackByItemId(index: number, item: Item): number | string {
|
|
return item.id || item.itemID;
|
|
}
|
|
|
|
/**
|
|
* Get the display description — supports both legacy HTML string
|
|
* and structured key-value pairs from backOffice API.
|
|
*/
|
|
export function hasStructuredDescription(item: Item): boolean {
|
|
return Array.isArray(item.descriptionFields) && item.descriptionFields.length > 0;
|
|
}
|
|
|
|
/**
|
|
* Compute stock status from quantity if the legacy `remainings` field is absent.
|
|
*/
|
|
export function getStockStatus(item: Item): string {
|
|
if (item.remainings) return item.remainings;
|
|
if (item.quantity == null) return 'high';
|
|
if (item.quantity <= 0) return 'out';
|
|
if (item.quantity <= 5) return 'low';
|
|
if (item.quantity <= 20) return 'medium';
|
|
return 'high';
|
|
}
|
|
|
|
/**
|
|
* Map backOffice badge names to CSS color classes.
|
|
*/
|
|
export function getBadgeClass(badge: string): string {
|
|
const map: Record<string, string> = {
|
|
'new': 'badge-new',
|
|
'sale': 'badge-sale',
|
|
'exclusive': 'badge-exclusive',
|
|
'hot': 'badge-hot',
|
|
'limited': 'badge-limited',
|
|
'bestseller': 'badge-bestseller',
|
|
'featured': 'badge-featured',
|
|
};
|
|
return map[badge.toLowerCase()] || 'badge-custom';
|
|
}
|
|
|
|
/**
|
|
* Get the translated name/description for the current language.
|
|
* Falls back to the default (base) field if no translation exists.
|
|
*/
|
|
export function getTranslatedField(
|
|
item: Item,
|
|
field: 'name' | 'simpleDescription',
|
|
lang: string
|
|
): string {
|
|
const translation = item.translations?.[lang];
|
|
if (translation && translation[field]) {
|
|
return translation[field]!;
|
|
}
|
|
if (field === 'name') return item.name;
|
|
if (field === 'simpleDescription') return item.simpleDescription || item.description || '';
|
|
return '';
|
|
}
|