using Microsoft.AspNetCore.Mvc; using PnvPanel.Api.Common; using PnvPanel.Application.Admin.Support; using PnvPanel.Application.Common.Messaging; using PnvPanel.Application.Common.Models; using PnvPanel.Application.Support; using PnvPanel.Application.Support.AddComment; using PnvPanel.Infrastructure.Identity; namespace PnvPanel.Api.Endpoints; public static class AdminSupportEndpoints { public static IEndpointRouteBuilder MapAdminSupportEndpoints(this IEndpointRouteBuilder app) { var admin = app.MapGroup("/api/admin/support") .WithTags("Admin.Support") .RequireAuthorization(policy => policy.RequireRole(RoleNames.Admin)); admin.MapGet("/tickets", ListTickets).Produces>(); admin.MapGet("/tickets/{id:guid}", GetTicket).Produces(); admin.MapPost("/tickets/{id:guid}/comments", AddComment).DisableAntiforgery().Produces(); admin.MapPost("/tickets/{id:guid}/resolve", Resolve).Produces(StatusCodes.Status204NoContent); admin.MapPost("/tickets/{id:guid}/close", Close).Produces(StatusCodes.Status204NoContent); admin.MapPost("/tickets/{id:guid}/approve", ApproveRoleRequest).Produces(StatusCodes.Status204NoContent); admin.MapPost("/tickets/{id:guid}/reject", RejectRoleRequest).Produces(StatusCodes.Status204NoContent); return app; } private static async Task ListTickets( [AsParameters] ListTicketsRequest request, ISender sender, CancellationToken cancellationToken) { var query = new ListAllTicketsQuery(request.Type, request.Status, request.Page, request.PageSize); var result = await sender.Send(query, cancellationToken); return result.ToHttpResult(); } private static async Task GetTicket(Guid id, ISender sender, CancellationToken cancellationToken) { var result = await sender.Send(new GetTicketAdminQuery(id), cancellationToken); return result.ToHttpResult(); } private static async Task AddComment( Guid id, [FromForm] string body, IFormFileCollection? files, ISender sender, CancellationToken cancellationToken) { var command = new AddTicketCommentCommand(id, body, SupportEndpoints.ToUploads(files)); var result = await sender.Send(command, cancellationToken); return result.ToHttpResult(); } private static async Task Resolve(Guid id, ISender sender, CancellationToken cancellationToken) { var result = await sender.Send(new ResolveTicketCommand(id), cancellationToken); return result.ToHttpResult(); } private static async Task Close(Guid id, ISender sender, CancellationToken cancellationToken) { var result = await sender.Send(new CloseTicketCommand(id), cancellationToken); return result.ToHttpResult(); } private static async Task ApproveRoleRequest(Guid id, ISender sender, CancellationToken cancellationToken) { var result = await sender.Send(new ApproveRoleRequestCommand(id), cancellationToken); return result.ToHttpResult(); } private static async Task RejectRoleRequest( Guid id, RejectRoleRequestBody body, ISender sender, CancellationToken cancellationToken) { var result = await sender.Send(new RejectRoleRequestCommand(id, body.Reason), cancellationToken); return result.ToHttpResult(); } } public sealed record RejectRoleRequestBody(string? Reason);