PlotDirector/PlotLine/Controllers/ScenariosController.cs
Nick Beckley 04a41e81b0 Phase 1T
2026-06-01 15:42:44 +01:00

90 lines
3.2 KiB
C#

using Microsoft.AspNetCore.Mvc;
using PlotLine.Services;
using PlotLine.ViewModels;
namespace PlotLine.Controllers;
public sealed class ScenariosController(IScenarioService scenarios) : Controller
{
public async Task<IActionResult> Index(int projectId)
{
var model = await scenarios.ListAsync(projectId);
return model is null ? NotFound() : View(model);
}
public async Task<IActionResult> Create(int projectId, int? bookId)
{
var model = await scenarios.GetCreateAsync(projectId, bookId);
return model is null ? NotFound() : View(model);
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create(ScenarioCreateViewModel model)
{
if (string.IsNullOrWhiteSpace(model.ScenarioName))
{
ModelState.AddModelError(nameof(model.ScenarioName), "Scenario name is required.");
var repopulated = await scenarios.GetCreateAsync(model.ProjectID, model.BookID);
model.BookOptions = repopulated?.BookOptions ?? [];
return View(model);
}
var scenarioId = await scenarios.CreateAsync(model);
return RedirectToAction(nameof(Timeline), new { id = scenarioId });
}
public async Task<IActionResult> Timeline(int id)
{
var model = await scenarios.GetTimelineAsync(id);
return model is null ? NotFound() : View(model);
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> MoveScene(int scenarioId, int sceneId, int? anchorSceneId, int? targetChapterId, string position)
{
await scenarios.MoveSceneAsync(scenarioId, sceneId, anchorSceneId, targetChapterId, position);
return RedirectToAction(nameof(Timeline), new { id = scenarioId });
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Validate(int id)
{
var warningCount = await scenarios.ValidateAsync(id);
TempData["ScenarioMessage"] = $"Scenario validation found {warningCount} warning{(warningCount == 1 ? "" : "s")}.";
return RedirectToAction(nameof(Timeline), new { id });
}
public async Task<IActionResult> Compare(int id)
{
var model = await scenarios.CompareAsync(id);
return model is null ? NotFound() : View(model);
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Apply(int id, string confirmation)
{
if (!string.Equals(confirmation, "This will replace the current scene order with the scenario order. Continue?", StringComparison.Ordinal))
{
TempData["ScenarioMessage"] = "Scenario was not applied. Use the exact confirmation text.";
return RedirectToAction(nameof(Compare), new { id });
}
await scenarios.ApplyAsync(id);
TempData["ScenarioMessage"] = "Scenario applied to the main story order.";
return RedirectToAction(nameof(Timeline), new { id });
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Archive(int id, int projectId)
{
await scenarios.ArchiveAsync(id);
TempData["ArchiveMessage"] = "Scenario archived. You can restore it from Archived Items.";
return RedirectToAction(nameof(Index), new { projectId });
}
}