using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using PlotLine.Models; using PlotLine.Services; using PlotLine.ViewModels; namespace PlotLine.Controllers; [Authorize(Policy = "AdminOnly")] [Route("admin")] public sealed class AdminController( ICurrentUserService currentUser, IFeatureRequestService featureRequests) : Controller { [HttpGet("")] [HttpGet("index")] public IActionResult Index() { return View(); } [HttpGet("theme-audit")] public IActionResult ThemeAudit() { return View(); } [HttpGet("feature-requests")] public async Task FeatureRequests(string? status) { var selectedStatus = FeatureRequestStatuses.IsValid(status) ? status : null; return View(new AdminFeatureRequestIndexViewModel { Status = selectedStatus, Requests = await featureRequests.ListForAdminAsync(selectedStatus) }); } [HttpGet("feature-requests/{id:int}")] public async Task FeatureRequestDetails(int id) { var request = await featureRequests.GetForAdminAsync(id); if (request is null) { return NotFound(); } return View(new FeatureRequestDetailsViewModel { IsAdminView = true, Request = request, Messages = await featureRequests.ListMessagesAsync(request.FeatureRequestID), Reply = new FeatureRequestReplyViewModel { FeatureRequestID = request.FeatureRequestID } }); } [HttpPost("feature-requests/update")] [ValidateAntiForgeryToken] public async Task UpdateFeatureRequest(AdminFeatureRequestUpdateViewModel model) { if (!FeatureRequestStatuses.IsValid(model.Status)) { return BadRequest(); } var updated = await featureRequests.UpdateAdminFieldsAsync(model); if (!updated) { return NotFound(); } TempData["AdminMessage"] = "Feature request updated."; return RedirectToAction(nameof(FeatureRequestDetails), new { id = model.FeatureRequestID }); } [HttpPost("feature-requests/reply")] [ValidateAntiForgeryToken] public async Task FeatureRequestReply([Bind(Prefix = "Reply")] FeatureRequestReplyViewModel model) { if (currentUser.UserId is not int userId) { return Forbid(); } var request = await featureRequests.GetForAdminAsync(model.FeatureRequestID); if (request is null) { return NotFound(); } if (!ModelState.IsValid) { return View(nameof(FeatureRequestDetails), new FeatureRequestDetailsViewModel { IsAdminView = true, Request = request, Messages = await featureRequests.ListMessagesAsync(request.FeatureRequestID), Reply = model }); } await featureRequests.AddAdminReplyAsync(model.FeatureRequestID, userId, model.MessageBody); return RedirectToAction(nameof(FeatureRequestDetails), new { id = model.FeatureRequestID }); } }