feat: add optional student nickname for informal display

Keep legal first and last names for formal lists; show DisplayFirstName on teams, calendars, and import matching so two Josiahs can be told apart.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-09-12 00:06:33 -04:00
co-authored by Cursor
parent c03ffc0833
commit 29101e2ead
35 changed files with 516 additions and 41 deletions
@@ -7,7 +7,7 @@
Label="@Label"
@bind-Value="_currentStudent"
SearchFunc="@SearchStudents"
ToStringFunc="@(s => ShowFullName ? s?.FirstNameLastName : s?.FirstName)"
ToStringFunc="@(s => ShowFullName ? s?.FirstNameLastName : s?.DisplayFirstName)"
Immediate="true"
ResetValueOnEmptyText="true"
CoerceText="false"
@@ -21,7 +21,7 @@
}
else
{
@student.FirstName
@student.DisplayFirstName
}
@if (ShowGrade)
{
@@ -33,11 +33,11 @@
@if (SelectedStudents.Any())
{
<MudChipSet T="Student" AllClosable="true" Class="mt-2">
@foreach (var student in SelectedStudents.OrderBy(s => s.FirstName))
@foreach (var student in SelectedStudents.OrderBy(s => s.DisplayFirstName))
{
<MudChip T="Student"
Value="@student"
Text="@(ShowFullName ? student.FirstNameLastName : student.FirstName)"
Text="@(ShowFullName ? student.FirstNameLastName : student.DisplayFirstName)"
OnClose="@(() => RemoveStudent(student))" />
}
</MudChipSet>
@@ -91,8 +91,9 @@
return Task.FromResult<IEnumerable<Student>>(Students
.Where(s => !SelectedStudents.Contains(s))
.Where(s => s.FirstName.ToLower().Contains(search) ||
s.LastName.ToLower().Contains(search))
.OrderBy(s => s.FirstName));
s.LastName.ToLower().Contains(search) ||
(s.Nickname != null && s.Nickname.ToLower().Contains(search)))
.OrderBy(s => s.DisplayFirstName));
}
private void RemoveStudent(Student student)
@@ -9,7 +9,7 @@
ValuesChanged="@OnSelectedStudentsChanged"
Vertical="true"
CheckMark>
@foreach (var student in Students.OrderBy(e => e.FirstName))
@foreach (var student in Students.OrderBy(e => e.DisplayFirstName))
{
<MudToggleItem Value="@student" Style="font-size: .75rem;">
@if (ShowFullName)
@@ -18,7 +18,7 @@
}
else
{
@student.FirstName
@student.DisplayFirstName
}
</MudToggleItem>
}
@@ -31,6 +31,9 @@
<MudItem xs="12" sm="6">
<MudTextField T="string" Label="Last Name" @bind-Value="Student.LastName" For="@(() => Student.LastName)" Variant="Variant.Outlined"></MudTextField>
</MudItem>
<MudItem xs="12" sm="6">
<MudTextField T="string" Label="Nickname" @bind-Value="Student.Nickname" For="@(() => Student.Nickname)" Variant="Variant.Outlined" HelperText="Shown instead of first name on teams, rankings, and printouts"></MudTextField>
</MudItem>
<MudItem xs="12" sm="6">
<MudTextField T="string" Label="Email Address" @bind-Value="Student.Email" For="@(() => Student.Email)" Variant="Variant.Outlined"></MudTextField>
</MudItem>
@@ -80,6 +83,7 @@
try
{
Student.NormalizeNickname();
Context.Students.Add(Student);
await Context.SaveChangesAsync();
@@ -41,6 +41,10 @@
<MudText Typo="Typo.subtitle2" Class="mud-text-secondary">Last Name</MudText>
<MudText Typo="Typo.body1">@student.LastName</MudText>
</MudItem>
<MudItem xs="12" sm="6" md="4">
<MudText Typo="Typo.subtitle2" Class="mud-text-secondary">Nickname</MudText>
<MudText Typo="Typo.body1">@(string.IsNullOrWhiteSpace(student.Nickname) ? "—" : student.Nickname)</MudText>
</MudItem>
<MudItem xs="12" sm="6" md="4">
<MudText Typo="Typo.subtitle2" Class="mud-text-secondary">Grade</MudText>
<MudText Typo="Typo.body1">@student.Grade</MudText>
@@ -35,6 +35,7 @@
<MudPaper Elevation="2" Class="pa-3 pa-md-6">
<MudTextField T="string" Label="First Name" @bind-Value="Student.FirstName" For="@(() => Student.FirstName)"></MudTextField>
<MudTextField T="string" Label="Last Name" @bind-Value="Student.LastName" For="@(() => Student.LastName)"></MudTextField>
<MudTextField T="string" Label="Nickname" @bind-Value="Student.Nickname" For="@(() => Student.Nickname)" HelperText="Shown instead of first name on teams, rankings, and printouts"></MudTextField>
<MudTextField T="string" Label="Email Adress" @bind-Value="Student.Email" For="@(() => Student.Email)"></MudTextField>
<MudTextField T="string" Label="Phone Number" @bind-Value="Student.PhoneNumber" For="@(() => Student.PhoneNumber)"></MudTextField>
<MudTextField T="int" Label="Grade" @bind-Value="Student.Grade" For="@(() => Student.Grade)"></MudTextField>
@@ -121,7 +122,8 @@
if (Student?.OfficerRole == 0)
Student.OfficerRole = null;
Context.Attach(Student!).State = EntityState.Modified;
Student!.NormalizeNickname();
Context.Attach(Student).State = EntityState.Modified;
try
{
@@ -67,6 +67,10 @@
Color="Color.Primary">
@context.Item.LastNameFirstName
</MudLink>
@if (!string.IsNullOrWhiteSpace(context.Item.Nickname))
{
<MudText Typo="Typo.caption" Class="mud-text-secondary">@context.Item.Nickname</MudText>
}
@if (context.Item.OfficerRole != null)
{
<MudChip T="string" Size="Size.Small" Icon="@(AppIcons.OfficerRoleIcon(context.Item.OfficerRole.Value))">@context.Item.OfficerRole</MudChip>