feature: user can change quantity and remove products
This commit is contained in:
parent
9000ea0052
commit
2b88cee10b
@ -13,3 +13,8 @@ export interface CartModel {
|
||||
totalPrice: number;
|
||||
items: CartItemModel[];
|
||||
}
|
||||
|
||||
export interface CartItemRequest {
|
||||
productId: number;
|
||||
quantity: number;
|
||||
}
|
||||
|
||||
@ -1,8 +1,9 @@
|
||||
import { HttpClient, HttpErrorResponse } from "@angular/common/http";
|
||||
import { effect, inject, Injectable, signal } from "@angular/core";
|
||||
import { API_URL } from "../tokens/api-url-tokens";
|
||||
import { CartModel } from "../models/cart.model";
|
||||
import { CartItemModel, CartItemRequest, CartModel } from "../models/cart.model";
|
||||
import { AuthService, AuthState } from "@app/features/auth/services/auth-service";
|
||||
import { Cart } from "@app/shared/components/cart/cart";
|
||||
|
||||
@Injectable({
|
||||
providedIn: "root",
|
||||
@ -36,4 +37,12 @@ export class CartService {
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
updateCart(data: CartItemRequest) {
|
||||
return this.http.patch<CartModel>(this.apiUrl + "/cart", data);
|
||||
}
|
||||
|
||||
removeFromCart(productId: number) {
|
||||
return this.http.delete<CartModel>(this.apiUrl + "/cart", { body: { productId: productId } });
|
||||
}
|
||||
}
|
||||
|
||||
@ -7,17 +7,19 @@
|
||||
<p class="text-sm truncate max-w-30 mt-2">{{ cartItem.title }}</p>
|
||||
<div class="mt-auto flex space-x-4 items-center text-gray-600">
|
||||
<p class="text-sm">Rs. {{ cartItem.price }} x {{ cartItem.quantity }}</p>
|
||||
<button class="active:scale-80" title="Remove Item">
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-col justify-between">
|
||||
<div class="mt-2 flex space-x-2 items-center">
|
||||
<p class="font-medium">Rs. {{ cartItem.subtotal }}</p>
|
||||
<button (click)="removeProduct()" class="active:scale-80 py-0" title="Remove Item">
|
||||
<lucide-angular [name]="TrashIcon" class="w-3" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-col">
|
||||
<p class="mt-2 font-medium flex-1">Rs. {{ cartItem.subtotal }}</p>
|
||||
<div class="flex max-h-7 text-xs text-center text-gray-700">
|
||||
<button class="btn btn-ghost py-1! px-2 rounded-r-none!">-</button>
|
||||
<p class="py-1 px-2 border-y border-y-gray-300">{{ cartItem.quantity }}</p>
|
||||
<button class="btn py-1! btn-ghost px-2 rounded-l-none!">+</button>
|
||||
<button (click)="decrementQty()" class="btn btn-ghost py-1! px-2 rounded-r-none!">-</button>
|
||||
<p class="w-7 text-center py-1 px-2 border-y border-y-gray-300">{{ cartItem.quantity }}</p>
|
||||
<button (click)="incrementQty()" class="btn py-1! btn-ghost px-2 rounded-l-none!">+</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { Component, Input } from "@angular/core";
|
||||
import { CartItemModel } from "@app/core/models/cart.model";
|
||||
import { Component, EventEmitter, Input, Output, signal } from "@angular/core";
|
||||
import { CartItemModel, CartItemRequest } from "@app/core/models/cart.model";
|
||||
import { LucideAngularModule, Trash } from "lucide-angular";
|
||||
|
||||
@Component({
|
||||
@ -10,5 +10,25 @@ import { LucideAngularModule, Trash } from "lucide-angular";
|
||||
})
|
||||
export class CartItem {
|
||||
@Input() cartItem!: CartItemModel;
|
||||
@Output() qtyChangeEvent = new EventEmitter<CartItemRequest>();
|
||||
@Output() productDeleteEvent = new EventEmitter<number>();
|
||||
TrashIcon = Trash;
|
||||
|
||||
incrementQty() {
|
||||
if (this.cartItem.quantity < 10) {
|
||||
this.cartItem.quantity += 1;
|
||||
this.qtyChangeEvent.emit({ productId: this.cartItem.id, quantity: this.cartItem.quantity });
|
||||
}
|
||||
}
|
||||
|
||||
decrementQty() {
|
||||
if (this.cartItem.quantity > 1) {
|
||||
this.cartItem.quantity -= 1;
|
||||
this.qtyChangeEvent.emit({ productId: this.cartItem.id, quantity: this.cartItem.quantity });
|
||||
}
|
||||
}
|
||||
|
||||
removeProduct() {
|
||||
this.productDeleteEvent.emit(this.cartItem.id);
|
||||
}
|
||||
}
|
||||
|
||||
@ -4,9 +4,17 @@
|
||||
} @else if (authService.authState() === AuthState.Loading) {
|
||||
<li><a class="block h-full w-full">Loading</a></li>
|
||||
} @else {
|
||||
<ol>
|
||||
<ol
|
||||
[class.pointer-events-none]="isLoading()"
|
||||
[class.opacity-40]="isLoading()"
|
||||
[class.cursor-block]="isLoading()"
|
||||
>
|
||||
@for (item of cart.items; track item.id) {
|
||||
<app-cart-item [cartItem]="item" />
|
||||
<app-cart-item
|
||||
(qtyChangeEvent)="updateProductQty($event)"
|
||||
(productDeleteEvent)="removeProduct($event)"
|
||||
[cartItem]="item"
|
||||
/>
|
||||
}
|
||||
</ol>
|
||||
|
||||
|
||||
@ -1,7 +1,9 @@
|
||||
import { Component, computed, inject, Input } from "@angular/core";
|
||||
import { CartModel } from "@app/core/models/cart.model";
|
||||
import { Component, computed, inject, Input, signal } from "@angular/core";
|
||||
import { CartItemModel, CartItemRequest, CartModel } from "@app/core/models/cart.model";
|
||||
import { CartItem } from "../cart-item/cart-item";
|
||||
import { AuthService, AuthState } from "@app/features/auth/services/auth-service";
|
||||
import { CartService } from "@app/core/services/cart-service";
|
||||
import { finalize, tap } from "rxjs";
|
||||
|
||||
@Component({
|
||||
selector: "app-cart",
|
||||
@ -12,6 +14,31 @@ import { AuthService, AuthState } from "@app/features/auth/services/auth-service
|
||||
export class Cart {
|
||||
@Input() cart!: CartModel;
|
||||
|
||||
isLoading = signal(false);
|
||||
|
||||
protected readonly authService = inject(AuthService);
|
||||
protected readonly cartService = inject(CartService);
|
||||
protected readonly AuthState = AuthState;
|
||||
|
||||
updateProductQty(cartItem: CartItemRequest) {
|
||||
this.isLoading.set(true);
|
||||
|
||||
this.cartService
|
||||
.updateCart(cartItem)
|
||||
.pipe(finalize(() => this.isLoading.set(false)))
|
||||
.subscribe((cartdata) => {
|
||||
this.cart = cartdata;
|
||||
});
|
||||
}
|
||||
|
||||
removeProduct(productId: number) {
|
||||
this.isLoading.set(true);
|
||||
|
||||
this.cartService
|
||||
.removeFromCart(productId)
|
||||
.pipe(finalize(() => this.isLoading.set(false)))
|
||||
.subscribe((cartData) => {
|
||||
this.cart = cartData;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user