Skip to content

Commit

Permalink
feat: implement shopping cart functionality and update layout
Browse files Browse the repository at this point in the history
  • Loading branch information
baotoq committed Dec 10, 2024
1 parent c6593ad commit a2571f6
Show file tree
Hide file tree
Showing 14 changed files with 95 additions and 258 deletions.
11 changes: 11 additions & 0 deletions code/src/MicroCommerce.Web/CartService.cs
Original file line number Diff line number Diff line change
@@ -0,0 1,11 @@
namespace MicroCommerce.Web;

public class CartService
{
public List<GetProductsResponse.Product> CartItems { get; private set; } = new();

public void AddToCart(GetProductsResponse.Product product)
{
CartItems.Add(product);
}
}
3 changes: 2 additions & 1 deletion code/src/MicroCommerce.Web/Components/App.razor
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 7,14 @@
<base href="/"/>
<link rel="stylesheet" href="bootstrap/bootstrap.min.css"/>
<link rel="stylesheet" href="app.css"/>
<link rel="stylesheet" href="MicroCommerce.Web.styles.css"/>
<link rel="icon" type="image/png" href="favicon.png"/>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.7.1/css/all.min.css" integrity="sha512-5Hs3dF2AEPkpNAR7UiOHba lRSJNeM2ECkwxUIxC1Q/FLycGTbNapWXB4tP889k5T5Ju8fs4b1P5z/iB4nMfSQ==" crossorigin="anonymous" referrerpolicy="no-referrer" />
<HeadOutlet/>
</head>

<body>
<Routes/>
<div id="app">Loading...</div>
<script src="_framework/blazor.web.js"></script>
</body>

Expand Down
18 changes: 3 additions & 15 deletions code/src/MicroCommerce.Web/Components/Layout/MainLayout.razor
Original file line number Diff line number Diff line change
@@ -1,20 1,8 @@
@inherits LayoutComponentBase

<div class="page">
<div class="sidebar">
<NavMenu/>
</div>

<main>
<div class="top-row px-4">
<a href="https://learn.microsoft.com/aspnet/core/" target="_blank">About</a>
</div>

<article class="content px-4">
@Body
</article>
</main>
</div>
<main>
@Body
</main>

<div id="blazor-error-ui">
An unhandled error has occurred.
Expand Down
78 changes: 0 additions & 78 deletions code/src/MicroCommerce.Web/Components/Layout/MainLayout.razor.css
Original file line number Diff line number Diff line change
@@ -1,81 1,3 @@
.page {
position: relative;
display: flex;
flex-direction: column;
}

main {
flex: 1;
}

