Skip to content

kira565/shelf-layout-manager

Repository files navigation

Shelf Layout Manager

Blazor WebAssembly application for managing SKU shelf layout in retail environments.

This application is designed for operations professionals in retail who are responsible for organizing and optimizing shelf layouts. The typical user is detail-oriented, familiar with store inventory processes, and values efficiency and collaboration. The tool is intuitive and user-friendly, requiring no advanced technical skills, and helps streamline the daily workflow of managing and visualizing SKU placement on store shelves.

Key features:

  • Visualize shelf layouts and SKU lists
  • Manual creation of new SKUs and shelves via the UI
  • Add Columns with SKUs to shelves and remove them
  • Move SKU columns on a shelf (swap columns) using both UI controls and keyboard navigation
  • Sort shelf columns by SKU properties (popularity, price, expiration date) and distribute by retail hot zone (left side, middle side, right side)
  • Search SKUs by name or ID
  • Sort SKUs by popularity, price, or expiration date
  • Import/export SKU data (JSON)
  • Import/export Shelf data (JSON)
  • Persistent storage for shelf layout and SKUs using LocalStorage

Prerequisites

  • .NET 9.0 SDK (Preview)
  • (Optional) Node.js (npx serve) or Python (python3 -m http.server) for static server preview

Running the Application in Local Development Mode

Build the entire solution. From the root directory, run:

dotnet build
  1. To launch the development server:
cd ShelfLayoutManager.UI
dotnet watch run

Your default browser will open automatically. You can now start testing the application locally.

Running/Deploying the Deliverable (Production Build)

To generate a production-ready build, run the following command from the root directory:

dotnet publish ShelfLayoutManager.UI/ShelfLayoutManager.UI.csproj -c Release -o ./publish

This will compile the solution and place the build output into the publish folder at the root level.

Running the Production Build Locally

To preview the production build locally, start a static server in the publish/wwwroot directory:

Option 1: Using Node.js

cd publish/wwwroot
npx serve

Option 2: Using Python

cd publish/wwwroot
python3 -m http.server 8080

