From bb3aafd89ed3a993c8ff2a6f7ae240a9f2923497 Mon Sep 17 00:00:00 2001 From: kusowl Date: Tue, 17 Mar 2026 16:10:43 +0530 Subject: [PATCH] feature: show order summary on address page --- .ai/mcp/mcp.json | 12 ++++++ .../features/checkout/address/address.html | 37 ++++++++++++++++++- src/app/features/checkout/address/address.ts | 30 +++++++++++---- .../components/address-form/address-form.html | 6 ++- .../address-select/address-select.html | 1 - .../order-summery/order-summery.html | 25 ++++++++++++- .../components/order-summery/order-summery.ts | 16 ++++++-- 7 files changed, 111 insertions(+), 16 deletions(-) diff --git a/.ai/mcp/mcp.json b/.ai/mcp/mcp.json index e69de29..bb3f251 100644 --- a/.ai/mcp/mcp.json +++ b/.ai/mcp/mcp.json @@ -0,0 +1,12 @@ +{ + "mcpServers": { + "angular-cli": { + "command": "npx", + "args": [ + "-y", + "@angular/cli", + "mcp" + ] + } + } +} \ No newline at end of file diff --git a/src/app/features/checkout/address/address.html b/src/app/features/checkout/address/address.html index dadbf33..ca829e0 100644 --- a/src/app/features/checkout/address/address.html +++ b/src/app/features/checkout/address/address.html @@ -4,12 +4,45 @@
@for (address of addresses(); track address.id) { - +
+ + +
} - +
+
+
+ Have any coupon ? +
+ + +
+
+ @if (addressIdControl.invalid && addressIdControl.touched) { +
+ Please select an address +
+ } + +
diff --git a/src/app/features/checkout/address/address.ts b/src/app/features/checkout/address/address.ts index 56404fd..e74443c 100644 --- a/src/app/features/checkout/address/address.ts +++ b/src/app/features/checkout/address/address.ts @@ -1,4 +1,4 @@ -import { Component, inject, OnInit, signal } from "@angular/core"; +import { Component, DestroyRef, inject, OnInit, signal } from "@angular/core"; import { AddressForm } from "../components/address-form/address-form"; import { GoBack } from "@app/shared/components/go-back/go-back"; import { AddressSelect } from "../components/address-select/address-select"; @@ -10,19 +10,27 @@ import { } from "@app/features/checkout/services/address-service"; import { AuthService } from "@core/services/auth-service"; import { User } from "@core/models/user.model"; -import { switchMap } from "rxjs"; +import { of, switchMap } from "rxjs"; +import { takeUntilDestroyed } from "@angular/core/rxjs-interop"; +import { FormControl, ReactiveFormsModule, Validators } from "@angular/forms"; @Component({ selector: "app-address", - imports: [AddressSelect, AddressForm, GoBack, OrderSummery], + imports: [AddressSelect, AddressForm, GoBack, OrderSummery, ReactiveFormsModule], templateUrl: "./address.html", styleUrl: "./address.css", }) export class Address implements OnInit { addressService = inject(AddressService); authService = inject(AuthService); - private user: User | undefined; + + // I am subscribing to the observable instead of using toSignal(), + // i have to destroy the subscription manually. + destroyRef = inject(DestroyRef); + protected addresses = signal([]); + protected addressIdControl = new FormControl(null, Validators.required); + private user: User | undefined; ngOnInit(): void { this.authService @@ -33,8 +41,9 @@ export class Address implements OnInit { if (user?.id) { return this.addressService.fetchAddresses(user.id); } - return []; + return of({ data: [] }); }), + takeUntilDestroyed(this.destroyRef), ) .subscribe({ next: (addresses) => { @@ -43,12 +52,12 @@ export class Address implements OnInit { }); } - createNewAddress(addressData: AddressRequest) { + protected createNewAddress(addressData: AddressRequest) { this.addressService.createAddress(this.user!.id, addressData).subscribe({ next: (address) => this.addresses.update((addresses) => [...addresses, address]), }); } - updateAddress(addressData: AddressResponse) { + protected updateAddress(addressData: AddressResponse) { console.log(addressData); this.addressService.updateAddress(addressData.id, addressData).subscribe({ next: (address) => @@ -57,4 +66,11 @@ export class Address implements OnInit { ), }); } + + protected proceedToPayment() { + if (this.addressIdControl.invalid) { + this.addressIdControl.markAsTouched(); + return; + } + } } diff --git a/src/app/features/checkout/components/address-form/address-form.html b/src/app/features/checkout/components/address-form/address-form.html index 6ac7da9..ac5ddf5 100644 --- a/src/app/features/checkout/components/address-form/address-form.html +++ b/src/app/features/checkout/components/address-form/address-form.html @@ -1,4 +1,8 @@ -
+
-

{{[address.firstName, address.lastName] | fullname}}

{{`${address.street}, ${address.city}, ${address.pinCode}`}} diff --git a/src/app/features/checkout/components/order-summery/order-summery.html b/src/app/features/checkout/components/order-summery/order-summery.html index 4d21641..49b9257 100644 --- a/src/app/features/checkout/components/order-summery/order-summery.html +++ b/src/app/features/checkout/components/order-summery/order-summery.html @@ -1,3 +1,24 @@ -

-

Order Summery

+
+

Order Summery

+ @if (cartItems | async; as cart) { @for (item of cart.items; track item.id) { +
+
+
+ product image +
+
+

{{item.title}}

+

Rs. {{item.price}} x {{item.quantity}}

+
+
+

Rs. {{item.subtotal}}

+
+ } +
+

Total

+

Rs. {{cart.totalPrice}}

+
+ }
diff --git a/src/app/features/checkout/components/order-summery/order-summery.ts b/src/app/features/checkout/components/order-summery/order-summery.ts index 3a03579..2bcdf1b 100644 --- a/src/app/features/checkout/components/order-summery/order-summery.ts +++ b/src/app/features/checkout/components/order-summery/order-summery.ts @@ -1,9 +1,19 @@ -import { Component } from "@angular/core"; +import { Component, inject, OnInit } from "@angular/core"; +import { CartService } from "@core/services/cart-service"; +import { CartModel } from "@core/models/cart.model"; +import { Observable } from "rxjs"; +import { AsyncPipe, NgOptimizedImage } from "@angular/common"; @Component({ selector: "app-order-summery", - imports: [], + imports: [AsyncPipe, NgOptimizedImage], templateUrl: "./order-summery.html", styleUrl: "./order-summery.css", }) -export class OrderSummery {} +export class OrderSummery implements OnInit { + cartService = inject(CartService); + cartItems: Observable | undefined; + ngOnInit(): void { + this.cartItems = this.cartService.cartItems$; + } +}