.sidebar {
background-image: linear-gradient(180deg, rgb(5, 39, 103) 0%, #3a0647 70%);
}

.top-row {
background-color: #f7f7f7;
border-bottom: 1px solid #d6d5d5;
justify-content: flex-end;
height: 3.5rem;
display: flex;
align-items: center;
}

.top-row ::deep a, .top-row ::deep .btn-link {
white-space: nowrap;
margin-left: 1.5rem;
text-decoration: none;
}

.top-row ::deep a:hover, .top-row ::deep .btn-link:hover {
text-decoration: underline;
}

.top-row ::deep a:first-child {
overflow: hidden;
text-overflow: ellipsis;
}

@media (max-width: 640.98px) {
.top-row {
justify-content: space-between;
}

.top-row ::deep a, .top-row ::deep .btn-link {
margin-left: 0;
}
}

@media (min-width: 641px) {
.page {
flex-direction: row;
}

.sidebar {
width: 250px;
height: 100vh;
position: sticky;
top: 0;
}

.top-row {
position: sticky;
top: 0;
z-index: 1;
}

.top-row.auth ::deep a:first-child {
flex: 1;
text-align: right;
width: 0;
}

.top-row, article {
padding-left: 2rem !important;
padding-right: 1.5rem !important;
}
}

#blazor-error-ui {
background: lightyellow;
bottom: 0;
Expand Down
22 changes: 0 additions & 22 deletions code/src/MicroCommerce.Web/Components/Layout/NavMenu.razor

This file was deleted.

102 changes: 0 additions & 102 deletions code/src/MicroCommerce.Web/Components/Layout/NavMenu.razor.css

This file was deleted.

22 changes: 22 additions & 0 deletions code/src/MicroCommerce.Web/Components/Pages/Cart.razor
Original file line number Diff line number Diff line change
@@ -0,0 1,22 @@
@page "/cart"
@inject CartService CartService

<h1 class="text-center my-4">Shopping Cart</h1>
<div class="container">
<ul class="list-group">
@if (CartService.CartItems.Count > 0)
{
@foreach (var item in CartService.CartItems)
{
<li class="list-group-item d-flex justify-content-between align-items-center">
@item.Name
<span class="badge bg-primary rounded-pill">$@item.Price</span>
</li>
}
}
else
{
<p>Your cart is empty.</p>
}
</ul>
</div>
25 changes: 8 additions & 17 deletions code/src/MicroCommerce.Web/Components/Pages/Home.razor
Original file line number Diff line number Diff line change
Expand Up @@ -5,30 5,21 @@
<PageTitle>Home</PageTitle>

<div class="container">
<h1 class="text-center my-4">Product List</h1>

@if (_products is null)
{
<p class="catalog-loading">Loading product catalog…</p>
<p>Loading product catalog…</p>
}
else
{
<div class="row">
@foreach (var item in _products)
<div class="row row-cols-1 row-cols-md-3 g-4">
@foreach (var product in _products)
{
<div class="col-4" data-id="@item.Id">
<div class="grid-item-content">
<img src="images/@item.ImageUrl" alt="@item.Name" class="catalog-item-image"/>
<div class="quick-view-overlay">
<i class="fa fa-search-plus" aria-hidden="true"></i>
</div>
<div class="grid-item-text">
<h4 class="pointer-events-none">@item.Name</h4>
<p class="item-description pointer-events-none">@item.Name</p>
<div class="d-flex justify-space-evenly align-items-center">
<p class="item-price pointer-events-none">@item.Price.ToString("C", new CultureInfo("en-US"))</p>
</div>
</div>
</div>
<div class="col-md-4">
<ProductCard Product="product" AddToCart="p => { }"></ProductCard>
</div>

}
</div>
}
Expand Down
29 changes: 29 additions & 0 deletions code/src/MicroCommerce.Web/Components/Shared/Cart.razor
Original file line number Diff line number Diff line change
@@ -0,0 1,29 @@
@inject NavigationManager Navigation

<div class="justify-content-end">
@if (true)
{
<EditForm Model="this" FormName="checkout" OnSubmit="HandleCheckout" data-enhance>
<button type="submit" class="align-content-end cart-button">
<span class="fa-stack fa-lg cart-stack pa-4">
<i class="fa fa-shopping-cart fa-stack-4x"></i>
<i class="fa fa-stack-1x badge">
10
</i>
</span>
</button>
</EditForm>
}
</div>

@code {
protected override async Task OnInitializedAsync()

Check warning on line 20 in code/src/MicroCommerce.Web/Components/Shared/Cart.razor

View workflow job for this annotation

GitHub Actions / unit-tests

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.

Check warning on line 20 in code/src/MicroCommerce.Web/Components/Shared/Cart.razor

View workflow job for this annotation

GitHub Actions / unit-tests

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.
{
}

private async Task HandleCheckout()

Check warning on line 24 in code/src/MicroCommerce.Web/Components/Shared/Cart.razor

View workflow job for this annotation

GitHub Actions / unit-tests

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.

Check warning on line 24 in code/src/MicroCommerce.Web/Components/Shared/Cart.razor

View workflow job for this annotation

GitHub Actions / unit-tests

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.
{
// Preserve query string
Navigation.NavigateTo($"/{new Uri(Navigation.Uri).Query}");
}
}
17 changes: 17 additions & 0 deletions code/src/MicroCommerce.Web/Components/Shared/ProductCard.razor
Original file line number Diff line number Diff line change
@@ -0,0 1,17 @@
@using System.Globalization

<div class="card mb-4 h-100">
<img src="images/@Product.ImageUrl" class="card-img-top" alt="@Product.Name">
<div class="card-body">
<h5 class="card-title">@Product.Name</h5>
<p class="card-text">$@Product.Price.ToString("C", new CultureInfo("en-US"))</p>
<button class="btn btn-primary" @onclick="() => AddToCart(Product)">
<i class="fas fa-cart-plus"></i> Add to Cart
</button>
</div>
</div>

@code {
[Parameter] public required GetProductsResponse.Product Product { get; set; }
[Parameter] public required Action<GetProductsResponse.Product> AddToCart { get; set; }
}
1 change: 1 addition & 0 deletions code/src/MicroCommerce.Web/Components/_Imports.razor
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 9,4 @@
@using Microsoft.JSInterop
@using MicroCommerce.Web
@using MicroCommerce.Web.Components
@using MicroCommerce.Web.Components.Shared
1 change: 0 additions & 1 deletion code/src/MicroCommerce.Web/ProductApiClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 23,3 @@ public record Product
public string ImageUrl { get; set; } = "";
}
}

2 changes: 2 additions & 0 deletions code/src/MicroCommerce.Web/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 21,8 @@
client.BaseAddress = new("https http://apiservice");
});

builder.Services.AddScoped<CartService>();

var app = builder.Build();

if (!app.Environment.IsDevelopment())
Expand Down
Loading

0 comments on commit a2571f6

Please sign in to comment.