@model OnboardingWizardViewModel @using PlotLine.Models @{ ViewData["Title"] = "Set up PlotDirector"; var currentJourneyOrder = CurrentJourneyOrder(Model); var journeySteps = new[] { new { Label = "Welcome", Order = 1 }, new { Label = "Writing Preferences", Order = 2 }, new { Label = "Project", Order = 3 }, new { Label = "Book", Order = 4 }, new { Label = "Connect Word", Order = 5 }, new { Label = "Scan", Order = 6 }, new { Label = "Review", Order = 7 }, new { Label = "Analyse", Order = 8 }, new { Label = "Complete", Order = 9 } }; }
Step @Model.StepNumber of @Model.TotalSteps
    @foreach (var step in journeySteps) {
  1. @step.Order @step.Label
  2. }
@if (Model.CurrentStep == OnboardingSteps.Welcome) {

Story intelligence setup

Welcome to PlotDirector

Answer a few quick questions so PlotDirector can shape the first setup around the way you write.

} else if (Model.CurrentStep == OnboardingSteps.WritingJourney) {

Your starting point

Where are you in your writing journey?

@foreach (var option in Model.Options) { }
} else if (Model.CurrentStep == OnboardingSteps.WritingSoftware) {

Writing workflow

What software do you write in?

@foreach (var option in Model.Options) { }
} else if (Model.CurrentStep == OnboardingSteps.Project) {

Story home

Create your first project

Choose the story space PlotDirector should use for this setup.

@if (Model.ProjectOptions.Any()) { }

Create new project

@Html.ValidationMessage("ProjectName", null, new { @class = "text-danger" })
@if (Model.ProjectOptions.Any()) {

Use existing project

@foreach (var project in Model.ProjectOptions) { }
@Html.ValidationMessage("SelectedProjectID", null, new { @class = "text-danger" })
}
} else if (Model.CurrentStep == OnboardingSteps.Book) {

@Model.SelectedProjectName

Create your first book

Choose the book this onboarding setup should prepare for later manuscript guidance.

@if (Model.BookOptions.Any()) { }

Create new book

@Html.ValidationMessage("BookTitle", null, new { @class = "text-danger" })
@Html.ValidationMessage("Subtitle", null, new { @class = "text-danger" })
@Html.ValidationMessage("TargetWordCount", null, new { @class = "text-danger" })
@if (Model.BookOptions.Any()) {

Use existing book

@foreach (var book in Model.BookOptions) { }
@Html.ValidationMessage("SelectedBookID", null, new { @class = "text-danger" })
}
} else {

Ready for the next phase

@if (Model.IsMicrosoftWordPath) {

Connect your Word Companion

Open Microsoft Word, open your manuscript, start the PlotDirector Word Companion, and sign in using your PlotDirector account. PlotDirector will stay on this page with you while the scan and build run.

} else {

Next: upload a Word export

In a later phase, PlotDirector will let you upload a .docx export from your writing tool and connect it to @Model.SelectedBookTitle.

}
@if (Model.IsMicrosoftWordPath) {

Word Companion

@(Model.CompanionPresence.IsConnected ? "Word Companion Connected" : "Waiting for Word Companion...")

@CompanionScanMessage(Model.CompanionPresence, Model.ScanState)

Version
@(Model.CompanionPresence.CompanionVersion ?? "Waiting")
Document
@(Model.CompanionPresence.CurrentDocumentName ?? "No document reported yet")
@ScanMessage(Model.ScanState) @ScanPercent(Model.ScanState)
Chapters @Model.ScanState.ChapterCount
Scenes @Model.ScanState.SceneCount
Characters @Model.ScanState.CharacterCandidateCount
Words @Model.ScanState.TotalWordCount.ToString("N0")
@if (string.Equals(Model.ScanState.ReviewStatus, ManuscriptScanReviewStatuses.ReadyToImport, StringComparison.Ordinal)) {

Review saved. PlotDirector can now analyse the approved chapters.

Next: analyse the manuscript and review suggested scenes.

Analyse manuscript }
}
Writing journey
@DisplayJourney(Model.WritingJourney)
Writing software
@DisplaySoftware(Model.WritingSoftware)
Project
@(Model.SelectedProjectName ?? "Not set")
Book
@(Model.SelectedBookTitle ?? "Not set")
@if (Model.ProjectID.HasValue) { Go to Project Overview } @if (Model.IsMicrosoftWordPath && string.Equals(Model.ScanState.ReviewStatus, ManuscriptScanReviewStatuses.ReadyToImport, StringComparison.Ordinal)) { Analyse manuscript } else if (Model.IsMicrosoftWordPath && Model.ScanState.IsComplete) { Review the scan above to continue. } else if (Model.IsMicrosoftWordPath) { Scan your manuscript to continue. } else {
}
}
@section Scripts { } @functions { private static string DisplayJourney(string? value) => value switch { WritingJourneyValues.PlanningNewStory => "Planning a brand new story", WritingJourneyValues.AlreadyStarted => "Already started writing", WritingJourneyValues.ManuscriptMostlyComplete => "Manuscript largely complete", _ => "Not set" }; private static string DisplaySoftware(string? value) => value switch { WritingSoftwareValues.MicrosoftWord => "Microsoft Word", WritingSoftwareValues.GoogleDocs => "Google Docs", WritingSoftwareValues.Scrivener => "Scrivener", WritingSoftwareValues.LibreOfficeOpenOffice => "LibreOffice / OpenOffice", WritingSoftwareValues.MarkdownObsidian => "Markdown / Obsidian", WritingSoftwareValues.Other => "Other", _ => "Not set" }; private static bool CanStartScan(CompanionPresenceViewModel presence, ManuscriptScanStateViewModel scan) => presence.IsConnected && presence.DocumentOpen && !scan.IsRunning; private static string CompanionScanMessage(CompanionPresenceViewModel presence, ManuscriptScanStateViewModel scan) { if (!presence.IsConnected) { return "Open Word and start the Companion. This page will update automatically."; } if (!presence.DocumentOpen) { return "Open your manuscript in Word, then the scan button will appear."; } if (scan.IsComplete) { return "Scan complete. Review the structure before anything is imported."; } if (scan.IsRunning) { return "The Companion is scanning your manuscript now."; } if (scan.IsFailed) { return "The scan needs another try. Your story data has not been changed."; } return "Your Companion is connected. Scan your manuscript when you are ready."; } private static string ScanMessage(ManuscriptScanStateViewModel scan) { if (!string.IsNullOrWhiteSpace(scan.Message)) { return scan.Message; } return scan.Status switch { ManuscriptScanStatuses.Complete => "We found:", ManuscriptScanStatuses.Running => "Preparing document scan", ManuscriptScanStatuses.Failed => "The scan could not finish.", _ => "Ready to scan" }; } private static string ScanPercent(ManuscriptScanStateViewModel scan) => scan.PercentComplete.HasValue ? $"{scan.PercentComplete.Value}%" : string.Empty; private static int CurrentJourneyOrder(OnboardingWizardViewModel model) { return model.CurrentStep switch { OnboardingSteps.Welcome => 1, OnboardingSteps.WritingJourney or OnboardingSteps.WritingSoftware => 2, OnboardingSteps.Project => 3, OnboardingSteps.Book => 4, OnboardingSteps.NextPathPreview when !model.IsMicrosoftWordPath => 9, OnboardingSteps.NextPathPreview when string.Equals(model.ScanState.ReviewStatus, ManuscriptScanReviewStatuses.ReadyToImport, StringComparison.Ordinal) => 8, OnboardingSteps.NextPathPreview when model.ScanState.IsComplete => 7, OnboardingSteps.NextPathPreview when model.ScanState.IsRunning || model.ScanState.IsFailed || model.ScanState.PercentComplete.HasValue => 6, OnboardingSteps.NextPathPreview when model.CompanionPresence.IsConnected => 6, OnboardingSteps.NextPathPreview => 5, OnboardingSteps.Complete => 9, _ => 1 }; } private static string JourneyStepClass(int order, int currentOrder) { if (order < currentOrder) { return "is-complete"; } return order == currentOrder ? "is-current" : "is-upcoming"; } }