diff --git a/MidrandBookshop/Components/Layout/MainLayout.razor.cs b/MidrandBookshop/Components/Layout/MainLayout.razor.cs index 158a5de..dd53781 100644 --- a/MidrandBookshop/Components/Layout/MainLayout.razor.cs +++ b/MidrandBookshop/Components/Layout/MainLayout.razor.cs @@ -122,7 +122,7 @@ public partial class MainLayout(CartService cartService) : IDisposable await cartService.SaveCartToStorageAsync(); } - private decimal GetCartTotal() => ShoppingCart?.TotalPrice ?? 0.00m; + private decimal GetCartTotal() => ShoppingCart?.TotalAmount ?? 0.00m; private void RedirectToCart() { diff --git a/MidrandBookshop/Components/Pages/Cart.razor b/MidrandBookshop/Components/Pages/Cart.razor index a3de54b..f6e12e9 100644 --- a/MidrandBookshop/Components/Pages/Cart.razor +++ b/MidrandBookshop/Components/Pages/Cart.razor @@ -1,106 +1,98 @@ @page "/cart" +@rendermode InteractiveServer -
-
-

Your Cart

- CONTINUE SHOPPING +
+ +
+

Your Cart

+ Continue Shopping
- @if (!CartItems.Any()) + @if (!ShoppingCart.Items.Any()) { -
-

Your collection is currently empty.

- Browse Catalog +
+
+ +
+

Your collection is currently vacant.

+

Even with careful scrutiny, the requested shelf remains empty.

+ Browse Catalog
} else { -
- @foreach (var item in CartItems) - { -
- -
-
- [COVER] -
-
-
@item.Title
-

by @item.Author

-
-
+
+
+
+ @foreach (var item in ShoppingCart.Items) + { +
- -
-
- - @item.Quantity - -
-
+
+
+ @if (!string.IsNullOrWhiteSpace(item.Product!.ImageUrl)) + { + @item.Product.Name + } + else + { + [COVER] + } +
+
+
@item.Product!.Name
+

by @($"{item.Author!.Name} {item.Author!.LastName}")

+
+
- -
- R @(item.Price * item.Quantity) - -
+
+
+ + @item.Quantity + +
+
+ +
+ R @(item.Amount.ToString("N2", System.Globalization.CultureInfo.GetCultureInfo("js"))) + +
+ +
+ }
- } -
+
- -
-
-
-
+
+
+

Order Summary

+ +
Subtotal - R @Subtotal.ToString("F2") + R @(ShoppingCart.TotalAmount.ToString("N2", System.Globalization.CultureInfo.GetCultureInfo("js")))
-
+ +
VAT (15%) - R @VatAmount.ToString("F2") + R @(ShoppingCart.TotalVat.ToString("N2", System.Globalization.CultureInfo.GetCultureInfo("js")))
-
-
- Total - R @Total.ToString("F2") + +
+ +
+ Total + R @((ShoppingCart.TotalAmount + ShoppingCart.TotalVat).ToString("N2", System.Globalization.CultureInfo.GetCultureInfo("js")))
- Proceed to Checkout + + + Proceed to Checkout +
} -
- -@code { - public class CartItem - { - public int Id { get; set; } - public string Title { get; set; } = string.Empty; - public string Author { get; set; } = string.Empty; - public int Price { get; set; } - public int Quantity { get; set; } - } - - private List CartItems = new() - { - new CartItem { Id = 1, Title = "Letters from M/M (Paris)", Author = "M/M Paris", Price = 720, Quantity = 1 }, - new CartItem { Id = 2, Title = "Daan Paans: Floating Signifiers", Author = "Daan Paans", Price = 540, Quantity = 1 }, - new CartItem { Id = 3, Title = "Album Architectures, Maputo", Author = "Guedes Archive", Price = 350, Quantity = 1 } - }; - - // Computed Properties for Calculations - private decimal Subtotal => CartItems.Sum(i => (decimal)i.Price * i.Quantity); - private decimal VatAmount => Subtotal * 0.15m; - private decimal Total => Subtotal + VatAmount; - - private void ChangeQuantity(CartItem item, int delta) - { - item.Quantity += delta; - if (item.Quantity <= 0) CartItems.Remove(item); - } - - private void RemoveFromCart(CartItem item) => CartItems.Remove(item); -} \ No newline at end of file +
\ No newline at end of file diff --git a/MidrandBookshop/Components/Pages/Cart.razor.cs b/MidrandBookshop/Components/Pages/Cart.razor.cs new file mode 100644 index 0000000..de784b5 --- /dev/null +++ b/MidrandBookshop/Components/Pages/Cart.razor.cs @@ -0,0 +1,36 @@ +using MidrandBookshop.Services.ShoppingCart; +using MidrandBookshop.Services.ShoppingCart.Models; + +namespace MidrandBookshop.Components.Pages; + +public partial class Cart(CartService cartService) +{ + protected Services.ShoppingCart.Models.Cart ShoppingCart => cartService?.ShoppingCart!; + + protected async void IncreaseQty(CartItem item) + { + if (item is not null) + { + cartService.UpdateQuantity(item!.Price!.Id, 1); + + await cartService.SaveCartToStorageAsync(); + } + } + protected async void DecreaseQty(CartItem item, int delta) + { + var peekQuantity = item.Quantity + delta; + + if (peekQuantity < 1) return; + + cartService.UpdateQuantity(item!.Price!.Id, delta); + + await cartService.SaveCartToStorageAsync(); + } + + private async void RemoveFromCart(CartItem item) + { + cartService.RemoveOneItem(item.Price!.Id); + + await cartService.SaveCartToStorageAsync(); + } +} diff --git a/MidrandBookshop/Components/Pages/Cart.razor.css b/MidrandBookshop/Components/Pages/Cart.razor.css new file mode 100644 index 0000000..46800d1 --- /dev/null +++ b/MidrandBookshop/Components/Pages/Cart.razor.css @@ -0,0 +1,2 @@ +body { +} diff --git a/MidrandBookshop/Components/Pages/ProductView.razor.cs b/MidrandBookshop/Components/Pages/ProductView.razor.cs index 0b67338..d8ad916 100644 --- a/MidrandBookshop/Components/Pages/ProductView.razor.cs +++ b/MidrandBookshop/Components/Pages/ProductView.razor.cs @@ -32,9 +32,6 @@ public partial class ProductView : ComponentBase protected Author? CurrentAuthor { get; private set; } - private static Func getCartItemQuantity = (shoppingCart, productPriceId) => - shoppingCart.Items.FirstOrDefault(p => p.Price!.Id == productPriceId)?.Quantity ?? 1; - protected override async Task OnParametersSetAsync() { try @@ -97,7 +94,7 @@ public partial class ProductView : ComponentBase { CartService.UpdateQuantity(CurrentPrice!.Id, 1); - Quantity = getCartItemQuantity(ShoppingCart, CurrentPrice.Id); + Quantity = CartService.GetCartItemQuantity(ShoppingCart, CurrentPrice.Id); await CartService.SaveCartToStorageAsync(); } @@ -108,7 +105,7 @@ public partial class ProductView : ComponentBase { CartService.UpdateQuantity(CurrentPrice!.Id, -1); - Quantity = getCartItemQuantity(ShoppingCart, CurrentPrice.Id); + Quantity = CartService.GetCartItemQuantity(ShoppingCart, CurrentPrice.Id); await CartService.SaveCartToStorageAsync(); } @@ -131,7 +128,7 @@ public partial class ProductView : ComponentBase CartService.AddItem(CurrentPrice, CurrentProduct, CurrentAuthor!); - Quantity = getCartItemQuantity(ShoppingCart, CurrentPrice.Id); + Quantity = CartService.GetCartItemQuantity(ShoppingCart, CurrentPrice.Id); await CartService.SaveCartToStorageAsync(); } diff --git a/MidrandBookshop/Services/ShoppingCart/CartService.cs b/MidrandBookshop/Services/ShoppingCart/CartService.cs index e8dfd0d..4a8185d 100644 --- a/MidrandBookshop/Services/ShoppingCart/CartService.cs +++ b/MidrandBookshop/Services/ShoppingCart/CartService.cs @@ -14,6 +14,9 @@ public sealed class CartService(LocalStorageService localStorage) 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(); @@ -123,7 +126,7 @@ public sealed class CartService(LocalStorageService localStorage) { if(ShoppingCart.CustomerId is not null || ShoppingCart.OrderId is not null) { - ShoppingCart.TotalPrice = 0; + ShoppingCart.TotalAmount = 0; ShoppingCart.TotalVat = 0; ShoppingCart.Items.Clear(); @@ -143,8 +146,8 @@ public sealed class CartService(LocalStorageService localStorage) if (!ShoppingCart.IsVatInclusive) ShoppingCart.TotalVat = gross * ShoppingCart.VatRate; - ShoppingCart.TotalPrice = gross + ShoppingCart.TotalVat; + ShoppingCart.TotalAmount = gross + ShoppingCart.TotalVat; - return ShoppingCart.TotalPrice; + return ShoppingCart.TotalAmount; } } diff --git a/MidrandBookshop/Services/ShoppingCart/Models/Cart.cs b/MidrandBookshop/Services/ShoppingCart/Models/Cart.cs index cc9f043..b0ea707 100644 --- a/MidrandBookshop/Services/ShoppingCart/Models/Cart.cs +++ b/MidrandBookshop/Services/ShoppingCart/Models/Cart.cs @@ -6,7 +6,7 @@ public sealed class Cart public long? OrderId { get; set; } - public decimal TotalPrice { get; set; } + public decimal TotalAmount { get; set; } public decimal TotalVat { get; set; }