diff --git a/apps/isa-app/src/page/customer/customer-search/kundenkarte-main-view/kundenkarte-main-view.component.html b/apps/isa-app/src/page/customer/customer-search/kundenkarte-main-view/kundenkarte-main-view.component.html
index 19229a385..14e4a1e2e 100644
--- a/apps/isa-app/src/page/customer/customer-search/kundenkarte-main-view/kundenkarte-main-view.component.html
+++ b/apps/isa-app/src/page/customer/customer-search/kundenkarte-main-view/kundenkarte-main-view.component.html
@@ -9,28 +9,30 @@
[customerId]="customerId$ | async"
[tabId]="processId$ | async"
(navigateToPraemienshop)="onNavigateToPraemienshop()"
+ (cardUpdated)="reloadCardTransactionsAndCards()"
class="mt-4"
/>
-@let cardCode = firstActiveCardCode();
+@let activeCardCode = firstActiveCardCode();
-@if (cardCode) {
+@if (activeCardCode) {
-
}
+
+
{
+ const cards = this.#bonusCardsResource.resource.value();
+ const firstCard = cards?.[0];
+ return firstCard?.code;
+ });
+
/**
* Get the first active card code
*/
diff --git a/libs/crm/feature/customer-bon-redemption/src/lib/crm-feature-customer-bon-redemption/components/bon-input-field/bon-input-field.component.html b/libs/crm/feature/customer-bon-redemption/src/lib/crm-feature-customer-bon-redemption/components/bon-input-field/bon-input-field.component.html
index 009dcd46f..65ec2b7b9 100644
--- a/libs/crm/feature/customer-bon-redemption/src/lib/crm-feature-customer-bon-redemption/components/bon-input-field/bon-input-field.component.html
+++ b/libs/crm/feature/customer-bon-redemption/src/lib/crm-feature-customer-bon-redemption/components/bon-input-field/bon-input-field.component.html
@@ -10,7 +10,7 @@
[ngModel]="store.bonNumber()"
(ngModelChange)="onBonNumberChange($event)"
required
- placeholder="Bon Nummer / Rechnungs-Nummer (HUG.de)*"
+ placeholder="Bon Nummer"
data-what="bon-number-input"
data-which="customer-loyalty"
aria-label="Bon Nummer eingeben"
diff --git a/libs/crm/feature/customer-loyalty-cards/src/lib/components/add-customer-card/add-customer-card.component.ts b/libs/crm/feature/customer-loyalty-cards/src/lib/components/add-customer-card/add-customer-card.component.ts
index 0f82892f2..72b19ce04 100644
--- a/libs/crm/feature/customer-loyalty-cards/src/lib/components/add-customer-card/add-customer-card.component.ts
+++ b/libs/crm/feature/customer-loyalty-cards/src/lib/components/add-customer-card/add-customer-card.component.ts
@@ -2,8 +2,7 @@ import {
ChangeDetectionStrategy,
Component,
inject,
- input,
- OnDestroy,
+ output,
} from '@angular/core';
import { Validators } from '@angular/forms';
import { logger } from '@isa/core/logging';
@@ -22,8 +21,7 @@ import { firstValueFrom } from 'rxjs';
changeDetection: ChangeDetectionStrategy.OnPush,
imports: [TextButtonComponent],
})
-export class AddCustomerCardComponent implements OnDestroy {
- #reloadTimeoutId?: ReturnType;
+export class AddCustomerCardComponent {
#logger = logger(() => ({
component: 'AddCustomerCardComponent',
}));
@@ -34,6 +32,12 @@ export class AddCustomerCardComponent implements OnDestroy {
#textDialog = injectTextInputDialog();
#feedbackDialog = injectFeedbackDialog();
+ /**
+ * Event emitted when a card has been successfully added.
+ * Parent should reload cards and transactions.
+ */
+ readonly cardAdded = output();
+
async addCardDialog() {
this.#logger.debug('Opening add card dialog');
const dialogRef = this.#textDialog({
@@ -52,7 +56,6 @@ export class AddCustomerCardComponent implements OnDestroy {
],
onConfirm: async (cardCode: string) => {
await this.addCard(cardCode);
- this.reloadCards();
},
},
width: '30rem',
@@ -62,6 +65,7 @@ export class AddCustomerCardComponent implements OnDestroy {
if (dialogResult?.inputValue) {
this.feedback();
+ this.cardAdded.emit();
}
}
@@ -90,16 +94,4 @@ export class AddCustomerCardComponent implements OnDestroy {
});
this.#logger.info('Adding customer card complete', () => ({ cardCode }));
}
-
- reloadCards() {
- this.#reloadTimeoutId = setTimeout(() => {
- this.#bonusCardsResource.resource.reload();
- }, 500);
- }
-
- ngOnDestroy(): void {
- if (this.#reloadTimeoutId) {
- clearTimeout(this.#reloadTimeoutId);
- }
- }
}
diff --git a/libs/crm/feature/customer-loyalty-cards/src/lib/components/customer-card/customer-card.component.html b/libs/crm/feature/customer-loyalty-cards/src/lib/components/customer-card/customer-card.component.html
index 47f65d600..41c847872 100644
--- a/libs/crm/feature/customer-loyalty-cards/src/lib/components/customer-card/customer-card.component.html
+++ b/libs/crm/feature/customer-loyalty-cards/src/lib/components/customer-card/customer-card.component.html
@@ -48,6 +48,7 @@
diff --git a/libs/crm/feature/customer-loyalty-cards/src/lib/components/customer-card/customer-card.component.ts b/libs/crm/feature/customer-loyalty-cards/src/lib/components/customer-card/customer-card.component.ts
index bc6a45edd..910fba544 100644
--- a/libs/crm/feature/customer-loyalty-cards/src/lib/components/customer-card/customer-card.component.ts
+++ b/libs/crm/feature/customer-loyalty-cards/src/lib/components/customer-card/customer-card.component.ts
@@ -1,4 +1,9 @@
-import { ChangeDetectionStrategy, Component, input } from '@angular/core';
+import {
+ ChangeDetectionStrategy,
+ Component,
+ input,
+ output,
+} from '@angular/core';
import { BonusCardInfo } from '@isa/crm/data-access';
import { BarcodeComponent } from '@isa/shared/barcode';
import { LockCustomerCardComponent } from '../lock-customer-card/lock-customer-card.component';
@@ -35,6 +40,12 @@ export class CustomerCardComponent {
*/
readonly card = input.required();
+ /**
+ * Event emitted when a card has been successfully locked or unlocked.
+ * Parent should reload cards and transactions.
+ */
+ readonly cardLocked = output();
+
/**
* Barcode dimensions in rem, converted to pixels for JsBarcode.
* Base: 1rem = 16px
diff --git a/libs/crm/feature/customer-loyalty-cards/src/lib/components/customer-cards-carousel/customer-cards-carousel.component.html b/libs/crm/feature/customer-loyalty-cards/src/lib/components/customer-cards-carousel/customer-cards-carousel.component.html
index 4686bfe7d..f9e5ba579 100644
--- a/libs/crm/feature/customer-loyalty-cards/src/lib/components/customer-cards-carousel/customer-cards-carousel.component.html
+++ b/libs/crm/feature/customer-loyalty-cards/src/lib/components/customer-cards-carousel/customer-cards-carousel.component.html
@@ -6,7 +6,7 @@
[padding]="'0.75rem 0.5rem'"
>
@for (card of sortedCards(); track card.code) {
-
+
}
diff --git a/libs/crm/feature/customer-loyalty-cards/src/lib/components/customer-cards-carousel/customer-cards-carousel.component.ts b/libs/crm/feature/customer-loyalty-cards/src/lib/components/customer-cards-carousel/customer-cards-carousel.component.ts
index bb84a6bc2..33ba03407 100644
--- a/libs/crm/feature/customer-loyalty-cards/src/lib/components/customer-cards-carousel/customer-cards-carousel.component.ts
+++ b/libs/crm/feature/customer-loyalty-cards/src/lib/components/customer-cards-carousel/customer-cards-carousel.component.ts
@@ -33,6 +33,12 @@ export class CustomerCardsCarouselComponent {
*/
readonly cards = input.required();
+ /**
+ * Event emitted when a card has been successfully locked or unlocked.
+ * Parent should reload cards and transactions.
+ */
+ readonly cardLocked = output();
+
/**
* Cards sorted with blocked cards at the end.
* Per Figma annotation: "gesperrte Karte immer nach hinten"
diff --git a/libs/crm/feature/customer-loyalty-cards/src/lib/components/lock-customer-card/lock-customer-card.component.ts b/libs/crm/feature/customer-loyalty-cards/src/lib/components/lock-customer-card/lock-customer-card.component.ts
index 94134616a..27e051299 100644
--- a/libs/crm/feature/customer-loyalty-cards/src/lib/components/lock-customer-card/lock-customer-card.component.ts
+++ b/libs/crm/feature/customer-loyalty-cards/src/lib/components/lock-customer-card/lock-customer-card.component.ts
@@ -3,7 +3,7 @@ import {
Component,
inject,
input,
- OnDestroy,
+ output,
signal,
} from '@angular/core';
import { logger } from '@isa/core/logging';
@@ -24,8 +24,7 @@ import {
changeDetection: ChangeDetectionStrategy.OnPush,
imports: [TextButtonComponent],
})
-export class LockCustomerCardComponent implements OnDestroy {
- #reloadTimeoutId?: ReturnType;
+export class LockCustomerCardComponent {
#logger = logger(() => ({
component: 'LockCustomerCardComponent',
}));
@@ -41,6 +40,12 @@ export class LockCustomerCardComponent implements OnDestroy {
readonly #customerId = this.#bonusCardsResource.customerId;
+ /**
+ * Event emitted when a card has been successfully locked or unlocked.
+ * Parent should reload cards and transactions.
+ */
+ readonly cardLocked = output();
+
loading = signal(false);
async lockCard() {
@@ -55,7 +60,7 @@ export class LockCustomerCardComponent implements OnDestroy {
message: 'Karte gesperrt',
},
});
- this.reloadCards();
+ this.cardLocked.emit();
} catch (error: unknown) {
this.#logger.error('Error locking card', error as Error, () => ({
cardCode,
@@ -90,7 +95,7 @@ export class LockCustomerCardComponent implements OnDestroy {
message: 'Karte entsperrt',
},
});
- this.reloadCards();
+ this.cardLocked.emit();
} catch (error: unknown) {
this.#logger.error('Error unlocking card', error as Error, () => ({
cardCode,
@@ -104,16 +109,4 @@ export class LockCustomerCardComponent implements OnDestroy {
this.loading.set(false);
}
}
-
- reloadCards() {
- this.#reloadTimeoutId = setTimeout(() => {
- this.#bonusCardsResource.resource.reload();
- }, 500);
- }
-
- ngOnDestroy(): void {
- if (this.#reloadTimeoutId) {
- clearTimeout(this.#reloadTimeoutId);
- }
- }
}
diff --git a/libs/crm/feature/customer-loyalty-cards/src/lib/customer-loyalty-cards.component.html b/libs/crm/feature/customer-loyalty-cards/src/lib/customer-loyalty-cards.component.html
index 6976add2e..6b1edf0c5 100644
--- a/libs/crm/feature/customer-loyalty-cards/src/lib/customer-loyalty-cards.component.html
+++ b/libs/crm/feature/customer-loyalty-cards/src/lib/customer-loyalty-cards.component.html
@@ -28,8 +28,12 @@
/>
-
+
-
+
}
diff --git a/libs/crm/feature/customer-loyalty-cards/src/lib/customer-loyalty-cards.component.ts b/libs/crm/feature/customer-loyalty-cards/src/lib/customer-loyalty-cards.component.ts
index dca5770d3..14b72b2ed 100644
--- a/libs/crm/feature/customer-loyalty-cards/src/lib/customer-loyalty-cards.component.ts
+++ b/libs/crm/feature/customer-loyalty-cards/src/lib/customer-loyalty-cards.component.ts
@@ -62,6 +62,12 @@ export class CustomerLoyaltyCardsComponent {
*/
readonly navigateToPraemienshop = output();
+ /**
+ * Event emitted when a card has been added, locked, or unlocked.
+ * Parent should reload cards and transactions.
+ */
+ readonly cardUpdated = output();
+
/**
* All bonus cards for the selected customer.
*/
@@ -96,4 +102,13 @@ export class CustomerLoyaltyCardsComponent {
this.#logger.info('Emit navigate to Prämienshop event');
this.navigateToPraemienshop.emit();
}
+
+ /**
+ * Handle card update events from child components.
+ * Forwards the event to parent for reload coordination.
+ */
+ onCardUpdated(): void {
+ this.#logger.debug('Card updated, forwarding event to parent');
+ this.cardUpdated.emit();
+ }
}