52e3ab16bf
continuous-integration/drone/pr Build is failing
Upgraded nuget packages to bring in new Payment and Product service functionality
224 lines
8.8 KiB
C#
224 lines
8.8 KiB
C#
using LiteCharms.Features;
|
|
using LiteCharms.Features.MidrandBooks.AuthorBooks;
|
|
using LiteCharms.Features.MidrandBooks.Authors;
|
|
using LiteCharms.Features.MidrandBooks.Categories;
|
|
using LiteCharms.Features.MidrandBooks.Products;
|
|
using LiteCharms.Features.MidrandBooks.Products.Models;
|
|
using LiteCharms.Features.Models;
|
|
|
|
namespace MidrandBookshop.Components.Pages;
|
|
|
|
public partial class Home : ComponentBase
|
|
{
|
|
[Inject] private ProductService ProductService { get; set; } = default!;
|
|
[Inject] private BooksService BooksService { get; set; } = default!;
|
|
[Inject] private AuthorService AuthorService { get; set; } = default!;
|
|
[Inject] private CategoryService CategoryService { get; set; } = default!;
|
|
[Inject] private NavigationManager Navigation { get; set; } = default!;
|
|
|
|
[SupplyParameterFromQuery(Name = "q")] public string? SharedSearchQuery { get; set; }
|
|
[SupplyParameterFromQuery] public long? AuthorId { get; set; }
|
|
|
|
private ElementReference topTargetRef;
|
|
public enum ViewMode { Grid, List }
|
|
private ViewMode CurrentViewMode = ViewMode.Grid;
|
|
private string ActiveCategory = "All";
|
|
private bool ShowExpandedCategories = false;
|
|
private bool ShowFilterMenu = false;
|
|
private string SelectedSortOption = "default";
|
|
private string ActivePriceFilter = "all";
|
|
private bool OnlyShowNew = false;
|
|
|
|
private List<string> MainCategories { get; set; } = ["All"];
|
|
private List<string> DynamicExtendedCategories { get; set; } = [];
|
|
|
|
private int ItemsPerPage = 12;
|
|
private int VisibleCount = 12;
|
|
|
|
private List<Product> ProductsCollection { get; set; } = [];
|
|
|
|
protected string? ActiveAuthorFilterName { get; private set; }
|
|
|
|
private Dictionary<long, decimal> ProductPriceCache { get; set; } = [];
|
|
private Dictionary<long, string> ProductPrimaryCategoryCache { get; set; } = [];
|
|
private Dictionary<long, string> ProductAuthorCache { get; set; } = [];
|
|
|
|
private IEnumerable<Product> FilteredData
|
|
{
|
|
get
|
|
{
|
|
var data = ProductsCollection.AsEnumerable();
|
|
|
|
if (ActiveCategory != "All" && !AuthorId.HasValue)
|
|
{
|
|
data = data.Where(p => ProductPrimaryCategoryCache.ContainsKey(p.Id) &&
|
|
ProductPrimaryCategoryCache[p.Id] == ActiveCategory);
|
|
}
|
|
|
|
if (!string.IsNullOrWhiteSpace(SharedSearchQuery))
|
|
{
|
|
var q = SharedSearchQuery.Trim();
|
|
data = data.Where(p => (p.Name ?? "").Contains(q, StringComparison.OrdinalIgnoreCase));
|
|
}
|
|
|
|
if (ActivePriceFilter != "all")
|
|
{
|
|
data = data.Where(p =>
|
|
{
|
|
var price = ProductPriceCache.TryGetValue(p.Id, out var amt) ? amt : 0m;
|
|
|
|
return ActivePriceFilter switch
|
|
{
|
|
"under-500" => price < 500m,
|
|
"500-1000" => price >= 500m && price <= 1000m,
|
|
"over-1000" => price > 1000m,
|
|
_ => true
|
|
};
|
|
});
|
|
}
|
|
|
|
if (OnlyShowNew) data = data.Where(p => p.Enabled);
|
|
|
|
data = SelectedSortOption switch
|
|
{
|
|
"price-low" => data.OrderBy(p => ProductPriceCache.TryGetValue(p.Id, out var amt) ? amt : 0m),
|
|
"price-high" => data.OrderByDescending(p => ProductPriceCache.TryGetValue(p.Id, out var amt) ? amt : 0m),
|
|
"title-asc" => data.OrderBy(p => p.Name ?? string.Empty, StringComparer.OrdinalIgnoreCase),
|
|
"default" or _ => data
|
|
};
|
|
|
|
return data;
|
|
}
|
|
}
|
|
|
|
private IEnumerable<Product> PaginatedBooks => FilteredData.Take(VisibleCount);
|
|
|
|
private bool HasMoreItems => FilteredData.Count() > VisibleCount;
|
|
|
|
protected override async Task OnParametersSetAsync() => await LoadCatalogDataAsync();
|
|
|
|
private async Task LoadCatalogDataAsync()
|
|
{
|
|
ProductsCollection.Clear();
|
|
ProductPriceCache.Clear();
|
|
ProductPrimaryCategoryCache.Clear();
|
|
ProductAuthorCache.Clear();
|
|
ActiveAuthorFilterName = null;
|
|
|
|
if (AuthorId.HasValue)
|
|
{
|
|
var authorResult = await AuthorService.GetAuthorAsync(AuthorId.Value);
|
|
|
|
if (authorResult.IsSuccess && authorResult.Value != null)
|
|
{
|
|
var author = authorResult.Value;
|
|
|
|
ActiveAuthorFilterName = author.PublisherType == PublisherTypes.Company && !string.IsNullOrWhiteSpace(author.Company)
|
|
? author.Company
|
|
: $"{author.Name} {author.LastName}".Trim();
|
|
}
|
|
|
|
var authorBooksResult = await BooksService.GetBooksByAuthorAsync(AuthorId.Value);
|
|
|
|
if (authorBooksResult.IsSuccess && authorBooksResult.Value != null)
|
|
{
|
|
foreach (var authorBook in authorBooksResult.Value)
|
|
{
|
|
if (authorBook.Product != null)
|
|
{
|
|
var product = authorBook.Product;
|
|
|
|
ProductsCollection.Add(product);
|
|
ProductPriceCache[product.Id] = product.Price?.Amount ?? 0m;
|
|
|
|
ProductAuthorCache[product.Id] = ActiveAuthorFilterName ?? "Unknown Author";
|
|
|
|
var categoryResult = await ProductService.GetProductCategoriesAsync(product.Id);
|
|
|
|
ProductPrimaryCategoryCache[product.Id] = (categoryResult.IsSuccess && categoryResult.Value.Length > 0)
|
|
? (categoryResult.Value[0].Name ?? "General")
|
|
: "General";
|
|
}
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
|
|
var selectionRange = new DateRange
|
|
{
|
|
From = new DateOnly(2020, 1, 1),
|
|
To = DateOnly.FromDateTime(DateTime.UtcNow.AddDays(1)),
|
|
MaxRecords = 100
|
|
};
|
|
|
|
var allProductsResult = await ProductService.GetProductsAsync(0, selectionRange);
|
|
|
|
if (allProductsResult.IsSuccess && allProductsResult.Value != null)
|
|
{
|
|
ProductsCollection = allProductsResult.Value.ToList();
|
|
|
|
foreach (var product in ProductsCollection)
|
|
{
|
|
var priceResult = await ProductService.GetProductPriceAsync(product.Id);
|
|
ProductPriceCache[product.Id] = priceResult.IsSuccess ? priceResult.Value.Amount : 0m;
|
|
|
|
var categoryResult = await ProductService.GetProductCategoriesAsync(product.Id);
|
|
ProductPrimaryCategoryCache[product.Id] = (categoryResult.IsSuccess && categoryResult.Value.Length > 0)
|
|
? (categoryResult.Value[0].Name ?? "General")
|
|
: "General";
|
|
|
|
ProductAuthorCache[product.Id] = !string.IsNullOrWhiteSpace(product.Metadata?.Manufacturer)
|
|
? product.Metadata.Manufacturer
|
|
: "Unknown Author";
|
|
}
|
|
}
|
|
|
|
var categoriesResult = await CategoryService.GetCategoriesAsync();
|
|
|
|
if (categoriesResult.IsSuccess && categoriesResult.Value != null)
|
|
{
|
|
var cleanNames = categoriesResult.Value
|
|
.Select(c => c.Name)
|
|
.Where(n => !string.IsNullOrEmpty(n)).Cast<string>()
|
|
.ToList();
|
|
|
|
MainCategories = ["All", .. cleanNames.Take(3)];
|
|
DynamicExtendedCategories = [.. cleanNames.Skip(3)];
|
|
}
|
|
}
|
|
|
|
private void ClearAuthorFilter()
|
|
{
|
|
var newUri = Navigation.GetUriWithQueryParameters("/", new Dictionary<string, object?> { { "authorId", null } });
|
|
|
|
Navigation.NavigateTo(newUri);
|
|
}
|
|
|
|
private void ResetFilters()
|
|
{
|
|
SelectedSortOption = "default";
|
|
ActivePriceFilter = "all";
|
|
OnlyShowNew = false;
|
|
VisibleCount = ItemsPerPage;
|
|
}
|
|
|
|
private void NavigateToProduct(long id) => Navigation.NavigateTo($"/product/{id}");
|
|
private void SetViewMode(ViewMode targetMode) => CurrentViewMode = targetMode;
|
|
|
|
private void SelectCategory(string categoryName)
|
|
{
|
|
ActiveCategory = categoryName;
|
|
VisibleCount = ItemsPerPage;
|
|
|
|
var updatedUri = Navigation.GetUriWithQueryParameters(Navigation.Uri, new Dictionary<string, object?> {{ "q", null }});
|
|
|
|
Navigation.NavigateTo(updatedUri);
|
|
}
|
|
|
|
private void ToggleExtraCategories() => ShowExpandedCategories = !ShowExpandedCategories;
|
|
private void ToggleFilterMenu() => ShowFilterMenu = !ShowFilterMenu;
|
|
private void ChangeSort(string sortOption) => SelectedSortOption = sortOption;
|
|
private void ChangePriceFilter(string priceBracket) { ActivePriceFilter = priceBracket; VisibleCount = ItemsPerPage; }
|
|
private void ToggleNewArrivalsOnly(ChangeEventArgs e) { OnlyShowNew = e.Value is bool b && b; VisibleCount = ItemsPerPage; }
|
|
private void LoadNextPage() { if (HasMoreItems) VisibleCount += ItemsPerPage; }
|
|
} |