Compare commits
1 Commits
8a68be797a
...
main-backu
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
905c8be8c5 |
@@ -31,8 +31,14 @@ export interface Subcategory {
|
|||||||
itemCount?: number;
|
itemCount?: number;
|
||||||
hasItems?: boolean;
|
hasItems?: boolean;
|
||||||
subcategories?: Subcategory[];
|
subcategories?: Subcategory[];
|
||||||
|
names?: ItemName[];
|
||||||
|
translations?: Record<string, SubcategoryTranslation>;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface CategoryTranslation {
|
interface CategoryTranslation {
|
||||||
name?: string;
|
name?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface SubcategoryTranslation {
|
||||||
|
name?: string;
|
||||||
|
}
|
||||||
|
|||||||
@@ -401,7 +401,7 @@ export class CartComponent implements OnDestroy {
|
|||||||
telegramUserId: telegramUserId,
|
telegramUserId: telegramUserId,
|
||||||
items: this.paidItems.map((item: CartItem) => ({
|
items: this.paidItems.map((item: CartItem) => ({
|
||||||
itemID: item.itemID,
|
itemID: item.itemID,
|
||||||
name: item.name,
|
name: this.itemName(item),
|
||||||
price: item.discount > 0
|
price: item.discount > 0
|
||||||
? item.price * (1 - item.discount / 100)
|
? item.price * (1 - item.discount / 100)
|
||||||
: item.price,
|
: item.price,
|
||||||
@@ -470,7 +470,7 @@ export class CartComponent implements OnDestroy {
|
|||||||
telegramUserId: this.getTelegramUserId(),
|
telegramUserId: this.getTelegramUserId(),
|
||||||
items: this.paidItems.map((item: CartItem) => ({
|
items: this.paidItems.map((item: CartItem) => ({
|
||||||
itemID: item.itemID,
|
itemID: item.itemID,
|
||||||
name: item.name,
|
name: this.itemName(item),
|
||||||
price: item.discount > 0
|
price: item.discount > 0
|
||||||
? item.price * (1 - item.discount / 100)
|
? item.price * (1 - item.discount / 100)
|
||||||
: item.price,
|
: item.price,
|
||||||
|
|||||||
@@ -52,7 +52,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<button class="add-to-cart-btn" (click)="addToCart(item.itemID, $event)" [attr.aria-label]="('category.addToCart' | translate) + ': ' + item.name">
|
<button class="add-to-cart-btn" (click)="addToCart(item.itemID, $event)" [attr.aria-label]="('category.addToCart' | translate) + ': ' + itemName(item)">
|
||||||
{{ 'category.addToCart' | translate }}
|
{{ 'category.addToCart' | translate }}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -25,13 +25,13 @@
|
|||||||
<a [routerLink]="['/category', sub.id] | langRoute" class="category-card">
|
<a [routerLink]="['/category', sub.id] | langRoute" class="category-card">
|
||||||
<div class="category-image">
|
<div class="category-image">
|
||||||
@if (sub.img) {
|
@if (sub.img) {
|
||||||
<img [src]="sub.img" [alt]="sub.name" loading="lazy" decoding="async" />
|
<img [src]="sub.img" [alt]="categoryName(sub)" loading="lazy" decoding="async" />
|
||||||
} @else {
|
} @else {
|
||||||
<div class="category-fallback">{{ sub.name.charAt(0) }}</div>
|
<div class="category-fallback">{{ categoryName(sub).charAt(0) }}</div>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
<div class="category-info">
|
<div class="category-info">
|
||||||
<h3 class="category-name">{{ sub.name }}</h3>
|
<h3 class="category-name">{{ categoryName(sub) }}</h3>
|
||||||
@if (sub.itemCount) {
|
@if (sub.itemCount) {
|
||||||
<span class="category-count">{{ sub.itemCount }}</span>
|
<span class="category-count">{{ sub.itemCount }}</span>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -150,5 +150,5 @@ export class SubcategoriesComponent implements OnInit, OnDestroy {
|
|||||||
|
|
||||||
itemName(item: Item): string { return getTranslatedField(item, 'name', this.langService.currentLanguage()); }
|
itemName(item: Item): string { return getTranslatedField(item, 'name', this.langService.currentLanguage()); }
|
||||||
|
|
||||||
categoryName(cat: Category): string { return getTranslatedCategoryName(cat, this.langService.currentLanguage()); }
|
categoryName(cat: Category | Subcategory): string { return getTranslatedCategoryName(cat, this.langService.currentLanguage()); }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
@if (item()!.photos![selectedPhotoIndex()]?.video) {
|
@if (item()!.photos![selectedPhotoIndex()]?.video) {
|
||||||
<video [src]="item()!.photos![selectedPhotoIndex()].url" controls></video>
|
<video [src]="item()!.photos![selectedPhotoIndex()].url" controls></video>
|
||||||
} @else {
|
} @else {
|
||||||
<img [src]="item()!.photos![selectedPhotoIndex()].url" [alt]="item()!.name" />
|
<img [src]="item()!.photos![selectedPhotoIndex()].url" [alt]="getItemName()" />
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -337,7 +337,7 @@
|
|||||||
@if (item()!.photos![selectedPhotoIndex()]?.video) {
|
@if (item()!.photos![selectedPhotoIndex()]?.video) {
|
||||||
<video [src]="item()!.photos![selectedPhotoIndex()].url" controls></video>
|
<video [src]="item()!.photos![selectedPhotoIndex()].url" controls></video>
|
||||||
} @else {
|
} @else {
|
||||||
<img [src]="item()!.photos![selectedPhotoIndex()].url" [alt]="item()!.name" fetchpriority="high" decoding="async" />
|
<img [src]="item()!.photos![selectedPhotoIndex()].url" [alt]="getItemName()" fetchpriority="high" decoding="async" />
|
||||||
}
|
}
|
||||||
} @else {
|
} @else {
|
||||||
<div class="dx-no-image">
|
<div class="dx-no-image">
|
||||||
|
|||||||
@@ -218,7 +218,7 @@ export class ItemDetailComponent implements OnInit, OnDestroy {
|
|||||||
getSimpleDescription(): string {
|
getSimpleDescription(): string {
|
||||||
const currentItem = this.item();
|
const currentItem = this.item();
|
||||||
if (!currentItem) return '';
|
if (!currentItem) return '';
|
||||||
return currentItem.simpleDescription || currentItem.description || '';
|
return getTranslatedField(currentItem, 'simpleDescription', this.languageService.currentLanguage());
|
||||||
}
|
}
|
||||||
|
|
||||||
hasDescriptionFields(): boolean {
|
hasDescriptionFields(): boolean {
|
||||||
|
|||||||
@@ -105,7 +105,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<button class="add-to-cart-btn" (click)="addToCart(item.itemID, $event)" [attr.aria-label]="('search.addToCart' | translate) + ': ' + item.name">
|
<button class="add-to-cart-btn" (click)="addToCart(item.itemID, $event)" [attr.aria-label]="('search.addToCart' | translate) + ': ' + itemName(item)">
|
||||||
{{ 'search.addToCart' | translate }}
|
{{ 'search.addToCart' | translate }}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -147,6 +147,23 @@ export class ApiService {
|
|||||||
: [],
|
: [],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (raw.names && Array.isArray(raw.names)) {
|
||||||
|
subcategory.names = raw.names;
|
||||||
|
subcategory.translations = subcategory.translations || {};
|
||||||
|
for (const entry of raw.names) {
|
||||||
|
const lang = this.normalizeLang(entry.language);
|
||||||
|
const val = entry.value || entry.valuue || '';
|
||||||
|
if (val) {
|
||||||
|
if (!subcategory.translations[lang]) subcategory.translations[lang] = {};
|
||||||
|
subcategory.translations[lang].name = val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!subcategory.name && raw.names.length > 0) {
|
||||||
|
const ruName = raw.names.find((n: any) => n.language === 'RU' || n.language === 'ru');
|
||||||
|
subcategory.name = ruName?.value || ruName?.valuue || raw.names[0].value || raw.names[0].valuue || '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return subcategory;
|
return subcategory;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { Item } from '../models';
|
import { Item } from '../models';
|
||||||
import { Category } from '../models/category.model';
|
import { Category, Subcategory } from '../models/category.model';
|
||||||
|
|
||||||
export function getDiscountedPrice(item: Item): number {
|
export function getDiscountedPrice(item: Item): number {
|
||||||
return item.price * (1 - (item.discount || 0) / 100);
|
return item.price * (1 - (item.discount || 0) / 100);
|
||||||
@@ -68,6 +68,9 @@ export function getTranslatedField(
|
|||||||
const val = entry?.value || (entry as any)?.valuue || '';
|
const val = entry?.value || (entry as any)?.valuue || '';
|
||||||
if (val) return val;
|
if (val) return val;
|
||||||
}
|
}
|
||||||
|
if (field === 'simpleDescription' && item.translations?.[lang]?.simpleDescription) {
|
||||||
|
return item.translations[lang].simpleDescription!;
|
||||||
|
}
|
||||||
// 3. Fallback to base field
|
// 3. Fallback to base field
|
||||||
if (field === 'name') return item.name;
|
if (field === 'name') return item.name;
|
||||||
if (field === 'simpleDescription') return item.simpleDescription || item.description || '';
|
if (field === 'simpleDescription') return item.simpleDescription || item.description || '';
|
||||||
@@ -77,7 +80,7 @@ export function getTranslatedField(
|
|||||||
/**
|
/**
|
||||||
* Get translated category name for the current language.
|
* Get translated category name for the current language.
|
||||||
*/
|
*/
|
||||||
export function getTranslatedCategoryName(cat: Category, lang: string): string {
|
export function getTranslatedCategoryName(cat: Category | Subcategory, lang: string): string {
|
||||||
const translation = cat.translations?.[lang];
|
const translation = cat.translations?.[lang];
|
||||||
if (translation?.name) return translation.name;
|
if (translation?.name) return translation.name;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user