336 lines
18 KiB
Plaintext
336 lines
18 KiB
Plaintext
@model OnboardingWizardViewModel
|
|
@using PlotLine.Models
|
|
@{
|
|
ViewData["Title"] = "Set up PlotDirector";
|
|
}
|
|
|
|
<section class="onboarding-shell" aria-labelledby="onboarding-title">
|
|
<div class="onboarding-panel">
|
|
<div class="onboarding-progress" aria-label="Setup progress">
|
|
<span>Step @Model.StepNumber of @Model.TotalSteps</span>
|
|
<div class="onboarding-progress-track">
|
|
<span style="width:@((Model.StepNumber * 100) / Model.TotalSteps)%"></span>
|
|
</div>
|
|
</div>
|
|
|
|
@if (Model.CurrentStep == OnboardingSteps.Welcome)
|
|
{
|
|
<div class="onboarding-copy">
|
|
<p class="eyebrow">Story intelligence setup</p>
|
|
<h1 id="onboarding-title">Welcome to PlotDirector</h1>
|
|
<p>Answer a few quick questions so PlotDirector can shape the first setup around the way you write.</p>
|
|
</div>
|
|
<form asp-controller="Onboarding" asp-action="Welcome" method="post" class="onboarding-actions">
|
|
<button class="btn btn-primary btn-lg" type="submit">Continue</button>
|
|
</form>
|
|
}
|
|
else if (Model.CurrentStep == OnboardingSteps.WritingJourney)
|
|
{
|
|
<div class="onboarding-copy">
|
|
<p class="eyebrow">Your starting point</p>
|
|
<h1 id="onboarding-title">Where are you in your writing journey?</h1>
|
|
</div>
|
|
<form asp-controller="Onboarding" asp-action="WritingJourney" method="post">
|
|
<div class="text-danger mb-3" asp-validation-summary="ModelOnly"></div>
|
|
<div class="onboarding-option-grid">
|
|
@foreach (var option in Model.Options)
|
|
{
|
|
<label class="onboarding-option-card">
|
|
<input type="radio" name="WritingJourney" value="@option.Value" checked="@(option.Value == Model.WritingJourney)" required />
|
|
<span>
|
|
<strong>@option.Title</strong>
|
|
<small>@option.Description</small>
|
|
</span>
|
|
</label>
|
|
}
|
|
</div>
|
|
<span class="text-danger field-validation-valid" data-valmsg-for="WritingJourney" data-valmsg-replace="true"></span>
|
|
<div class="onboarding-actions">
|
|
<button class="btn btn-outline-secondary" type="submit" formaction="/onboarding/back" formnovalidate name="currentStep" value="@OnboardingSteps.WritingJourney">Back</button>
|
|
<button class="btn btn-primary" type="submit">Continue</button>
|
|
</div>
|
|
</form>
|
|
}
|
|
else if (Model.CurrentStep == OnboardingSteps.WritingSoftware)
|
|
{
|
|
<div class="onboarding-copy">
|
|
<p class="eyebrow">Writing workflow</p>
|
|
<h1 id="onboarding-title">What software do you write in?</h1>
|
|
</div>
|
|
<form asp-controller="Onboarding" asp-action="WritingSoftware" method="post">
|
|
<div class="text-danger mb-3" asp-validation-summary="ModelOnly"></div>
|
|
<div class="onboarding-option-grid onboarding-option-grid--software">
|
|
@foreach (var option in Model.Options)
|
|
{
|
|
<label class="onboarding-option-card">
|
|
<input type="radio" name="WritingSoftware" value="@option.Value" checked="@(option.Value == Model.WritingSoftware)" required />
|
|
<span>
|
|
<strong>
|
|
@option.Title
|
|
@if (!string.IsNullOrWhiteSpace(option.Badge))
|
|
{
|
|
<em>@option.Badge</em>
|
|
}
|
|
</strong>
|
|
<small>@option.Description</small>
|
|
</span>
|
|
</label>
|
|
}
|
|
</div>
|
|
<span class="text-danger field-validation-valid" data-valmsg-for="WritingSoftware" data-valmsg-replace="true"></span>
|
|
<div class="onboarding-actions">
|
|
<button class="btn btn-outline-secondary" type="submit" formaction="/onboarding/back" formnovalidate name="currentStep" value="@OnboardingSteps.WritingSoftware">Back</button>
|
|
<button class="btn btn-primary" type="submit">Continue</button>
|
|
</div>
|
|
</form>
|
|
}
|
|
else if (Model.CurrentStep == OnboardingSteps.Project)
|
|
{
|
|
<div class="onboarding-copy">
|
|
<p class="eyebrow">Story home</p>
|
|
<h1 id="onboarding-title">Create your first project</h1>
|
|
<p>Choose the story space PlotDirector should use for this setup.</p>
|
|
</div>
|
|
<form asp-controller="Onboarding" asp-action="Project" method="post">
|
|
<div class="text-danger mb-3" asp-validation-summary="ModelOnly"></div>
|
|
<div class="onboarding-choice-grid">
|
|
<label class="onboarding-option-card">
|
|
<input type="radio" name="Mode" value="@OnboardingSelectionModes.Create" checked="@(Model.ProjectForm.Mode == OnboardingSelectionModes.Create)" />
|
|
<span>
|
|
<strong>Create a new project</strong>
|
|
<small>Start a fresh series or standalone story space.</small>
|
|
</span>
|
|
</label>
|
|
@if (Model.ProjectOptions.Any())
|
|
{
|
|
<label class="onboarding-option-card">
|
|
<input type="radio" name="Mode" value="@OnboardingSelectionModes.Select" checked="@(Model.ProjectForm.Mode == OnboardingSelectionModes.Select)" />
|
|
<span>
|
|
<strong>Use an existing project</strong>
|
|
<small>Continue setup inside one of your current projects.</small>
|
|
</span>
|
|
</label>
|
|
}
|
|
</div>
|
|
|
|
<section class="onboarding-form-section">
|
|
<h2>Create new project</h2>
|
|
<div class="row g-3">
|
|
<div class="col-md-7">
|
|
<label class="form-label" for="ProjectName">Project name</label>
|
|
<input class="form-control" id="ProjectName" name="ProjectName" maxlength="200" value="@Model.ProjectForm.ProjectName" />
|
|
@Html.ValidationMessage("ProjectName", null, new { @class = "text-danger" })
|
|
</div>
|
|
<div class="col-12">
|
|
<label class="form-label" for="Description">Description</label>
|
|
<textarea class="form-control" id="Description" name="Description" rows="3">@Model.ProjectForm.Description</textarea>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
@if (Model.ProjectOptions.Any())
|
|
{
|
|
<section class="onboarding-form-section">
|
|
<h2>Use existing project</h2>
|
|
<div class="onboarding-option-grid">
|
|
@foreach (var project in Model.ProjectOptions)
|
|
{
|
|
<label class="onboarding-option-card">
|
|
<input type="radio" name="SelectedProjectID" value="@project.ProjectID" checked="@(project.ProjectID == Model.ProjectForm.SelectedProjectID)" />
|
|
<span>
|
|
<strong>@project.ProjectName</strong>
|
|
<small>@project.Description</small>
|
|
</span>
|
|
</label>
|
|
}
|
|
</div>
|
|
@Html.ValidationMessage("SelectedProjectID", null, new { @class = "text-danger" })
|
|
</section>
|
|
}
|
|
|
|
<div class="onboarding-actions">
|
|
<button class="btn btn-outline-secondary" type="submit" formaction="/onboarding/back" formnovalidate name="currentStep" value="@OnboardingSteps.Project">Back</button>
|
|
<button class="btn btn-primary" type="submit">Continue</button>
|
|
</div>
|
|
</form>
|
|
}
|
|
else if (Model.CurrentStep == OnboardingSteps.Book)
|
|
{
|
|
<div class="onboarding-copy">
|
|
<p class="eyebrow">@Model.SelectedProjectName</p>
|
|
<h1 id="onboarding-title">Create your first book</h1>
|
|
<p>Choose the book this onboarding setup should prepare for later manuscript guidance.</p>
|
|
</div>
|
|
<form asp-controller="Onboarding" asp-action="Book" method="post">
|
|
<div class="text-danger mb-3" asp-validation-summary="ModelOnly"></div>
|
|
<div class="onboarding-choice-grid">
|
|
<label class="onboarding-option-card">
|
|
<input type="radio" name="Mode" value="@OnboardingSelectionModes.Create" checked="@(Model.BookForm.Mode == OnboardingSelectionModes.Create)" />
|
|
<span>
|
|
<strong>Create a new book</strong>
|
|
<small>Add a book shell to @Model.SelectedProjectName.</small>
|
|
</span>
|
|
</label>
|
|
@if (Model.BookOptions.Any())
|
|
{
|
|
<label class="onboarding-option-card">
|
|
<input type="radio" name="Mode" value="@OnboardingSelectionModes.Select" checked="@(Model.BookForm.Mode == OnboardingSelectionModes.Select)" />
|
|
<span>
|
|
<strong>Use an existing book</strong>
|
|
<small>Continue with a book already in this project.</small>
|
|
</span>
|
|
</label>
|
|
}
|
|
</div>
|
|
|
|
<section class="onboarding-form-section">
|
|
<h2>Create new book</h2>
|
|
<div class="row g-3">
|
|
<div class="col-md-7">
|
|
<label class="form-label" for="BookTitle">Book title</label>
|
|
<input class="form-control" id="BookTitle" name="BookTitle" maxlength="200" value="@Model.BookForm.BookTitle" />
|
|
@Html.ValidationMessage("BookTitle", null, new { @class = "text-danger" })
|
|
</div>
|
|
<div class="col-md-5">
|
|
<label class="form-label" for="Subtitle">Subtitle</label>
|
|
<input class="form-control" id="Subtitle" name="Subtitle" maxlength="200" value="@Model.BookForm.Subtitle" />
|
|
@Html.ValidationMessage("Subtitle", null, new { @class = "text-danger" })
|
|
</div>
|
|
<div class="col-md-5">
|
|
<label class="form-label" for="TargetWordCount">Target word count</label>
|
|
<input class="form-control" id="TargetWordCount" name="TargetWordCount" type="number" min="1" value="@Model.BookForm.TargetWordCount" />
|
|
@Html.ValidationMessage("TargetWordCount", null, new { @class = "text-danger" })
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
@if (Model.BookOptions.Any())
|
|
{
|
|
<section class="onboarding-form-section">
|
|
<h2>Use existing book</h2>
|
|
<div class="onboarding-option-grid">
|
|
@foreach (var book in Model.BookOptions)
|
|
{
|
|
<label class="onboarding-option-card">
|
|
<input type="radio" name="SelectedBookID" value="@book.BookID" checked="@(book.BookID == Model.BookForm.SelectedBookID)" />
|
|
<span>
|
|
<strong>@book.DisplayTitle</strong>
|
|
<small>@book.Detail</small>
|
|
</span>
|
|
</label>
|
|
}
|
|
</div>
|
|
@Html.ValidationMessage("SelectedBookID", null, new { @class = "text-danger" })
|
|
</section>
|
|
}
|
|
|
|
<div class="onboarding-actions">
|
|
<button class="btn btn-outline-secondary" type="submit" formaction="/onboarding/back" formnovalidate name="currentStep" value="@OnboardingSteps.Book">Back</button>
|
|
<button class="btn btn-primary" type="submit">Continue</button>
|
|
</div>
|
|
</form>
|
|
}
|
|
else
|
|
{
|
|
<div class="onboarding-copy">
|
|
<p class="eyebrow">Ready for the next phase</p>
|
|
@if (Model.IsMicrosoftWordPath)
|
|
{
|
|
<h1 id="onboarding-title">Connect your Word Companion</h1>
|
|
<p>Open Microsoft Word, open your manuscript, start the PlotDirector Word Companion, and sign in using your PlotDirector account.</p>
|
|
}
|
|
else
|
|
{
|
|
<h1 id="onboarding-title">Next: upload a Word export</h1>
|
|
<p>In a later phase, PlotDirector will let you upload a .docx export from your writing tool and connect it to @Model.SelectedBookTitle.</p>
|
|
}
|
|
</div>
|
|
@if (Model.IsMicrosoftWordPath)
|
|
{
|
|
<section class="onboarding-companion-card @(Model.CompanionPresence.IsConnected ? "is-connected" : "is-offline")"
|
|
data-word-companion-presence
|
|
data-word-companion-status="@Model.CompanionPresence.Status"
|
|
aria-label="Word Companion connection">
|
|
<div class="onboarding-companion-mark" aria-hidden="true">
|
|
<span></span>
|
|
</div>
|
|
<div class="onboarding-companion-body">
|
|
<p class="eyebrow">Word Companion</p>
|
|
<h2 data-word-companion-waiting-status>@(Model.CompanionPresence.IsConnected ? "Word Companion Connected" : "Waiting for Word Companion...")</h2>
|
|
<p data-word-companion-connected-copy>
|
|
@(Model.CompanionPresence.IsConnected
|
|
? "Your Companion is connected. Continue when you are ready."
|
|
: "Once connected this page will update automatically. You stay in control before continuing.")
|
|
</p>
|
|
<dl class="onboarding-companion-details">
|
|
<div>
|
|
<dt>Version</dt>
|
|
<dd data-word-companion-version>@(Model.CompanionPresence.CompanionVersion ?? "Waiting")</dd>
|
|
</div>
|
|
<div>
|
|
<dt>Document</dt>
|
|
<dd data-word-companion-document>@(Model.CompanionPresence.CurrentDocumentName ?? "No document reported yet")</dd>
|
|
</div>
|
|
</dl>
|
|
</div>
|
|
</section>
|
|
}
|
|
<dl class="onboarding-summary">
|
|
<div>
|
|
<dt>Writing journey</dt>
|
|
<dd>@DisplayJourney(Model.WritingJourney)</dd>
|
|
</div>
|
|
<div>
|
|
<dt>Writing software</dt>
|
|
<dd>@DisplaySoftware(Model.WritingSoftware)</dd>
|
|
</div>
|
|
<div>
|
|
<dt>Project</dt>
|
|
<dd>@(Model.SelectedProjectName ?? "Not set")</dd>
|
|
</div>
|
|
<div>
|
|
<dt>Book</dt>
|
|
<dd>@(Model.SelectedBookTitle ?? "Not set")</dd>
|
|
</div>
|
|
</dl>
|
|
<div class="onboarding-actions">
|
|
<form asp-controller="Onboarding" asp-action="Back" method="post">
|
|
<button class="btn btn-outline-secondary" type="submit" name="currentStep" value="@OnboardingSteps.NextPathPreview">Back</button>
|
|
</form>
|
|
@if (Model.ProjectID.HasValue)
|
|
{
|
|
<a class="btn btn-outline-primary" asp-controller="Projects" asp-action="Details" asp-route-id="@Model.ProjectID">Go to Project Overview</a>
|
|
}
|
|
<form asp-controller="Onboarding" asp-action="Finish" method="post">
|
|
<button class="btn btn-primary" type="submit">@(Model.IsMicrosoftWordPath ? "Continue" : "Finish setup for now")</button>
|
|
</form>
|
|
</div>
|
|
}
|
|
</div>
|
|
</section>
|
|
|
|
@section Scripts {
|
|
<partial name="_ValidationScriptsPartial" />
|
|
}
|
|
|
|
@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"
|
|
};
|
|
}
|