feat: enhance checkout process with purchase editing and status handling

- Implemented purchase editing functionality in CheckoutPageComponent, allowing users to modify items in their purchase.
- Added a new guard (checkoutPendingPurchaseGuard) to prevent navigation away from the checkout page while a purchase is in progress.
- Updated the login page to handle return URLs after authentication.
- Enhanced product detail page to support direct purchases with a new buyNow method.
- Introduced new UI elements and logic to handle purchase status, including expired and rejected states in PurchaseStatusPageComponent.
- Improved cart component to allow editing of item quantities with a toggle button.
- Added quantity selector enhancements to disable controls when necessary.
- Updated tests to cover new functionalities and ensure proper behavior of components.
This commit is contained in:
2026-07-27 12:49:00 -03:00
parent 9dcedc9382
commit 902f65d8d0
31 changed files with 1253 additions and 219 deletions

View File

@@ -4,6 +4,7 @@ import {
computed,
inject,
input,
model,
output,
signal,
} from '@angular/core';
@@ -48,11 +49,21 @@ export class CartComponent {
readonly discount = input<number>(0);
readonly total = input<number>(0);
readonly backgroundColor = input<string>('#ffffff');
readonly readonly = input<boolean>(false);
readonly allowEditing = input<boolean>(false);
readonly allowRemove = input<boolean>(true);
readonly persistQuantityChanges = input<boolean>(true);
readonly editingDisabled = input<boolean>(false);
readonly editing = model<boolean>(false);
readonly closed = output<void>();
readonly itemQuantityChange = output<{
item: CartItemMock;
index: number;
quantity: number;
}>();
protected readonly quantityOverrides = signal<Record<number, number>>({});
constructor() {
this.quantityUpdates$
.pipe(
@@ -103,6 +114,20 @@ export class CartComponent {
protected onItemQuantityChange(index: number, newQuantity: number): void {
const mockItem = this.items()[index];
if (!mockItem) {
return;
}
this.itemQuantityChange.emit({
item: mockItem,
index,
quantity: newQuantity,
});
if (!this.persistQuantityChanges()) {
return;
}
const cartItemId = mockItem?.cartItemId;
if (cartItemId) {
this.quantityOverrides.update((overrides) => ({
@@ -153,6 +178,15 @@ export class CartComponent {
protected readonly formattedDiscount = computed(() => this.formatCurrency(this.discount()));
protected readonly formattedTotal = computed(() => this.formatCurrency(this.total()));
protected toggleEditing(): void {
if (this.editingDisabled()) {
return;
}
const editing = !this.editing();
this.editing.set(editing);
}
private formatCurrency(value: number): string {
const rounded = Math.round(value);
const parts = rounded.toString().split('.');