Added in Local Storage functionality to store products and cart items into the users local storage.
Cleaned up code and removed excess files.
This commit is contained in:
parent
4a358ede89
commit
c4f54c70b6
|
@ -3,66 +3,60 @@
|
|||
|
||||
<h3>Checkout</h3>
|
||||
|
||||
@if (ShoppingCartItems.Count() == 0)
|
||||
{
|
||||
<h4 class="text-warning">You currently have no items in your shopping cart.</h4>
|
||||
}
|
||||
else
|
||||
{
|
||||
<div class="mb-5">
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<h4 class="mb-2">Payment Method</h4>
|
||||
<div id="smart-button-container">
|
||||
<input type="hidden" name="descriptionInput" id="description" @bind="PaymentDescription" />
|
||||
<input name="amountInput" type="hidden" id="amount" @bind="PaymentAmount" />
|
||||
<div style="text-align: center; margin-top: 0.625rem;" id="paypal-button-container"></div>
|
||||
</div>
|
||||
|
||||
<div class="mb-5">
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<h4 class="mb-2">Payment Method</h4>
|
||||
<div id="smart-button-container">
|
||||
<input type="hidden" name="descriptionInput" id="description" @bind="PaymentDescription" />
|
||||
<input name="amountInput" type="hidden" id="amount" @bind="PaymentAmount" />
|
||||
<div style="text-align: center; margin-top: 0.625rem;" id="paypal-button-container"></div>
|
||||
</div>
|
||||
</div>
|
||||
@if (ShoppingCartItems == null)
|
||||
{
|
||||
<div class="row d-flex justify-content-center">
|
||||
<div class="col-md-1">
|
||||
<DisplayCustomSpinner />
|
||||
</div>
|
||||
@if (ShoppingCartItems == null)
|
||||
</div>
|
||||
}
|
||||
else
|
||||
{
|
||||
<div class="col-md-6">
|
||||
<h4 class="mb-2">Payment Summary</h4>
|
||||
@if (ShoppingCartItems.Count() > 0)
|
||||
{
|
||||
<div class="row d-flex justify-content-center">
|
||||
<div class="col-md-1">
|
||||
<DisplayCustomSpinner />
|
||||
</div>
|
||||
</div>
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Product</th>
|
||||
<th>Price</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach (var item in ShoppingCartItems)
|
||||
{
|
||||
<tr>
|
||||
<td>@item.Quantity x @item.ProductName</td>
|
||||
<td>@item.TotalPrice.ToString("C")</td>
|
||||
</tr>
|
||||
}
|
||||
<tr>
|
||||
<td><b>Total</b></td>
|
||||
<td><b>@PaymentAmount.ToString("C")</b></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
}
|
||||
else
|
||||
{
|
||||
<div class="col-md-6">
|
||||
<h4 class="mb-2">Payment Summary</h4>
|
||||
@if (ShoppingCartItems.Count() > 0)
|
||||
{
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Product</th>
|
||||
<th>Price</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach (var item in ShoppingCartItems)
|
||||
{
|
||||
<tr>
|
||||
<td>@item.Quantity x @item.ProductName</td>
|
||||
<td>@item.TotalPrice.ToString("C")</td>
|
||||
</tr>
|
||||
}
|
||||
<tr>
|
||||
<td><b>Total</b></td>
|
||||
<td><b>@PaymentAmount.ToString("C")</b></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
}
|
||||
else
|
||||
{
|
||||
<p class="text-warning">You currently have no items in your shopping cart.</p>
|
||||
}
|
||||
</div>
|
||||
<p class="text-warning">You currently have no items in your shopping cart.</p>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
|
|
@ -21,11 +21,14 @@ namespace ShopOnline.Web.Pages
|
|||
[Inject]
|
||||
public IShoppingCartService ShoppingCartService { get; set; }
|
||||
|
||||
[Inject]
|
||||
public IManageCartItemsLocalStorageService ManageCartItemsLocalStorage { get; set; }
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
ShoppingCartItems = await ShoppingCartService.GetItems(HardCoded.UserId);
|
||||
ShoppingCartItems = await ManageCartItemsLocalStorage.GetCollection();
|
||||
|
||||
if(ShoppingCartItems != null)
|
||||
{
|
||||
|
@ -49,7 +52,6 @@ namespace ShopOnline.Web.Pages
|
|||
{
|
||||
if(firstRender)
|
||||
{
|
||||
Console.WriteLine("HIT");
|
||||
await Js.InvokeVoidAsync("initPayPalButton");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
@foreach (var item in Products)
|
||||
{
|
||||
Console.WriteLine(@item.Price);
|
||||
<div class="col-md-3 mb-2">
|
||||
<a href="/ProductDetails/@item.Id">
|
||||
<div class="card">
|
||||
|
|
|
@ -1,57 +0,0 @@
|
|||
@page "/fetchdata"
|
||||
@inject HttpClient Http
|
||||
|
||||
<PageTitle>Weather forecast</PageTitle>
|
||||
|
||||
<h1>Weather forecast</h1>
|
||||
|
||||
<p>This component demonstrates fetching data from the server.</p>
|
||||
|
||||
@if (forecasts == null)
|
||||
{
|
||||
<p><em>Loading...</em></p>
|
||||
}
|
||||
else
|
||||
{
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Date</th>
|
||||
<th>Temp. (C)</th>
|
||||
<th>Temp. (F)</th>
|
||||
<th>Summary</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach (var forecast in forecasts)
|
||||
{
|
||||
<tr>
|
||||
<td>@forecast.Date.ToShortDateString()</td>
|
||||
<td>@forecast.TemperatureC</td>
|
||||
<td>@forecast.TemperatureF</td>
|
||||
<td>@forecast.Summary</td>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
}
|
||||
|
||||
@code {
|
||||
private WeatherForecast[]? forecasts;
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
forecasts = await Http.GetFromJsonAsync<WeatherForecast[]>("sample-data/weather.json");
|
||||
}
|
||||
|
||||
public class WeatherForecast
|
||||
{
|
||||
public DateTime Date { get; set; }
|
||||
|
||||
public int TemperatureC { get; set; }
|
||||
|
||||
public string? Summary { get; set; }
|
||||
|
||||
public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
|
||||
}
|
||||
}
|
|
@ -13,16 +13,26 @@ namespace ShopOnline.Web.Pages
|
|||
public IProductService ProductService { get; set; }
|
||||
[Inject]
|
||||
public IShoppingCartService ShoppingCartService { get; set; }
|
||||
|
||||
[Inject]
|
||||
public IManageProductsLocalStorageService ManageProductsLocalStorageService { get; set; }
|
||||
|
||||
[Inject]
|
||||
public IManageCartItemsLocalStorageService ManageCartItemsLocalStorageService { get; set; }
|
||||
|
||||
[Inject]
|
||||
public NavigationManager NavigationManager { get; set; }
|
||||
public ProductDto Product { get; set; }
|
||||
public string ErrorMessage { get; set; }
|
||||
|
||||
private List<CartItemDto> ShoppingCartItems { get; set; }
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
Product = await ProductService.GetItem(Id);
|
||||
ShoppingCartItems = await ManageCartItemsLocalStorageService.GetCollection();
|
||||
Product = await GetProductById(Id);
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
|
@ -35,6 +45,13 @@ namespace ShopOnline.Web.Pages
|
|||
try
|
||||
{
|
||||
var cartItemDto = await ShoppingCartService.AddItem(cartItemToAddDto);
|
||||
|
||||
if(cartItemDto != null)
|
||||
{
|
||||
ShoppingCartItems.Add(cartItemDto);
|
||||
await ManageCartItemsLocalStorageService.SaveCollection(ShoppingCartItems);
|
||||
}
|
||||
|
||||
NavigationManager.NavigateTo("/ShoppingCart");
|
||||
}
|
||||
catch (Exception)
|
||||
|
@ -43,5 +60,15 @@ namespace ShopOnline.Web.Pages
|
|||
}
|
||||
}
|
||||
|
||||
private async Task<ProductDto> GetProductById(int id)
|
||||
{
|
||||
var productDtos = await ManageProductsLocalStorageService.GetCollection();
|
||||
|
||||
if(productDtos != null)
|
||||
{
|
||||
return productDtos.SingleOrDefault(p => p.Id == id);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,6 +13,13 @@ namespace ShopOnline.Web.Pages
|
|||
[Inject]
|
||||
public IShoppingCartService ShoppingCartService { get; set; }
|
||||
|
||||
[Inject]
|
||||
public IManageProductsLocalStorageService ManageProductsLocalStorageService { get; set; }
|
||||
|
||||
[Inject]
|
||||
public IManageCartItemsLocalStorageService ManageCartItemsLocalStorageService { get; set; }
|
||||
|
||||
|
||||
public IEnumerable<ProductDto> Products { get; set; }
|
||||
|
||||
[Inject]
|
||||
|
@ -24,9 +31,11 @@ namespace ShopOnline.Web.Pages
|
|||
{
|
||||
try
|
||||
{
|
||||
Products = await ProductService.GetItems();
|
||||
await ClearLocalStorage();
|
||||
|
||||
var shoppingCartItems = await ShoppingCartService.GetItems(HardCoded.UserId);
|
||||
Products = await ManageProductsLocalStorageService.GetCollection();
|
||||
|
||||
var shoppingCartItems = await ManageCartItemsLocalStorageService.GetCollection();
|
||||
var totalQuantity = shoppingCartItems.Sum(i => i.Quantity);
|
||||
|
||||
ShoppingCartService.RaiseEventOnShoppingCartChanged(totalQuantity);
|
||||
|
@ -51,5 +60,11 @@ namespace ShopOnline.Web.Pages
|
|||
return groupedProductDtos.FirstOrDefault(pg => pg.CategoryId == groupedProductDtos.Key).CategoryName;
|
||||
}
|
||||
|
||||
private async Task ClearLocalStorage()
|
||||
{
|
||||
await ManageProductsLocalStorageService.RemoveCollection();
|
||||
await ManageCartItemsLocalStorageService.RemoveCollection();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,6 +12,12 @@ namespace ShopOnline.Web.Pages
|
|||
[Inject]
|
||||
public IProductService ProductService { get; set; }
|
||||
|
||||
[Inject]
|
||||
public IManageProductsLocalStorageService ManageProductsLocalStorageService { get; set; }
|
||||
|
||||
[Inject]
|
||||
|
||||
|
||||
public IEnumerable<ProductDto> Products { get; set; }
|
||||
public string CategoryName { get; set; }
|
||||
public string ErrorMessage { get; set; }
|
||||
|
@ -20,7 +26,7 @@ namespace ShopOnline.Web.Pages
|
|||
{
|
||||
try
|
||||
{
|
||||
Products = await ProductService.GetItemsByCategory(CategoryId);
|
||||
Products = await GetProductCollectionByCategoryId(CategoryId);
|
||||
if(Products != null && Products.Count() > 0)
|
||||
{
|
||||
var productDto = Products.FirstOrDefault(p => p.CategoryId == CategoryId);
|
||||
|
@ -35,5 +41,19 @@ namespace ShopOnline.Web.Pages
|
|||
ErrorMessage = ex.Message;
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<IEnumerable<ProductDto>> GetProductCollectionByCategoryId(int categoryId)
|
||||
{
|
||||
var productCollection = await ManageProductsLocalStorageService.GetCollection();
|
||||
|
||||
if(productCollection != null)
|
||||
{
|
||||
return productCollection.Where(p => p.CategoryId == categoryId);
|
||||
}
|
||||
else
|
||||
{
|
||||
return await ProductService.GetItemsByCategory(categoryId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,6 +13,9 @@ namespace ShopOnline.Web.Pages
|
|||
[Inject]
|
||||
public IShoppingCartService ShoppingCartService { get; set; }
|
||||
|
||||
[Inject]
|
||||
public IManageCartItemsLocalStorageService ManageCartItemsLocalStorageService { get; set; }
|
||||
|
||||
public List<CartItemDto> ShoppingCartItems { get; set; }
|
||||
|
||||
public string ErrorMessage { get; set; }
|
||||
|
@ -24,7 +27,7 @@ namespace ShopOnline.Web.Pages
|
|||
{
|
||||
try
|
||||
{
|
||||
ShoppingCartItems = await ShoppingCartService.GetItems(HardCoded.UserId);
|
||||
ShoppingCartItems = await ManageCartItemsLocalStorageService.GetCollection();
|
||||
CartChanged();
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
@ -56,7 +59,7 @@ namespace ShopOnline.Web.Pages
|
|||
|
||||
var returnedUpdateItemDto = await this.ShoppingCartService.UpdateQuantity(updateItemDto);
|
||||
|
||||
UpdateItemTotalPrice(returnedUpdateItemDto);
|
||||
await UpdateItemTotalPrice(returnedUpdateItemDto);
|
||||
CartChanged();
|
||||
await MakeUpdateQuantityButtonVisible(id, false);
|
||||
|
||||
|
@ -90,7 +93,7 @@ namespace ShopOnline.Web.Pages
|
|||
|
||||
}
|
||||
|
||||
private void UpdateItemTotalPrice(CartItemDto cartItemDto)
|
||||
private async Task UpdateItemTotalPrice(CartItemDto cartItemDto)
|
||||
{
|
||||
var item = GetCartItem(cartItemDto.Id);
|
||||
|
||||
|
@ -98,6 +101,8 @@ namespace ShopOnline.Web.Pages
|
|||
{
|
||||
item.TotalPrice = cartItemDto.Price * cartItemDto.Quantity;
|
||||
}
|
||||
|
||||
await ManageCartItemsLocalStorageService.SaveCollection(ShoppingCartItems);
|
||||
}
|
||||
|
||||
private void CalculateCartSummaryTotals()
|
||||
|
@ -121,11 +126,13 @@ namespace ShopOnline.Web.Pages
|
|||
return ShoppingCartItems.FirstOrDefault(i => i.Id == id);
|
||||
}
|
||||
|
||||
private void RemoveCartItem(int id)
|
||||
private async Task RemoveCartItem(int id)
|
||||
{
|
||||
var CartItemDto = GetCartItem(id);
|
||||
|
||||
ShoppingCartItems.Remove(CartItemDto);
|
||||
|
||||
await ManageCartItemsLocalStorageService.SaveCollection(ShoppingCartItems);
|
||||
}
|
||||
|
||||
private void CartChanged()
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
using Blazored.LocalStorage;
|
||||
using Microsoft.AspNetCore.Components.Web;
|
||||
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
|
||||
using ShopOnline.Web;
|
||||
|
@ -12,4 +13,8 @@ builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri("https:/
|
|||
builder.Services.AddScoped<IProductService, ProductService>();
|
||||
builder.Services.AddScoped<IShoppingCartService, ShoppingCartService>();
|
||||
|
||||
builder.Services.AddBlazoredLocalStorage();
|
||||
builder.Services.AddScoped<IManageProductsLocalStorageService, ManageProductsLocalStorageService>();
|
||||
builder.Services.AddScoped<IManageCartItemsLocalStorageService, ManageCartItemsLocalStorageService>();
|
||||
|
||||
await builder.Build().RunAsync();
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
using ShopOnline.Models.Dtos;
|
||||
|
||||
namespace ShopOnline.Web.Services.Contracts
|
||||
{
|
||||
public interface IManageCartItemsLocalStorageService
|
||||
{
|
||||
Task<List<CartItemDto>> GetCollection();
|
||||
Task SaveCollection(List<CartItemDto> cartItemDtos);
|
||||
Task RemoveCollection();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
using ShopOnline.Models.Dtos;
|
||||
|
||||
namespace ShopOnline.Web.Services.Contracts
|
||||
{
|
||||
public interface IManageProductsLocalStorageService
|
||||
{
|
||||
Task<IEnumerable<ProductDto>> GetCollection();
|
||||
Task RemoveCollection();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
using Blazored.LocalStorage;
|
||||
using ShopOnline.Models.Dtos;
|
||||
using ShopOnline.Web.Services.Contracts;
|
||||
|
||||
namespace ShopOnline.Web.Services
|
||||
{
|
||||
public class ManageCartItemsLocalStorageService : IManageCartItemsLocalStorageService
|
||||
{
|
||||
private readonly ILocalStorageService localStorageService;
|
||||
private readonly IShoppingCartService shoppingCartService;
|
||||
|
||||
const string key = "CartItemCollection";
|
||||
|
||||
public ManageCartItemsLocalStorageService(ILocalStorageService localStorageService, IShoppingCartService shoppingCartService)
|
||||
{
|
||||
this.localStorageService = localStorageService;
|
||||
this.shoppingCartService = shoppingCartService;
|
||||
}
|
||||
public async Task<List<CartItemDto>> GetCollection()
|
||||
{
|
||||
return await this.localStorageService.GetItemAsync<List<CartItemDto>>(key) ?? await AddCollection();
|
||||
}
|
||||
|
||||
public async Task RemoveCollection()
|
||||
{
|
||||
await this.localStorageService.RemoveItemAsync(key);
|
||||
}
|
||||
|
||||
public async Task SaveCollection(List<CartItemDto> cartItemDtos)
|
||||
{
|
||||
await this.localStorageService.SetItemAsync(key, cartItemDtos);
|
||||
|
||||
}
|
||||
|
||||
private async Task<List<CartItemDto>> AddCollection()
|
||||
{
|
||||
var shoppingCartCollection = await this.shoppingCartService.GetItems(HardCoded.UserId);
|
||||
|
||||
if(shoppingCartCollection != null)
|
||||
{
|
||||
await this.localStorageService.SetItemAsync(key, shoppingCartCollection);
|
||||
}
|
||||
|
||||
return shoppingCartCollection;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
using Blazored.LocalStorage;
|
||||
using ShopOnline.Models.Dtos;
|
||||
using ShopOnline.Web.Services.Contracts;
|
||||
|
||||
namespace ShopOnline.Web.Services
|
||||
{
|
||||
public class ManageProductsLocalStorageService : IManageProductsLocalStorageService
|
||||
{
|
||||
private readonly ILocalStorageService localStorageService;
|
||||
private readonly IProductService productService;
|
||||
|
||||
private const string key = "ProductCollection";
|
||||
|
||||
public ManageProductsLocalStorageService(ILocalStorageService localStorageService, IProductService productService)
|
||||
{
|
||||
this.localStorageService = localStorageService;
|
||||
this.productService = productService;
|
||||
}
|
||||
public async Task<IEnumerable<ProductDto>> GetCollection()
|
||||
{
|
||||
return await this.localStorageService.GetItemAsync<IEnumerable<ProductDto>>(key) ?? await AddCollection();
|
||||
}
|
||||
|
||||
public async Task RemoveCollection()
|
||||
{
|
||||
await this.localStorageService.RemoveItemAsync(key);
|
||||
}
|
||||
|
||||
private async Task<IEnumerable<ProductDto>> AddCollection()
|
||||
{
|
||||
var productCollection = await this.productService.GetItems();
|
||||
|
||||
if(productCollection != null)
|
||||
{
|
||||
await this.localStorageService.SetItemAsync(key, productCollection);
|
||||
}
|
||||
|
||||
return productCollection;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
<div class="alert alert-secondary mt-4">
|
||||
<span class="oi oi-pencil me-2" aria-hidden="true"></span>
|
||||
<strong>@Title</strong>
|
||||
|
||||
<span class="text-nowrap">
|
||||
Please take our
|
||||
<a target="_blank" class="font-weight-bold link-dark" href="https://go.microsoft.com/fwlink/?linkid=2148851">brief survey</a>
|
||||
</span>
|
||||
and tell us what you think.
|
||||
</div>
|
||||
|
||||
@code {
|
||||
// Demonstrates how a parent component can supply parameters
|
||||
[Parameter]
|
||||
public string? Title { get; set; }
|
||||
}
|
|
@ -7,6 +7,7 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Blazored.LocalStorage" Version="4.2.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="6.0.8" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="6.0.8" PrivateAssets="all" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
||||
|
|
Loading…
Reference in New Issue