118 lines
4.1 KiB
C#
118 lines
4.1 KiB
C#
using Microsoft.AspNetCore.Mvc;
|
|
using Microsoft.AspNetCore.Authorization;
|
|
using PlotLine.Models;
|
|
using PlotLine.Services;
|
|
using PlotLine.ViewModels;
|
|
|
|
namespace PlotLine.Controllers;
|
|
|
|
[Authorize]
|
|
public sealed class BooksController(IBookService books, IOnboardingService onboarding) : Controller
|
|
{
|
|
public async Task<IActionResult> Details(int id)
|
|
{
|
|
var model = await books.GetDetailAsync(id);
|
|
return model is null ? NotFound() : View(model);
|
|
}
|
|
|
|
public async Task<IActionResult> Create(int projectId)
|
|
{
|
|
var model = await books.GetCreateAsync(projectId);
|
|
return model is null ? NotFound() : View("Edit", model);
|
|
}
|
|
|
|
public async Task<IActionResult> Edit(int id)
|
|
{
|
|
var model = await books.GetEditAsync(id);
|
|
return model is null ? NotFound() : View(model);
|
|
}
|
|
|
|
[HttpPost]
|
|
[ValidateAntiForgeryToken]
|
|
public async Task<IActionResult> Save(BookEditViewModel model)
|
|
{
|
|
if (model.BeginMode is not (BookBeginModes.Manual or BookBeginModes.Import))
|
|
{
|
|
model.BeginMode = BookBeginModes.Manual;
|
|
}
|
|
|
|
if (!BookStatuses.IsValid(model.Status))
|
|
{
|
|
ModelState.AddModelError(nameof(model.Status), "Select a valid book status.");
|
|
}
|
|
|
|
if (!ModelState.IsValid)
|
|
{
|
|
await books.PopulateEditContextAsync(model);
|
|
return View("Edit", model);
|
|
}
|
|
|
|
BookSaveResult result;
|
|
try
|
|
{
|
|
result = await books.SaveAsync(model);
|
|
}
|
|
catch (SubscriptionLimitException ex) when (model.BookID == 0)
|
|
{
|
|
ModelState.AddModelError(string.Empty, ex.Message);
|
|
var createModel = await books.GetCreateAsync(model.ProjectID);
|
|
if (createModel is null)
|
|
{
|
|
return NotFound();
|
|
}
|
|
|
|
createModel.BookTitle = model.BookTitle;
|
|
createModel.Subtitle = model.Subtitle;
|
|
createModel.Tagline = model.Tagline;
|
|
createModel.ShortDescription = model.ShortDescription;
|
|
createModel.Status = model.Status;
|
|
createModel.BookNumber = model.BookNumber;
|
|
createModel.Description = model.Description;
|
|
createModel.TargetWordCount = model.TargetWordCount;
|
|
createModel.WritingStartDate = model.WritingStartDate;
|
|
createModel.TargetCompletionDate = model.TargetCompletionDate;
|
|
createModel.PublicationDate = model.PublicationDate;
|
|
createModel.UsesExplicitScenes = model.UsesExplicitScenes;
|
|
createModel.BeginMode = model.BeginMode;
|
|
await books.PopulateEditContextAsync(createModel);
|
|
return View("Edit", createModel);
|
|
}
|
|
|
|
if (!result.Succeeded)
|
|
{
|
|
model.BookID = result.BookID;
|
|
ModelState.AddModelError(nameof(model.CoverUpload), result.ErrorMessage ?? "Cover image could not be uploaded.");
|
|
await books.PopulateEditContextAsync(model);
|
|
return View("Edit", model);
|
|
}
|
|
|
|
if (model.BookID == 0 && string.Equals(model.BeginMode, BookBeginModes.Import, StringComparison.Ordinal))
|
|
{
|
|
await onboarding.BeginManuscriptImportForBookAsync(model.ProjectID, result.BookID);
|
|
return RedirectToAction("Index", "Onboarding");
|
|
}
|
|
|
|
return RedirectToAction(nameof(Details), new { id = result.BookID });
|
|
}
|
|
|
|
[HttpPost]
|
|
[ValidateAntiForgeryToken]
|
|
public async Task<IActionResult> Archive(int id, int projectId)
|
|
{
|
|
await books.ArchiveAsync(id);
|
|
TempData["ArchiveMessage"] = "Book archived. You can restore it from Archived Items.";
|
|
return RedirectToAction("Details", "Projects", new { id = projectId });
|
|
}
|
|
|
|
[HttpPost]
|
|
[ValidateAntiForgeryToken]
|
|
public async Task<IActionResult> UnlinkManuscript(int id)
|
|
{
|
|
var result = await books.UnlinkManuscriptAsync(id);
|
|
TempData["ManuscriptMessage"] = result is null
|
|
? "Unable to unlink manuscript. It may already be unlinked, or you may not have access."
|
|
: result.Message;
|
|
return RedirectToAction(nameof(Details), new { id });
|
|
}
|
|
}
|