Add news feature with CRUD operations and real-time notifications
- Implemented news management functionality, allowing admins to create, read, update, and delete news posts. - Introduced a new SignalR event for broadcasting news updates to all connected clients. - Updated API documentation to include new endpoints for news management. - Enhanced frontend with a dedicated news page and admin interface for managing news posts. - Added necessary localization for news-related terms in both Russian and English.
This commit is contained in:
@@ -0,0 +1,52 @@
|
||||
using PnvPanel.Api.Common;
|
||||
using PnvPanel.Application.Admin.News;
|
||||
using PnvPanel.Application.Common.Messaging;
|
||||
using PnvPanel.Application.Common.Models;
|
||||
using PnvPanel.Application.News;
|
||||
using PnvPanel.Infrastructure.Identity;
|
||||
|
||||
namespace PnvPanel.Api.Endpoints;
|
||||
|
||||
public static class AdminNewsEndpoints
|
||||
{
|
||||
public static IEndpointRouteBuilder MapAdminNewsEndpoints(this IEndpointRouteBuilder app)
|
||||
{
|
||||
var admin = app.MapGroup("/api/admin/news")
|
||||
.WithTags("Admin.News")
|
||||
.RequireAuthorization(policy => policy.RequireRole(RoleNames.Admin));
|
||||
|
||||
admin.MapGet("", ListAdminNews).Produces<PagedList<NewsPostDto>>();
|
||||
admin.MapPost("", CreatePost).Produces<NewsPostDto>();
|
||||
admin.MapPut("/{id:guid}", UpdatePost).Produces<NewsPostDto>();
|
||||
admin.MapDelete("/{id:guid}", DeletePost).Produces(StatusCodes.Status204NoContent);
|
||||
|
||||
return app;
|
||||
}
|
||||
|
||||
private static async Task<IResult> ListAdminNews(int page, int pageSize, ISender sender, CancellationToken cancellationToken)
|
||||
{
|
||||
var result = await sender.Send(new ListAdminNewsQuery(page, pageSize), cancellationToken);
|
||||
return result.ToHttpResult();
|
||||
}
|
||||
|
||||
private static async Task<IResult> CreatePost(CreatePostCommand command, ISender sender, CancellationToken cancellationToken)
|
||||
{
|
||||
var result = await sender.Send(command, cancellationToken);
|
||||
return result.ToHttpResult();
|
||||
}
|
||||
|
||||
private static async Task<IResult> UpdatePost(Guid id, UpdatePostBody body, ISender sender, CancellationToken cancellationToken)
|
||||
{
|
||||
var command = new UpdatePostCommand(id, body.Title, body.Body);
|
||||
var result = await sender.Send(command, cancellationToken);
|
||||
return result.ToHttpResult();
|
||||
}
|
||||
|
||||
private static async Task<IResult> DeletePost(Guid id, ISender sender, CancellationToken cancellationToken)
|
||||
{
|
||||
var result = await sender.Send(new DeletePostCommand(id), cancellationToken);
|
||||
return result.ToHttpResult();
|
||||
}
|
||||
}
|
||||
|
||||
public sealed record UpdatePostBody(string Title, string Body);
|
||||
@@ -0,0 +1,24 @@
|
||||
using PnvPanel.Api.Common;
|
||||
using PnvPanel.Application.Common.Messaging;
|
||||
using PnvPanel.Application.Common.Models;
|
||||
using PnvPanel.Application.News;
|
||||
|
||||
namespace PnvPanel.Api.Endpoints;
|
||||
|
||||
public static class NewsEndpoints
|
||||
{
|
||||
public static IEndpointRouteBuilder MapNewsEndpoints(this IEndpointRouteBuilder app)
|
||||
{
|
||||
app.MapGet("/api/news", ListNews)
|
||||
.WithTags("News")
|
||||
.RequireAuthorization()
|
||||
.Produces<PagedList<NewsPostDto>>();
|
||||
return app;
|
||||
}
|
||||
|
||||
private static async Task<IResult> ListNews(int page, int pageSize, ISender sender, CancellationToken cancellationToken)
|
||||
{
|
||||
var result = await sender.Send(new ListNewsQuery(page, pageSize), cancellationToken);
|
||||
return result.ToHttpResult();
|
||||
}
|
||||
}
|
||||
@@ -48,4 +48,12 @@ internal sealed class SignalRRealtimeNotifier(IHubContext<PanelHub> hubContext)
|
||||
new { userId },
|
||||
cancellationToken);
|
||||
}
|
||||
|
||||
public Task NotifyNewsPublishedAsync(Guid postId, string title, DateTimeOffset createdAt, CancellationToken cancellationToken)
|
||||
{
|
||||
return hubContext.Clients.All.SendAsync(
|
||||
"newsPublished",
|
||||
new { id = postId, title, createdAt },
|
||||
cancellationToken);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -151,9 +151,11 @@ app.MapInboundEndpoints();
|
||||
app.MapConfigEndpoints();
|
||||
app.MapSubscriptionEndpoints();
|
||||
app.MapAppEndpoints();
|
||||
app.MapNewsEndpoints();
|
||||
app.MapAdminUserEndpoints();
|
||||
app.MapAdminStatsEndpoints();
|
||||
app.MapAdminAppEndpoints();
|
||||
app.MapAdminNewsEndpoints();
|
||||
app.MapTelegramEndpoints();
|
||||
|
||||
app.MapHub<PanelHub>("/hubs/panel");
|
||||
|
||||
Reference in New Issue
Block a user