Files
marketplaces/docs/Catalog-Module-Report.md
sdarbinyan a16c856537
Some checks failed
Architecture Governance / architecture (push) Has been cancelled
feat(catalog): sprint 10.2 ux responsive empty-states polish
2026-07-09 01:46:32 +04:00

7.0 KiB

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:

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.