From 1388182ebecd07b9703795c905af9da16e36386c Mon Sep 17 00:00:00 2001 From: 6d486f49 Date: Thu, 11 Jun 2026 09:04:54 -0400 Subject: [PATCH] Day 2 vibes --- ET/Console/Program.cs | 132 +- ET/Web/App.razor | 3 +- ET/Web/Layout/MainLayout.razor | 4 +- ET/Web/Layout/MainLayout.razor.css | 27 +- ET/Web/Layout/NavMenu.razor | 23 +- ET/Web/Layout/NavMenu.razor.css | 66 +- ET/Web/Models/NoteInfo.cs | 6 +- ET/Web/Pages/DocViewer.razor | 5 +- ET/Web/Pages/Docs.razor | 41 +- ET/Web/Pages/Gear.razor | 51 + ET/Web/Pages/Home.razor | 22 +- ET/Web/Pages/NotFound.razor | 19 +- ET/Web/Program.cs | 2 + ET/Web/Services/DocsService.cs | 97 +- ET/Web/Web.csproj | 4 + ET/Web/_Imports.razor | 2 + ET/Web/wwwroot/css/app.css | 592 +- ET/Web/wwwroot/docs/images/Contents.png | Bin 0 -> 1601364 bytes .../docs/images/Event Card Example 2.png | Bin 0 -> 925134 bytes .../docs/images/Event Card Example.png | Bin 0 -> 300606 bytes ET/Web/wwwroot/docs/images/Map 1.png | Bin 0 -> 604466 bytes ET/Web/wwwroot/docs/images/Map.png | Bin 0 -> 603311 bytes ET/Web/wwwroot/docs/images/Market Deck.png | Bin 0 -> 24182 bytes ET/Web/wwwroot/docs/images/Market Example.png | Bin 0 -> 77745 bytes .../images/Pasted image 20260609163414.png | Bin 0 -> 2595748 bytes .../images/Pasted image 20260609163625.png | Bin 0 -> 2185489 bytes .../images/Pasted image 20260609163839.png | Bin 0 -> 388663 bytes .../images/Pasted image 20260609170252.png | Bin 0 -> 413947 bytes .../images/Pasted image 20260609170321.png | Bin 0 -> 413947 bytes .../images/Pasted image 20260609170335.png | Bin 0 -> 413947 bytes .../images/Pasted image 20260609211711.png | Bin 0 -> 341498 bytes ET/Web/wwwroot/docs/images/Role Example 2.png | Bin 0 -> 454196 bytes ET/Web/wwwroot/docs/images/Role Example.png | Bin 0 -> 413947 bytes .../wwwroot/docs/images/Table MVP Example.png | Bin 0 -> 2317926 bytes ET/Web/wwwroot/docs/notes-index.json | 62 +- ET/Web/wwwroot/docs/notes/dolewood-canoe.md | 2 +- .../Web/wwwroot/docs/notes/overview.md | 0 ET/Web/wwwroot/index.html | 47 +- .../lib/bootstrap/dist/css/bootstrap-grid.css | 7866 ++++--- .../bootstrap/dist/css/bootstrap-grid.rtl.css | 7867 ++++--- .../bootstrap/dist/css/bootstrap-reboot.css | 666 +- .../dist/css/bootstrap-reboot.rtl.css | 670 +- .../dist/css/bootstrap-utilities.css | 8572 ++++---- .../dist/css/bootstrap-utilities.rtl.css | 8570 ++++---- .../lib/bootstrap/dist/css/bootstrap.css | 18340 ++++++++------- .../lib/bootstrap/dist/css/bootstrap.rtl.css | 18349 +++++++++------- .../lib/bootstrap/dist/js/bootstrap.bundle.js | 12484 +++++------ .../lib/bootstrap/dist/js/bootstrap.esm.js | 6657 +++--- .../lib/bootstrap/dist/js/bootstrap.js | 9022 ++++---- docs/.obsidian/workspace.json | 22 +- docs/Notes/Dolewood Canoe.md | 2 +- docs/Overview.md | 26 + docs/{_Tasks.base => Tasks.base} | 0 53 files changed, 54413 insertions(+), 45907 deletions(-) create mode 100644 ET/Web/Pages/Gear.razor create mode 100644 ET/Web/wwwroot/docs/images/Contents.png create mode 100644 ET/Web/wwwroot/docs/images/Event Card Example 2.png create mode 100644 ET/Web/wwwroot/docs/images/Event Card Example.png create mode 100644 ET/Web/wwwroot/docs/images/Map 1.png create mode 100644 ET/Web/wwwroot/docs/images/Map.png create mode 100644 ET/Web/wwwroot/docs/images/Market Deck.png create mode 100644 ET/Web/wwwroot/docs/images/Market Example.png create mode 100644 ET/Web/wwwroot/docs/images/Pasted image 20260609163414.png create mode 100644 ET/Web/wwwroot/docs/images/Pasted image 20260609163625.png create mode 100644 ET/Web/wwwroot/docs/images/Pasted image 20260609163839.png create mode 100644 ET/Web/wwwroot/docs/images/Pasted image 20260609170252.png create mode 100644 ET/Web/wwwroot/docs/images/Pasted image 20260609170321.png create mode 100644 ET/Web/wwwroot/docs/images/Pasted image 20260609170335.png create mode 100644 ET/Web/wwwroot/docs/images/Pasted image 20260609211711.png create mode 100644 ET/Web/wwwroot/docs/images/Role Example 2.png create mode 100644 ET/Web/wwwroot/docs/images/Role Example.png create mode 100644 ET/Web/wwwroot/docs/images/Table MVP Example.png rename docs/_Overview.md => ET/Web/wwwroot/docs/notes/overview.md (100%) create mode 100644 docs/Overview.md rename docs/{_Tasks.base => Tasks.base} (100%) diff --git a/ET/Console/Program.cs b/ET/Console/Program.cs index 48cc2d0..fa4a099 100644 --- a/ET/Console/Program.cs +++ b/ET/Console/Program.cs @@ -1,10 +1,12 @@ -using System.Text.RegularExpressions; +using System.Text; +using System.Text.Encodings.Web; using System.Text.Json; +using System.Text.RegularExpressions; var exeDir = AppContext.BaseDirectory; var solutionDir = FindContainingDir(exeDir, "ET.sln") - ?? throw new InvalidOperationException("Cannot find ET.sln"); + ?? throw new InvalidOperationException("Cannot find ET.sln"); var srcDir = Path.GetFullPath(Path.Combine(solutionDir, "..", "docs", "Notes")); var dstDir = Path.GetFullPath(Path.Combine(solutionDir, "Web", "wwwroot", "docs", "notes")); @@ -18,13 +20,17 @@ if (!Directory.Exists(srcDir)) return 1; } -SyncNotes(srcDir, dstDir); +var entries = SyncNotes(srcDir, dstDir); +CopyOverview(solutionDir, dstDir, entries); +CopyImages(solutionDir, Path.GetFullPath(Path.Combine(solutionDir, "Web", "wwwroot", "docs"))); +var indexJson = BuildIndex(entries); +File.WriteAllText(Path.Combine(Path.GetDirectoryName(dstDir)!, "notes-index.json"), indexJson); GenerateMap(srcDir, Path.GetFullPath(Path.Combine(solutionDir, "Web", "wwwroot", "docs"))); Console.WriteLine("Done."); return 0; -static void SyncNotes(string srcDir, string dstDir) +static List SyncNotes(string srcDir, string dstDir) { Directory.CreateDirectory(dstDir); @@ -38,16 +44,33 @@ static void SyncNotes(string srcDir, string dstDir) var name = Path.GetFileNameWithoutExtension(file); var slug = Slugify(name); - File.Copy(file, Path.Combine(dstDir, $"{slug}.md"), overwrite: true); + File.Copy(file, Path.Combine(dstDir, $"{slug}.md"), true); string? category = null; + string? cost = null; + string? gearCategory = null; + string? effect = null; + string? location = null; var content = File.ReadAllText(file); var fmMatch = Regex.Match(content, @"^---\s*\n(.*?)\n---", RegexOptions.Singleline); if (fmMatch.Success) { - var catMatch = Regex.Match(fmMatch.Groups[1].Value, @"(?m)^category:\s*(.+)$"); + var fm = fmMatch.Groups[1].Value; + var catMatch = Regex.Match(fm, @"(?m)^category:\s*(.+)$", RegexOptions.IgnoreCase); if (catMatch.Success) category = catMatch.Groups[1].Value.Trim().Trim('"'); + var costMatch = Regex.Match(fm, @"(?m)^cost:\s*(.+)$", RegexOptions.IgnoreCase); + if (costMatch.Success) + cost = costMatch.Groups[1].Value.Trim().Trim('"'); + var gcMatch = Regex.Match(fm, @"(?m)^gear category:\s*(.+)$", RegexOptions.IgnoreCase); + if (gcMatch.Success) + gearCategory = gcMatch.Groups[1].Value.Trim().Trim('"'); + var effMatch = Regex.Match(fm, @"(?m)^effect:\s*(.+)$", RegexOptions.IgnoreCase); + if (effMatch.Success) + effect = effMatch.Groups[1].Value.Trim().Trim('"'); + var locMatch = Regex.Match(fm, @"(?m)^location:\s*(.+)$", RegexOptions.IgnoreCase); + if (locMatch.Success) + location = locMatch.Groups[1].Value.Trim().Trim('"'); } var entry = new Dictionary @@ -57,18 +80,61 @@ static void SyncNotes(string srcDir, string dstDir) }; if (category != null) entry["category"] = category; + if (cost != null) + entry["cost"] = cost; + if (gearCategory != null) + entry["gearCategory"] = gearCategory; + if (effect != null) + entry["effect"] = effect; + if (location != null) + entry["location"] = location; entries.Add(entry); } - var index = new Dictionary { ["notes"] = entries }; - var json = JsonSerializer.Serialize(index, new JsonSerializerOptions { WriteIndented = true }); - - var indexPath = Path.Combine(Path.GetDirectoryName(dstDir)!, "notes-index.json"); - File.WriteAllText(indexPath, json); - Console.WriteLine($"Copied {entries.Count} notes."); - Console.WriteLine($"Index written to: {indexPath}"); + return entries; +} + +static void CopyOverview(string solutionDir, string dstDir, List entries) +{ + var srcOverview = Path.GetFullPath(Path.Combine(solutionDir, "..", "docs", "Overview.md")); + if (!File.Exists(srcOverview)) return; + + var slug = "overview"; + File.Copy(srcOverview, Path.Combine(dstDir, $"{slug}.md"), true); + + entries.Add(new Dictionary + { + ["slug"] = slug, + ["title"] = "Overview", + ["category"] = "Overview" + }); + + Console.WriteLine("Copied Overview.md."); +} + +static void CopyImages(string solutionDir, string dstDir) +{ + var srcImgs = Path.GetFullPath(Path.Combine(solutionDir, "..", "docs", "Images")); + if (!Directory.Exists(srcImgs)) return; + + var dstImgs = Path.Combine(dstDir, "images"); + Directory.CreateDirectory(dstImgs); + + foreach (var file in Directory.EnumerateFiles(srcImgs)) + { + var name = Path.GetFileName(file); + File.Copy(file, Path.Combine(dstImgs, name), true); + } + + Console.WriteLine($"Copied images from {srcImgs}."); +} + +static string BuildIndex(List entries) +{ + var index = new Dictionary { ["notes"] = entries }; + return JsonSerializer.Serialize(index, new JsonSerializerOptions { WriteIndented = true }); } static void GenerateMap(string srcDir, string dstDir) @@ -79,7 +145,7 @@ static void GenerateMap(string srcDir, string dstDir) ["Forest"] = "#2e7d32", ["Mountain"] = "#78909c", ["Water"] = "#42a5f5", - ["Wasteland"] = "#8d6e63", + ["Wasteland"] = "#8d6e63" }; var regionFiles = Directory.EnumerateFiles(srcDir, "*.md") @@ -130,19 +196,19 @@ static void GenerateMap(string srcDir, string dstDir) var srcMapImage = Path.GetFullPath(Path.Combine(srcDir, "..", "Images", "Map.png")); var dstMapImage = Path.Combine(dstDir, "Map.png"); if (File.Exists(srcMapImage)) - File.Copy(srcMapImage, dstMapImage, overwrite: true); + File.Copy(srcMapImage, dstMapImage, true); var nameLookup = regions.ToDictionary(r => r.Name); var pad = 60; var maxX = (regions.Count > 0 ? regions.Max(r => r.X) : 0) + pad * 2; var maxY = (regions.Count > 0 ? regions.Max(r => r.Y) : 0) + pad * 2; - var svg = new System.Text.StringBuilder(); + var svg = new StringBuilder(); svg.AppendLine(""); svg.AppendLine(""""""); - svg.AppendLine($""""""); + svg.AppendLine(""""""); foreach (var (terrain, color) in terrainColors) { svg.AppendLine($""""""); @@ -150,17 +216,18 @@ static void GenerateMap(string srcDir, string dstDir) svg.AppendLine($""""""); svg.AppendLine(""); } + svg.AppendLine(""); foreach (var region in regions) + foreach (var conn in region.Connections) { - foreach (var conn in region.Connections) - { - if (!nameLookup.TryGetValue(conn, out var target) || string.Compare(region.Name, conn, StringComparison.OrdinalIgnoreCase) >= 0) - continue; + if (!nameLookup.TryGetValue(conn, out var target) || + string.Compare(region.Name, conn, StringComparison.OrdinalIgnoreCase) >= 0) + continue; - svg.AppendLine($""""""); - } + svg.AppendLine( + $""""""); } foreach (var region in regions) @@ -171,17 +238,20 @@ static void GenerateMap(string srcDir, string dstDir) svg.AppendLine($""""""); svg.AppendLine($""""""); - svg.AppendLine($""""""); + svg.AppendLine( + $""""""); var labelX = cx + 24; - svg.AppendLine($""""""); - svg.Append(System.Text.Encodings.Web.HtmlEncoder.Default.Encode(region.Name)); + svg.AppendLine( + $""""""); + svg.Append(HtmlEncoder.Default.Encode(region.Name)); svg.AppendLine(""); foreach (var lm in region.Landmarks) { - svg.AppendLine($""""""); - svg.Append(System.Text.Encodings.Web.HtmlEncoder.Default.Encode($"\u2605 {lm}")); + svg.AppendLine( + $""""""); + svg.Append(HtmlEncoder.Default.Encode($"\u2605 {lm}")); svg.AppendLine(""); } @@ -231,10 +301,11 @@ static string? FindContainingDir(string startDir, string markerFile) return dir.FullName; dir = dir.Parent; } + return null; } -class RegionData +internal class RegionData { public string Name { get; set; } = ""; public string Slug { get; set; } = ""; @@ -243,5 +314,4 @@ class RegionData public int Y { get; set; } public List Connections { get; set; } = new(); public List Landmarks { get; set; } = new(); -} - +} \ No newline at end of file diff --git a/ET/Web/App.razor b/ET/Web/App.razor index 3e84bca..735b1ff 100644 --- a/ET/Web/App.razor +++ b/ET/Web/App.razor @@ -1,4 +1,5 @@ - +@using Web.Pages + diff --git a/ET/Web/Layout/MainLayout.razor b/ET/Web/Layout/MainLayout.razor index fdc3d5d..29a0f6f 100644 --- a/ET/Web/Layout/MainLayout.razor +++ b/ET/Web/Layout/MainLayout.razor @@ -5,7 +5,9 @@
- @Body + + @Body +
\ No newline at end of file diff --git a/ET/Web/Layout/MainLayout.razor.css b/ET/Web/Layout/MainLayout.razor.css index ecf25e5..96750bb 100644 --- a/ET/Web/Layout/MainLayout.razor.css +++ b/ET/Web/Layout/MainLayout.razor.css @@ -9,7 +9,8 @@ main { } .sidebar { - background-image: linear-gradient(180deg, rgb(5, 39, 103) 0%, #3a0647 70%); + background-color: var(--bg-sidebar); + border-right: 1px solid var(--border-color); } .top-row { @@ -21,20 +22,20 @@ main { align-items: center; } - .top-row ::deep a, .top-row ::deep .btn-link { - white-space: nowrap; - margin-left: 1.5rem; - text-decoration: none; - } +.top-row ::deep a, .top-row ::deep .btn-link { + white-space: nowrap; + margin-left: 1.5rem; + text-decoration: none; +} - .top-row ::deep a:hover, .top-row ::deep .btn-link:hover { - text-decoration: underline; - } +.top-row ::deep a:hover, .top-row ::deep .btn-link:hover { + text-decoration: underline; +} - .top-row ::deep a:first-child { - overflow: hidden; - text-overflow: ellipsis; - } +.top-row ::deep a:first-child { + overflow: hidden; + text-overflow: ellipsis; +} @media (max-width: 640.98px) { .top-row { diff --git a/ET/Web/Layout/NavMenu.razor b/ET/Web/Layout/NavMenu.razor index 6525fc7..c8fbce2 100644 --- a/ET/Web/Layout/NavMenu.razor +++ b/ET/Web/Layout/NavMenu.razor @@ -1,8 +1,10 @@ -@inject Web.Services.DocsService DocsService +@inject DocsService DocsService