using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using LittleShop.Services; using LittleShop.DTOs; namespace LittleShop.Areas.Admin.Controllers; [Area("Admin")] [Authorize(Policy = "AdminOnly")] public class UsersController : Controller { private readonly IAuthService _authService; public UsersController(IAuthService authService) { _authService = authService; } public async Task Index() { var users = await _authService.GetAllUsersAsync(); return View(users); } public IActionResult Create() { return View(); } [HttpPost] [ValidateAntiForgeryToken] public async Task Create(CreateUserDto model) { try { if (!ModelState.IsValid) { return View(model); } var user = await _authService.CreateUserAsync(model); if (user == null) { ModelState.AddModelError("Username", "User with this username already exists"); return View(model); } TempData["SuccessMessage"] = $"User '{user.Username}' created successfully"; return RedirectToAction(nameof(Index)); } catch (Exception ex) { ModelState.AddModelError("", "An error occurred while creating the user: " + ex.Message); return View(model); } } public async Task Edit(Guid id) { var user = await _authService.GetUserByIdAsync(id); if (user == null) { return NotFound(); } var model = new UpdateUserDto { Username = user.Username, IsActive = user.IsActive }; ViewData["UserId"] = id; return View(model); } [HttpPost] [ValidateAntiForgeryToken] public async Task Edit(Guid id, UpdateUserDto model) { try { // Additional validation for required username if (string.IsNullOrWhiteSpace(model.Username)) { ModelState.AddModelError("Username", "Username is required"); } // Validate password if provided if (!string.IsNullOrEmpty(model.Password) && model.Password.Length < 8) { ModelState.AddModelError("Password", "Password must be at least 8 characters if changing"); } if (!ModelState.IsValid) { ViewData["UserId"] = id; return View(model); } var success = await _authService.UpdateUserAsync(id, model); if (!success) { // Check if it's because of duplicate username var existingUser = await _authService.GetUserByIdAsync(id); if (existingUser == null) { return NotFound(); } ModelState.AddModelError("Username", "Username is already taken by another user"); ViewData["UserId"] = id; return View(model); } TempData["SuccessMessage"] = "User updated successfully"; return RedirectToAction(nameof(Index)); } catch (Exception ex) { ModelState.AddModelError("", "An error occurred while updating the user: " + ex.Message); ViewData["UserId"] = id; return View(model); } } [HttpPost] [ValidateAntiForgeryToken] public async Task Delete(Guid id) { try { // Prevent admin user from deleting themselves var currentUserIdClaim = User.FindFirst(System.Security.Claims.ClaimTypes.NameIdentifier)?.Value; if (Guid.TryParse(currentUserIdClaim, out Guid currentUserId) && currentUserId == id) { TempData["ErrorMessage"] = "You cannot delete your own account"; return RedirectToAction(nameof(Index)); } // Get user info for confirmation message var user = await _authService.GetUserByIdAsync(id); if (user == null) { TempData["ErrorMessage"] = "User not found"; return RedirectToAction(nameof(Index)); } var success = await _authService.DeleteUserAsync(id); if (success) { TempData["SuccessMessage"] = $"User '{user.Username}' has been deactivated"; } else { TempData["ErrorMessage"] = "Failed to delete user"; } return RedirectToAction(nameof(Index)); } catch (Exception ex) { TempData["ErrorMessage"] = "An error occurred while deleting the user: " + ex.Message; return RedirectToAction(nameof(Index)); } } }