From 27dc995bb82b3f20e9cb7b0e43cff6347df2e07e Mon Sep 17 00:00:00 2001 From: James Kolpack Date: Thu, 11 Dec 2025 14:17:33 -0500 Subject: [PATCH] Improvements for home page and formatting --- .../Events/Components/EventAttributes.razor | 67 +++++++------------ WebApp/Components/Pages/Home.razor | 25 +++++-- WebApp/Models/AppIcons.cs | 19 +++++- WebApp/Program.cs | 29 ++++++-- 4 files changed, 83 insertions(+), 57 deletions(-) diff --git a/WebApp/Components/Features/Events/Components/EventAttributes.razor b/WebApp/Components/Features/Events/Components/EventAttributes.razor index ee579b1..d5e0212 100644 --- a/WebApp/Components/Features/Events/Components/EventAttributes.razor +++ b/WebApp/Components/Features/Events/Components/EventAttributes.razor @@ -1,49 +1,34 @@ @using WebApp.Models -@* -@AppIcons.LevelOfEffortIcon(EventDefinition.LevelOfEffort) -@if(EventDefinition.EventFormat == EventFormat.Individual) { - @AppIcons.IndividualEvent -} -@if (EventDefinition.OnSiteActivity) -{ - @AppIcons.OnSiteActivity -} - -@if (EventDefinition.RegionalEvent) -{ - @AppIcons.RegionalEvent -} - -@if (EventDefinition.Presubmission) -{ - @AppIcons.PresubmissionEvent -} *@ - - -@AppIcons.LevelOfEffortIcon(EventDefinition.LevelOfEffort) - -@if (EventDefinition.EventFormat == EventFormat.Individual) -{ - @AppIcons.IndividualEvent -} -@if (EventDefinition.OnSiteActivity) -{ - @AppIcons.OnSiteActivity -} - -@if (EventDefinition.RegionalEvent) -{ - @AppIcons.RegionalEvent -} - -@if (EventDefinition.Presubmission) -{ - @AppIcons.PresubmissionEvent -} + + @foreach (var charStr in _attributes.Select(c => c.ToString())) + { + if (AppIcons.IconTooltips.TryGetValue(charStr, out var tooltip)) + { + @charStr + } + else + { + @charStr + } + } + @code { [Parameter] public EventDefinition EventDefinition { get; set; } + + private string _attributes; + + protected override void OnParametersSet() + { + _attributes = AppIcons.LevelOfEffortIcon(EventDefinition.LevelOfEffort); + _attributes += " "; + _attributes += EventDefinition.EventFormat == EventFormat.Individual ? AppIcons.IndividualEvent : " "; + _attributes += EventDefinition.OnSiteActivity ? AppIcons.OnSiteActivity : " "; + _attributes += EventDefinition.RegionalEvent ? AppIcons.RegionalEvent : " "; + _attributes += EventDefinition.InterviewOrPresentation ? AppIcons.PresentationEvent : " "; + _attributes += EventDefinition.Presubmission ? AppIcons.PresubmissionEvent : " "; + } } diff --git a/WebApp/Components/Pages/Home.razor b/WebApp/Components/Pages/Home.razor index 2ad67bc..5798448 100644 --- a/WebApp/Components/Pages/Home.razor +++ b/WebApp/Components/Pages/Home.razor @@ -9,10 +9,17 @@
- - - @Configuration["ChapterSettings:Name"] - + + + + @Configuration["ChapterSettings:Name"] + + + + + @Configuration["ChapterSettings:Name"] + + @Configuration["ChapterSettings:CompetitionYear"] Competition Year @@ -25,7 +32,7 @@ Title="Events" Count="@_eventCount" Subtitle="Total Events" - Caption="@($"{_individualEventsCount} Individual | {_teamEventsCount} Team")" + Caption="@($"{_teamEventsCount} Team | {_individualEventsCount} Individual")" NavigateUrl="/events" /> @@ -51,6 +58,7 @@ Title="Teams" Count="@_teamCount" Subtitle="Total Teams" + Caption="@($"{_groupTeamsCount} Team | {_individualTeamsCount} Individual")" NavigateUrl="/teams" /> @@ -67,6 +75,8 @@ private int _studentCount; private string _gradeDistribution = ""; private int _teamCount; + private int _individualTeamsCount; + private int _groupTeamsCount; protected override async Task OnInitializedAsync() { @@ -102,6 +112,9 @@ } // Teams statistics - _teamCount = await Context.Teams.CountAsync(); + var contextTeams = await Context.Teams.ToListAsync(); + _teamCount = contextTeams.Count; + _individualTeamsCount = contextTeams.Count(e => e.Event.EventFormat == EventFormat.Individual); + _groupTeamsCount = contextTeams.Count(e => e.Event.EventFormat == EventFormat.Team); } } diff --git a/WebApp/Models/AppIcons.cs b/WebApp/Models/AppIcons.cs index a97f166..f0e8917 100644 --- a/WebApp/Models/AppIcons.cs +++ b/WebApp/Models/AppIcons.cs @@ -16,9 +16,9 @@ namespace WebApp.Models return loe switch { - 1 => "①", - 2 => "②", - 3 => "③", + 1 => "‧", + 2 => "⁚", + 3 => "⁝", _ => Icons.Material.Filled.QuestionMark }; } @@ -31,6 +31,19 @@ namespace WebApp.Models public static string PresentationEvent = ""; public static string QuestionMark = "❔"; + // Tooltip mapping for icon unicode characters + public static Dictionary IconTooltips => new() + { + { OnSiteActivity, "On-Site Activity" }, + { RegionalEvent, "Regional Event" }, + { IndividualEvent, "Individual Event" }, + { PresubmissionEvent, "Presubmission" }, + { PresentationEvent, "Presentation/Interview" }, + { "①", "Level of Effort: 1" }, + { "②", "Level of Effort: 2" }, + { "③", "Level of Effort: 3" } + }; + public static string EventEffort(EventDefinition eventDefinition) { return LevelOfEffortIcon(eventDefinition.LevelOfEffort); diff --git a/WebApp/Program.cs b/WebApp/Program.cs index 1710056..14fa215 100644 --- a/WebApp/Program.cs +++ b/WebApp/Program.cs @@ -7,6 +7,7 @@ using System.Text.Json; using WebApp; using WebApp.Authentication; using WebApp.Components; +using WebApp.Logging; var builder = WebApplication.CreateBuilder(args); @@ -66,18 +67,32 @@ if (builder.Environment.IsProduction()) } } -// Configure Serilog +// Configure Serilog with custom handling for antiforgery errors builder.Host.UseSerilog((context, configuration) => - configuration - .ReadFrom.Configuration(context.Configuration) - .Enrich.FromLogContext() - .WriteTo.Console( - outputTemplate: "[{Timestamp:HH:mm:ss} {Level:u3}] {Message:lj} {Properties:j}{NewLine}{Exception}") +{ + var consoleOutputTemplate = "[{Timestamp:HH:mm:ss} {Level:u3}] {Message:lj} {Properties:j}{NewLine}{Exception}"; + var fileOutputTemplate = "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level:u3}] {Message:lj} {Properties:j}{NewLine}{Exception}"; + + // Create console logger with antiforgery error handling + var consoleConfig = new LoggerConfiguration() + .WriteTo.Console(outputTemplate: consoleOutputTemplate); + var consoleLogger = consoleConfig.CreateLogger(); + + // Create file logger with antiforgery error handling + var fileConfig = new LoggerConfiguration() .WriteTo.File( path: "logs/webapp-.txt", rollingInterval: RollingInterval.Day, retainedFileCountLimit: 30, - outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level:u3}] {Message:lj} {Properties:j}{NewLine}{Exception}")); + outputTemplate: fileOutputTemplate); + var fileLogger = fileConfig.CreateLogger(); + + configuration + .ReadFrom.Configuration(context.Configuration) + .Enrich.FromLogContext() + .WriteTo.Sink(new AntiforgeryLogEventSink(consoleLogger)) + .WriteTo.Sink(new AntiforgeryLogEventSink(fileLogger)); +}); // Configure authentication secrets for production (Docker, etc.) if (builder.Environment.IsProduction())