From fa704ab996db18314bb5c99ffa4a2394bb0befd1 Mon Sep 17 00:00:00 2001 From: Arne Moerman Date: Mon, 18 May 2026 23:56:28 +0200 Subject: [PATCH] Add user profile fields and completion prompt Added `FirstName`, `LastName`, and `Address` fields to `ApplicationUser` for extended user profiles. Updated `Index.razor` to include these fields in the profile form with validation. Introduced `ProfileCompletionService` to check profile completeness and added a prompt in `TopBar.razor` for incomplete profiles. Created migration `20260518213355_AddUserProfileFields` to update the database schema. Updated `RegistryService` to use new fields for user display names. Registered `ProfileCompletionService` and `DbContextFactory` in `Program.cs`. Styled the profile completion banner in `TopBar.razor.css`. --- .../Account/Pages/Manage/Index.razor | 40 +++ .../Components/Layout/TopBar.razor | 34 ++- .../Components/Layout/TopBar.razor.css | 22 ++ src/BirthList.Web/Data/ApplicationUser.cs | 3 + ...518213355_AddUserProfileFields.Designer.cs | 288 ++++++++++++++++++ .../20260518213355_AddUserProfileFields.cs | 48 +++ .../ApplicationDbContextModelSnapshot.cs | 22 +- .../Features/Registries/RegistryService.cs | 60 +++- src/BirthList.Web/Program.cs | 12 + .../Services/ProfileCompletionService.cs | 30 ++ 10 files changed, 541 insertions(+), 18 deletions(-) create mode 100644 src/BirthList.Web/Data/Migrations/20260518213355_AddUserProfileFields.Designer.cs create mode 100644 src/BirthList.Web/Data/Migrations/20260518213355_AddUserProfileFields.cs create mode 100644 src/BirthList.Web/Services/ProfileCompletionService.cs diff --git a/src/BirthList.Web/Components/Account/Pages/Manage/Index.razor b/src/BirthList.Web/Components/Account/Pages/Manage/Index.razor index 3fb6298..6ac6eb9 100644 --- a/src/BirthList.Web/Components/Account/Pages/Manage/Index.razor +++ b/src/BirthList.Web/Components/Account/Pages/Manage/Index.razor @@ -23,6 +23,21 @@ +
+ + + +
+
+ + + +
+
+ + + +
@@ -51,6 +66,9 @@ phoneNumber = await UserManager.GetPhoneNumberAsync(user); Input.PhoneNumber ??= phoneNumber; + Input.FirstName ??= user.FirstName; + Input.LastName ??= user.LastName; + Input.Address ??= user.Address; } private async Task OnValidSubmitAsync() @@ -64,12 +82,34 @@ } } + user.FirstName = string.IsNullOrWhiteSpace(Input.FirstName) ? null : Input.FirstName.Trim(); + user.LastName = string.IsNullOrWhiteSpace(Input.LastName) ? null : Input.LastName.Trim(); + user.Address = string.IsNullOrWhiteSpace(Input.Address) ? null : Input.Address.Trim(); + + var updateResult = await UserManager.UpdateAsync(user); + if (!updateResult.Succeeded) + { + RedirectManager.RedirectToCurrentPageWithStatus("Error: Failed to update profile.", HttpContext); + } + await SignInManager.RefreshSignInAsync(user); RedirectManager.RedirectToCurrentPageWithStatus("Your profile has been updated", HttpContext); } private sealed class InputModel { + [StringLength(100)] + [Display(Name = "First name")] + public string? FirstName { get; set; } + + [StringLength(100)] + [Display(Name = "Last name")] + public string? LastName { get; set; } + + [StringLength(500)] + [Display(Name = "Address")] + public string? Address { get; set; } + [Phone] [Display(Name = "Phone number")] public string? PhoneNumber { get; set; } diff --git a/src/BirthList.Web/Components/Layout/TopBar.razor b/src/BirthList.Web/Components/Layout/TopBar.razor index 20a66d8..9e991b6 100644 --- a/src/BirthList.Web/Components/Layout/TopBar.razor +++ b/src/BirthList.Web/Components/Layout/TopBar.razor @@ -1,7 +1,19 @@ +@using BirthList.Web.Features.Registries +@using BirthList.Web.Services @implements IDisposable @inject NavigationManager NavigationManager @inject AuthenticationStateProvider AuthenticationStateProvider +@inject RegistryUserContext RegistryUserContext +@inject ProfileCompletionService ProfileCompletionService + +@if (ShowProfileCompletionPrompt) +{ +
+ Please complete your profile (first name, last name, and address). + Complete profile +
+}