Merged PR 2026: feat(crm): add customer loyalty cards feature with points summary

Related work items: #5312
This commit is contained in:
Lorenz Hilpert
2025-11-14 12:59:02 +00:00
committed by Nino Righi
parent 70ded96858
commit 5057d56532
40 changed files with 1176 additions and 108 deletions

View File

@@ -1,34 +1,12 @@
<div class="flex flex-row justify-end -mt-2">
<page-customer-menu [customerId]="customerId$ | async" [processId]="processId$ | async" [showCustomerCard]="false"></page-customer-menu>
</div>
<h1 class="text-center text-2xl font-bold">Kundenkarte</h1>
@if (!(noDataFound$ | async)) {
<p class="text-center text-xl">
Alle Infos zu Ihrer Kundenkarte
<br />
und allen Partnerkarten.
</p>
}
@if (noDataFound$ | async) {
<p class="text-center text-xl">Keine Kundenkarte gefunden.</p>
}
@for (karte of primaryKundenkarte$ | async; track karte) {
<page-customer-kundenkarte
class="justify-self-center"
[cardDetails]="karte"
[isCustomerCard]="true"
[customerId]="customerId$ | async"
></page-customer-kundenkarte>
}
@if ((partnerKundenkarte$ | async)?.length) {
<p class="text-center text-xl font-bold">Partnerkarten</p>
}
@for (karte of partnerKundenkarte$ | async; track karte) {
<page-customer-kundenkarte
class="justify-self-center"
[cardDetails]="karte"
[isCustomerCard]="false"
></page-customer-kundenkarte>
}
<div class="flex flex-row justify-end -mt-2">
<page-customer-menu
[customerId]="customerId$ | async"
[processId]="processId$ | async"
[showCustomerCard]="false"
/>
</div>
<crm-customer-loyalty-cards
[customerId]="customerId$ | async"
[tabId]="processId$ | async"
class="mt-4"
/>

View File

@@ -1,63 +1,26 @@
import { Component, ChangeDetectionStrategy, OnInit, OnDestroy, inject } from '@angular/core';
import { CustomerSearchStore } from '../store';
import { ActivatedRoute } from '@angular/router';
import { Subject, combineLatest, of } from 'rxjs';
import { catchError, map, share, switchMap } from 'rxjs/operators';
import { CrmCustomerService } from '@domain/crm';
import { KundenkarteComponent } from '../../components/kundenkarte';
import { AsyncPipe } from '@angular/common';
import { CustomerSearchNavigation } from '@shared/services/navigation';
import { BonusCardInfoDTO } from '@generated/swagger/crm-api';
import { CustomerMenuComponent } from '../../components/customer-menu';
@Component({
selector: 'page-customer-kundenkarte-main-view',
templateUrl: 'kundenkarte-main-view.component.html',
styleUrls: ['kundenkarte-main-view.component.css'],
changeDetection: ChangeDetectionStrategy.OnPush,
host: { class: 'page-customer-kundenkarte-main-view' },
imports: [CustomerMenuComponent, KundenkarteComponent, AsyncPipe],
})
export class KundenkarteMainViewComponent implements OnInit, OnDestroy {
private _store = inject(CustomerSearchStore);
private _activatedRoute = inject(ActivatedRoute);
private _customerService = inject(CrmCustomerService);
private _navigation = inject(CustomerSearchNavigation);
private _onDestroy$ = new Subject<void>();
customerId$ = this._activatedRoute.params.pipe(map((params) => params.customerId));
processId$ = this._store.processId$;
kundenkarte$ = this.customerId$.pipe(
switchMap((customerId) =>
this._customerService.getCustomerCard(customerId).pipe(
map((response) => response.result?.filter((f) => f.isActive)),
catchError(() => of<BonusCardInfoDTO[]>([])),
),
),
share(),
);
noDataFound$ = this.kundenkarte$.pipe(map((kundenkarte) => kundenkarte?.length == 0));
primaryKundenkarte$ = this.kundenkarte$.pipe(map((kundenkarte) => kundenkarte?.filter((k) => k.isPrimary)));
partnerKundenkarte$ = this.kundenkarte$.pipe(map((kundenkarte) => kundenkarte?.filter((k) => !k.isPrimary)));
detailsRoute$ = combineLatest([this._store.processId$, this._store.customerId$]).pipe(
map(([processId, customerId]) => this._navigation.detailsRoute({ processId, customerId })),
);
ngOnInit() {
this.customerId$.subscribe((customerId) => {
this._store.selectCustomer(customerId);
});
}
ngOnDestroy() {
this._onDestroy$.next();
this._onDestroy$.complete();
}
}
import { Component, ChangeDetectionStrategy, inject } from '@angular/core';
import { CustomerSearchStore } from '../store';
import { ActivatedRoute } from '@angular/router';
import { map } from 'rxjs/operators';
import { AsyncPipe } from '@angular/common';
import { CustomerMenuComponent } from '../../components/customer-menu';
import { CustomerLoyaltyCardsComponent } from '@isa/crm/feature/customer-loyalty-cards';
@Component({
selector: 'page-customer-kundenkarte-main-view',
templateUrl: 'kundenkarte-main-view.component.html',
styleUrls: ['kundenkarte-main-view.component.css'],
changeDetection: ChangeDetectionStrategy.OnPush,
host: { class: 'page-customer-kundenkarte-main-view' },
imports: [CustomerMenuComponent, AsyncPipe, CustomerLoyaltyCardsComponent],
})
export class KundenkarteMainViewComponent {
private _store = inject(CustomerSearchStore);
private _activatedRoute = inject(ActivatedRoute);
customerId$ = this._activatedRoute.params.pipe(
map((params) => params.customerId),
);
processId$ = this._store.processId$;
}