2026-06-15 15:31:44 +01:00

165 lines
8.9 KiB
Plaintext

@model ProjectDetailViewModel
@{
ViewData["Title"] = Model.Project.ProjectName;
ViewData["ProjectSection"] = "Overview";
var summaryCards = new[]
{
("Total Books", Model.Summary.TotalBooks.ToString("N0")),
("Published Books", Model.Summary.PublishedBooks.ToString("N0")),
("Drafting Books", Model.Summary.DraftingBooks.ToString("N0")),
("Planning Books", Model.Summary.PlanningBooks.ToString("N0")),
("Total Words", Model.Summary.TotalWords.ToString("N0")),
("Characters", Model.Summary.CharacterCount.ToString("N0")),
("Locations", Model.Summary.LocationCount.ToString("N0")),
("Active Plot Threads", Model.Summary.ActivePlotThreadCount.ToString("N0")),
("Continuity Warnings", Model.Summary.ContinuityWarningCount.ToString("N0"))
};
}
<nav class="breadcrumb-trail" aria-label="Breadcrumb">
<a asp-controller="Projects" asp-action="Index">Projects</a>
<span>@Model.Project.ProjectName</span>
</nav>
<partial name="_ProjectSectionNav" model="Model.Project" />
<div class="page-heading pw-page-heading">
<div>
<p class="eyebrow">Series Dashboard</p>
<h1>@Model.Project.ProjectName <help-icon key="projectDashboard.overview" /></h1>
@if (!string.IsNullOrWhiteSpace(Model.Project.Description))
{
<p class="lead-text">@Model.Project.Description</p>
}
</div>
<div class="button-row">
<a class="btn btn-outline-secondary" asp-action="Edit" asp-route-id="@Model.Project.ProjectID">Edit project</a>
<a class="btn btn-primary" asp-controller="Books" asp-action="Create" asp-route-projectId="@Model.Project.ProjectID">Add book</a>
<div class="dropdown pw-actions">
<button class="btn pw-actions__toggle dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false">
Actions
</button>
<div class="dropdown-menu dropdown-menu-end">
<a class="dropdown-item" asp-action="Activity" asp-route-id="@Model.Project.ProjectID">Activity</a>
@if (Model.Project.IsOwner)
{
<a class="dropdown-item" asp-controller="ProjectCollaborators" asp-action="Index" asp-route-projectId="@Model.Project.ProjectID">Collaborators</a>
}
@if (Model.Project.IsOwner)
{
<a class="dropdown-item" asp-controller="Exports" asp-action="ProjectBackup" asp-route-projectId="@Model.Project.ProjectID">Download Project Backup</a>
}
<a class="dropdown-item" asp-controller="ProjectRestorePoints" asp-action="Index" asp-route-projectId="@Model.Project.ProjectID">Restore Points</a>
<a class="dropdown-item" asp-controller="Acceptance" asp-action="Phase1" asp-route-projectId="@Model.Project.ProjectID">Phase 1 Checklist</a>
@if (Model.Project.IsOwner)
{
<div class="dropdown-divider"></div>
<form asp-action="Archive" method="post" class="archive-button-form" data-confirm-message="Archive this project?&#10;&#10;Archived projects are hidden from your active workspace but remain stored within PlotDirector. Export your project first if you wish to maintain an external backup.">
<input type="hidden" name="id" value="@Model.Project.ProjectID" />
<button class="dropdown-item text-danger" type="submit">Archive Project</button>
</form>
}
</div>
</div>
</div>
</div>
@if (TempData["ProjectExportMessage"] is string projectExportMessage)
{
<div class="alert alert-warning">@projectExportMessage</div>
}
<section class="mb-4" aria-label="Series summary">
<div class="row g-3">
@foreach (var card in summaryCards)
{
<div class="col-6 col-md-4 col-xl-2">
<div class="card h-100">
<div class="card-body py-3">
<p class="eyebrow mb-2">@card.Item1</p>
<strong class="fs-3 lh-1">@card.Item2</strong>
</div>
</div>
</div>
}
</div>
</section>
<section aria-label="Books">
<div class="d-flex align-items-center justify-content-between gap-3 flex-wrap mb-3">
<h2 class="h4 mb-0">Books <help-icon key="projects.books" /></h2>
<a class="btn btn-primary btn-sm" asp-controller="Books" asp-action="Create" asp-route-projectId="@Model.Project.ProjectID">Add book</a>
</div>
@if (!Model.Books.Any())
{
<div class="empty-panel">
<h2>No books yet</h2>
<p class="muted mb-0">Add the first book to begin shaping this series.</p>
</div>
}
else
{
<div class="row g-4">
@foreach (var book in Model.Books)
{
<div class="col-12 col-md-6 col-lg-4">
<article class="card h-100 overflow-hidden">
<div class="row g-0 h-100">
<div class="col-4 d-flex align-items-center justify-content-center" style="aspect-ratio:2 / 3; background:var(--plotline-soft);">
<img src="@book.CoverThumbnailPath"
alt="Cover for @book.BookTitle"
class="img-fluid"
style="max-width:100%; max-height:100%; object-fit:contain;" />
</div>
<div class="col-8">
<div class="card-body h-100 d-flex flex-column">
<div class="d-flex align-items-start justify-content-between gap-2 mb-2">
<div>
<p class="eyebrow mb-1">Book @book.BookNumber</p>
<h3 class="h5 mb-1">
<a asp-controller="Books" asp-action="Details" asp-route-id="@book.BookID">@book.BookTitle</a>
</h3>
@if (!string.IsNullOrWhiteSpace(book.Subtitle))
{
<p class="muted mb-0">@book.Subtitle</p>
}
</div>
<span class="status-pill">@book.Status</span>
</div>
<p class="mb-2">@book.WordCountLabel</p>
@if (book.ProgressPercentage.HasValue)
{
var progressValue = Math.Round(book.ProgressPercentage.Value);
<div class="progress mb-3" role="progressbar" aria-label="Book progress" aria-valuenow="@progressValue" aria-valuemin="0" aria-valuemax="100" style="height:8px;">
<div class="progress-bar" style="width:@progressValue%"></div>
</div>
}
<div class="d-flex gap-3 flex-wrap small text-muted mb-3">
<span>@book.ChapterCount.ToString("N0") chapters</span>
<span>@book.SceneCount.ToString("N0") scenes</span>
<span>Modified @book.UpdatedDate.ToString("dd MMM yyyy")</span>
</div>
<div class="button-row mt-auto">
<a class="btn btn-primary btn-sm" asp-controller="Books" asp-action="Details" asp-route-id="@book.BookID">Open Book</a>
<a class="btn btn-outline-secondary btn-sm" asp-controller="Books" asp-action="Edit" asp-route-id="@book.BookID">Edit Book</a>
<form asp-controller="Books" asp-action="Archive" method="post" class="archive-button-form" data-confirm-message="Archive this book?&#10;&#10;This will hide it from active lists and timelines, but the data will be kept and can be restored later.">
<input type="hidden" name="id" value="@book.BookID" />
<input type="hidden" name="projectId" value="@Model.Project.ProjectID" />
<button class="btn btn-outline-danger btn-sm" type="submit">Archive</button>
</form>
</div>
</div>
</div>
</div>
</article>
</div>
}
</div>
}
</section>