Design: Recently Viewed Products Strip
Component architecture
ProductCatalogPageComponent (existing)
└── RecentlyViewedComponent (new)
└── RecentlyViewedItemComponent (optional sub-component or *ngFor template)RecentlyViewedComponent is a presentational component declared in ProductsModule. It reads from and writes to a RecentlyViewedService (also new) that owns the localStorage interaction.
Service: RecentlyViewedService
typescript
// src/app/features/products/services/recently-viewed.service.ts
export interface RecentlyViewedProduct {
id: string;
name: string;
imageUrl: string;
}
const STORAGE_KEY = 'recently-viewed';
const MAX_ITEMS = 10;Methods:
add(product: RecentlyViewedProduct): void— prepend; deduplicate by id; slice to MAX_ITEMS; persist to localStorage.remove(id: string): void— filter out; persist.getAll(): RecentlyViewedProduct[]— parse from localStorage; return empty array on error.
Uses a BehaviorSubject<RecentlyViewedProduct[]> so the component can subscribe and get live updates without manual change detection.
Component: RecentlyViewedComponent
products$: Observable<RecentlyViewedProduct[]>from service.- Template:
*ngIf="(products$ | async)?.length"wraps the strip (hidden when empty). - Each item: thumbnail + name + "×" button.
- Click on item:
[routerLink]="['/products', item.id]". - Click on "×":
service.remove(item.id).
ProductDetailPageComponent change
In ngOnInit, inject RecentlyViewedService and call service.add({ id, name, imageUrl }) with the current product's data (already available from the existing product resolver/store).
File list
| File | Action |
|---|---|
src/app/features/products/services/recently-viewed.service.ts | Create |
src/app/features/products/components/recently-viewed/recently-viewed.component.ts | Create |
src/app/features/products/components/recently-viewed/recently-viewed.component.html | Create |
src/app/features/products/components/recently-viewed/recently-viewed.component.scss | Create |
src/app/features/products/products.module.ts | Modify — declare RecentlyViewedComponent |
src/app/features/products/components/pages/product-catalog-page/product-catalog-page.component.html | Modify — add <app-recently-viewed> below product grid |
src/app/features/products/components/pages/product-detail-page/product-detail-page.component.ts | Modify — inject service, call add() in ngOnInit |