@model StoryIntelligencePipelineHeaderViewModel @{ var phases = new[] { new { Name = "Phase 1", Label = "Prepare manuscript", Stages = new[] { "Connect Word Companion", "Scan Manuscript", "Review Chapters" } }, new { Name = "Phase 2", Label = "Analyse manuscript", Stages = new[] { "Analyse Manuscript" } }, new { Name = "Phase 3", Label = "Review Story Intelligence", Stages = new[] { "Review Scenes", "Review Characters", "Review Locations", "Review Assets", "Review Relationships", "Review Knowledge" } }, new { Name = "Phase 4", Label = "Build Story Database", Stages = new[] { "Create Scenes", "Create Characters", "Complete" } } }; var flatStages = phases.SelectMany(phase => phase.Stages).ToList(); var currentIndex = Math.Max(0, flatStages.FindIndex(stage => string.Equals(stage, Model.CurrentStage, StringComparison.OrdinalIgnoreCase))); var percent = flatStages.Count <= 1 ? 100 : Math.Clamp((currentIndex * 100) / (flatStages.Count - 1), 0, 100); }
@Model.CurrentStage
    @foreach (var phase in phases) { var firstStageIndex = flatStages.FindIndex(stage => phase.Stages.Contains(stage)); var lastStageIndex = firstStageIndex + phase.Stages.Length - 1; var phaseClass = currentIndex > lastStageIndex ? "is-complete" : currentIndex >= firstStageIndex && currentIndex <= lastStageIndex ? "is-current" : "is-upcoming";
  1. @phase.Name.Replace("Phase ", string.Empty) @phase.Label @StageSummary(phase.Stages, currentIndex, firstStageIndex)
  2. }
@functions { private static string StageSummary(IReadOnlyList stages, int currentIndex, int firstStageIndex) { var localIndex = currentIndex - firstStageIndex; if (localIndex >= 0 && localIndex < stages.Count) { return stages[localIndex]; } return stages.Count == 1 ? stages[0] : $"{stages.Count} stages"; } }