diff --git a/src/Congo.Contracts/Requests/Cart/AddToCartRequest.cs b/src/Congo.Contracts/Requests/Cart/AddToCartRequest.cs new file mode 100644 index 0000000..7e09d7c --- /dev/null +++ b/src/Congo.Contracts/Requests/Cart/AddToCartRequest.cs @@ -0,0 +1,10 @@ +using System; + +namespace Congo.WebApi.Requests.Cart +{ + public class AddToCartRequest + { + public Guid ProductId { get; set; } + public int Quantity { get; set; } + } +} diff --git a/src/Congo.RazorPages/Congo.RazorPages.csproj b/src/Congo.RazorPages/Congo.RazorPages.csproj index 71f0238..1975a22 100644 --- a/src/Congo.RazorPages/Congo.RazorPages.csproj +++ b/src/Congo.RazorPages/Congo.RazorPages.csproj @@ -13,6 +13,7 @@ + diff --git a/src/Congo.RazorPages/Pages/Products.cshtml b/src/Congo.RazorPages/Pages/Products.cshtml index 0533df0..67d0966 100644 --- a/src/Congo.RazorPages/Pages/Products.cshtml +++ b/src/Congo.RazorPages/Pages/Products.cshtml @@ -6,21 +6,38 @@

Products

-
-
- @foreach (var product in Model.Products) - { -
- @product.Name -
-

@product.Name

-

$@product.Price

-
- +
+ @foreach (var product in Model.Products) + { +
+ @product.Name +
+

@product.Name

+

$@product.Price

- } -
- + +
+ +
+
+ + +
+
+ +
+
+
+
+ } +
+ + diff --git a/src/Congo.RazorPages/Pages/Products.cshtml.cs b/src/Congo.RazorPages/Pages/Products.cshtml.cs index cfbe273..0d86d81 100644 --- a/src/Congo.RazorPages/Pages/Products.cshtml.cs +++ b/src/Congo.RazorPages/Pages/Products.cshtml.cs @@ -26,10 +26,11 @@ public async Task OnGetAsync() return Page(); } - public async Task OnPostPurchaseAsync(Guid id) + public async Task OnPostAddToCartAsync(Guid productId, int quantity) { - var order = await _productsService.PurchaseAsync(id); - return RedirectToPage("/OrderSuccessful", new { order.OrderId }); + // call _cartService.AddToCart(new AddToCartRequest(...)) + await Task.Delay(0); + return new OkObjectResult(true); } } } diff --git a/src/Congo.RazorPages/Pages/Products.cshtml.css b/src/Congo.RazorPages/Pages/Products.cshtml.css new file mode 100644 index 0000000..5523f1b --- /dev/null +++ b/src/Congo.RazorPages/Pages/Products.cshtml.css @@ -0,0 +1,8 @@ +input, label { + display: block; +} + +.product-quantity { + float: left; + margin-right: 20px; +} diff --git a/src/Congo.RazorPages/Pages/Shared/_Layout.cshtml b/src/Congo.RazorPages/Pages/Shared/_Layout.cshtml index 84dc14d..b823a74 100644 --- a/src/Congo.RazorPages/Pages/Shared/_Layout.cshtml +++ b/src/Congo.RazorPages/Pages/Shared/_Layout.cshtml @@ -6,6 +6,7 @@ @ViewData["Title"] - Congo.RazorPages +
@@ -44,6 +45,7 @@ + @await RenderSectionAsync("Scripts", required: false) diff --git a/src/Congo.WebApi.Tests/Controllers/CartControllerTests.cs b/src/Congo.WebApi.Tests/Controllers/CartControllerTests.cs index 55cf6b3..8e9b399 100644 --- a/src/Congo.WebApi.Tests/Controllers/CartControllerTests.cs +++ b/src/Congo.WebApi.Tests/Controllers/CartControllerTests.cs @@ -28,6 +28,6 @@ public async void CartController_ReturnsCartOfTypeCartResponse() // Assert cartResponse.Result.Should().BeAssignableTo(); - } + } } } diff --git a/src/Congo.WebApi/Controllers/CartController.cs b/src/Congo.WebApi/Controllers/CartController.cs index 475049d..9dc1519 100644 --- a/src/Congo.WebApi/Controllers/CartController.cs +++ b/src/Congo.WebApi/Controllers/CartController.cs @@ -2,6 +2,8 @@ using System.Threading.Tasks; using Congo.Contracts.Responses.Cart; using Congo.WebApi.Data.CartAccess; +using Congo.WebApi.Data.Models; +using Congo.WebApi.Requests.Cart; using Mapster; using MediatR; using Microsoft.AspNetCore.Mvc; @@ -24,15 +26,30 @@ public async Task> GetCartById(Guid id) return Ok(cart.Adapt()); } - [HttpPost("/add-to-cart")] + [HttpPost("add-to-cart")] [ProducesResponseType(204)] - [ProducesResponseType(typeof(Guid), 200)] - public async Task AddToCart(Guid? cartId, Guid productId, int quantity) + [ProducesResponseType(typeof(CartResponse), 200)] + [ProducesResponseType(400)] + public async Task> AddToCart(AddToCartRequest request) { - var cart = await _mediator.Send(new AddToCartCommand(cartId, productId, quantity)); - if (cart == Guid.Empty) + var cart = await _mediator.Send(new AddToCartCommand(CurrentCartId, request.ProductId, request.Quantity)); + + if (cart == null) return BadRequest(); - return Ok(cart); + else if (!cart.IsNewCart) + return NoContent(); + + return Ok(cart.Adapt()); + } + + private Guid? CurrentCartId + { + get + { + if (Guid.TryParse(HttpContext.Request.Cookies["cart_id"], out var cartId)) + return cartId; + return null; + } } } } diff --git a/src/Congo.WebApi/Data/CartAccess/AddToCartHandler.cs b/src/Congo.WebApi/Data/CartAccess/AddToCartHandler.cs index 2068753..aa65aec 100644 --- a/src/Congo.WebApi/Data/CartAccess/AddToCartHandler.cs +++ b/src/Congo.WebApi/Data/CartAccess/AddToCartHandler.cs @@ -2,14 +2,16 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; +using Congo.Contracts.Responses.Cart; using Congo.WebApi.Data.Models; using MediatR; +using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using static Congo.WebApi.Data.CartAccess.CartCommands; namespace Congo.WebApi.Data.CartAccess { - public class AddToCartHandler : IRequestHandler + public class AddToCartHandler : IRequestHandler { private readonly CongoContext _dbContext; @@ -18,17 +20,22 @@ public AddToCartHandler(CongoContext dbContext) _dbContext = dbContext; } - public async Task Handle(AddToCartCommand request, CancellationToken cancellationToken) + public async Task Handle(AddToCartCommand request, CancellationToken cancellationToken) { var cart = await _dbContext.Carts .Include(c => c.CartItems) .FirstOrDefaultAsync(C => C.Id == request.cartId); + if (cart != null) + { + cart.IsNewCart = false; + } + var product = await _dbContext.Products.FindAsync(request.productId); if (request.cartId != null && cart == null) { - return Guid.Empty; + return null; } else if (request.cartId == null) { @@ -43,7 +50,7 @@ public async Task Handle(AddToCartCommand request, CancellationToken cance await _dbContext.SaveChangesAsync(); - return cart.Id; + return cart; } private async Task AddCartItem(AddToCartCommand request, Cart cart, Product product, CongoContext _dbContext) diff --git a/src/Congo.WebApi/Data/CartAccess/CartCommands.cs b/src/Congo.WebApi/Data/CartAccess/CartCommands.cs index 8f82e05..651b604 100644 --- a/src/Congo.WebApi/Data/CartAccess/CartCommands.cs +++ b/src/Congo.WebApi/Data/CartAccess/CartCommands.cs @@ -1,10 +1,11 @@ using System; +using Congo.WebApi.Data.Models; using MediatR; namespace Congo.WebApi.Data.CartAccess { public class CartCommands { - public record AddToCartCommand(Guid? cartId, Guid productId, int quantity) : IRequest; + public record AddToCartCommand(Guid? cartId, Guid productId, int quantity) : IRequest; } } diff --git a/src/Congo.WebApi/Data/Models/Cart.cs b/src/Congo.WebApi/Data/Models/Cart.cs index 473c666..cbb2a3e 100644 --- a/src/Congo.WebApi/Data/Models/Cart.cs +++ b/src/Congo.WebApi/Data/Models/Cart.cs @@ -7,5 +7,6 @@ public class Cart { public Guid Id { get; init; } public ICollection CartItems { get; set; } = new List(); + public bool IsNewCart { get; set; } = true; } }