192 lines
8.4 KiB
Plaintext
192 lines
8.4 KiB
Plaintext
@model StoryIntelligenceProgressViewModel
|
|
@{
|
|
ViewData["Title"] = "Story Intelligence Review Centre";
|
|
}
|
|
|
|
<section class="story-review-centre-shell" aria-labelledby="story-review-centre-title">
|
|
<div class="story-review-centre-workspace">
|
|
<div class="story-review-centre-heading">
|
|
<p class="eyebrow">Story Intelligence</p>
|
|
<h1 id="story-review-centre-title">Review Centre</h1>
|
|
<p>@(Model.CharacterGateSatisfied
|
|
? "Your manuscript analysis is complete. Choose any category to inspect or review."
|
|
: "Resolve Characters first. Once character identities are confirmed, the remaining Story Intelligence categories can be reviewed in any order.")</p>
|
|
</div>
|
|
|
|
@if (TempData["OnboardingStoryIntelligenceError"] is string error)
|
|
{
|
|
<div class="alert alert-danger">@error</div>
|
|
}
|
|
@if (TempData["OnboardingStoryIntelligenceMessage"] is string message)
|
|
{
|
|
<div class="alert alert-success">@message</div>
|
|
}
|
|
|
|
<section class="story-review-centre-grid" aria-label="Story Intelligence review categories">
|
|
@ReviewModule(
|
|
"Characters",
|
|
Model.CharacterNeedsAttentionCount,
|
|
Model.CharacterGateSatisfied,
|
|
false,
|
|
"Resolve character identities before reviewing dependent Story Intelligence.",
|
|
Model.CharacterGateSatisfied ? "Review Characters" : "Resolve Characters",
|
|
"StoryIntelligenceCharacters",
|
|
true)
|
|
|
|
@ReviewModule(
|
|
"Assets",
|
|
Model.AssetNeedsAttentionCount,
|
|
Model.PipelineDashboard.AssetStageComplete,
|
|
!Model.CharacterGateSatisfied,
|
|
"Important objects and possessions found in the manuscript.",
|
|
ModuleAction("Assets", Model.AssetNeedsAttentionCount, Model.PipelineDashboard.AssetStageComplete),
|
|
"StoryIntelligenceAssets")
|
|
|
|
@ReviewModule(
|
|
"Knowledge",
|
|
Model.KnowledgeNeedsAttentionCount,
|
|
Model.PipelineDashboard.KnowledgeStageComplete,
|
|
!Model.CharacterGateSatisfied,
|
|
"Facts, discoveries, beliefs, and suspicions found in the manuscript.",
|
|
ModuleAction("Knowledge", Model.KnowledgeNeedsAttentionCount, Model.PipelineDashboard.KnowledgeStageComplete),
|
|
"StoryIntelligenceKnowledge")
|
|
|
|
@ReviewModule(
|
|
"Locations",
|
|
Model.LocationNeedsAttentionCount,
|
|
Model.PipelineDashboard.LocationStageComplete,
|
|
!Model.CharacterGateSatisfied,
|
|
"Places found in the manuscript.",
|
|
ModuleAction("Locations", Model.LocationNeedsAttentionCount, Model.PipelineDashboard.LocationStageComplete),
|
|
"StoryIntelligenceLocations")
|
|
|
|
@ReviewModule(
|
|
"Plot Lines & Threads",
|
|
Model.NarrativeNeedsAttentionCount,
|
|
Model.PipelineDashboard.NarrativeStageComplete,
|
|
!Model.CharacterGateSatisfied,
|
|
"Recurring arcs and threads discovered from scene evidence.",
|
|
ModuleAction("Plot Lines & Threads", Model.NarrativeNeedsAttentionCount, Model.PipelineDashboard.NarrativeStageComplete),
|
|
"StoryIntelligenceNarrative")
|
|
|
|
@ReviewModule(
|
|
"Relationships",
|
|
Model.RelationshipNeedsAttentionCount,
|
|
Model.PipelineDashboard.RelationshipStageComplete,
|
|
!Model.CharacterGateSatisfied,
|
|
"Character relationships found in scene evidence.",
|
|
ModuleAction("Relationships", Model.RelationshipNeedsAttentionCount, Model.PipelineDashboard.RelationshipStageComplete),
|
|
"StoryIntelligenceRelationships")
|
|
|
|
@ReviewMetrics(!Model.CharacterGateSatisfied)
|
|
|
|
@if (Model.AnalysisIssueCount > 0)
|
|
{
|
|
@ReviewModule(
|
|
"Analysis Issues",
|
|
Model.AnalysisIssueCount,
|
|
false,
|
|
false,
|
|
"Some chapters or scenes reported analysis issues.",
|
|
"Return to Book",
|
|
null)
|
|
}
|
|
</section>
|
|
|
|
<div class="onboarding-actions story-review-centre-actions">
|
|
<a class="btn btn-outline-secondary" asp-controller="Books" asp-action="Details" asp-route-id="@Model.BookID">Return to Book</a>
|
|
<a class="btn btn-outline-primary" asp-controller="Writer" asp-action="Index" asp-route-projectId="@Model.ProjectID">Open Writer Workspace</a>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
@functions {
|
|
private string ModuleAction(string title, int count, bool complete)
|
|
=> count > 0 && !complete ? $"Review {title}" : $"View {title}";
|
|
|
|
private string StatusText(string title, int count, bool complete, bool blocked)
|
|
{
|
|
if (blocked)
|
|
{
|
|
return "Locked until Characters are resolved";
|
|
}
|
|
|
|
if (string.Equals(title, "Scene Metrics", StringComparison.Ordinal))
|
|
{
|
|
return "Available";
|
|
}
|
|
|
|
if (complete)
|
|
{
|
|
return "Complete";
|
|
}
|
|
|
|
return count switch
|
|
{
|
|
0 => "No review needed",
|
|
1 => "1 needs attention",
|
|
_ => $"{count:N0} need attention"
|
|
};
|
|
}
|
|
|
|
private Microsoft.AspNetCore.Html.IHtmlContent ReviewMetrics(bool blocked)
|
|
{
|
|
var status = StatusText("Scene Metrics", Model.TotalAnalysedScenes, false, blocked);
|
|
var statusClass = blocked
|
|
? "story-review-centre-tile__status story-review-centre-tile__status--locked"
|
|
: "story-review-centre-tile__status story-review-centre-tile__status--ready";
|
|
var actionHtml = blocked
|
|
? "<span class=\"btn btn-outline-secondary btn-sm disabled\" aria-disabled=\"true\">Locked</span>"
|
|
: "<span class=\"btn btn-outline-primary btn-sm disabled\" aria-disabled=\"true\">View Metrics</span>";
|
|
|
|
return new Microsoft.AspNetCore.Html.HtmlString($$"""
|
|
<article class="story-review-centre-tile{{(blocked ? " story-review-centre-tile--locked" : string.Empty)}}">
|
|
<div>
|
|
<h2>Scene Metrics</h2>
|
|
<p>Auto-applied metrics from analysed scenes.</p>
|
|
</div>
|
|
<strong class="{{statusClass}}">{{System.Net.WebUtility.HtmlEncode(status)}}</strong>
|
|
{{actionHtml}}
|
|
</article>
|
|
""");
|
|
}
|
|
|
|
private Microsoft.AspNetCore.Html.IHtmlContent ReviewModule(
|
|
string title,
|
|
int count,
|
|
bool complete,
|
|
bool blocked,
|
|
string description,
|
|
string actionLabel,
|
|
string? action,
|
|
bool primary = false)
|
|
{
|
|
var status = StatusText(title, count, complete, blocked);
|
|
var statusClass = blocked
|
|
? "story-review-centre-tile__status story-review-centre-tile__status--locked"
|
|
: count > 0 && !complete
|
|
? "story-review-centre-tile__status story-review-centre-tile__status--warning"
|
|
: "story-review-centre-tile__status story-review-centre-tile__status--ready";
|
|
var tileClass = "story-review-centre-tile"
|
|
+ (primary ? " story-review-centre-tile--primary" : string.Empty)
|
|
+ (blocked ? " story-review-centre-tile--locked" : string.Empty);
|
|
var href = action is null
|
|
? Url.Action("Details", "Books", new { id = Model.BookID }) ?? "#"
|
|
: Url.Action(action, "Onboarding", new { batchId = Model.BatchID }) ?? "#";
|
|
var actionHtml = blocked
|
|
? "<span class=\"btn btn-outline-secondary btn-sm disabled\" aria-disabled=\"true\">Locked</span>"
|
|
: $"<a class=\"btn btn-outline-primary btn-sm\" href=\"{System.Net.WebUtility.HtmlEncode(href)}\">{System.Net.WebUtility.HtmlEncode(actionLabel)}</a>";
|
|
|
|
return new Microsoft.AspNetCore.Html.HtmlString($$"""
|
|
<article class="{{tileClass}}">
|
|
<div>
|
|
<h2>{{System.Net.WebUtility.HtmlEncode(title)}}</h2>
|
|
<p>{{System.Net.WebUtility.HtmlEncode(description)}}</p>
|
|
</div>
|
|
<strong class="{{statusClass}}">{{System.Net.WebUtility.HtmlEncode(status)}}</strong>
|
|
{{actionHtml}}
|
|
</article>
|
|
""");
|
|
}
|
|
}
|