Skip to content

[Feature] product list blockΒ #332

@marcinkrasowski

Description

@marcinkrasowski

Overview

Implement a new content block (ProductListBlock) that renders a configurable list of products with support for both grid and table views. The block should leverage the existing products and cms modules, and strictly follow the documented conventions for structure and customization.

Requirements

1. Block Generation

  • Use the block generator to scaffold the initial structure
    • Run npm run generate at the project root and select the "block" generator
    • Provide the block name: product-list or ProductList
    • Reference: Using Generators

The generator will create the following structure in packages/blocks/product-list/:

  • API Harmonization layer (module, controller, service, mapper, model, request)
  • Frontend layer (server component, client component, renderer, typings, API methods)
  • SDK layer

2. Integration with Products Module

3. CMS Model Extension and Mocked Data

The block generator automatically creates the base CMS model in the framework. You need to:

1. Extend the generated framework CMS model (automatically created by the generator):

2. Add mocked data in the mocked integration:

4. Standard Filters and Pagination

Filter types should include:

  • Category
  • Price range
  • Availability
  • Tags

5. Grid and Table View Toggle

6. Design Reference

  • Follow examples from shadcn-ui-blocks for inspiration:
  • Note: Similar aesthetic but does not need to be an exact match, it's enough that it matches the overall app design and "looks nice"; we will adjust it later if necessary

7. UI Library Integration

  • Reuse existing shadcn/ui components from the UI library
    • Located in packages/ui/src/
  • Install additional shadcn/ui components if needed:
    • Use the shadcn/ui CLI to add new components to packages/ui/src/elements/
    • Example: npx shadcn@latest add [component-name]

8. Reusable Components

  • Place any new reusable React components in the UI library: packages/ui/src/components/
  • Follow the existing pattern for component exports and structure

9. Accessibility and SEO

  • Ensure semantic HTML structure
  • Add proper ARIA labels and roles for interactive elements
  • Use proper heading hierarchy (h1 β†’ h2 β†’ h3)
  • Include alt text for all images
  • Use proper link semantics and keyboard navigation
  • Ensure color contrast meets WCAG standards
  • Add meta descriptions and structured data if applicable

Implementation Steps

  1. Generate the block structure using the generator (this automatically creates the framework CMS model)
  2. Extend framework CMS model and add mocked data:
    • Extend the generated framework CMS model with required fields
    • Create a mapper for mocked data in the mocked integration
    • Add the mapper service method
  3. Implement API harmonization layer:
    • Declare dependencies (CMS, Products)
    • Define data models
    • Fetch and aggregate data
    • Map responses to normalized format
    • Reference: Creating the harmonizing block
  4. Implement frontend layer:
    • Create server component for data fetching
    • Create client component with view toggle
    • Implement grid and table rendering
    • Add filters and pagination
    • Reference: Creating the frontend block
  5. Register the block:
  6. Test the implementation:
    • API testing: http://localhost:3001/api/blocks/product-list
    • Frontend testing: Add block to a page in the CMS

Adding the ProductListBlock to a CMS Page in Mocked Integration

To add the ProductListBlock to a new "Products" page in the mocked integration with support for EN/DE/PL locales, follow these steps:

1. Create a New Page Definition File

Create a new file at packages/integrations/mocked/src/modules/cms/mappers/mocks/pages/product-list.page.ts that defines the page for all three locales (EN, DE, PL).

For an example of how to structure this file, refer to:

Your page definition should:

  • Use a unique ID (e.g., '20')
  • Define slugs for each locale ('/products', '/produkte', '/produkty')
  • Include appropriate SEO information for each language
  • Set permissions to [Auth.Constants.Roles.ORG_USER, Auth.Constants.Roles.ORG_ADMIN]
  • Use 'OneColumnTemplate' with the ProductListBlock in the main slot

For more information on page structure, see the CMS content model documentation.

Note: When creating mocked content, especially for locales other than English (DE, PL), you can use AI tools to help generate appropriate translations and locale-specific content. This can save time and ensure consistency across different language versions.

2. Update the Page Mapper

Modify the packages/integrations/mocked/src/modules/cms/mappers/cms.page.mapper.ts file to include your new page definitions.

For reference on how to update the page mapper, see:

You'll need to make the following changes:

  1. Import the new page definitions from your product-list.page.ts file
  2. Add the new page routes to the mapPage function with cases for each locale's slug ('/products', '/produkte', '/produkty')
  3. Add the new pages to the getAllPages function for each locale (pl, de, en)
  4. Add the new pages to the getAlternativePages function

For more information on how the page mapper works, see the Mocked integration documentation.

3. Test the Implementation

After implementing the ProductListBlock and adding the page definitions:

  1. Start the development server
  2. Navigate to:
    • /products for English
    • /produkte for German
    • /produkty for Polish

The page should display the ProductListBlock with the appropriate content for each locale.

Reference Documentation


As an additional requirement, please provide a short feedback on your experiences with working with this framework - how easy or difficult it was to get started (including starting the project, getting around the monorepo or readings our docs) and to make the required changes.



This repo is using Opire - what does it mean? πŸ‘‡
πŸ’΅ Everyone can add rewards for this issue commenting /reward 100 (replace 100 with the amount).
πŸ•΅οΈβ€β™‚οΈ If someone starts working on this issue to earn the rewards, they can comment /try to let everyone know!
πŸ™Œ And when they open the PR, they can comment /claim #332 either in the PR description or in a PR's comment.

πŸͺ™ Also, everyone can tip any user commenting /tip 20 @marcinkrasowski (replace 20 with the amount, and @marcinkrasowski with the user to tip).

πŸ“– If you want to learn more, check out our documentation.

Metadata

Metadata

Assignees

No one assigned

    Projects

    Status

    In progress

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions