# Catalog Module Report ## Scope Sprint 5 added a Catalog Module on the frozen platform architecture. No backend APIs, authentication, payment, or bootstrap contracts were changed. The catalog uses existing domain boundaries: - Category data: `CategoryFacade` -> `CategoryService` -> Category Repository -> existing `GET /category` - Product data: `ProductFacade` -> `ProductDataService` -> Product Provider -> existing product/category item endpoints ## Implemented Module ### Catalog Container - `src/app/features/website/catalog/containers/catalog-container.component.ts` - `src/app/features/website/catalog/containers/catalog-container.component.html` - `src/app/features/website/catalog/containers/catalog-container.component.scss` Responsibilities implemented: - Reads the route category id. - Requests category data through `CategoryFacade` only. - Requests product data through `ProductFacade` only. - Determines whether the current category has child categories. - Renders category grid when child categories exist. - Renders product grid when no child categories exist. - Supports root catalog entry with root categories. - Handles loading, empty, and error states. - Cancels prior category/product data subscriptions when the route changes. No `HttpClient`, backend DTO, auth, payment, bootstrap, or tenant-specific logic is used in the container. ### Category Grid - `src/app/features/website/catalog/components/category-grid/category-grid.component.ts` - `src/app/features/website/catalog/components/category-grid/category-grid.component.html` - `src/app/features/website/catalog/components/category-grid/category-grid.component.scss` Reusable category grid implemented with: - Input: `Category[]` - Output: selected `Category` - Responsive grid layout - Domain model only - No data fetching - No backend DTOs ### Product Grid - `src/app/features/website/catalog/components/product-grid/product-grid.component.ts` - `src/app/features/website/catalog/components/product-grid/product-grid.component.html` - `src/app/features/website/catalog/components/product-grid/product-grid.component.scss` Reusable product grid implemented with: - Input: `Product[]` - Output: selected `Product` - Output: add-to-cart payload - Output: product preview id - Responsive grid layout - Uses existing reusable product card - No `HttpClient` - No backend DTOs ### Product Card Compatibility - `src/app/components/product-card/product-card.component.ts` - `src/app/components/product-card/product-card.component.html` Updated the reusable product card to depend on the Product Domain type and added an explicit selected output. The product card remains input/output-only and does not use services, storage, `HttpClient`, or environment configuration. It displays image, title, price, discount, badges, and stock. ### Catalog State - `src/app/features/website/catalog/models/catalog-state.model.ts` Prepared future state architecture for: - Category - Search - Sort - Price range - Attributes - Pagination - Filters Backend filtering was intentionally not implemented in this sprint. ## Navigation Updated routes in `src/app/app.routes.ts`: - `/catalog` - `/catalog/:id` Both routes load the same catalog container. Legacy category URLs redirect to the catalog route: - `/category/:id` -> `/catalog/:id` - `/category/:id/items` -> `/catalog/:id` Home category links now point to `/catalog/:id`. ## Unlimited Category Depth Unlimited nesting is supported by the Category Domain tree utilities from Sprint 4. The catalog container does not assume a fixed depth. For any category id, it asks `CategoryFacade.getChildren(categoryId)`: - if children exist, it renders the category grid - if no children exist, it loads the product grid This same decision repeats for every category route depth. ## Localization Added catalog translations in: - `src/app/i18n/en.ts` - `src/app/i18n/ru.ts` - `src/app/i18n/hy.ts` - `src/app/i18n/translations.ts` ## Validation Completed checks: - Unlimited category depth is supported through facade child lookup and recursive category domain tree utilities. - Product grid is reusable and consumes `Product[]`. - Category grid is reusable and consumes `Category[]`. - Catalog components use domain models only. - Catalog data requests go through facades only. - DTOs remain isolated outside the catalog module. - Catalog module has no `HttpClient` usage. - Product card has no services, storage, `HttpClient`, or environment usage. - Authentication was not modified. - Payment was not modified. - Bootstrap contracts were not modified. - Backend APIs were not modified. Build validation passed: ```bash npm run build ``` ## Stop Point Catalog Module implementation is complete for Sprint 5. Stop here for approval before starting the next module or any Builder/Backoffice work. ## Sprint 10.2 Catalog UX Polish Sprint 10.2 improves catalog UX and responsiveness without changing facades, business logic, bootstrap flow, runtime architecture, routing, authentication, or payment. ### Empty State Behavior Two separate states are now rendered in the catalog container: - Empty category state (`rawProducts.length === 0`): - hides filter/sort/layout/result controls - shows dedicated empty category component with icon, category context, friendly message, and "Browse Categories" action - Filtered empty state (`rawProducts.length > 0 && products.length === 0`): - shows "no filter match" message - provides "Clear Filters" action - keeps filter access available (sidebar on desktop, drawer trigger on tablet/mobile) ### Mobile Filter Drawer - Desktop keeps visible sticky sidebar filters. - Tablet and mobile switch to a drawer-based filter UI. - Drawer includes filter groups, Reset, and Apply actions. - Apply closes the drawer. - Accessibility: - drawer uses dialog semantics (`role="dialog"`, `aria-modal="true"`) - focus trap is enabled while drawer is open - `Esc` closes the drawer ### Mobile Sort - Desktop keeps dropdown sort control. - Tablet keeps compact dropdown with drawer-based filters. - Mobile opens a bottom-sheet sort modal. - Supported mobile sort options: - Recommended - Newest - Price Low -> High - Price High -> Low - Rating - Popularity ### Responsive Grid Modes and Toolbar - Grid selector uses icon buttons and keeps active-state highlighting. - Mobile sticky toolbar added with quick actions: - Filters - Sort - Grid cycle - Grid cycle rotates through supported layouts while preserving existing layout architecture. ### Responsive Spacing and Overflow Catalog spacing and controls were polished for desktop/tablet/mobile: - filter/input/button spacing - sort/reset row behavior (single row on desktop, stacked naturally on mobile) - card and grid spacing - search block spacing - drawer/sheet interaction surfaces - horizontal overflow prevention ### Localization and Accessibility - New strings for empty states, drawer/sheet UI, and toolbar were added to all languages: - `src/app/i18n/en.ts` - `src/app/i18n/ru.ts` - `src/app/i18n/hy.ts` - `src/app/i18n/translations.ts` - No hardcoded catalog UX strings were introduced for Sprint 10.2 additions.