Improvements for home page and formatting

This commit is contained in:
2025-12-11 14:17:33 -05:00
parent 8289b7139a
commit 27dc995bb8
4 changed files with 83 additions and 57 deletions
@@ -1,49 +1,34 @@
@using WebApp.Models @using WebApp.Models
@*
<MudTooltip Text="Level of Effort">@AppIcons.LevelOfEffortIcon(EventDefinition.LevelOfEffort)</MudTooltip>
@if(EventDefinition.EventFormat == EventFormat.Individual) { <MudText Style="font-family: monospace; white-space: pre;">
<MudTooltip Text="Individual">@AppIcons.IndividualEvent</MudTooltip> @foreach (var charStr in _attributes.Select(c => c.ToString()))
} {
@if (EventDefinition.OnSiteActivity) if (AppIcons.IconTooltips.TryGetValue(charStr, out var tooltip))
{ {
<MudTooltip Text="On-site Activity"> @AppIcons.OnSiteActivity</MudTooltip> <MudTooltip Text="@tooltip">@charStr</MudTooltip>
} }
else
@if (EventDefinition.RegionalEvent) {
{ @charStr
<MudTooltip Text="Regional Event">@AppIcons.RegionalEvent</MudTooltip> }
} }
</MudText>
@if (EventDefinition.Presubmission)
{
<MudTooltip Text="Presubmission Event">@AppIcons.PresubmissionEvent</MudTooltip>
} *@
@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
}
@code { @code {
[Parameter] [Parameter]
public EventDefinition EventDefinition { get; set; } 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 : " ";
}
} }
+19 -6
View File
@@ -9,10 +9,17 @@
<MudPaper Elevation="0" Class="mb-6"> <MudPaper Elevation="0" Class="mb-6">
<div class="d-flex flex-column align-center text-center mb-4"> <div class="d-flex flex-column align-center text-center mb-4">
<MudImage Fluid="true" Src="TCO_Title.png" Alt="TSA Chapter Organizer" Class="mb-4" Style="max-width: 600px;" /> <MudImage Fluid="true" Src="TCO_Title.png" Alt="TSA Chapter Organizer" Class="mb-4" Style="width: 100%; max-width: 600px; height: auto;" />
<MudText Typo="Typo.h3" Class="mb-2"> <MudHidden Breakpoint="Breakpoint.SmAndDown">
<strong>@Configuration["ChapterSettings:Name"]</strong> <MudText Typo="Typo.h3" Class="mb-2">
</MudText> <strong>@Configuration["ChapterSettings:Name"]</strong>
</MudText>
</MudHidden>
<MudHidden Breakpoint="Breakpoint.MdAndUp">
<MudText Typo="Typo.h5" Class="mb-2">
<strong>@Configuration["ChapterSettings:Name"]</strong>
</MudText>
</MudHidden>
<MudText Typo="Typo.h6" Color="Color.Secondary"> <MudText Typo="Typo.h6" Color="Color.Secondary">
@Configuration["ChapterSettings:CompetitionYear"] Competition Year @Configuration["ChapterSettings:CompetitionYear"] Competition Year
</MudText> </MudText>
@@ -25,7 +32,7 @@
Title="Events" Title="Events"
Count="@_eventCount" Count="@_eventCount"
Subtitle="Total Events" Subtitle="Total Events"
Caption="@($"{_individualEventsCount} Individual | {_teamEventsCount} Team")" Caption="@($"{_teamEventsCount} Team | {_individualEventsCount} Individual")"
NavigateUrl="/events" /> NavigateUrl="/events" />
<!-- Students Card --> <!-- Students Card -->
@@ -51,6 +58,7 @@
Title="Teams" Title="Teams"
Count="@_teamCount" Count="@_teamCount"
Subtitle="Total Teams" Subtitle="Total Teams"
Caption="@($"{_groupTeamsCount} Team | {_individualTeamsCount} Individual")"
NavigateUrl="/teams" /> NavigateUrl="/teams" />
<!-- Meeting Schedule Card --> <!-- Meeting Schedule Card -->
@@ -67,6 +75,8 @@
private int _studentCount; private int _studentCount;
private string _gradeDistribution = ""; private string _gradeDistribution = "";
private int _teamCount; private int _teamCount;
private int _individualTeamsCount;
private int _groupTeamsCount;
protected override async Task OnInitializedAsync() protected override async Task OnInitializedAsync()
{ {
@@ -102,6 +112,9 @@
} }
// Teams statistics // 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);
} }
} }
+16 -3
View File
@@ -16,9 +16,9 @@ namespace WebApp.Models
return loe switch return loe switch
{ {
1 => "", 1 => "",
2 => "", 2 => "",
3 => "", 3 => "",
_ => Icons.Material.Filled.QuestionMark _ => Icons.Material.Filled.QuestionMark
}; };
} }
@@ -31,6 +31,19 @@ namespace WebApp.Models
public static string PresentationEvent = ""; public static string PresentationEvent = "";
public static string QuestionMark = "❔"; public static string QuestionMark = "❔";
// Tooltip mapping for icon unicode characters
public static Dictionary<string, string> 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) public static string EventEffort(EventDefinition eventDefinition)
{ {
return LevelOfEffortIcon(eventDefinition.LevelOfEffort); return LevelOfEffortIcon(eventDefinition.LevelOfEffort);
+22 -7
View File
@@ -7,6 +7,7 @@ using System.Text.Json;
using WebApp; using WebApp;
using WebApp.Authentication; using WebApp.Authentication;
using WebApp.Components; using WebApp.Components;
using WebApp.Logging;
var builder = WebApplication.CreateBuilder(args); 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) => builder.Host.UseSerilog((context, configuration) =>
configuration {
.ReadFrom.Configuration(context.Configuration) var consoleOutputTemplate = "[{Timestamp:HH:mm:ss} {Level:u3}] {Message:lj} {Properties:j}{NewLine}{Exception}";
.Enrich.FromLogContext() var fileOutputTemplate = "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level:u3}] {Message:lj} {Properties:j}{NewLine}{Exception}";
.WriteTo.Console(
outputTemplate: "[{Timestamp:HH:mm:ss} {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( .WriteTo.File(
path: "logs/webapp-.txt", path: "logs/webapp-.txt",
rollingInterval: RollingInterval.Day, rollingInterval: RollingInterval.Day,
retainedFileCountLimit: 30, 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.) // Configure authentication secrets for production (Docker, etc.)
if (builder.Environment.IsProduction()) if (builder.Environment.IsProduction())