using System.Security.Claims; using MediatR; using Web.Api.Common; using Web.Api.Extensions; namespace Web.Api.Endpoints.Studio.Donation; /// 후원 목표 위젯 설정 (스튜디오 전용) internal sealed class DonationGoalConfig : IEndpoint { internal sealed record SaveRequest( int? ID, int ChannelID, string Title, int Style, int StartAmount, int TargetAmount, DateTime? StartAt, DateTime? EndAt, bool IsShowPercent, string BarColor, string BarBackgroundColor, int BarHeightPx, int TitleFontSizePx, string TitleFontColor, int AmountFontSizePx, string AmountFontColor, string? TitleFontFamily, string? AmountFontFamily, int Period, bool IsActive ); public void MapEndpoint(IEndpointRouteBuilder app) { /// 목표 설정 목록 조회 app.MapGet("api/studio/donation/goal/config/{channelID}", async ( int channelID, ISender sender, CancellationToken ct ) => { var data = await sender.Send(new Application.Features.Api.DonationGoal.GetConfig.Query(channelID), ct); return ApiResponse.Ok(data); }) .WithTags("StudioDonationGoal") .RequireAuthorization(); /// 목표 설정 저장/수정 app.MapPost("api/studio/donation/goal/config", async ( SaveRequest body, ClaimsPrincipal user, ISender sender, CancellationToken ct ) => { var memberID = user.GetRequiredMemberID(); var command = new Application.Features.Api.DonationGoal.SaveConfig.Command( body.ChannelID, memberID, body.ID, body.Title, body.Style, body.StartAmount, body.TargetAmount, body.StartAt, body.EndAt, body.IsShowPercent, body.BarColor, body.BarBackgroundColor, body.BarHeightPx, body.TitleFontSizePx, body.TitleFontColor, body.AmountFontSizePx, body.AmountFontColor, body.TitleFontFamily, body.AmountFontFamily, body.Period, body.IsActive ); await sender.Send(command, ct); return ApiResponse.Ok(); }) .WithTags("StudioDonationGoal") .RequireAuthorization(); /// 목표 설정 삭제 app.MapDelete("api/studio/donation/goal/config/{id}/{channelID}", async ( int id, int channelID, ISender sender, CancellationToken ct ) => { await sender.Send(new Application.Features.Api.DonationGoal.DeleteConfig.Command(id, channelID), ct); return ApiResponse.Ok(); }) .WithTags("StudioDonationGoal") .RequireAuthorization(); /// 목표 활성/비활성 토글 app.MapPatch("api/studio/donation/goal/config/{id}/active", async ( int id, ToggleActiveRequest body, ISender sender, CancellationToken ct ) => { var result = await sender.Send(new Application.Features.Api.DonationGoal.ToggleActive.Command(id, body.ChannelID, body.IsActive), ct); return result.Match( data => ApiResponse.Ok(data), CustomResults.Problem ); }) .WithTags("StudioDonationGoal") .RequireAuthorization(); } internal sealed record ToggleActiveRequest(int ChannelID, bool IsActive); }