@model OnboardingWizardViewModel @using PlotLine.Models @{ ViewData["Title"] = "Set up PlotDirector"; var currentJourneyOrder = CurrentJourneyOrder(Model); }
@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 {

Step @currentJourneyOrder of 10

@if (Model.IsMicrosoftWordPath) {

@(currentJourneyOrder >= 6 ? "Scan Manuscript" : "Connect your Word Companion")

Open your manuscript in Word and start the Companion. When it is connected, use the wizard button below to scan and continue.

} 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 import the approved manuscript structure.

Next: detect scene boundaries, create PlotDirector scenes, then update and save Word markers.

}
}
@if (Model.IsMicrosoftWordPath && string.Equals(Model.ScanState.ReviewStatus, ManuscriptScanReviewStatuses.ReadyToImport, StringComparison.Ordinal)) { } else if (Model.IsMicrosoftWordPath && Model.ScanState.IsComplete) { Review chapters } else if (Model.IsMicrosoftWordPath) { Review chapters } 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 => 2, OnboardingSteps.WritingSoftware => 3, OnboardingSteps.Project => 4, OnboardingSteps.Book => 5, OnboardingSteps.NextPathPreview when !model.IsMicrosoftWordPath => 10, OnboardingSteps.NextPathPreview when string.Equals(model.ScanState.ReviewStatus, ManuscriptScanReviewStatuses.ReadyToImport, StringComparison.Ordinal) => 9, 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 => 6, OnboardingSteps.Complete => 10, _ => 1 }; } private static string JourneyStepClass(int order, int currentOrder) { if (order < currentOrder) { return "is-complete"; } return order == currentOrder ? "is-current" : "is-upcoming"; } }