Route marketplace data through product facade

This commit is contained in:
sdarbinyan
2026-07-05 01:03:37 +04:00
parent 05d75421f5
commit ae3512ad37
6 changed files with 31 additions and 23 deletions

View File

@@ -4,13 +4,14 @@ import { RouterLink } from '@angular/router';
import { CarouselModule } from 'primeng/carousel';
import { ButtonModule } from 'primeng/button';
import { TagModule } from 'primeng/tag';
import { ApiService, CartService } from '../../services';
import { CartService } from '../../services';
import { Item } from '../../models';
import { getDiscountedPrice, getMainImage, getBadgeClass, getTranslatedField } from '../../utils/item.utils';
import { LanguageService } from '../../services/language.service';
import { LangRoutePipe } from '../../pipes/lang-route.pipe';
import { TranslatePipe } from '../../i18n/translate.pipe';
import { UiRuntimeFacade } from '../../facades/runtime/ui-runtime.facade';
import { ProductFacade } from '../../facades/platform/product.facade';
@Component({
selector: 'app-items-carousel',
@@ -27,14 +28,14 @@ export class ItemsCarouselComponent implements OnInit {
responsiveOptions: { breakpoint: string; numVisible: number; numScroll: number }[] | undefined;
constructor(
private apiService: ApiService,
private productFacade: ProductFacade,
private cartService: CartService
) {}
ngOnInit() {
this.apiService.getRandomItems(10).subscribe({
next: (items) => {
this.products.set(items);
this.productFacade.getFeaturedProducts({ count: 10 }).subscribe({
next: (result) => {
this.products.set(result.items);
this.loading.set(false);
},
error: () => {

View File

@@ -1,7 +1,7 @@
import { Component, OnInit, OnDestroy, signal, HostListener, ChangeDetectionStrategy, inject } from '@angular/core';
import { DecimalPipe } from '@angular/common';
import { ActivatedRoute, RouterLink } from '@angular/router';
import { ApiService, CartService } from '../../services';
import { CartService } from '../../services';
import { PrefetchService } from '../../services/prefetch.service';
import { Item } from '../../models';
import { Subscription } from 'rxjs';
@@ -10,6 +10,7 @@ import { LanguageService } from '../../services/language.service';
import { LangRoutePipe } from '../../pipes/lang-route.pipe';
import { TranslatePipe } from '../../i18n/translate.pipe';
import { SCROLL_THRESHOLD_PX, SCROLL_DEBOUNCE_MS, ITEMS_PER_PAGE } from '../../config/constants';
import { ProductFacade } from '../../facades/platform/product.facade';
@Component({
selector: 'app-category',
@@ -33,7 +34,7 @@ export class CategoryComponent implements OnInit, OnDestroy {
constructor(
private route: ActivatedRoute,
private apiService: ApiService,
private productFacade: ProductFacade,
private cartService: CartService,
private prefetchService: PrefetchService
) {}
@@ -64,8 +65,9 @@ export class CategoryComponent implements OnInit, OnDestroy {
this.loading.set(true);
this.isLoadingMore = true;
this.apiService.getCategoryItems(this.categoryID(), this.count, this.skip).subscribe({
next: (newItems) => {
this.productFacade.getProductsByCategory(this.categoryID(), { count: this.count, skip: this.skip }).subscribe({
next: (result) => {
const newItems = result.items;
// Handle null or empty response
if (!newItems || newItems.length === 0) {
this.hasMore.set(false);

View File

@@ -1,13 +1,14 @@
import { Component, OnInit, OnDestroy, signal, ChangeDetectionStrategy, inject } from '@angular/core';
import { DecimalPipe } from '@angular/common';
import { ActivatedRoute, Router, RouterLink } from '@angular/router';
import { ApiService, CartService, LanguageService } from '../../services';
import { CartService, LanguageService } from '../../services';
import { Category, Item, Subcategory } from '../../models';
import { Subscription } from 'rxjs';
import { LangRoutePipe } from '../../pipes/lang-route.pipe';
import { TranslatePipe } from '../../i18n/translate.pipe';
import { TranslateService } from '../../i18n/translate.service';
import { getDiscountedPrice, getMainImage, trackByItemId, getBadgeClass, getTranslatedField, getTranslatedCategoryName } from '../../utils/item.utils';
import { ProductFacade } from '../../facades/platform/product.facade';
@Component({
selector: 'app-subcategories',
@@ -34,7 +35,7 @@ export class SubcategoriesComponent implements OnInit, OnDestroy {
constructor(
private route: ActivatedRoute,
private router: Router,
private apiService: ApiService,
private productFacade: ProductFacade,
private langService: LanguageService,
private cartService: CartService
) {}
@@ -55,7 +56,7 @@ export class SubcategoriesComponent implements OnInit, OnDestroy {
this.categoryItems.set([]);
this.nestedSubcategories.set([]);
this.apiService.getCategories().subscribe({
this.productFacade.getCategories().subscribe({
next: (cats) => {
this.categories.set(cats);
const parent = cats.find(c => c.categoryID === parentID);
@@ -100,9 +101,9 @@ export class SubcategoriesComponent implements OnInit, OnDestroy {
/** Load items that belong directly to this category */
private loadCategoryItems(categoryID: number): void {
this.apiService.getCategoryItems(categoryID, 50, 0).subscribe({
next: (items) => {
this.categoryItems.set(items);
this.productFacade.getProductsByCategory(categoryID, { count: 50, skip: 0 }).subscribe({
next: (result) => {
this.categoryItems.set(result.items);
},
error: () => {
// Not critical — subcategories still work

View File

@@ -1,12 +1,13 @@
import { Component, OnInit, OnDestroy, signal, computed, ChangeDetectionStrategy } from '@angular/core';
import { Router, RouterLink } from '@angular/router';
import { ApiService, LanguageService } from '../../services';
import { LanguageService } from '../../services';
import { Category } from '../../models';
import { getTranslatedCategoryName } from '../../utils/item.utils';
import { ItemsCarouselComponent } from '../../components/items-carousel/items-carousel.component';
import { LangRoutePipe } from '../../pipes/lang-route.pipe';
import { TranslatePipe } from '../../i18n/translate.pipe';
import { UiRuntimeFacade } from '../../facades/runtime/ui-runtime.facade';
import { ProductFacade } from '../../facades/platform/product.facade';
@Component({
selector: 'app-home',
@@ -17,10 +18,10 @@ import { UiRuntimeFacade } from '../../facades/runtime/ui-runtime.facade';
})
export class HomeComponent implements OnInit, OnDestroy {
constructor(
private apiService: ApiService,
private router: Router,
private langService: LanguageService,
private readonly uiRuntime: UiRuntimeFacade
private readonly uiRuntime: UiRuntimeFacade,
private readonly productFacade: ProductFacade
) {}
categories = signal<Category[]>([]);
@@ -80,7 +81,7 @@ export class HomeComponent implements OnInit, OnDestroy {
loadCategories(): void {
this.loading.set(true);
this.apiService.getCategories().subscribe({
this.productFacade.getCategories().subscribe({
next: (categories) => {
this.categories.set(categories);
this.loading.set(false);

View File

@@ -13,6 +13,7 @@ import { LangRoutePipe } from '../../pipes/lang-route.pipe';
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';
@Component({
selector: 'app-item-detail',
@@ -108,6 +109,7 @@ export class ItemDetailComponent implements OnInit, OnDestroy {
constructor(
private route: ActivatedRoute,
private apiService: ApiService,
private productFacade: ProductFacade,
private cartService: CartService,
private telegramService: TelegramService,
private sanitizer: DomSanitizer,
@@ -132,7 +134,7 @@ export class ItemDetailComponent implements OnInit, OnDestroy {
loadItem(itemID: number): void {
this.loading.set(true);
this.apiService.getItem(itemID).subscribe({
this.productFacade.getProduct(itemID).subscribe({
next: (item) => {
this.item.set(item);
this.initVariantSelection(item);

View File

@@ -2,7 +2,7 @@ import { Component, signal, HostListener, OnDestroy, ChangeDetectionStrategy, in
import { DecimalPipe } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { RouterLink } from '@angular/router';
import { ApiService, CartService } from '../../services';
import { CartService } from '../../services';
import { PrefetchService } from '../../services/prefetch.service';
import { Item } from '../../models';
import { Subject, Subscription } from 'rxjs';
@@ -13,6 +13,7 @@ import { LangRoutePipe } from '../../pipes/lang-route.pipe';
import { TranslatePipe } from '../../i18n/translate.pipe';
import { TranslateService } from '../../i18n/translate.service';
import { SEARCH_DEBOUNCE_MS, ITEMS_PER_PAGE, SCROLL_THRESHOLD_PX, SCROLL_DEBOUNCE_MS } from '../../config/constants';
import { ProductFacade } from '../../facades/platform/product.facade';
@Component({
selector: 'app-search',
@@ -37,7 +38,7 @@ export class SearchComponent implements OnDestroy {
private i18n = inject(TranslateService);
constructor(
private apiService: ApiService,
private productFacade: ProductFacade,
private cartService: CartService,
private prefetchService: PrefetchService
) {
@@ -85,7 +86,7 @@ export class SearchComponent implements OnDestroy {
this.loading.set(true);
this.isLoadingMore = true;
this.apiService.searchItems(this.searchQuery, this.count, this.skip).subscribe({
this.productFacade.searchProducts({ search: this.searchQuery, count: this.count, skip: this.skip }).subscribe({
next: (response) => {
// Update total results (only on first load)
if (this.skip === 0) {