@page "/events/edit" @attribute [Authorize] @using Microsoft.EntityFrameworkCore @using WebApp.Components.Shared.Components @using Core.Utility @inject AppDbContext context @inject NavigationManager NavigationManager @if (EventDefinition is null) {

Loading...

return; } Basic Information Event Format @foreach (EventFormat format in Enum.GetValues(typeof(EventFormat))) { @format.ToString() } Event Details Team Configuration Competition Details Save Cancel @code { [SupplyParameterFromQuery] private int Id { get; set; } [SupplyParameterFromQuery] private string? ReturnUrl { get; set; } [SupplyParameterFromForm] private EventDefinition? EventDefinition { get; set; } private FormChangeTracker? _formChangeTracker; protected override async Task OnInitializedAsync() { EventDefinition ??= await context.Events .Include(e => e.RelatedCareers) .FirstOrDefaultAsync(m => m.Id == Id); if (EventDefinition is null) { NavigationManager.NavigateTo("notfound"); } else { // Populate RelatedCareersText from RelatedCareers collection EventDefinition.RelatedCareersText = string.Join("\n", EventDefinition.RelatedCareers.Select(c => c.Name)); } } // 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 OnValidSubmit() { // Get the tracked entity from the database var trackedEntity = await context.Events .Include(e => e.RelatedCareers) .FirstOrDefaultAsync(e => e.Id == EventDefinition!.Id); if (trackedEntity == null) { NavigationManager.NavigateTo("notfound"); return; } // Update scalar properties from the form-bound entity context.Entry(trackedEntity).CurrentValues.SetValues(EventDefinition!); // Normalize and process related careers await ProcessRelatedCareersAsync(trackedEntity); try { await context.SaveChangesAsync(); _formChangeTracker?.AllowNavigation(); NavigationManager.NavigateTo(ReturnUrl ?? "/events"); } catch (DbUpdateConcurrencyException) { if (!EventDefinitionExists(EventDefinition!.Id)) { NavigationManager.NavigateTo("notfound"); } else { throw; } } } private async Task ProcessRelatedCareersAsync(EventDefinition eventDefinition) { if (string.IsNullOrWhiteSpace(eventDefinition.RelatedCareersText)) { eventDefinition.RelatedCareers.Clear(); return; } var normalizedNames = CareerNormalizer.NormalizeCareerNames(eventDefinition.RelatedCareersText).ToList(); if (!normalizedNames.Any()) { eventDefinition.RelatedCareers.Clear(); return; } // Get all existing careers from database (case-insensitive lookup) var existingCareers = await context.Careers.ToListAsync(); var careerLookup = existingCareers.ToDictionary( c => CareerNormalizer.GetNormalizedKey(c.Name), c => c, StringComparer.OrdinalIgnoreCase); var careersToAdd = new List(); foreach (var normalizedName in normalizedNames) { var normalizedKey = CareerNormalizer.GetNormalizedKey(normalizedName); if (careerLookup.TryGetValue(normalizedKey, out var existingCareer)) { // Use existing career (preserve original capitalization) careersToAdd.Add(existingCareer); } else { // Create new career with the normalized name (preserving capitalization from input) var newCareer = new Career { Name = normalizedName }; context.Careers.Add(newCareer); careersToAdd.Add(newCareer); careerLookup[normalizedKey] = newCareer; } } // Replace the collection eventDefinition.RelatedCareers = careersToAdd; } private async Task HandleCancel() { // Discard all in-memory changes by reloading from database if (EventDefinition != null) { await context.Entry(EventDefinition).ReloadAsync(); } _formChangeTracker?.AllowNavigation(); NavigationManager.NavigateTo(ReturnUrl ?? "/events"); } private bool EventDefinitionExists(int id) { return context.Events.Any(e => e.Id == id); } }