feature: show order summary on address page
This commit is contained in:
parent
419e8281e2
commit
bb3aafd89e
@ -0,0 +1,12 @@
|
||||
{
|
||||
"mcpServers": {
|
||||
"angular-cli": {
|
||||
"command": "npx",
|
||||
"args": [
|
||||
"-y",
|
||||
"@angular/cli",
|
||||
"mcp"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -4,12 +4,45 @@
|
||||
<div class="grid grid-cols-3 gap-x-10">
|
||||
<div class="col-span-2 flex flex-col space-y-4">
|
||||
@for (address of addresses(); track address.id) {
|
||||
<app-address-select [address]="address" (addressUpdated)="updateAddress($event)" />
|
||||
<div class="flex space-x-2">
|
||||
<input
|
||||
type="radio"
|
||||
name="address"
|
||||
value="{{address.id}}"
|
||||
[formControl]="addressIdControl"
|
||||
/>
|
||||
<app-address-select
|
||||
class="flex-1"
|
||||
[address]="address"
|
||||
(addressUpdated)="updateAddress($event)"
|
||||
/>
|
||||
</div>
|
||||
}
|
||||
<app-address-form (submitAddress)="createNewAddress($event)" />
|
||||
<app-address-form class="ml-5" (submitAddress)="createNewAddress($event)" />
|
||||
</div>
|
||||
<div>
|
||||
<app-order-summery />
|
||||
<div class="card mt-4">
|
||||
<fieldset class="fieldset">
|
||||
<legend class="fieldset-legend">Have any coupon ?</legend>
|
||||
<div class="flex items-center space-x-2">
|
||||
<input placeholder="Enter coupon here" type="text" class="input" />
|
||||
<button class="btn btn-ghost px-4">Apply</button>
|
||||
</div>
|
||||
</fieldset>
|
||||
@if (addressIdControl.invalid && addressIdControl.touched) {
|
||||
<div class="text-red-500 text-sm p-4 mt-4 rounded-xl bg-red-50">
|
||||
Please select an address
|
||||
</div>
|
||||
}
|
||||
<button
|
||||
class="btn btn-primary w-full mt-4"
|
||||
(click)="proceedToPayment()"
|
||||
[disabled]="addressIdControl.invalid && addressIdControl.touched"
|
||||
>
|
||||
Proceed to payment
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -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<AddressResponse[]>([]);
|
||||
protected addressIdControl = new FormControl<number | null>(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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,8 @@
|
||||
<details class="card p-0!" title="Click to add a new address">
|
||||
<details
|
||||
class="card p-0!"
|
||||
title="Click to add a new address"
|
||||
[open]="isEditing()"
|
||||
>
|
||||
<summary class="p-6">
|
||||
<label for="currentAddress" class="font-medium text-gray-600 ml-2"
|
||||
>{{isEditing() ? 'Update address' : 'Add new address'}}</label
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
@if (!isEditing()) {
|
||||
<div class="flex justify-between card">
|
||||
<div class="flex space-x-4 items-center">
|
||||
<input type="radio" name="address" />
|
||||
<p class="text-gray-600 font-medium">{{[address.firstName, address.lastName] | fullname}}</p>
|
||||
<p class="text-gray-400 text-sm">
|
||||
{{`${address.street}, ${address.city}, ${address.pinCode}`}}
|
||||
|
||||
@ -1,3 +1,24 @@
|
||||
<div class="card h-155">
|
||||
<p class="text-gray-600 font-medium">Order Summery</p>
|
||||
<div class="card">
|
||||
<p class="text-gray-800 font-medium text-xl">Order Summery</p>
|
||||
@if (cartItems | async; as cart) { @for (item of cart.items; track item.id) {
|
||||
<article
|
||||
class="mt-4 pb-4 border-b border-b-gray-400 border-dashed flex justify-between items-center"
|
||||
>
|
||||
<div class="flex space-x-4">
|
||||
<div class="w-15 h-15 rounded-lg aspect-square relative overflow-hidden">
|
||||
<img ngSrc="{{item.image}}" fill class="object-cover" alt="product image" />
|
||||
</div>
|
||||
<article>
|
||||
<h2>{{item.title}}</h2>
|
||||
<p class="text-gray-600 text-sm">Rs. {{item.price}} x {{item.quantity}}</p>
|
||||
</article>
|
||||
</div>
|
||||
<p class="text-gray-800 font-medium">Rs. {{item.subtotal}}</p>
|
||||
</article>
|
||||
}
|
||||
<article class="mt-4 flex justify-between items-center text-lg">
|
||||
<p class="text-gray-800 font-medium">Total</p>
|
||||
<p class="text-gray-800 font-medium">Rs. {{cart.totalPrice}}</p>
|
||||
</article>
|
||||
}
|
||||
</div>
|
||||
|
||||
@ -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<CartModel> | undefined;
|
||||
ngOnInit(): void {
|
||||
this.cartItems = this.cartService.cartItems$;
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user