Improvements for home page and formatting
This commit is contained in:
@@ -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 : " ";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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,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
@@ -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())
|
||||||
|
|||||||
Reference in New Issue
Block a user