PlotDirector/PlotLine/Views/Writing/_WritingContextPlace.cshtml

96 lines
4.4 KiB
Plaintext

@model WritingContextDisplayViewModel
@{
var scene = Model.Context!.Scene!;
var floorPlan = Model.FloorPlan;
var floorId = scene.InitialFloorPlanFloorID
?? floorPlan?.OccupancyScenes.FirstOrDefault(x => x.SceneID == scene.SceneID)?.InitialFloorPlanFloorID
?? floorPlan?.Floors.OrderBy(x => x.SortOrder).FirstOrDefault()?.FloorPlanFloorID;
var floor = floorPlan?.Floors.FirstOrDefault(x => x.FloorPlanFloorID == floorId);
var blocks = floor is null ? [] : floorPlan!.Blocks.Where(x => x.FloorPlanFloorID == floor.FloorPlanFloorID).ToList();
var tokens = floor is null ? [] : floorPlan!.OccupancyTokens.Where(x => x.SceneID == scene.SceneID && x.FloorPlanFloorID == floor.FloorPlanFloorID).ToList();
var tokensByLocation = tokens.GroupBy(x => x.LocationID).ToDictionary(x => x.Key, x => x.ToList());
static string TextOr(string? value, string fallback) => string.IsNullOrWhiteSpace(value) ? fallback : value.Trim();
}
<div class="writing-context-grid writing-context-grid--place">
<article class="writing-context-card">
<p class="eyebrow">Location</p>
<h3>@TextOr(scene.LocationOptions.FirstOrDefault(x => x.Value == scene.PrimaryLocationID?.ToString())?.Text, "No primary location")</h3>
<dl class="writing-context-facts">
<dt>Floor plan</dt><dd>@(floorPlan?.FloorPlan.Name ?? "No floor plan linked to this scene")</dd>
<dt>Floor</dt><dd>@(floor?.Name ?? "No floor selected")</dd>
</dl>
</article>
<article class="writing-context-card writing-context-card--wide">
<p class="eyebrow">Occupancy</p>
@if (floorPlan is null)
{
<p>No floor plan linked to this scene.</p>
}
else if (floor is null || !blocks.Any())
{
<p>No placed rooms are available for this floor.</p>
}
else
{
<div class="writing-context-floor"
style="--floor-cols:@floor.GridWidth;--floor-rows:@floor.GridHeight;"
aria-label="@floor.Name floor plan">
@foreach (var block in blocks)
{
var locationTokens = block.LocationID.HasValue && tokensByLocation.TryGetValue(block.LocationID.Value, out var blockTokens)
? blockTokens
: [];
<div class="writing-context-floor-block"
style="grid-column:@(block.X + 1) / span @block.WidthCells;grid-row:@(block.Y + 1) / span @block.HeightCells;">
<strong>@block.DisplayLabel</strong>
@if (locationTokens.Any())
{
<span>@string.Join(", ", locationTokens.Select(x => x.DisplayName).Take(3))@(locationTokens.Count > 3 ? $" +{locationTokens.Count - 3}" : string.Empty)</span>
}
</div>
}
</div>
}
</article>
<article class="writing-context-card">
<p class="eyebrow">Characters</p>
@if (!scene.SceneCharacters.Any(x => !string.IsNullOrWhiteSpace(x.LocationName) || !string.IsNullOrWhiteSpace(x.LocationPath)))
{
<p>No character locations recorded.</p>
}
else
{
<ul class="writing-context-list">
@foreach (var character in scene.SceneCharacters.Where(x => !string.IsNullOrWhiteSpace(x.LocationName) || !string.IsNullOrWhiteSpace(x.LocationPath)))
{
<li><strong>@character.CharacterName</strong> @TextOr(character.LocationPath ?? character.LocationName, "Unknown")</li>
}
</ul>
}
</article>
<article class="writing-context-card">
<p class="eyebrow">Assets</p>
@if (!scene.SceneAssetLocations.Any() && !scene.AssetCustodyEvents.Any())
{
<p>No asset locations or custody changes recorded.</p>
}
else
{
<ul class="writing-context-list">
@foreach (var asset in scene.SceneAssetLocations.Take(6))
{
<li><strong>@asset.AssetName</strong> @asset.LocationPath</li>
}
@foreach (var custody in scene.AssetCustodyEvents.Take(6))
{
<li><strong>@custody.AssetName</strong> @TextOr(custody.CustodianSummary, custody.CustodyEventTypeName)</li>
}
</ul>
}
</article>
</div>