diff --git a/src/app/i18n/en.ts b/src/app/i18n/en.ts index bc4b804..71ce6d0 100644 --- a/src/app/i18n/en.ts +++ b/src/app/i18n/en.ts @@ -188,6 +188,7 @@ export const en: Translations = { weeksAgo: 'w. ago', colour: 'Colour', size: 'Size', + relatedProducts: 'Related products', }, app: { connecting: 'Connecting to server...', diff --git a/src/app/i18n/hy.ts b/src/app/i18n/hy.ts index a186331..fa037c8 100644 --- a/src/app/i18n/hy.ts +++ b/src/app/i18n/hy.ts @@ -188,6 +188,7 @@ export const hy: Translations = { weeksAgo: 'շաբաթ առաջ', colour: 'Գույն', size: 'Չափ', + relatedProducts: 'Նման ապրանքներ', }, app: { connecting: 'Կապ սերվերի հետ...', diff --git a/src/app/i18n/ru.ts b/src/app/i18n/ru.ts index 74af3e8..8e8131b 100644 --- a/src/app/i18n/ru.ts +++ b/src/app/i18n/ru.ts @@ -188,6 +188,7 @@ export const ru: Translations = { weeksAgo: 'нед. назад', colour: 'Цвет', size: 'Размер', + relatedProducts: 'Похожие товары', }, app: { connecting: 'Подключение к серверу...', diff --git a/src/app/i18n/translations.ts b/src/app/i18n/translations.ts index 5a2b113..568db87 100644 --- a/src/app/i18n/translations.ts +++ b/src/app/i18n/translations.ts @@ -186,6 +186,7 @@ export interface Translations { weeksAgo: string; colour: string; size: string; + relatedProducts: string; }; app: { connecting: string; diff --git a/src/app/pages/item-detail/item-detail.component.html b/src/app/pages/item-detail/item-detail.component.html index 7c16d67..68315a9 100644 --- a/src/app/pages/item-detail/item-detail.component.html +++ b/src/app/pages/item-detail/item-detail.component.html @@ -294,6 +294,23 @@ } + + @if (relatedProducts().length > 0) { + + } } } @else { @@ -634,6 +651,23 @@ } + + @if (relatedProducts().length > 0) { + + } } } \ No newline at end of file diff --git a/src/app/pages/item-detail/item-detail.component.scss b/src/app/pages/item-detail/item-detail.component.scss index f393381..e925d5a 100644 --- a/src/app/pages/item-detail/item-detail.component.scss +++ b/src/app/pages/item-detail/item-detail.component.scss @@ -65,6 +65,23 @@ $dx-card-bg: #f5f3f9; margin-bottom: 48px; } +.related-products { + margin-top: 48px; + + h2 { + margin: 0 0 20px; + color: $dx-dark; + font-size: 1.5rem; + font-weight: 800; + } +} + +.related-products-grid { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); + gap: 24px; +} + // Gallery: thumbnails left + main photo right .dx-gallery { display: flex; diff --git a/src/app/pages/item-detail/item-detail.component.ts b/src/app/pages/item-detail/item-detail.component.ts index e960942..a223c19 100644 --- a/src/app/pages/item-detail/item-detail.component.ts +++ b/src/app/pages/item-detail/item-detail.component.ts @@ -14,10 +14,11 @@ import { TranslatePipe } from '../../i18n/translate.pipe'; import { TranslateService } from '../../i18n/translate.service'; import { UiRuntimeFacade } from '../../facades/runtime/ui-runtime.facade'; import { ProductFacade } from '../../facades/platform/product.facade'; +import { ProductCardComponent } from '../../components/product-card/product-card.component'; @Component({ selector: 'app-item-detail', - imports: [DecimalPipe, RouterLink, FormsModule, LangRoutePipe, TranslatePipe], + imports: [DecimalPipe, RouterLink, FormsModule, LangRoutePipe, TranslatePipe, ProductCardComponent], templateUrl: './item-detail.component.html', styleUrls: ['./item-detail.component.scss'], changeDetection: ChangeDetectionStrategy.OnPush @@ -25,6 +26,7 @@ import { ProductFacade } from '../../facades/platform/product.facade'; export class ItemDetailComponent implements OnInit, OnDestroy { item = signal(null); selectedPhotoIndex = signal(0); + relatedProducts = signal([]); loading = signal(true); error = signal(null); private readonly uiRuntime = inject(UiRuntimeFacade); @@ -139,6 +141,7 @@ export class ItemDetailComponent implements OnInit, OnDestroy { this.item.set(item); this.initVariantSelection(item); this.seoService.setItemMeta(item); + this.loadRelatedProducts(item); this.loading.set(false); }, error: (err) => { @@ -163,6 +166,17 @@ export class ItemDetailComponent implements OnInit, OnDestroy { } } + private loadRelatedProducts(item: Item): void { + this.productFacade.getRelatedProducts({ + productID: item.itemID, + categoryID: item.categoryID, + count: 8 + }).subscribe({ + next: (result) => this.relatedProducts.set(result.items), + error: () => this.relatedProducts.set([]) + }); + } + selectColour(colour: string): void { this.selectedColour.set(colour); // If current size is not available for the new colour, reset to first available @@ -192,6 +206,12 @@ export class ItemDetailComponent implements OnInit, OnDestroy { } } + addRelatedToCart(itemID: number, event: Event): void { + event.preventDefault(); + event.stopPropagation(); + this.cartService.addItem(itemID); + } + getDiscountedPrice(): number { const currentItem = this.item(); if (!currentItem) return 0; @@ -221,6 +241,10 @@ export class ItemDetailComponent implements OnInit, OnDestroy { return getTranslatedField(currentItem, 'name', lang); } + relatedItemName(item: Item): string { + return getTranslatedField(item, 'name', this.languageService.currentLanguage()); + } + getSimpleDescription(): string { const currentItem = this.item(); if (!currentItem) return '';