From 0765e63d8ad84ef510b120d938bac02fe60ec1bd Mon Sep 17 00:00:00 2001 From: Khwezi Mngoma Date: Fri, 12 Jun 2026 08:54:53 +0200 Subject: [PATCH] Using shared service for Cart management --- .../Components/Layout/MainLayout.razor.cs | 4 +- .../Pages/{Cart.razor => CartReview.razor} | 0 .../{Cart.razor.cs => CartReview.razor.cs} | 8 +- .../{Cart.razor.css => CartReview.razor.css} | 0 .../Components/Pages/Checkout.razor.cs | 6 +- .../Components/Pages/ProductView.razor.cs | 6 +- MidrandBookshop/MidrandBookshop.csproj | 4 +- MidrandBookshop/Program.cs | 2 - .../Services/ShoppingCart/CartService.cs | 153 ------------------ .../Services/ShoppingCart/Models/Cart.cs | 18 --- .../Services/ShoppingCart/Models/CartItem.cs | 17 -- 11 files changed, 14 insertions(+), 204 deletions(-) rename MidrandBookshop/Components/Pages/{Cart.razor => CartReview.razor} (100%) rename MidrandBookshop/Components/Pages/{Cart.razor.cs => CartReview.razor.cs} (75%) rename MidrandBookshop/Components/Pages/{Cart.razor.css => CartReview.razor.css} (100%) delete mode 100644 MidrandBookshop/Services/ShoppingCart/CartService.cs delete mode 100644 MidrandBookshop/Services/ShoppingCart/Models/Cart.cs delete mode 100644 MidrandBookshop/Services/ShoppingCart/Models/CartItem.cs diff --git a/MidrandBookshop/Components/Layout/MainLayout.razor.cs b/MidrandBookshop/Components/Layout/MainLayout.razor.cs index dd53781..0c82f33 100644 --- a/MidrandBookshop/Components/Layout/MainLayout.razor.cs +++ b/MidrandBookshop/Components/Layout/MainLayout.razor.cs @@ -1,5 +1,5 @@ -using MidrandBookshop.Services.ShoppingCart; -using MidrandBookshop.Services.ShoppingCart.Models; +using LiteCharms.Features.MidrandBooks.Payments; +using LiteCharms.Features.MidrandBooks.Payments.Models; namespace MidrandBookshop.Components.Layout; diff --git a/MidrandBookshop/Components/Pages/Cart.razor b/MidrandBookshop/Components/Pages/CartReview.razor similarity index 100% rename from MidrandBookshop/Components/Pages/Cart.razor rename to MidrandBookshop/Components/Pages/CartReview.razor diff --git a/MidrandBookshop/Components/Pages/Cart.razor.cs b/MidrandBookshop/Components/Pages/CartReview.razor.cs similarity index 75% rename from MidrandBookshop/Components/Pages/Cart.razor.cs rename to MidrandBookshop/Components/Pages/CartReview.razor.cs index de784b5..2745574 100644 --- a/MidrandBookshop/Components/Pages/Cart.razor.cs +++ b/MidrandBookshop/Components/Pages/CartReview.razor.cs @@ -1,11 +1,11 @@ -using MidrandBookshop.Services.ShoppingCart; -using MidrandBookshop.Services.ShoppingCart.Models; +using LiteCharms.Features.MidrandBooks.Payments; +using LiteCharms.Features.MidrandBooks.Payments.Models; namespace MidrandBookshop.Components.Pages; -public partial class Cart(CartService cartService) +public partial class CartReview(CartService cartService) { - protected Services.ShoppingCart.Models.Cart ShoppingCart => cartService?.ShoppingCart!; + protected Cart ShoppingCart => cartService?.ShoppingCart!; protected async void IncreaseQty(CartItem item) { diff --git a/MidrandBookshop/Components/Pages/Cart.razor.css b/MidrandBookshop/Components/Pages/CartReview.razor.css similarity index 100% rename from MidrandBookshop/Components/Pages/Cart.razor.css rename to MidrandBookshop/Components/Pages/CartReview.razor.css diff --git a/MidrandBookshop/Components/Pages/Checkout.razor.cs b/MidrandBookshop/Components/Pages/Checkout.razor.cs index d980d9c..e166799 100644 --- a/MidrandBookshop/Components/Pages/Checkout.razor.cs +++ b/MidrandBookshop/Components/Pages/Checkout.razor.cs @@ -1,5 +1,5 @@ -using MidrandBookshop.Services.ShoppingCart; -using MidrandBookshop.Services.ShoppingCart.Models; +using LiteCharms.Features.MidrandBooks.Payments; +using LiteCharms.Features.MidrandBooks.Payments.Models; namespace MidrandBookshop.Components.Pages; @@ -8,7 +8,7 @@ public partial class Checkout(CartService cartService) [Inject] private AuthenticationStateProvider AuthStateProvider { get; set; } = default!; - private Services.ShoppingCart.Models.Cart ShoppingCart => cartService.ShoppingCart; + private LiteCharms.Features.MidrandBooks.Payments.Models.Cart ShoppingCart => cartService.ShoppingCart; private AuthenticationState? AuthState { get; set; } private System.Security.Claims.ClaimsPrincipal? User { get; set; } diff --git a/MidrandBookshop/Components/Pages/ProductView.razor.cs b/MidrandBookshop/Components/Pages/ProductView.razor.cs index d8ad916..53bea11 100644 --- a/MidrandBookshop/Components/Pages/ProductView.razor.cs +++ b/MidrandBookshop/Components/Pages/ProductView.razor.cs @@ -1,10 +1,10 @@ using LiteCharms.Features; using LiteCharms.Features.MidrandBooks.Authors; using LiteCharms.Features.MidrandBooks.Authors.Models; +using LiteCharms.Features.MidrandBooks.Payments; +using LiteCharms.Features.MidrandBooks.Payments.Models; using LiteCharms.Features.MidrandBooks.Products; using LiteCharms.Features.MidrandBooks.Products.Models; -using Microsoft.AspNetCore.Cors.Infrastructure; -using MidrandBookshop.Services.ShoppingCart; namespace MidrandBookshop.Components.Pages; @@ -17,7 +17,7 @@ public partial class ProductView : ComponentBase [Inject] private NavigationManager Navigation { get; set; } = default!; [Inject] private CartService CartService { get; set; } = default!; - protected Services.ShoppingCart.Models.Cart ShoppingCart => CartService?.ShoppingCart!; + protected Cart ShoppingCart => CartService?.ShoppingCart!; protected bool IsLoading { get; private set; } = true; protected Product? CurrentProduct { get; private set; } diff --git a/MidrandBookshop/MidrandBookshop.csproj b/MidrandBookshop/MidrandBookshop.csproj index f9c9cce..dcbb80e 100644 --- a/MidrandBookshop/MidrandBookshop.csproj +++ b/MidrandBookshop/MidrandBookshop.csproj @@ -18,13 +18,13 @@ - + - + diff --git a/MidrandBookshop/Program.cs b/MidrandBookshop/Program.cs index 0c2f01b..1172d23 100644 --- a/MidrandBookshop/Program.cs +++ b/MidrandBookshop/Program.cs @@ -3,7 +3,6 @@ using LiteCharms.Features.Mediator; using LiteCharms.Features.MidrandBooks.Extensions; using Microsoft.AspNetCore.HttpOverrides; using MidrandBookshop.Components; -using MidrandBookshop.Services.ShoppingCart; using static LiteCharms.Features.Extensions.Quartz; var builder = WebApplication.CreateBuilder(args); @@ -27,7 +26,6 @@ builder.Services.AddEmailServiceBus(); builder.Services.AddHttpClient(); builder.Services.AddShopServices(); -builder.Services.AddScoped(); builder.Services.AddHashServices(builder.Configuration); builder.Services.AddMidrandShopDatabase(builder.Configuration); diff --git a/MidrandBookshop/Services/ShoppingCart/CartService.cs b/MidrandBookshop/Services/ShoppingCart/CartService.cs deleted file mode 100644 index 4a8185d..0000000 --- a/MidrandBookshop/Services/ShoppingCart/CartService.cs +++ /dev/null @@ -1,153 +0,0 @@ -using LiteCharms.Features.Browser; -using LiteCharms.Features.Hasher; -using LiteCharms.Features.MidrandBooks.Authors.Models; -using LiteCharms.Features.MidrandBooks.Products.Models; -using MidrandBookshop.Services.ShoppingCart.Models; - -namespace MidrandBookshop.Services.ShoppingCart; - -public sealed class CartService(LocalStorageService localStorage) -{ - private readonly string CartStorageKey = HashService.ToMd5Hash(nameof(Cart)).Value; - - public Cart ShoppingCart { get; private set; } = new(); - - public event Action? OnCartChanged; - - public static Func GetCartItemQuantity = (shoppingCart, productPriceId) => - shoppingCart.Items.FirstOrDefault(p => p.Price!.Id == productPriceId)?.Quantity ?? 1; - - public Cart GetCart() => ShoppingCart; - - public void NotifyStateChanged() => OnCartChanged?.Invoke(); - - public async Task LoadCartFromStorageAsync() - { - var loadResult = await localStorage.GetAsync(CartStorageKey); - - if (loadResult.IsFailed) await localStorage.SaveAsync(CartStorageKey, ShoppingCart); - - if (loadResult.IsSuccess) ShoppingCart = loadResult.Value; - - NotifyStateChanged(); - } - - public async Task SaveCartToStorageAsync() => await localStorage.SaveAsync(CartStorageKey, ShoppingCart); - - public void AddItem(ProductPrice productPrice, Product product, Author author) - { - var itemExists = false; - - for (var i = 0; i < ShoppingCart.Items.Count; i++) - { - if (ShoppingCart.Items[i].Price!.Id == productPrice.Id) - { - ShoppingCart.Items[i].Quantity++; - ShoppingCart.Items[i].Amount += productPrice.Amount; - - itemExists = true; - - break; - } - } - - if (!itemExists) - ShoppingCart.Items.Add(new CartItem - { - Product = product, - Author = author, - Price = productPrice, - Amount = productPrice.Amount, - Quantity = 1, - }); - - CalculateTotalPrice(); - NotifyStateChanged(); - } - - public void UpdateQuantity(long productPriceId, int delta) - { - for (var i = 0; i < ShoppingCart.Items.Count; i++) - { - if (ShoppingCart.Items[i].Price!.Id == productPriceId) - { - var oldQuantity = ShoppingCart.Items[i].Quantity; - var pricePerUnit = ShoppingCart.Items[i].Price!.Amount; - - ShoppingCart.Items[i].Quantity += delta; - ShoppingCart.Items[i].Amount = pricePerUnit * ShoppingCart.Items[i].Quantity; - break; - } - } - - CalculateTotalPrice(); - NotifyStateChanged(); - } - - public void RemoveOneItem(long productPriceId) - { - for (var i = 0; i < ShoppingCart.Items.Count; i++) - { - if (ShoppingCart.Items[i].Price!.Id == productPriceId) - { - if (ShoppingCart.Items[i].Quantity <= 1) - { - ShoppingCart.Items.Remove(ShoppingCart.Items[i]); - - break; - } - else - { - ShoppingCart.Items[i].Quantity--; - ShoppingCart.Items[i].Amount -= ShoppingCart.Items[i].Price!.Amount; - } - - break; - } - } - - CalculateTotalPrice(); - NotifyStateChanged(); - } - - public void RemoveAllSameItem(long productPriceId) - { - if (ShoppingCart.Items.Count == 0) return; - - var item = ShoppingCart.Items.FirstOrDefault(i => i.Price?.Id == productPriceId); - - if (item is not null) ShoppingCart.Items.Remove(item); - - CalculateTotalPrice(); - NotifyStateChanged(); - } - - public void Clear() - { - if(ShoppingCart.CustomerId is not null || ShoppingCart.OrderId is not null) - { - ShoppingCart.TotalAmount = 0; - ShoppingCart.TotalVat = 0; - ShoppingCart.Items.Clear(); - - return; - } - - ShoppingCart = new Cart(); - - NotifyStateChanged(); - } - - public decimal CalculateTotalPrice() - { - if (ShoppingCart.Items.Count == 0) return 0; - - var gross = ShoppingCart.Items.Sum(i => i.Amount); - - if (!ShoppingCart.IsVatInclusive) ShoppingCart.TotalVat = gross * ShoppingCart.VatRate; - - ShoppingCart.TotalAmount = gross + ShoppingCart.TotalVat; - - return ShoppingCart.TotalAmount; - } -} diff --git a/MidrandBookshop/Services/ShoppingCart/Models/Cart.cs b/MidrandBookshop/Services/ShoppingCart/Models/Cart.cs deleted file mode 100644 index b0ea707..0000000 --- a/MidrandBookshop/Services/ShoppingCart/Models/Cart.cs +++ /dev/null @@ -1,18 +0,0 @@ -namespace MidrandBookshop.Services.ShoppingCart.Models; - -public sealed class Cart -{ - public long? CustomerId { get; set; } - - public long? OrderId { get; set; } - - public decimal TotalAmount { get; set; } - - public decimal TotalVat { get; set; } - - public decimal VatRate { get; set; } = 0.15m; - - public bool IsVatInclusive { get; set; } = true; - - public IList Items { get; set; } = []; -} diff --git a/MidrandBookshop/Services/ShoppingCart/Models/CartItem.cs b/MidrandBookshop/Services/ShoppingCart/Models/CartItem.cs deleted file mode 100644 index ca790a2..0000000 --- a/MidrandBookshop/Services/ShoppingCart/Models/CartItem.cs +++ /dev/null @@ -1,17 +0,0 @@ -using LiteCharms.Features.MidrandBooks.Authors.Models; -using LiteCharms.Features.MidrandBooks.Products.Models; - -namespace MidrandBookshop.Services.ShoppingCart.Models; - -public sealed class CartItem -{ - public Author? Author { get; set; } - - public Product? Product { get; set; } - - public ProductPrice? Price { get; set; } - - public int Quantity { get; set; } - - public decimal Amount { get; set; } -}