Store leftover CSV columns on hidden student notes, move catalog import to /events/import, and persist Students index columns from Chapter Settings. Co-authored-by: Cursor <cursoragent@cursor.com>
177 lines
6.7 KiB
Plaintext
177 lines
6.7 KiB
Plaintext
@page "/students/edit"
|
|
@attribute [Authorize]
|
|
@using Microsoft.EntityFrameworkCore
|
|
@using WebApp.Components.Shared.Components
|
|
@using MudBlazor
|
|
@using WebApp.Services
|
|
@inject AppDbContext Context
|
|
@inject NavigationManager NavigationManager
|
|
@inject ISnackbar Snackbar
|
|
@inject FormValidationService ValidationService
|
|
|
|
@if (Student is null || _editContext is null)
|
|
{
|
|
<p><em>Loading...</em></p>
|
|
return;
|
|
}
|
|
|
|
<PageHeader
|
|
Title="Edit Student"
|
|
Subtitle="@($"{Student.FirstNameLastName}")"
|
|
ShowBackButton="true"
|
|
BackButtonUrl="@(ReturnUrl ?? "/students")" />
|
|
|
|
@* https://www.mudblazor.com/components/form *@
|
|
@* https://medium.com/@husainalbar/applying-mudblazor-for-crud-operations-in-our-blazor-project-a343037a52ef *@
|
|
<EditForm method="post" EditContext="@_editContext" OnInvalidSubmit="OnInvalidSubmit" FormName="edit" Enhance>
|
|
<FormChangeTracker @ref="_formChangeTracker" />
|
|
<AntiforgeryToken />
|
|
<DataAnnotationsValidator/>
|
|
|
|
<ValidationErrorDisplay Errors="_validationErrors" />
|
|
|
|
<MudGrid>
|
|
<MudItem xs="12" sm="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="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>
|
|
<MudTextField T="int" Label="TSA Year" @bind-Value="Student.TsaYear" For="@(() => Student.TsaYear)"></MudTextField>
|
|
<MudTextField T="string" Label="Regional Id" @bind-Value="Student.RegionalId" For="@(() => Student.RegionalId)"></MudTextField>
|
|
<MudTextField T="string" Label="State Id" @bind-Value="Student.StateId" For="@(() => Student.StateId)"></MudTextField>
|
|
<MudTextField T="string" Label="National Id" @bind-Value="Student.NationalId" For="@(() => Student.NationalId)"></MudTextField>
|
|
<MudSelect T="OfficerRole?" @bind-Value="@Student.OfficerRole" Label="Officer Role">
|
|
|
|
<MudSelectItem T="OfficerRole?" Value="@null">-not an officer-</MudSelectItem>
|
|
@foreach (var officerRole in Enum.GetValues(typeof(OfficerRole)).Cast<OfficerRole>())
|
|
{
|
|
<MudSelectItem T="OfficerRole?" Value="@(officerRole)"></MudSelectItem>
|
|
}
|
|
</MudSelect>
|
|
</MudPaper>
|
|
</MudItem>
|
|
<MudItem xs="12" sm="5">
|
|
<MudPaper Elevation="2" Class="pa-3 pa-md-6">
|
|
<StudentNotePanel @ref="_notePanel" StudentId="Student.Id" />
|
|
</MudPaper>
|
|
</MudItem>
|
|
</MudGrid>
|
|
</EditForm>
|
|
|
|
<FormActions>
|
|
<MudButton OnClick="UpdateStudent" Variant="Variant.Filled" Color="Color.Primary">Save</MudButton>
|
|
<MudButton OnClick="HandleCancel" Variant="Variant.Text">Cancel</MudButton>
|
|
</FormActions>
|
|
|
|
@code {
|
|
[SupplyParameterFromQuery]
|
|
private int Id { get; set; }
|
|
|
|
[SupplyParameterFromQuery]
|
|
private string? ReturnUrl { get; set; }
|
|
|
|
[SupplyParameterFromForm]
|
|
private Student? Student { get; set; }
|
|
|
|
private FormChangeTracker? _formChangeTracker;
|
|
private EditContext? _editContext;
|
|
private List<string> _validationErrors = new();
|
|
private StudentNotePanel? _notePanel;
|
|
|
|
protected override async Task OnInitializedAsync()
|
|
{
|
|
Student ??= await Context.Students.FirstOrDefaultAsync(m => m.Id == Id);
|
|
|
|
if (Student is null)
|
|
{
|
|
NavigationManager.NavigateTo("notfound");
|
|
}
|
|
else
|
|
{
|
|
_editContext = new EditContext(Student);
|
|
}
|
|
}
|
|
|
|
private void OnInvalidSubmit(EditContext editContext)
|
|
{
|
|
_validationErrors = ValidationService.HandleInvalidSubmit(editContext, Student!, errors => _validationErrors = errors);
|
|
StateHasChanged();
|
|
}
|
|
|
|
// To protect from overposting attacks, enable the specific properties you want to bind to.
|
|
// For more information, see https://learn.microsoft.com/aspnet/core/blazor/forms/#mitigate-overposting-attacks.
|
|
private async Task UpdateStudent()
|
|
{
|
|
// Validate before processing
|
|
if (_editContext != null)
|
|
{
|
|
var errors = ValidationService.CollectValidationErrors(_editContext, Student!);
|
|
if (errors.Any())
|
|
{
|
|
_validationErrors = ValidationService.HandleInvalidSubmit(_editContext, Student!, err => _validationErrors = err);
|
|
StateHasChanged();
|
|
return;
|
|
}
|
|
}
|
|
|
|
_validationErrors.Clear();
|
|
|
|
if (Student?.OfficerRole == 0)
|
|
Student.OfficerRole = null;
|
|
|
|
Context.Attach(Student!).State = EntityState.Modified;
|
|
|
|
try
|
|
{
|
|
await Context.SaveChangesAsync();
|
|
if (_notePanel is not null)
|
|
await _notePanel.SaveAsync();
|
|
Snackbar.Add($"Student '{Student!.FirstNameLastName}' saved successfully.", Severity.Success);
|
|
_formChangeTracker?.AllowNavigation();
|
|
NavigationManager.NavigateTo(ReturnUrl ?? "/students");
|
|
}
|
|
catch (DbUpdateConcurrencyException ex)
|
|
{
|
|
if (!ValidationService.HandleDbUpdateConcurrencyException(
|
|
ex,
|
|
() => StudentExists(Student!.Id),
|
|
"student",
|
|
() => NavigationManager.NavigateTo("notfound")))
|
|
{
|
|
throw;
|
|
}
|
|
}
|
|
catch (DbUpdateException ex)
|
|
{
|
|
ValidationService.HandleDbUpdateException(
|
|
ex,
|
|
"An error occurred while saving the student.",
|
|
"student",
|
|
"saving");
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
ValidationService.HandleException(ex);
|
|
}
|
|
}
|
|
|
|
private async Task HandleCancel()
|
|
{
|
|
// Discard all in-memory changes by reloading from database
|
|
if (Student != null)
|
|
{
|
|
await Context.Entry(Student).ReloadAsync();
|
|
}
|
|
|
|
_formChangeTracker?.AllowNavigation();
|
|
NavigationManager.NavigateTo(ReturnUrl ?? "/students");
|
|
}
|
|
|
|
private bool StudentExists(int id)
|
|
{
|
|
return Context.Students.Any(e => e.Id == id);
|
|
}
|
|
}
|