@page "/creators" @inject VoiceWorksClient Client @inject IJSRuntime JS @using AntDesign @using JSMR.Application.Common.Search @using JSMR.Application.Creators.Commands.UpdateCreatorStatus @using JSMR.Application.Creators.Contracts @using JSMR.Application.Creators.Queries.Search @using JSMR.Application.Creators.Queries.Search.Contracts @using JSMR.UI.Blazor.Components @using JSMR.UI.Blazor.Filters @using JSMR.UI.Blazor.Services @using Microsoft.AspNetCore.WebUtilities Creators @*

Creators

*@ @context.VoiceWorkCount.ToString("n0") @if (context.Favorite) { Favorite } @if (context.Blacklisted) { Blacklisted } @if (!context.Favorite) { Set as Favorite } @if (!context.Blacklisted) { Set as Blacklisted } @if (context.Favorite || context.Blacklisted) { Set as Neutral } @code { [Inject] protected NavigationManager NavigationManager { get; set; } = default!; [Inject] INotificationService NotificationService { get; set; } = default!; public string? Keywords { get; set; } public int PageNumber { get; set; } = 1; public int PageSize { get; set; } = 100; public int TotalItems => searchResults?.TotalItems ?? 0; public bool LoadingData { get; set; } SearchResult? searchResults; protected override async Task OnInitializedAsync() { //await UpdateDataAsync(true); } public async Task OnKeywordsChanged(string? newKeywords) { Keywords = newKeywords; await UpdateDataAsync(true); } public async Task OnPageNumberChanged(int newPageNumber) { PageNumber = newPageNumber; await UpdateDataAsync(false); } public async Task OnPageSizeChanged(int newPageSize) { PageSize = newPageSize; await UpdateDataAsync(true); } private async Task UpdateDataAsync(bool resetPageNumber) { if (resetPageNumber) PageNumber = 1; await LoadCreatorsAsync(); } private async Task LoadCreatorsAsync() { LoadingData = true; SearchCreatorsRequest request = new( Options: new() { PageNumber = PageNumber, PageSize = PageSize, Criteria = new() { Name = Keywords }, SortOptions = [.. _sortOptions] } ); await JS.InvokeVoidAsync("pageHelpers.scrollToTop"); var result = await Client.SearchAsync(request); searchResults = result?.Results ?? new(); LoadingData = false; //await InvokeAsync(StateHasChanged); } private List> _sortOptions = [ new(CreatorSortField.Name, Application.Common.Search.SortDirection.Ascending) ]; private async Task HandleTableChange(AntDesign.TableModels.QueryModel queryModel) { //PageNumber = queryModel.PageIndex; //PageSize = queryModel.PageSize; _sortOptions = MapSortOptions(queryModel); await LoadCreatorsAsync(); } private List> MapSortOptions(AntDesign.TableModels.QueryModel queryModel) { var requestedSorts = queryModel.SortModel .Select(sort => new { Field = sort.FieldName switch { nameof(CreatorSearchItem.Favorite) => CreatorSortField.Favorite, nameof(CreatorSearchItem.Blacklisted) => CreatorSortField.Blacklisted, nameof(CreatorSearchItem.VoiceWorkCount) => CreatorSortField.VoiceWorkCount, nameof(CreatorSearchItem.Name) => CreatorSortField.Name, _ => (CreatorSortField?)null }, Direction = sort.SortDirection switch { AntDesign.SortDirection.Ascending => Application.Common.Search.SortDirection.Ascending, AntDesign.SortDirection.Descending => Application.Common.Search.SortDirection.Descending, _ => (Application.Common.Search.SortDirection?)null } }) .Where(x => x.Field is not null && x.Direction is not null) .ToDictionary(x => x.Field!.Value, x => x.Direction!.Value); var finalSorts = new List>(); // Force your preferred precedence if (requestedSorts.TryGetValue(CreatorSortField.Favorite, out var favoriteDir)) finalSorts.Add(new(CreatorSortField.Favorite, favoriteDir)); if (requestedSorts.TryGetValue(CreatorSortField.Blacklisted, out var blacklistedDir)) finalSorts.Add(new(CreatorSortField.Blacklisted, blacklistedDir)); if (requestedSorts.TryGetValue(CreatorSortField.VoiceWorkCount, out var countDir)) finalSorts.Add(new(CreatorSortField.VoiceWorkCount, countDir)); if (requestedSorts.TryGetValue(CreatorSortField.Name, out var nameDir)) finalSorts.Add(new(CreatorSortField.Name, nameDir)); // Default fallback if (finalSorts.Count == 0) finalSorts.Add(new(CreatorSortField.Name, Application.Common.Search.SortDirection.Ascending)); return finalSorts; } private void NavigateToVoiceWorkSearch(CreatorSearchItem item) { VoiceWorkFilterState state = new() { CreatorIds = [item.CreatorId] }; //string basePath = new Uri(NavigationManager.Uri).GetLeftPart(UriPartial.Path); string basePath = new Uri(NavigationManager.Uri).GetLeftPart(UriPartial.Authority); string uri = QueryHelpers.AddQueryString($"{basePath}/voiceworks", state.ToQuery()); NavigationManager.NavigateTo(uri); } private async Task SetStatus(CreatorSearchItem item, CreatorStatus status) { UpdateCreatorStatusRequest request = new( CreatorId: item.CreatorId, CreatorStatus: status ); UpdateCreatorStatusResponse? response = await Client.UpdateCreatorStatusAsync(request); if (response is not null) { item.Favorite = response.CreatorStatus is CreatorStatus.Favorite; item.Blacklisted = response.CreatorStatus is CreatorStatus.Blacklisted; } await InvokeAsync(StateHasChanged); var config = new NotificationConfig() { Message = $"Creator Status Update", Description = $"Creator '{item.Name}' set to {status.ToString()}.", Placement = NotificationPlacement.Top }; await NotificationService.Open(config); } }