Working search
continuous-integration/drone/pr Build is passing

This commit is contained in:
Khwezi Mngoma
2026-05-30 21:00:13 +02:00
parent af02cbc649
commit 01a0264452
7 changed files with 220 additions and 116 deletions
+38 -18
View File
@@ -16,7 +16,7 @@ public partial class Home : ComponentBase
[Inject] private CategoryService CategoryService { get; set; } = default!;
[Inject] private NavigationManager Navigation { get; set; } = default!;
[CascadingParameter] public string SharedSearchQuery { get; set; } = string.Empty;
[SupplyParameterFromQuery(Name = "q")] public string? SharedSearchQuery { get; set; }
[SupplyParameterFromQuery] public long? AuthorId { get; set; }
public enum ViewMode { Grid, List }
@@ -40,6 +40,7 @@ public partial class Home : ComponentBase
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
{
@@ -47,26 +48,24 @@ public partial class Home : ComponentBase
{
var data = ProductsCollection.AsEnumerable();
// 1. Category Filtering
if (ActiveCategory != "All" && !AuthorId.HasValue)
{
data = data.Where(p => ProductPrimaryCategoryCache.ContainsKey(p.Id) &&
ProductPrimaryCategoryCache[p.Id] == ActiveCategory);
}
// 2. Text Search Query Matching
if (!string.IsNullOrWhiteSpace(SharedSearchQuery))
{
var q = SharedSearchQuery.Trim();
data = data.Where(p => (p.Name ?? "").Contains(q, StringComparison.OrdinalIgnoreCase));
}
// 3. FIX: Price Tier Constraint Selection Layout
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,
@@ -77,20 +76,14 @@ public partial class Home : ComponentBase
});
}
// 4. FIX: New Acquisition Flag Status Check
if (OnlyShowNew)
{
// Utilizing your mapping configuration: book.Enabled defines new arrival status
data = data.Where(p => p.Enabled);
}
if (OnlyShowNew) data = data.Where(p => p.Enabled);
// 5. FIX: Collection Sorting Pipeline Extensions
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 // Fallback to raw catalog chronological order sequence
"default" or _ => data
};
return data;
@@ -108,9 +101,9 @@ public partial class Home : ComponentBase
ProductsCollection.Clear();
ProductPriceCache.Clear();
ProductPrimaryCategoryCache.Clear();
ProductAuthorCache.Clear();
ActiveAuthorFilterName = null;
// Pipeline A: Extract scoped books directly associated with an ID token parameter
if (AuthorId.HasValue)
{
var authorResult = await AuthorService.GetAuthorAsync(AuthorId.Value);
@@ -135,9 +128,10 @@ public partial class Home : ComponentBase
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)
@@ -149,7 +143,6 @@ public partial class Home : ComponentBase
return;
}
// Pipeline B: Safe structural fallback mapping utilizing the exact backend DateRange object setup
var selectionRange = new DateRange
{
From = new DateOnly(2020, 1, 1),
@@ -172,6 +165,10 @@ public partial class Home : ComponentBase
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";
}
}
@@ -189,15 +186,38 @@ public partial class Home : ComponentBase
}
}
private void ClearAuthorFilter() => Navigation.NavigateTo("/");
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; }
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 ResetFilters() { SelectedSortOption = "default"; ActivePriceFilter = "all"; OnlyShowNew = false; VisibleCount = ItemsPerPage; }
private void LoadNextPage() { if (HasMoreItems) VisibleCount += ItemsPerPage; }
}
@@ -169,4 +169,4 @@ html {
color: #ffffff !important;
border-color: #ffffff !important;
box-shadow: 0 0 0 2px #1a1a1a, 0 6px 16px rgba(0, 0, 0, 0.25) !important;
}
}