Then, open your browser and navigate to the address displayed in the console (e.g., http://localhost:8080).

Deploying to a Static Host

To deploy the production build:

  1. Upload the contents of the publish/wwwroot directory to any static web host or CDN.
  2. Ensure your server is configured to serve index.html as the fallback for all routes, in order to support Blazor client-side routing.

Testing

Run unit tests from the root of the solution:

dotnet test

Usage Guide

1. Shelf Editor Page (Main Page)

  • Create or Import a Shelf

    • On first launch, you can create a new shelf using the form or import an existing shelf from a JSON file ("Import Shelf" button).
    • Once a shelf is loaded or created, the shelf visualization and SKU placement list will be displayed.
  • SKU Placement List

    • The right/both side depending on screen resolution shows a list of SKUs available for placement on the shelf.
    • You can only add SKUs that have been previously created on the SKU List page.
    • When you add a SKU, a new column matching the SKU’s size is automatically created.
  • Managing Columns

    • Select a column to view its details.
    • Move columns left or right using the arrow buttons or keyboard navigation.
    • Remove a column using the "Remove" button.
    • Sort columns by popularity, price, expiration date, and by hot zone using the top control panel. You can choose a sorting property (popularity, price, or expiration date) and a target retail hot zone (left, center, or right part of the shelf). When you apply sorting, the columns will be rearranged so that the SKUs with the highest value for the selected property (e.g., most popular, most expensive, or soonest to expire) are placed in the chosen hot zone. For example, if you select "Sort by Price" and "Left Zone," the most expensive SKUs will be placed on the left side of the shelf
  • Import/Export and Reset

    • You can import or export the shelf state as a JSON file.
    • Warning: Both "Import" and "Reset" operations are destructive and will prompt a confirmation modal before proceeding.

2. SKU List Page

  • Managing SKUs

    • Here you can create new SKUs using the form, as well as import or export the entire SKU list as a JSON file.
    • You can search SKUs by Name, ID and and sort by price, popularity, or expiration date.
  • Import/Export and Clear

    • Importing and clearing the SKU list are also destructive operations and will prompt a confirmation modal to prevent accidental data loss.

Technical Details

  • Clean Architecture:
    The solution is structured by Clean Architecture principles:

    • Domain (ShelfLayoutManager.Domain): Core business entities and validation logic (no dependencies on infrastructure).
    • UseCases (ShelfLayoutManager.UseCases): Application logic and service interfaces.
    • Adapters (ShelfLayoutManager.Adapters): Infrastructure implementations (e.g., persistent storage).
    • UI (ShelfLayoutManager.UI): Blazor frontend, interacts only with use case interfaces and subscribes to their observables for real-time updates.
    • ViewModels (ShelfLayoutManager.ViewModels): Presentation models for the UI, primarily produced as a result of processing and combining observable streams.
  • Frontend:
    Implemented with Blazor WebAssembly (.NET 9.0). The UI is reactive and updates in real time as data changes.

  • Reactive Programming:

    All core data (SKUs, shelves, filters, sorting) is managed as observable streams using System.Reactive. Services like SkuManager and ShelfManager expose IObservable streams (e.g., SkuDictObservableStandObservable). UI components subscribe to these streams and update automatically when data changes. Filtering, sorting, and view models are built by combining streams with CombineLatest, ensuring real-time, decoupled updates across the app.

  • Dependency Injection:
    All services (storage, managers) are registered and resolved via .NET's built-in Dependency Injection container.

  • Global error and info notifications:
    The application uses a centralized UIEventBus to broadcast error and informational events from any part of the app (including use cases and adapters) to the UI layer. These events are displayed to the user via the EventToast component as non-intrusive toast notifications. This decouples error handling from UI logic, provides a consistent and user-friendly way to display feedback, and ensures users are always informed about errors, warnings, or important actions, regardless of where they occur in the application flow.

  • Unit Testing:

    All core logic (use cases, validators, services, blazer components, domain entities) is covered by unit tests using bUnit, xUnit and Moq.

  • Accessibility (a11y), Fail-safe design, UX Best practices

    • All interactive elements are keyboard-accessible and labeled for screen readers (e.g., aria-labels, labels for inputs).
    • Forms provide inline validation and clear error messages.
    • The UI is responsive and provides immediate feedback for user actions.
    • All user inputs are validated both on the client (via data annotations and custom validators) and in the Domain layer.
    • Invalid or incomplete data cannot be submitted
    • Destructive actions require explicit confirmation.
    • Application state is persisted, reducing risk of data loss on reload.**
    • Layout adapts for different screen sizes (Starting from Tablet).
    • Consistent button placement and icon usage for common actions.
    • Global error and info notifications are handled via a UIEventBus and EventToast, ensuring users are always informed about errors or important events.

Limitations, Improvements and current State

Core MVP Limitations

Limitation Explanation / Future Direction
Only one shelf can be managed at a time Multi-shelf support is planned; the domain model already includes a Stand class for grouping multiple shelves.
Only SKU-to-shelf addition is supported; no pre-defined column layout Each time a SKU is added to a shelf, a new column (SkuColumn) is automatically created with the appropriate size and quantity. This approach was chosen for MVP as it is more user-friendly and requires less effort from the user. However, support for pre-defining shelf columns is planned for future versions, and the current implementation already lays the foundation for this feature.
shelf columns cannot be adjusted after creation Currently, once a SKU column is created (automatically when adding a SKU), its width and other parameters cannot be changed directly. The column size is determined by the SKU dimensions and the global column gap set in the shelf parameters. The foundation for adjustable columns exists thnaks to SkuColumn class, and support for editing column properties will be added in future versions.
SKUs cannot be edited (patched), only deleted and recreated Currently, SKU items cannot be modified after creation; they can only be deleted and new ones created. This is because columns are not yet adjustable, so editing a SKU would have no effect until that feature is implemented. Support for editing SKUs will be added together with adjustable columns in future versions.
Shelf parameters cannot be adjusted after creation Currently, shelf properties (width, height, depth, column gap) are set only at creation and cannot be changed later. The architecture stores these parameters in a dedicated ShelfStaticProps object and validation is supported, making it straightforward to add support for shelf editing in future versions.
Manual adjustment of SKU quantity per column is not supported Currently, when adding a SKU to a shelf, a new column is created and filled to its maximum capacity (or less if available quantity is limited). There is no option to manually specify a partial fill for a column, nor does the system auto-fill existing partially filled columns before creating new ones. This was chosen for MVP simplicity, but future versions may support auto-filling incomplete columns and manual adjustment of column fill, especially once SKU editing is implemented (means when we can change SKU quantity of the card).
No full UI error boundary for rendering failures While most business and infrastructure errors are surfaced to the user via toast notifications, there is currently no global UI error boundary to catch unexpected rendering errors. Im planning to add Error Boundaries in future updates.
"Add SKU" button is not disabled when there is no space on the shelf Currently, the "Add SKU" button in the SKU placement list remains enabled even when there is no available space on the shelf. If the user tries to add a SKU in this state, a toast error message is shown. Disabling the button when the shelf is full would improve UX and prevent unnecessary actions.

Must-have features

  • Support for managing multiple shelves (multi-shelf/stand UI and logic)
  • Ability to pre-define and edit shelf columns independently of SKU addition
  • Adjustable shelf columns (change width, quantity, and other parameters after creation)
  • Ability to edit (patch) existing SKUs and have changes reflected in the shelf layout
  • Editable shelf parameters (Width, Height, Depth, ColumnGap) after shelf creation
  • Manual adjustment of SKU quantity per column, or smart auto-fill logic that fills existing partially filled columns before creating new ones
  • Migration to a more robust persistent storage solution (e.g., server-side database or cloud storage) to enable advanced collaboration, backup, and multi-user support
  • Disable Add SKU button when there is no space in the shelf instead of showing error toast.

Good-to-have features

  • Drag-and-drop support for rearranging shelf columns to provide a more intuitive user experience.
  • Add UI Error Boundary for unexpected UI errors
  • Localization and multi-language support (for international users and teams)
  • Migration of shelf visualization to advanced solutions (e.g. Canvas or SVG for smoother, more interactive shelf rendering)
  • Mobile screen adaptiveness (currently, the application is optimized for tablets and larger screens)
  • Export/import in additional formats (CSV, Excel)
  • Bootstrap components are used for rapid MVP development; migration to custom or more advanced UI components may be considered as the project evolves.
  • Add the ability to merge the existing SKU list with the imported list, instead of fully replacing it
  • Allow users to configure the priority of columns for advanced SKU sorting, not only left, mid, right hot zone.

Refactoring Plans

  • Better styles organization in code: SASS preprocessor is already used, but its capabilities (such as variables, mixins, and separating constants into a dedicated layer) are not fully leveraged yet. Refactoring styles into a more modular and maintainable structure is recommended.
  • Refactoring of ShelfEditorPage: As this is the highest-level component, it contains a lot of logic, such as subscriptions and calls to UseCase service methods. It would be beneficial to move some of this business logic to a partial class and split parts of the markup into separate components to make the code more readable and maintainable.
  • Unify test naming, extract repeated error/info messages and other constants, and improve error message clarity.
  • Need fix for form validation messages now it quck-fixed

Time Spent

Task Time Spent
Reading docs 30 min
Architecture setup 4 h
Implementation 18 h~
Unit tests 6 h
Refactor & cleanup 4 h
Writing documentation 2 h
Blazor Web App and
Clean Architecture understanding
4h~

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors