From 204e186354813b235092abc409c219d0a3994de9 Mon Sep 17 00:00:00 2001 From: Brian Bicknell Date: Sat, 25 Apr 2026 14:17:13 -0400 Subject: [PATCH] Added tag/creator status update functionality on the API and UI layers. --- JSMR.Api/Startup/WebApplicationExtensions.cs | 38 ++++++++++ .../Search/Contracts/CreatorSearchItem.cs | 10 +-- .../ApplicationServiceCollectionExtensions.cs | 2 + .../Queries/Search/Contracts/TagSearchItem.cs | 12 ++-- JSMR.UI.Blazor/Layout/MainLayout.razor | 8 ++- JSMR.UI.Blazor/Pages/Creators.razor | 70 +++++++++++++++---- JSMR.UI.Blazor/Pages/Tags.razor | 62 ++++++++++++++-- JSMR.UI.Blazor/Services/VoiceWorksClient.cs | 14 ++++ 8 files changed, 182 insertions(+), 34 deletions(-) diff --git a/JSMR.Api/Startup/WebApplicationExtensions.cs b/JSMR.Api/Startup/WebApplicationExtensions.cs index c9fb08e..b783e1a 100644 --- a/JSMR.Api/Startup/WebApplicationExtensions.cs +++ b/JSMR.Api/Startup/WebApplicationExtensions.cs @@ -1,5 +1,8 @@ using JSMR.Application.Circles.Queries.Search; +using JSMR.Application.Creators.Commands.UpdateCreatorStatus; using JSMR.Application.Creators.Queries.Search; +using JSMR.Application.Tags.Commands.SetEnglishName; +using JSMR.Application.Tags.Commands.UpdateTagStatus; using JSMR.Application.Tags.Queries.Search; using JSMR.Application.Users; using JSMR.Application.VoiceWorks.Queries.Search; @@ -56,6 +59,8 @@ public static class WebApplicationExtensions app.MapGet("/health", () => Results.Ok(new { status = "ok" })); app.MapSearchEndpoints(); + app.MapTagCommandEndpoints(); + app.MapCreatorCommandEndpoints(); app.MapAuthenticationEndpoints(); } @@ -105,6 +110,39 @@ public static class WebApplicationExtensions }); } + private static void MapTagCommandEndpoints(this WebApplication app) + { + app.MapPost("/api/tags/update-status", async ( + UpdateTagStatusRequest request, + UpdateTagStatusHandler handler, + CancellationToken ct) => + { + var result = await handler.HandleAsync(request, ct); + return Results.Ok(result); + }); + + app.MapPost("/api/tags/set-english-name", async ( + SetTagEnglishNameRequest request, + SetTagEnglishNameHandler handler, + CancellationToken ct) => + { + var result = await handler.HandleAsync(request, ct); + return Results.Ok(result); + }); + } + + private static void MapCreatorCommandEndpoints(this WebApplication app) + { + app.MapPost("/api/creators/update-status", async ( + UpdateCreatorStatusRequest request, + UpdateCreatorStatusHandler handler, + CancellationToken ct) => + { + var result = await handler.HandleAsync(request, ct); + return Results.Ok(result); + }); + } + private static void MapAuthenticationEndpoints(this WebApplication app) { app.MapPost("/auth/login", async (LoginRequest req, IUserRepository users, HttpContext http) => diff --git a/JSMR.Application/Creators/Queries/Search/Contracts/CreatorSearchItem.cs b/JSMR.Application/Creators/Queries/Search/Contracts/CreatorSearchItem.cs index 25bd28e..b967f7b 100644 --- a/JSMR.Application/Creators/Queries/Search/Contracts/CreatorSearchItem.cs +++ b/JSMR.Application/Creators/Queries/Search/Contracts/CreatorSearchItem.cs @@ -2,9 +2,9 @@ public record CreatorSearchItem { - public int CreatorId { get; init; } - public required string Name { get; init; } - public bool Favorite { get; init; } - public bool Blacklisted { get; init; } - public int VoiceWorkCount { get; init; } + public int CreatorId { get; set; } + public required string Name { get; set; } + public bool Favorite { get; set; } + public bool Blacklisted { get; set; } + public int VoiceWorkCount { get; set; } } \ No newline at end of file diff --git a/JSMR.Application/DI/ApplicationServiceCollectionExtensions.cs b/JSMR.Application/DI/ApplicationServiceCollectionExtensions.cs index beb3c1e..4853a91 100644 --- a/JSMR.Application/DI/ApplicationServiceCollectionExtensions.cs +++ b/JSMR.Application/DI/ApplicationServiceCollectionExtensions.cs @@ -1,4 +1,5 @@ using JSMR.Application.Circles.Queries.Search; +using JSMR.Application.Creators.Commands.UpdateCreatorStatus; using JSMR.Application.Creators.Queries.Search; using JSMR.Application.Scanning; using JSMR.Application.Tags.Commands.SetEnglishName; @@ -24,6 +25,7 @@ public static class ApplicationServiceCollectionExtensions services.AddScoped(); services.AddScoped(); + services.AddScoped(); return services; } diff --git a/JSMR.Application/Tags/Queries/Search/Contracts/TagSearchItem.cs b/JSMR.Application/Tags/Queries/Search/Contracts/TagSearchItem.cs index be2e897..f8f38f9 100644 --- a/JSMR.Application/Tags/Queries/Search/Contracts/TagSearchItem.cs +++ b/JSMR.Application/Tags/Queries/Search/Contracts/TagSearchItem.cs @@ -2,10 +2,10 @@ public record TagSearchItem { - public int TagId { get; init; } - public required string Name { get; init; } - public bool Favorite { get; init; } - public bool Blacklisted { get; init; } - public string? EnglishName { get; init; } - public int VoiceWorkCount { get; init; } + public int TagId { get; set; } + public required string Name { get; set; } + public bool Favorite { get; set; } + public bool Blacklisted { get; set; } + public string? EnglishName { get; set; } + public int VoiceWorkCount { get; set; } } \ No newline at end of file diff --git a/JSMR.UI.Blazor/Layout/MainLayout.razor b/JSMR.UI.Blazor/Layout/MainLayout.razor index 5d42a7b..e8447ee 100644 --- a/JSMR.UI.Blazor/Layout/MainLayout.razor +++ b/JSMR.UI.Blazor/Layout/MainLayout.razor @@ -1,4 +1,5 @@ -@using JSMR.UI.Blazor.Components +@using AntDesign +@using JSMR.UI.Blazor.Components @using JSMR.UI.Blazor.Services @inject SessionState Session @@ -6,6 +7,8 @@ @inherits LayoutComponentBase + + @@ -40,6 +43,7 @@ @Body + @* Required *@ @@ -49,10 +53,10 @@ @* Needed for snackbars *@ + - @code{ private bool _open = false; diff --git a/JSMR.UI.Blazor/Pages/Creators.razor b/JSMR.UI.Blazor/Pages/Creators.razor index a964da7..7709863 100644 --- a/JSMR.UI.Blazor/Pages/Creators.razor +++ b/JSMR.UI.Blazor/Pages/Creators.razor @@ -1,7 +1,10 @@ @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 @@ -50,20 +53,29 @@ Blacklisted } - @* - - - - - Some Menu Item - - - - - - - - *@ + + + + + @if (!context.Favorite) + { + Set as Favorite + } + @if (!context.Blacklisted) + { + Set as Blacklisted + } + @if (context.Favorite || context.Blacklisted) + { + Set as Neutral + } + + + + + + + @@ -119,6 +131,9 @@ [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; @@ -259,4 +274,31 @@ 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); + } } \ No newline at end of file diff --git a/JSMR.UI.Blazor/Pages/Tags.razor b/JSMR.UI.Blazor/Pages/Tags.razor index c50270c..d8ef36e 100644 --- a/JSMR.UI.Blazor/Pages/Tags.razor +++ b/JSMR.UI.Blazor/Pages/Tags.razor @@ -3,6 +3,8 @@ @inject IJSRuntime JS @using AntDesign @using JSMR.Application.Common.Search +@using JSMR.Application.Tags.Commands.UpdateTagStatus +@using JSMR.Application.Tags.Contracts @using JSMR.Application.Tags.Queries.Search @using JSMR.Application.Tags.Queries.Search.Contracts @using JSMR.UI.Blazor.Components @@ -13,10 +15,6 @@ Tags
- @*

Tags

*@ - - @* - *@ @@ -53,14 +51,34 @@ Blacklisted } + + + + + @if (!context.Favorite) + { + Set as Favorite + } + @if (!context.Blacklisted) + { + Set as Blacklisted + } + @if (context.Favorite || context.Blacklisted) + { + Set as Neutral + } + + + + + + + - - @* - *@