mirror of
https://dev.azure.com/hugendubel/ISA/_git/ISA-Frontend
synced 2025-12-28 22:42:11 +01:00
📝 docs: update README documentation for 13 libraries
This commit is contained in:
@@ -1,135 +1,249 @@
|
||||
# checkout-feature-reward-order-confirmation
|
||||
# @isa/checkout/feature/reward-order-confirmation
|
||||
|
||||
A feature library providing a comprehensive order confirmation page for reward orders with support for printing, address display, and loyalty reward collection.
|
||||
|
||||
## Overview
|
||||
|
||||
The `@isa/checkout/feature/reward-order-confirmation` library provides the **reward order confirmation screen** displayed after customers complete a loyalty reward redemption purchase. It shows a comprehensive summary of completed reward orders, including shipping/billing addresses, product details, loyalty points used, and delivery method information.
|
||||
This feature provides a complete order confirmation experience after a reward order has been placed. It displays order details grouped by delivery destination, shows payer and shipping information, and enables users with appropriate permissions to print order confirmations. For items with the 'Rücklage' (layaway) feature, it provides an action card that allows staff to collect loyalty rewards in various ways (collect, donate, or cancel).
|
||||
|
||||
**Type:** Routed feature library with lazy-loaded components
|
||||
The library uses NgRx Signal Store for reactive state management, integrating with the OMS (Order Management System) API to load and display order data. It supports multiple orders being displayed simultaneously by accepting comma-separated display order IDs in the route parameter.
|
||||
|
||||
## Features
|
||||
## Architecture
|
||||
|
||||
- **Multi-Order Support**: Display multiple orders from a single shopping cart session
|
||||
- **Order Type Awareness**: Conditional display based on delivery method (Delivery, Pickup, In-Store)
|
||||
- **Address Deduplication**: Smart handling of duplicate addresses across multiple orders
|
||||
- **Loyalty Points Display**: Shows loyalty points (Lesepunkte) used for each reward item
|
||||
- **Product Information**: Comprehensive product details including name, contributors, EAN, and quantity
|
||||
- **Destination Information**: Delivery/pickup destination details
|
||||
### State Management
|
||||
|
||||
## Main Components
|
||||
The library uses a **signalStore** (`OrderConfiramtionStore`) that:
|
||||
- Loads display orders via `DisplayOrdersResource`
|
||||
- Computes derived state (payers, shipping addresses, target branches)
|
||||
- Determines which order type features are present (delivery, pickup, in-store)
|
||||
- Provides reactive data to all child components
|
||||
|
||||
### RewardOrderConfirmationComponent (Main Container)
|
||||
- **Selector:** `checkout-reward-order-confirmation`
|
||||
- **Route:** `/:orderIds` (accepts multiple order IDs separated by `+`)
|
||||
- Orchestrates the entire confirmation view
|
||||
- Manages state via `OrderConfiramtionStore`
|
||||
### Route Configuration
|
||||
|
||||
The feature is accessible via the route pattern: `:displayOrderIds`
|
||||
|
||||
Example: `/order-confirmation/1234,5678` displays orders with display IDs 1234 and 5678.
|
||||
|
||||
The route includes:
|
||||
- OMS action handlers for command execution
|
||||
- Tab cleanup on deactivation
|
||||
- Lazy-loaded main component
|
||||
|
||||
## Components
|
||||
|
||||
### RewardOrderConfirmationComponent
|
||||
|
||||
**Selector:** `checkout-reward-order-confirmation`
|
||||
|
||||
Main container component that orchestrates the order confirmation page.
|
||||
|
||||
**Key Responsibilities:**
|
||||
- Parses display order IDs from route parameters (comma-separated)
|
||||
- Initializes the store with tab ID and order IDs
|
||||
- Triggers display order loading via `DisplayOrdersResource`
|
||||
- Composes child components (header, addresses, item list)
|
||||
|
||||
**Effects:**
|
||||
- Updates store state when route parameters or tab ID change
|
||||
- Loads display orders when order IDs change
|
||||
|
||||
### OrderConfirmationHeaderComponent
|
||||
- **Selector:** `checkout-order-confirmation-header`
|
||||
- Displays header: "Prämienausgabe abgeschlossen" (Reward distribution completed)
|
||||
|
||||
**Selector:** `checkout-order-confirmation-header`
|
||||
|
||||
Displays the page header with print functionality.
|
||||
|
||||
**Features:**
|
||||
- Print button that triggers `CheckoutPrintFacade.printOrderConfirmation()`
|
||||
- Role-based access control (print feature restricted by role)
|
||||
- Integrates with the ISA printing system
|
||||
|
||||
**Dependencies:**
|
||||
- `@isa/common/print` - Print button and printer selection
|
||||
- `@isa/core/auth` - Role-based directive (`*ifRole`)
|
||||
|
||||
### OrderConfirmationAddressesComponent
|
||||
- **Selector:** `checkout-order-confirmation-addresses`
|
||||
- Displays billing addresses, shipping addresses, and pickup branch information
|
||||
- Conditionally shows sections based on order type
|
||||
|
||||
**Selector:** `checkout-order-confirmation-addresses`
|
||||
|
||||
Displays payer and destination information based on order types.
|
||||
|
||||
**Displayed Information:**
|
||||
- **Payers:** Deduplicated list of buyers across all orders
|
||||
- **Shipping Addresses:** Shown only if orders have delivery features (Delivery, DigitalShipping, B2BShipping)
|
||||
- **Target Branches:** Shown only if orders have in-store features (InStore, Pickup)
|
||||
|
||||
**Dependencies:**
|
||||
- `@isa/shared/address` - Address display component
|
||||
- `@isa/crm/data-access` - Customer name formatting and address deduplication
|
||||
|
||||
### OrderConfirmationItemListComponent
|
||||
- **Selector:** `checkout-order-confirmation-item-list`
|
||||
- Displays order type badge with icon (Delivery/Pickup/In-Store)
|
||||
- Renders list of order items for each order
|
||||
|
||||
**Selector:** `checkout-order-confirmation-item-list`
|
||||
|
||||
Groups and displays order items by delivery destination and type.
|
||||
|
||||
**Key Features:**
|
||||
- Groups items using `groupItemsByDeliveryDestination()` helper
|
||||
- Displays delivery type icons (Versand, Rücklage, B2B Versand)
|
||||
- Optimized rendering with `trackBy` function for item groups
|
||||
|
||||
**Grouping Logic:**
|
||||
Items are grouped by:
|
||||
1. Order type (e.g., Delivery, Pickup, InStore)
|
||||
2. Shipping address (for delivery orders)
|
||||
3. Target branch (for pickup/in-store orders)
|
||||
|
||||
### OrderConfirmationItemListItemComponent
|
||||
- **Selector:** `checkout-order-confirmation-item-list-item`
|
||||
- Displays individual product information, quantity, loyalty points, and destination info
|
||||
|
||||
**Selector:** `checkout-order-confirmation-item-list-item`
|
||||
|
||||
Displays individual order item details within a group.
|
||||
|
||||
**Inputs:**
|
||||
- `item` (required): `DisplayOrderItemDTO` - The order item to display
|
||||
- `order` (required): `OrderItemGroup` - The group containing delivery type and destination
|
||||
|
||||
**Features:**
|
||||
- Product information display via `ProductInfoComponent`
|
||||
- Destination information via `DisplayOrderDestinationInfoComponent`
|
||||
- Action card for loyalty reward collection (conditional)
|
||||
- Loyalty points display
|
||||
|
||||
### ConfirmationListItemActionCardComponent
|
||||
- **Selector:** `checkout-confirmation-list-item-action-card`
|
||||
- Placeholder component for future action functionality
|
||||
|
||||
## State Management
|
||||
**Selector:** `checkout-confirmation-list-item-action-card`
|
||||
|
||||
**OrderConfiramtionStore** (NgRx Signals)
|
||||
Provides loyalty reward collection interface for layaway items.
|
||||
|
||||
**State:**
|
||||
- `tabId`: Current tab identifier
|
||||
- `orderIds`: Array of order IDs to display
|
||||
**Inputs:**
|
||||
- `item` (required): `DisplayOrderItem` - The order item with loyalty information
|
||||
|
||||
**Computed Properties:**
|
||||
- `orders`: Filtered display orders from OMS metadata service
|
||||
- `shoppingCart`: Associated completed shopping cart
|
||||
- `payers`: Deduplicated billing addressees
|
||||
- `shippingAddresses`: Deduplicated shipping addressees
|
||||
- `targetBranches`: Deduplicated pickup branches
|
||||
- `hasDeliveryOrderTypeFeature`: Boolean indicating delivery orders
|
||||
- `hasTargetBranchFeature`: Boolean indicating pickup/in-store orders
|
||||
**Display Conditions:**
|
||||
The action card is displayed when ALL of the following are met:
|
||||
- Item has the 'Rücklage' (layaway) order type feature
|
||||
- AND either:
|
||||
- Item has a loyalty collect command available, OR
|
||||
- Item processing is already complete
|
||||
|
||||
**Features:**
|
||||
- **Action Selection:** Dropdown to choose collection type:
|
||||
- `Collect` - Collect loyalty points for customer
|
||||
- `Donate` - Donate points to charity
|
||||
- `Cancel` - Cancel the reward collection
|
||||
- **Processing States:** Shows current processing status (Ordered, InProgress, Complete)
|
||||
- **Command Execution:** Integrates with OMS command system for reward collection
|
||||
- **Loading States:** Displays loading indicators during API calls
|
||||
- **Completion Status:** Shows check icon when processing is complete
|
||||
|
||||
**Role-Based Access:** Collection functionality is restricted by role permissions.
|
||||
|
||||
**Dependencies:**
|
||||
- `@isa/oms/data-access` - Order reward collection facade and command handling
|
||||
- `@isa/ui/buttons` - Button and dropdown components
|
||||
- `@isa/checkout/data-access` - Order type feature detection and item utilities
|
||||
|
||||
## Routes
|
||||
|
||||
```typescript
|
||||
export const routes: Routes = [
|
||||
{
|
||||
path: ':displayOrderIds',
|
||||
loadComponent: () => import('./reward-order-confirmation.component'),
|
||||
canDeactivate: [canDeactivateTabCleanup],
|
||||
providers: [CoreCommandModule.forChild(OMS_ACTION_HANDLERS)]
|
||||
}
|
||||
];
|
||||
```
|
||||
|
||||
**Route Parameters:**
|
||||
- `displayOrderIds` - Comma-separated list of display order IDs (e.g., "1234,5678")
|
||||
|
||||
## Usage
|
||||
|
||||
### Routing Integration
|
||||
### Importing Routes
|
||||
|
||||
```typescript
|
||||
// In parent routing module
|
||||
{
|
||||
path: 'reward-confirmation',
|
||||
loadChildren: () => import('@isa/checkout/feature/reward-order-confirmation')
|
||||
.then(m => m.routes)
|
||||
}
|
||||
import { routes as rewardOrderConfirmationRoutes } from '@isa/checkout/feature/reward-order-confirmation';
|
||||
|
||||
const appRoutes: Routes = [
|
||||
{
|
||||
path: 'order-confirmation',
|
||||
children: rewardOrderConfirmationRoutes
|
||||
}
|
||||
];
|
||||
```
|
||||
|
||||
### URL Structure
|
||||
### Navigation Example
|
||||
|
||||
```
|
||||
/reward-confirmation/123+456+789
|
||||
```
|
||||
```typescript
|
||||
// Navigate to confirmation for single order
|
||||
router.navigate(['/order-confirmation', '1234']);
|
||||
|
||||
This displays confirmation for orders with IDs 123, 456, and 789.
|
||||
// Navigate to confirmation for multiple orders
|
||||
router.navigate(['/order-confirmation', '1234,5678,9012']);
|
||||
```
|
||||
|
||||
## Dependencies
|
||||
|
||||
**Data Access:**
|
||||
- `@isa/oms/data-access` - Order metadata and models
|
||||
- `@isa/checkout/data-access` - Checkout metadata and order type utilities
|
||||
- `@isa/crm/data-access` - Address deduplication utilities
|
||||
### Core Angular & NgRx
|
||||
- `@angular/core` - Angular framework
|
||||
- `@angular/router` - Routing
|
||||
- `@ngrx/signals` - Signal-based state management
|
||||
|
||||
**Core:**
|
||||
- `@isa/core/tabs` - Tab context management
|
||||
### ISA Libraries
|
||||
|
||||
**Shared Components:**
|
||||
- `@isa/shared/address` - Address rendering
|
||||
- `@isa/checkout/shared/product-info` - Product and destination information
|
||||
#### Data Access
|
||||
- `@isa/checkout/data-access` - Order type features, grouping utilities
|
||||
- `@isa/oms/data-access` - Display orders resource, reward collection, command handling
|
||||
- `@isa/crm/data-access` - Customer name formatting, address/branch deduplication
|
||||
|
||||
**UI:**
|
||||
- `@isa/icons` - Delivery method icons
|
||||
#### Shared Components
|
||||
- `@isa/checkout/shared/product-info` - Product display components
|
||||
- `@isa/shared/address` - Address display component
|
||||
- `@isa/common/print` - Print button and printer integration
|
||||
- `@isa/ui/buttons` - Button components
|
||||
- `@isa/ui/input-controls` - Dropdown components
|
||||
|
||||
## Data Flow
|
||||
#### Core Services
|
||||
- `@isa/core/tabs` - Tab service and cleanup guard
|
||||
- `@isa/core/auth` - Role-based access control
|
||||
- `@isa/core/command` - Command module integration
|
||||
|
||||
1. Route parameter (`orderIds`) is parsed into array of integers
|
||||
2. Store receives `tabId` from `TabService` and `orderIds` from route
|
||||
3. Store fetches orders from `OmsMetadataService` filtered by IDs
|
||||
4. Store fetches completed shopping cart from `CheckoutMetadataService`
|
||||
5. Components consume computed properties from store (addresses, order items, points)
|
||||
#### Icons
|
||||
- `@isa/icons` - ISA custom icon set
|
||||
- `@ng-icons/core` - Icon component
|
||||
|
||||
## Order Type Support
|
||||
|
||||
The library supports three delivery methods with specific icons:
|
||||
|
||||
- **Delivery** (`isaDeliveryVersand`): Shows shipping addresses
|
||||
- **Pickup** (`isaDeliveryRuecklage2`): Shows pickup branch
|
||||
- **In-Store** (`isaDeliveryRuecklage1`): Shows store branch
|
||||
### Generated APIs
|
||||
- `@generated/swagger/oms-api` - OMS API types (DisplayOrderItemDTO)
|
||||
|
||||
## Testing
|
||||
|
||||
Run tests with Vitest:
|
||||
The library uses Vitest for testing with comprehensive coverage of:
|
||||
- Component rendering and interactions
|
||||
- State management and computed signals
|
||||
- Route parameter parsing
|
||||
- Reward collection workflows
|
||||
- Conditional display logic
|
||||
|
||||
Run tests:
|
||||
```bash
|
||||
npx nx test checkout-feature-reward-order-confirmation --skip-nx-cache
|
||||
nx test checkout-feature-reward-order-confirmation
|
||||
```
|
||||
|
||||
**Test Framework:** Vitest
|
||||
**Coverage Output:** `coverage/libs/checkout/feature/reward-order-confirmation`
|
||||
## Key Features Summary
|
||||
|
||||
## Architecture Notes
|
||||
1. **Multi-Order Support:** Display confirmation for multiple orders simultaneously
|
||||
2. **Smart Grouping:** Items grouped by delivery destination for clarity
|
||||
3. **Conditional Displays:** Address sections shown based on order type features
|
||||
4. **Print Integration:** Role-based printing with printer selection
|
||||
5. **Loyalty Rewards:** In-page reward collection for layaway items
|
||||
6. **Reactive State:** Signal-based state management with computed values
|
||||
7. **Tab Integration:** Proper cleanup on tab deactivation
|
||||
8. **Role-Based Access:** Permissions enforced for sensitive operations
|
||||
|
||||
- **Component Prefix:** `checkout`
|
||||
- **Change Detection:** All components use `OnPush` strategy
|
||||
- **Standalone Architecture:** All components are standalone with explicit imports
|
||||
- **Project Name:** `checkout-feature-reward-order-confirmation`
|
||||
## Related Libraries
|
||||
|
||||
- `@isa/checkout/feature/checkout-process` - Main checkout flow
|
||||
- `@isa/oms/data-access` - Order management system integration
|
||||
- `@isa/checkout/data-access` - Checkout domain logic and utilities
|
||||
|
||||
@@ -1,205 +1,310 @@
|
||||
# Reward Selection Dialog
|
||||
# @isa/checkout/shared/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.
|
||||
A comprehensive Angular dialog library for managing reward selection in the checkout process, allowing customers to allocate cart items between regular purchases (paid with money) and reward redemptions (paid with loyalty points).
|
||||
|
||||
## Features
|
||||
## Overview
|
||||
|
||||
- 🎯 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
|
||||
This library provides a sophisticated dialog system that enables customers to decide how they want to purchase items that are eligible for both regular checkout and reward redemption. The dialog presents items from both the regular shopping cart and reward shopping cart, allowing customers to allocate quantities between payment methods.
|
||||
|
||||
The library includes:
|
||||
- A main dialog component with quantity allocation interface
|
||||
- A trigger component for opening the dialog from various contexts
|
||||
- State management using NgRx Signal Store
|
||||
- Services for managing dialog lifecycle and popup behavior
|
||||
- Automatic resource loading and validation
|
||||
|
||||
## Installation
|
||||
|
||||
```typescript
|
||||
```ts
|
||||
import {
|
||||
RewardSelectionDialogComponent,
|
||||
RewardSelectionService,
|
||||
RewardSelectionPopUpService,
|
||||
RewardSelectionTriggerComponent,
|
||||
RewardSelectionTriggerComponent
|
||||
} from '@isa/checkout/shared/reward-selection-dialog';
|
||||
```
|
||||
|
||||
## Quick Start
|
||||
## Components
|
||||
|
||||
### Using the Trigger Component (Recommended)
|
||||
### RewardSelectionDialogComponent
|
||||
|
||||
Simplest integration - includes all providers automatically:
|
||||
The main dialog component that displays eligible items and allows customers to allocate quantities between regular cart and reward cart.
|
||||
|
||||
```typescript
|
||||
**Features:**
|
||||
- Displays customer's available loyalty points
|
||||
- Shows item grouping by order type (delivery, pickup, etc.) and branch
|
||||
- Real-time calculation of total price and loyalty points needed
|
||||
- Validates sufficient loyalty points before allowing save
|
||||
- Integrates with shopping cart resources
|
||||
|
||||
### RewardSelectionTriggerComponent
|
||||
|
||||
A button component that can be embedded in the UI to trigger the reward selection dialog.
|
||||
|
||||
**Features:**
|
||||
- Automatically shows/hides based on eligibility
|
||||
- Skeleton loader during resource loading
|
||||
- Handles dialog result and navigation
|
||||
- Provides feedback after selection
|
||||
|
||||
## API Reference
|
||||
|
||||
### Dialog Data Interface
|
||||
|
||||
```ts
|
||||
export type RewardSelectionDialogData = {
|
||||
rewardSelectionItems: RewardSelectionItem[];
|
||||
customerRewardPoints: number;
|
||||
closeText: string;
|
||||
};
|
||||
|
||||
export type RewardSelectionDialogResult =
|
||||
| {
|
||||
rewardSelectionItems: RewardSelectionItem[];
|
||||
}
|
||||
| undefined;
|
||||
```
|
||||
|
||||
**RewardSelectionDialogData:**
|
||||
- `rewardSelectionItems`: Array of items eligible for reward selection with current cart/reward quantities
|
||||
- `customerRewardPoints`: Total loyalty points available to the customer
|
||||
- `closeText`: Text for the cancel/close button
|
||||
|
||||
**RewardSelectionDialogResult:**
|
||||
- Returns updated `rewardSelectionItems` array if customer saves changes
|
||||
- Returns `undefined` if dialog is cancelled or no changes made
|
||||
|
||||
### Opening the Dialog
|
||||
|
||||
#### Using RewardSelectionService
|
||||
|
||||
```ts
|
||||
import { inject } from '@angular/core';
|
||||
import { RewardSelectionService } from '@isa/checkout/shared/reward-selection-dialog';
|
||||
|
||||
export class MyComponent {
|
||||
#rewardSelectionService = inject(RewardSelectionService);
|
||||
|
||||
async openDialog() {
|
||||
// Check if dialog can be opened (has eligible items and customer has points)
|
||||
if (this.#rewardSelectionService.canOpen()) {
|
||||
const result = await this.#rewardSelectionService.open({
|
||||
closeText: 'Abbrechen'
|
||||
});
|
||||
|
||||
if (result) {
|
||||
// Handle the result
|
||||
console.log('Updated items:', result.rewardSelectionItems);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Using RewardSelectionPopUpService
|
||||
|
||||
For automatic popup behavior (e.g., showing dialog once per session):
|
||||
|
||||
```ts
|
||||
import { inject } from '@angular/core';
|
||||
import {
|
||||
RewardSelectionPopUpService,
|
||||
NavigateAfterRewardSelection
|
||||
} from '@isa/checkout/shared/reward-selection-dialog';
|
||||
|
||||
export class CheckoutComponent {
|
||||
#popUpService = inject(RewardSelectionPopUpService);
|
||||
|
||||
async showPopupIfNeeded() {
|
||||
const navigation = await this.#popUpService.popUp();
|
||||
|
||||
switch (navigation) {
|
||||
case NavigateAfterRewardSelection.CART:
|
||||
// Navigate to regular shopping cart
|
||||
break;
|
||||
case NavigateAfterRewardSelection.REWARD:
|
||||
// Navigate to reward checkout
|
||||
break;
|
||||
case NavigateAfterRewardSelection.CATALOG:
|
||||
// Navigate back to catalog
|
||||
break;
|
||||
case undefined:
|
||||
// Stay on current page
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Using RewardSelectionTriggerComponent
|
||||
|
||||
Add the trigger component directly to your template:
|
||||
|
||||
```html
|
||||
<lib-reward-selection-trigger />
|
||||
```
|
||||
|
||||
The trigger component:
|
||||
- Automatically determines eligibility
|
||||
- Shows loading skeleton during resource fetching
|
||||
- Opens dialog on click
|
||||
- Handles navigation after selection
|
||||
|
||||
## Usage Examples
|
||||
|
||||
### Basic Dialog Integration
|
||||
|
||||
```ts
|
||||
import { Component, inject } from '@angular/core';
|
||||
import { RewardSelectionService } from '@isa/checkout/shared/reward-selection-dialog';
|
||||
|
||||
@Component({
|
||||
selector: 'app-checkout',
|
||||
template: `
|
||||
<button (click)="openRewardSelection()">
|
||||
Select Reward Items
|
||||
</button>
|
||||
`,
|
||||
providers: [RewardSelectionService]
|
||||
})
|
||||
export class CheckoutComponent {
|
||||
#rewardSelectionService = inject(RewardSelectionService);
|
||||
|
||||
async openRewardSelection() {
|
||||
await this.#rewardSelectionService.reloadResources();
|
||||
|
||||
if (this.#rewardSelectionService.canOpen()) {
|
||||
const result = await this.#rewardSelectionService.open({
|
||||
closeText: 'Cancel'
|
||||
});
|
||||
|
||||
if (result?.rewardSelectionItems.length) {
|
||||
// Process updated selections
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Using Trigger Component
|
||||
|
||||
```ts
|
||||
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],
|
||||
selector: 'app-cart-summary',
|
||||
template: `
|
||||
<div class="cart-actions">
|
||||
<lib-reward-selection-trigger />
|
||||
<button>Proceed to Checkout</button>
|
||||
</div>
|
||||
`,
|
||||
imports: [RewardSelectionTriggerComponent]
|
||||
})
|
||||
export class CheckoutComponent {}
|
||||
export class CartSummaryComponent {}
|
||||
```
|
||||
|
||||
### Using the Pop-Up Service
|
||||
### One-Time Popup on Checkout Entry
|
||||
|
||||
More control over navigation flow:
|
||||
|
||||
```typescript
|
||||
import { Component, inject } from '@angular/core';
|
||||
```ts
|
||||
import { Component, inject, OnInit } from '@angular/core';
|
||||
import { Router } from '@angular/router';
|
||||
import {
|
||||
RewardSelectionPopUpService,
|
||||
NavigateAfterRewardSelection,
|
||||
RewardSelectionService,
|
||||
NavigateAfterRewardSelection
|
||||
} 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,
|
||||
],
|
||||
selector: 'app-checkout-entry',
|
||||
template: `<p>Loading checkout...</p>`,
|
||||
providers: [RewardSelectionPopUpService]
|
||||
})
|
||||
export class CustomCheckoutComponent {
|
||||
export class CheckoutEntryComponent implements OnInit {
|
||||
#router = inject(Router);
|
||||
#popUpService = inject(RewardSelectionPopUpService);
|
||||
|
||||
async openRewardSelection() {
|
||||
async ngOnInit() {
|
||||
const result = await this.#popUpService.popUp();
|
||||
|
||||
// Handle navigation: 'cart' | 'reward' | 'catalog' | undefined
|
||||
|
||||
if (result === NavigateAfterRewardSelection.CART) {
|
||||
// Navigate to cart
|
||||
await this.#router.navigate(['/cart']);
|
||||
} else if (result === NavigateAfterRewardSelection.REWARD) {
|
||||
await this.#router.navigate(['/reward-checkout']);
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Using the Service Directly
|
||||
### Checking Eligibility
|
||||
|
||||
For custom UI or advanced use cases:
|
||||
|
||||
```typescript
|
||||
import { Component, inject } from '@angular/core';
|
||||
```ts
|
||||
import { Component, inject, computed } from '@angular/core';
|
||||
import { RewardSelectionService } from '@isa/checkout/shared/reward-selection-dialog';
|
||||
import {
|
||||
SelectedShoppingCartResource,
|
||||
} from '@isa/checkout/data-access';
|
||||
|
||||
@Component({
|
||||
selector: 'app-advanced',
|
||||
selector: 'app-cart',
|
||||
template: `
|
||||
@if (canOpen()) {
|
||||
<button (click)="openDialog()" [disabled]="isLoading()">
|
||||
{{ eligibleItemsCount() }} items as rewards ({{ availablePoints() }} points)
|
||||
</button>
|
||||
@if (hasRewardEligibleItems()) {
|
||||
<div class="reward-banner">
|
||||
You have items eligible for reward redemption!
|
||||
<button (click)="openDialog()">Choose Payment Method</button>
|
||||
</div>
|
||||
}
|
||||
`,
|
||||
providers: [
|
||||
SelectedShoppingCartResource,
|
||||
RewardSelectionService,
|
||||
],
|
||||
providers: [RewardSelectionService]
|
||||
})
|
||||
export class AdvancedComponent {
|
||||
#service = inject(RewardSelectionService);
|
||||
export class CartComponent {
|
||||
#rewardSelectionService = inject(RewardSelectionService);
|
||||
|
||||
canOpen = this.#service.canOpen;
|
||||
isLoading = this.#service.isLoading;
|
||||
eligibleItemsCount = computed(() => this.#service.eligibleItems().length);
|
||||
availablePoints = this.#service.primaryBonusCardPoints;
|
||||
hasRewardEligibleItems = this.#rewardSelectionService.canOpen;
|
||||
|
||||
async openDialog() {
|
||||
const result = await this.#service.open({ closeText: 'Cancel' });
|
||||
if (result) {
|
||||
// Handle result.rewardSelectionItems
|
||||
await this.#service.reloadResources();
|
||||
}
|
||||
const result = await this.#rewardSelectionService.open({
|
||||
closeText: 'Cancel'
|
||||
});
|
||||
// Handle result...
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## API Reference
|
||||
## State Management
|
||||
|
||||
### RewardSelectionService
|
||||
The library uses `RewardSelectionStore` (NgRx Signal Store) internally to manage:
|
||||
|
||||
**Key Signals:**
|
||||
- `canOpen()`: `boolean` - Can dialog be opened
|
||||
- `isLoading()`: `boolean` - Loading state
|
||||
- `eligibleItems()`: `RewardSelectionItem[]` - Items available as rewards
|
||||
- `primaryBonusCardPoints()`: `number` - Available points
|
||||
- **State:** Item allocations, customer loyalty points
|
||||
- **Computed Values:** Total price, total loyalty points needed
|
||||
- **Methods:** Update cart quantities, update reward cart quantities
|
||||
|
||||
**Methods:**
|
||||
- `open({ closeText }): Promise<RewardSelectionDialogResult>` - Opens dialog
|
||||
- `reloadResources(): Promise<void>` - Reloads all data
|
||||
The store is scoped to each dialog instance and automatically initialized with dialog data.
|
||||
|
||||
### RewardSelectionPopUpService
|
||||
## Validation
|
||||
|
||||
**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
|
||||
|
||||
```typescript
|
||||
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:
|
||||
|
||||
```typescript
|
||||
providers: [
|
||||
SelectedShoppingCartResource, // Regular cart data
|
||||
RewardSelectionService, // Core service
|
||||
RewardSelectionPopUpService, // Optional: only if using pop-up
|
||||
]
|
||||
```
|
||||
|
||||
**Note:** `RewardSelectionTriggerComponent` includes all required providers automatically.
|
||||
|
||||
## Testing
|
||||
|
||||
```bash
|
||||
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
|
||||
```
|
||||
The dialog automatically validates:
|
||||
- Customer has sufficient loyalty points for selected reward items
|
||||
- Items are eligible for reward redemption (have loyalty points configured)
|
||||
- Changes were made before saving (prevents unnecessary API calls)
|
||||
|
||||
## 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
|
||||
Key dependencies on other @isa libraries:
|
||||
|
||||
- **@isa/checkout/data-access**: Shopping cart resources, reward selection models and facades
|
||||
- **@isa/ui/dialog**: Dialog infrastructure and directives
|
||||
- **@isa/ui/buttons**: Button components
|
||||
- **@isa/core/tabs**: Tab ID management for multi-tab support
|
||||
- **@isa/crm/data-access**: Customer card resource for loyalty points
|
||||
- **@isa/icons**: Order type icons for grouping display
|
||||
- **@ngrx/signals**: Signal Store for state management
|
||||
|
||||
## Architecture
|
||||
|
||||
The library follows a layered architecture:
|
||||
|
||||
1. **Presentation Layer**: Dialog and trigger components
|
||||
2. **State Layer**: Signal Store for reactive state management
|
||||
3. **Service Layer**: Dialog lifecycle and popup behavior services
|
||||
4. **Resource Layer**: Price and redemption points loading
|
||||
5. **Integration Layer**: Shopping cart and customer card resources
|
||||
|
||||
This separation ensures the dialog can be used in various contexts (manual trigger, automatic popup, embedded component) while maintaining consistent behavior and state management.
|
||||
|
||||
Reference in New Issue
Block a user