Files
ISA-Frontend/libs/checkout/shared/reward-selection-dialog/README.md
Lorenz Hilpert 89b3d9aa60 Merged PR 2000: open tasks
Related work items: #5309
2025-11-06 10:01:41 +00:00

5.5 KiB

Reward Selection Dialog

Angular library for managing reward selection in shopping cart context. Allows users to toggle between regular purchase and reward redemption using bonus points.

Features

  • 🎯 Pre-built trigger component or direct service integration
  • 🔄 Automatic resource management (carts, bonus cards)
  • 📊 Smart grouping by order type and branch
  • 💾 NgRx Signals state management
  • Full TypeScript support

Installation

import {
  RewardSelectionService,
  RewardSelectionPopUpService,
  RewardSelectionTriggerComponent,
} from '@isa/checkout/shared/reward-selection-dialog';

Quick Start

Simplest integration - includes all providers automatically:

import { Component } from '@angular/core';
import { RewardSelectionTriggerComponent } from '@isa/checkout/shared/reward-selection-dialog';

@Component({
  selector: 'app-checkout',
  template: `<lib-reward-selection-trigger />`,
  imports: [RewardSelectionTriggerComponent],
})
export class CheckoutComponent {}

Using the Pop-Up Service

More control over navigation flow:

import { Component, inject } from '@angular/core';
import {
  RewardSelectionPopUpService,
  NavigateAfterRewardSelection,
  RewardSelectionService,
} from '@isa/checkout/shared/reward-selection-dialog';
import {
  SelectedShoppingCartResource,
  SelectedRewardShoppingCartResource,
} from '@isa/checkout/data-access';

@Component({
  selector: 'app-custom-checkout',
  template: `<button (click)="openRewardSelection()">Select Rewards</button>`,
  providers: [
    // Required providers
    SelectedShoppingCartResource,
    RewardSelectionService,
    RewardSelectionPopUpService,
  ],
})
export class CustomCheckoutComponent {
  #popUpService = inject(RewardSelectionPopUpService);

  async openRewardSelection() {
    const result = await this.#popUpService.popUp();
    
    // Handle navigation: 'cart' | 'reward' | 'catalog' | undefined
    if (result === NavigateAfterRewardSelection.CART) {
      // Navigate to cart
    }
  }
}

Using the Service Directly

For custom UI or advanced use cases:

import { Component, inject } from '@angular/core';
import { RewardSelectionService } from '@isa/checkout/shared/reward-selection-dialog';
import {
  SelectedShoppingCartResource,
} from '@isa/checkout/data-access';

@Component({
  selector: 'app-advanced',
  template: `
    @if (canOpen()) {
      <button (click)="openDialog()" [disabled]="isLoading()">
        {{ eligibleItemsCount() }} items as rewards ({{ availablePoints() }} points)
      </button>
    }
  `,
  providers: [
    SelectedShoppingCartResource,
    RewardSelectionService,
  ],
})
export class AdvancedComponent {
  #service = inject(RewardSelectionService);

  canOpen = this.#service.canOpen;
  isLoading = this.#service.isLoading;
  eligibleItemsCount = computed(() => this.#service.eligibleItems().length);
  availablePoints = this.#service.primaryBonusCardPoints;

  async openDialog() {
    const result = await this.#service.open({ closeText: 'Cancel' });
    if (result) {
      // Handle result.rewardSelectionItems
      await this.#service.reloadResources();
    }
  }
}

API Reference

RewardSelectionService

Key Signals:

  • canOpen(): boolean - Can dialog be opened
  • isLoading(): boolean - Loading state
  • eligibleItems(): RewardSelectionItem[] - Items available as rewards
  • primaryBonusCardPoints(): number - Available points

Methods:

  • open({ closeText }): Promise<RewardSelectionDialogResult> - Opens dialog
  • reloadResources(): Promise<void> - Reloads all data

RewardSelectionPopUpService

Methods:

  • popUp(): Promise<NavigateAfterRewardSelection | undefined> - Opens dialog with navigation flow

Return values:

  • 'cart' - Navigate to shopping cart
  • 'reward' - Navigate to reward checkout
  • 'catalog' - Navigate to catalog
  • undefined - No navigation needed

Types

interface RewardSelectionItem {
  item: ShoppingCartItem;
  catalogPrice: Price | undefined;
  availabilityPrice: Price | undefined;
  catalogRewardPoints: number | undefined;
  cartQuantity: number;
  rewardCartQuantity: number;
}

type RewardSelectionDialogResult = {
  rewardSelectionItems: RewardSelectionItem[];
} | undefined;

type NavigateAfterRewardSelection = 'cart' | 'reward' | 'catalog';

Required Providers

When using RewardSelectionService or RewardSelectionPopUpService directly, provide:

providers: [
  SelectedShoppingCartResource,      // Regular cart data
  RewardSelectionService,             // Core service
  RewardSelectionPopUpService,        // Optional: only if using pop-up
]

Note: RewardSelectionTriggerComponent includes all required providers automatically.

Testing

nx test reward-selection-dialog

Architecture

reward-selection-dialog/
├── helper/           # Pure utility functions
├── resource/         # Data resources
├── service/          # Business logic
├── store/           # NgRx Signals state
└── trigger/         # Trigger component

Dependencies

  • @isa/checkout/data-access - Cart resources
  • @isa/crm/data-access - Customer data
  • @isa/catalogue/data-access - Product catalog
  • @isa/ui/dialog - Dialog infrastructure
  • @ngrx/signals - State management