using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using PlotLine.Services; using PlotLine.ViewModels; namespace PlotLine.Controllers; [Authorize] public sealed class FloorPlansController(IFloorPlanService floorPlans) : Controller { public async Task Index(int projectId) { var model = await floorPlans.ListAsync(projectId); return model is null ? NotFound() : View(model); } public async Task Edit(int id) { var model = await floorPlans.GetEditorAsync(id); return model is null ? NotFound() : View(model); } [HttpPost] [ValidateAntiForgeryToken] public async Task Create(FloorPlanEditViewModel model) { if (!ModelState.IsValid) { return RedirectToAction(nameof(Index), new { projectId = model.ProjectID }); } var floorPlanId = await floorPlans.SavePlanAsync(model); return RedirectToAction(nameof(Edit), new { id = floorPlanId }); } [HttpPost] [ValidateAntiForgeryToken] public async Task SavePlan(FloorPlanEditViewModel model) { if (!ModelState.IsValid) { var editor = await floorPlans.GetEditorAsync(model.FloorPlanID); if (editor is null) { return NotFound(); } editor.FloorPlan = model; return View("Edit", editor); } var floorPlanId = await floorPlans.SavePlanAsync(model); TempData["FloorPlanMessage"] = "Floor plan saved."; return RedirectToAction(nameof(Edit), new { id = floorPlanId }); } [HttpPost] [ValidateAntiForgeryToken] public async Task SaveLayout(FloorPlanEditorViewModel model) { try { await floorPlans.SaveLayoutAsync(model); TempData["FloorPlanMessage"] = "Layout saved."; } catch (InvalidOperationException ex) { TempData["FloorPlanError"] = ex.Message; } return RedirectToAction(nameof(Edit), new { id = model.FloorPlan.FloorPlanID }); } [HttpPost] [ValidateAntiForgeryToken] public async Task DeletePlan(int id, int projectId) { await floorPlans.DeletePlanAsync(id); TempData["FloorPlanMessage"] = "Floor plan deleted."; return RedirectToAction(nameof(Index), new { projectId }); } [HttpPost] [ValidateAntiForgeryToken] public async Task AddFloor(FloorPlanFloorEditViewModel model) { if (ModelState.IsValid) { await floorPlans.SaveFloorAsync(model); TempData["FloorPlanMessage"] = "Floor added."; } return RedirectToAction(nameof(Edit), new { id = model.FloorPlanID }); } [HttpPost] [ValidateAntiForgeryToken] public async Task DeleteFloor(int floorPlanId, int floorPlanFloorId) { await floorPlans.DeleteFloorAsync(floorPlanFloorId); TempData["FloorPlanMessage"] = "Floor deleted."; return RedirectToAction(nameof(Edit), new { id = floorPlanId }); } [HttpPost] [ValidateAntiForgeryToken] public async Task AddBlock(int floorPlanId, FloorPlanBlockEditViewModel model) { try { if (ModelState.IsValid) { var floorPlanBlockId = await floorPlans.SaveBlockAsync(model); TempData["FloorPlanMessage"] = "Block added."; return RedirectToAction(nameof(Edit), new { id = floorPlanId, selectedBlockId = floorPlanBlockId }); } } catch (InvalidOperationException ex) { TempData["FloorPlanError"] = ex.Message; } return RedirectToAction(nameof(Edit), new { id = floorPlanId }); } [HttpPost] [ValidateAntiForgeryToken] public async Task DeleteBlock(int floorPlanId, int floorPlanBlockId) { await floorPlans.DeleteBlockAsync(floorPlanBlockId); TempData["FloorPlanMessage"] = "Block deleted."; return RedirectToAction(nameof(Edit), new { id = floorPlanId }); } }