From fb6a8da94df2ca1a7f41dbebef8119ffd75c3aef Mon Sep 17 00:00:00 2001 From: Musa Ahmed Date: Sat, 28 Feb 2026 14:22:04 -0500 Subject: [PATCH 01/18] US-002 - Fix issue with z-index and stepper line --- .../wwwroot/css/custom.css | 0 .../wwwroot/css/sysinfocus-styles.css | 15 +++++++++++++++ 2 files changed, 15 insertions(+) delete mode 100644 WardrobeManager.Presentation/wwwroot/css/custom.css diff --git a/WardrobeManager.Presentation/wwwroot/css/custom.css b/WardrobeManager.Presentation/wwwroot/css/custom.css deleted file mode 100644 index e69de29..0000000 diff --git a/WardrobeManager.Presentation/wwwroot/css/sysinfocus-styles.css b/WardrobeManager.Presentation/wwwroot/css/sysinfocus-styles.css index 512d953..35c4a36 100644 --- a/WardrobeManager.Presentation/wwwroot/css/sysinfocus-styles.css +++ b/WardrobeManager.Presentation/wwwroot/css/sysinfocus-styles.css @@ -1,8 +1,23 @@ /* Replacing Sysinfocus css styles.css file because it is override default tailwind styles */ /* this is hacky since if the library styles change in the future something might break but what can you do? */ + @import url(https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,300,0,0); @import url('https://fonts.googleapis.com/css2?family=Geist:wght@100..900&display=swap'); +/* Custom modifications */ +/* + So basically this line that connects Stepper steps is not being displayed + because the z-index is being weird so i'm manually overriding it here +*/ +.sbc-stepper-step { + z-index: 2 !important; +} +/* ::before is where the line is */ +.sbc-stepper::before { + z-index: 1 !important; +} + + :root { --grid-height: 200px; --color-scheme: dark; From 2c4a518b04a3349d56cd5872061e56f6df36c0c0 Mon Sep 17 00:00:00 2001 From: Musa Ahmed Date: Sat, 28 Feb 2026 14:22:29 -0500 Subject: [PATCH 02/18] US-002 - Update launchSettings.json to automatically restart on breaking change --- WardrobeManager.Api/Properties/launchSettings.json | 3 ++- WardrobeManager.Presentation/Properties/launchSettings.json | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/WardrobeManager.Api/Properties/launchSettings.json b/WardrobeManager.Api/Properties/launchSettings.json index f081300..7dccebf 100644 --- a/WardrobeManager.Api/Properties/launchSettings.json +++ b/WardrobeManager.Api/Properties/launchSettings.json @@ -15,7 +15,8 @@ "launchBrowser": false, "launchUrl": "swagger", "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" + "ASPNETCORE_ENVIRONMENT": "Development", + "DOTNET_WATCH_RESTART_ON_RUDE_EDIT": "1" }, "dotnetRunMessages": true, "applicationUrl": "https://localhost:7026;http://localhost:5054" diff --git a/WardrobeManager.Presentation/Properties/launchSettings.json b/WardrobeManager.Presentation/Properties/launchSettings.json index 64af980..68ff6e7 100644 --- a/WardrobeManager.Presentation/Properties/launchSettings.json +++ b/WardrobeManager.Presentation/Properties/launchSettings.json @@ -26,7 +26,8 @@ "inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}", "applicationUrl": "https://localhost:7147;http://localhost:5281", "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" + "ASPNETCORE_ENVIRONMENT": "Development", + "DOTNET_WATCH_RESTART_ON_RUDE_EDIT": "1" } }, "IIS Express": { From 24f6d4e013d123408ca3c2fa4bb243bbca7d817b Mon Sep 17 00:00:00 2001 From: Musa Ahmed Date: Sat, 28 Feb 2026 14:22:59 -0500 Subject: [PATCH 03/18] US-002 - Working on onboarding --- .../Endpoints/IdentityEndpoints.cs | 4 +- .../Services/Implementation/UserService.cs | 12 +- .../Services/Interfaces/IUserService.cs | 2 +- .../Onboarding/OnboardingSection.razor | 10 +- .../Pages/Public/Onboarding.razor | 77 +++++++++- WardrobeManager.Presentation/Pages/Test.razor | 141 ++++++++---------- .../Services/Implementation/ApiService.cs | 2 +- .../Services/Interfaces/IApiService.cs | 2 +- .../ViewModels/OnboardingViewModel.cs | 102 +++++++++++++ .../Models/AdminUserCredentials.cs | 9 -- 10 files changed, 254 insertions(+), 107 deletions(-) create mode 100644 WardrobeManager.Presentation/ViewModels/OnboardingViewModel.cs delete mode 100644 WardrobeManager.Shared/Models/AdminUserCredentials.cs diff --git a/WardrobeManager.Api/Endpoints/IdentityEndpoints.cs b/WardrobeManager.Api/Endpoints/IdentityEndpoints.cs index d2f318d..298e54f 100644 --- a/WardrobeManager.Api/Endpoints/IdentityEndpoints.cs +++ b/WardrobeManager.Api/Endpoints/IdentityEndpoints.cs @@ -68,9 +68,9 @@ public static async Task DoesAdminUserExist(IUserService userService) } public static async Task CreateAdminIfMissing(IUserService userService, - [FromBody] AdminUserCredentials credentials) + [FromBody] AuthenticationCredentialsModel credentials) { - var res = await userService.CreateAdminIfMissing(credentials.email, credentials.password); + var res = await userService.CreateAdminIfMissing(credentials); if (res.Item1) { diff --git a/WardrobeManager.Api/Services/Implementation/UserService.cs b/WardrobeManager.Api/Services/Implementation/UserService.cs index 42ee7ae..327204f 100644 --- a/WardrobeManager.Api/Services/Implementation/UserService.cs +++ b/WardrobeManager.Api/Services/Implementation/UserService.cs @@ -103,7 +103,7 @@ public async Task DoesAdminUserExist() return false; } - public async Task<(bool, string)> CreateAdminIfMissing(string email, string password) + public async Task<(bool, string)> CreateAdminIfMissing(AuthenticationCredentialsModel credentials) { if (await DoesAdminUserExist()) { @@ -115,13 +115,13 @@ public async Task DoesAdminUserExist() var user = new User { - Email = email, - NormalizedEmail = email.ToUpper(), - UserName = email.ToUpper(), - NormalizedUserName = email.ToUpper(), + Email = credentials.Email, + NormalizedEmail = credentials.Email.ToUpper(), + UserName = credentials.Email.ToUpper(), + NormalizedUserName = credentials.Email.ToUpper(), }; - var createResult = await _userManager.CreateAsync(user, password); + var createResult = await _userManager.CreateAsync(user, credentials.Password); if (createResult.Succeeded is false) { diff --git a/WardrobeManager.Api/Services/Interfaces/IUserService.cs b/WardrobeManager.Api/Services/Interfaces/IUserService.cs index 7aba802..04665b7 100644 --- a/WardrobeManager.Api/Services/Interfaces/IUserService.cs +++ b/WardrobeManager.Api/Services/Interfaces/IUserService.cs @@ -12,5 +12,5 @@ public interface IUserService Task UpdateUser(string userId, EditedUserDTO editedUser); Task DeleteUser(string userId); Task DoesAdminUserExist(); - Task<(bool, string)> CreateAdminIfMissing(string email, string password); + Task<(bool, string)> CreateAdminIfMissing(AuthenticationCredentialsModel credentials); } \ No newline at end of file diff --git a/WardrobeManager.Presentation/Components/Onboarding/OnboardingSection.razor b/WardrobeManager.Presentation/Components/Onboarding/OnboardingSection.razor index c16e31c..8831cc8 100644 --- a/WardrobeManager.Presentation/Components/Onboarding/OnboardingSection.razor +++ b/WardrobeManager.Presentation/Components/Onboarding/OnboardingSection.razor @@ -1,14 +1,18 @@ @namespace WardrobeManager.Presentation.Components.Onboarding
-

@Title

+

@Title

@ChildContent - +
+
@code { [Parameter] public required string Title { get; set; } [Parameter] public required RenderFragment ChildContent { get; set; } [Parameter] public required string ButtonText { get; set; } - [Parameter] public required EventCallback ButtonClickCallback { get; set; } + [Parameter] public required EventCallback NextButtonClickCallback { get; set; } + [Parameter] public required EventCallback PreviousButtonClickCallback { get; set; } } \ No newline at end of file diff --git a/WardrobeManager.Presentation/Pages/Public/Onboarding.razor b/WardrobeManager.Presentation/Pages/Public/Onboarding.razor index 8e1b9cd..f3595b1 100644 --- a/WardrobeManager.Presentation/Pages/Public/Onboarding.razor +++ b/WardrobeManager.Presentation/Pages/Public/Onboarding.razor @@ -1,10 +1,83 @@ @page "/onboarding" -@using WardrobeManager.Presentation.Components.FormItems + +@using System.Linq.Expressions @using WardrobeManager.Presentation.Components.Onboarding +@using WardrobeManager.Presentation.Components.FormItems @using WardrobeManager.Shared.StaticResources @namespace WardrobeManager.Presentation.Pages.Public +@inherits MvvmComponentBase + Onboarding - WardrobeManager -

Onboarding!

+
+

Welcome to WardrobeManager!

+ + + @for (int i = 0; i < ViewModel.NumberOfSteps; i++) + { + var currentStep = i; + @currentStep.ToString() + } + blah + + +
+ @switch (ViewModel.CurrentStepIndex) + { + case 0: + { + + + + break; + } + case 1: + { + +
+ + + + + + + + +
+
+ break; + } + case 2: + { + +

+ If you encounter any issues, please open an issue on the GitHub repo +

+
+ break; + } + } + +
+ +
diff --git a/WardrobeManager.Presentation/Pages/Test.razor b/WardrobeManager.Presentation/Pages/Test.razor index 355fc3a..f21aae2 100644 --- a/WardrobeManager.Presentation/Pages/Test.razor +++ b/WardrobeManager.Presentation/Pages/Test.razor @@ -4,93 +4,70 @@ @page "/test" @using WardrobeManager.Shared.DTOs - + + +
+
+

Notification

+

Type: @notification.Type.ToString()

+

Created: @notification.CreationDate

+
+
+ + Message: @notification.Message + +
+
+
+
+
} @code { - - protected override void OnInitialized() + protected override async Task OnInitializedAsync() { _notificationService.OnChange += StateHasChanged; // this runs the callback method supplied every 5 seconds. it does not wait for the last @@ -59,4 +80,25 @@ }; } + public string GetNotificationCss(NotificationType type) + { + return type switch + { + NotificationType.Success => "text-[#28a745]", + NotificationType.Warning => "text-[#ffc107]", + NotificationType.Error => "text-[#dc3545]", + _ => "text-[#007bff]", // default is 'info' colour + }; + } + + private string GetTruncatedMessage(NotificationMessage notification) + { + if (notification.Message.Length >= 40) + { + return notification.Message.Substring(0, 36) + "..."; + } + + return notification.Message; + } + } diff --git a/WardrobeManager.Presentation/Layout/MainLayout.razor b/WardrobeManager.Presentation/Layout/MainLayout.razor index b25beee..2598884 100644 --- a/WardrobeManager.Presentation/Layout/MainLayout.razor +++ b/WardrobeManager.Presentation/Layout/MainLayout.razor @@ -5,7 +5,7 @@ @inject Initialization sysinfocusComponentsinit @inject BrowserExtensions browserExtensions - @@ -21,8 +21,8 @@ } - + @code { private ErrorBoundary? errorBoundary; diff --git a/WardrobeManager.Presentation/Pages/Test.razor b/WardrobeManager.Presentation/Pages/Test.razor index f21aae2..2690931 100644 --- a/WardrobeManager.Presentation/Pages/Test.razor +++ b/WardrobeManager.Presentation/Pages/Test.razor @@ -32,6 +32,11 @@ + + - +
@@ -25,11 +26,13 @@
- Message: @notification.Message + Message: + @notification.Message +
-
@@ -37,6 +40,7 @@ @code { + protected override async Task OnInitializedAsync() { _notificationService.OnChange += StateHasChanged; From c0164dfec8be1754413d980e2e3599b553ebd694 Mon Sep 17 00:00:00 2001 From: Musa Ahmed Date: Wed, 4 Mar 2026 09:56:23 -0500 Subject: [PATCH 08/18] US-002 - Moved MainLayout to view model --- .../Onboarding/OnboardingSection.razor | 30 +++++++++-- .../Components/Shared/Notifications.razor | 4 +- .../Layout/MainLayout.razor | 48 ++--------------- .../Layout/NavMenu.razor | 5 ++ .../Pages/Public/Onboarding.razor | 32 +++++++---- .../ViewModels/MainLayoutViewModel.cs | 53 +++++++++++++++++++ .../ViewModels/OnboardingViewModel.cs | 13 +++-- 7 files changed, 124 insertions(+), 61 deletions(-) create mode 100644 WardrobeManager.Presentation/ViewModels/MainLayoutViewModel.cs diff --git a/WardrobeManager.Presentation/Components/Onboarding/OnboardingSection.razor b/WardrobeManager.Presentation/Components/Onboarding/OnboardingSection.razor index 3904af5..6974e37 100644 --- a/WardrobeManager.Presentation/Components/Onboarding/OnboardingSection.razor +++ b/WardrobeManager.Presentation/Components/Onboarding/OnboardingSection.razor @@ -1,20 +1,42 @@ @namespace WardrobeManager.Presentation.Components.Onboarding
-
-

@Title

+
+

@Title

@ChildContent
-
+
+ + + }
@code { [Parameter] public required string Title { get; set; } [Parameter] public required RenderFragment ChildContent { get; set; } - [Parameter] public required string ButtonText { get; set; } [Parameter] public required EventCallback NextButtonClickCallback { get; set; } [Parameter] public required EventCallback PreviousButtonClickCallback { get; set; } + [Parameter] public EventCallback SkipTutorialButtonClickCallback { get; set; } + private bool ShowSkipTutorialDialog { get; set; } } \ No newline at end of file diff --git a/WardrobeManager.Presentation/Components/Shared/Notifications.razor b/WardrobeManager.Presentation/Components/Shared/Notifications.razor index 245445d..dddd41b 100644 --- a/WardrobeManager.Presentation/Components/Shared/Notifications.razor +++ b/WardrobeManager.Presentation/Components/Shared/Notifications.razor @@ -3,7 +3,7 @@ @inject INotificationService _notificationService -
+
@foreach (var notification in _notificationService.Notifications) { var cssClass = GetNotificationCss(notification.Type); @@ -27,7 +27,7 @@ Message: - @notification.Message + @notification.Message
diff --git a/WardrobeManager.Presentation/Layout/MainLayout.razor b/WardrobeManager.Presentation/Layout/MainLayout.razor index 2598884..45e3d29 100644 --- a/WardrobeManager.Presentation/Layout/MainLayout.razor +++ b/WardrobeManager.Presentation/Layout/MainLayout.razor @@ -1,13 +1,8 @@ -@inherits LayoutComponentBase +@inherits MvvmLayoutComponentBase -@inject IJSRuntime JSRuntime -@inject INotificationService _notificationService -@inject Initialization sysinfocusComponentsinit -@inject BrowserExtensions browserExtensions - - - + + @Body @@ -17,41 +12,8 @@ @{ // fixlater: In the future, we should maybe not display raw exceptions to the user _notificationService.AddNotification(ex.Message, NotificationType.Error); - Console.WriteLine(ex.Message); } - - -@code { - private ErrorBoundary? errorBoundary; - - - // This runs every time any page is (fully) reloaded (in the browser) - protected override async Task OnInitializedAsync() - { - // var res = await _apiService.DoesAdminUserExist(); - // if (res is false) - // { - // _navManager.NavigateTo("/onboarding"); - // } - // - // await base.OnInitializedAsync(); - } - - protected override async Task OnAfterRenderAsync(bool firstRender) - { - if (firstRender) - { - await browserExtensions.SetToLocalStorage("theme", "dark"); - await sysinfocusComponentsinit.InitializeTheme(); - } - } - - protected override void OnParametersSet() - { - errorBoundary?.Recover(); - } - -} \ No newline at end of file + \ No newline at end of file diff --git a/WardrobeManager.Presentation/Layout/NavMenu.razor b/WardrobeManager.Presentation/Layout/NavMenu.razor index 2c7ed9b..db2961e 100644 --- a/WardrobeManager.Presentation/Layout/NavMenu.razor +++ b/WardrobeManager.Presentation/Layout/NavMenu.razor @@ -50,6 +50,11 @@
+ +
diff --git a/WardrobeManager.Presentation/ViewModels/OnboardingViewModel.cs b/WardrobeManager.Presentation/ViewModels/OnboardingViewModel.cs index b280ca8..7858274 100644 --- a/WardrobeManager.Presentation/ViewModels/OnboardingViewModel.cs +++ b/WardrobeManager.Presentation/ViewModels/OnboardingViewModel.cs @@ -88,7 +88,6 @@ public void GoToPreviousSection() public void FinishOnboardingAsync() { - Console.WriteLine("here!"); navManager.NavigateTo(); } diff --git a/WardrobeManager.Shared/Models/AuthenticationCredentialsModel.cs b/WardrobeManager.Shared/Models/AuthenticationCredentialsModel.cs index c8ed1ae..05a267c 100644 --- a/WardrobeManager.Shared/Models/AuthenticationCredentialsModel.cs +++ b/WardrobeManager.Shared/Models/AuthenticationCredentialsModel.cs @@ -1,7 +1,7 @@ namespace WardrobeManager.Shared.Models; -public class AuthenticationCredentialsModel +public record AuthenticationCredentialsModel { - public string Email = string.Empty; - public string Password = string.Empty; + public string Email { get; set; }= string.Empty; + public string Password { get; set; } = string.Empty; } \ No newline at end of file From 8de7682b539973e917a5cf88a8a7a21b37abca41 Mon Sep 17 00:00:00 2001 From: Musa Ahmed Date: Wed, 4 Mar 2026 10:37:43 -0500 Subject: [PATCH 10/18] US-002 - Do not notify user of unauthorized requests --- WardrobeManager.Presentation/CustomHttpMessageHandler.cs | 9 ++++++--- .../Identity/CookieAuthenticationStateProvider.cs | 1 - WardrobeManager.Presentation/Layout/MainLayout.razor | 2 +- .../Pages/Public/Onboarding.razor | 2 +- 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/WardrobeManager.Presentation/CustomHttpMessageHandler.cs b/WardrobeManager.Presentation/CustomHttpMessageHandler.cs index e52288a..fb99aa8 100644 --- a/WardrobeManager.Presentation/CustomHttpMessageHandler.cs +++ b/WardrobeManager.Presentation/CustomHttpMessageHandler.cs @@ -1,5 +1,6 @@ #region +using System.Net; using Microsoft.AspNetCore.Components.WebAssembly.Http; using WardrobeManager.Presentation.Services.Interfaces; using WardrobeManager.Shared.Enums; @@ -29,9 +30,11 @@ protected override async Task SendAsync(HttpRequestMessage { // This sends the actual HTTP request var response = await base.SendAsync(request, cancellationToken); - - // 1. Check for standard HTTP errors (like 404 Not Found, 500 Server Error) - if (!response.IsSuccessStatusCode) + + // The application continually checks the authentication state of the user via GetAuthenticationStateAsync + // The method calls the backend. If the user is not authenticated the backend returns HTTP 401. + // We don't want to notify the user of this as it is benign + if (!response.IsSuccessStatusCode && response.StatusCode != HttpStatusCode.Unauthorized) { notificationService.AddNotification($"Server Error: {(int)response.StatusCode}", NotificationType.Error); } diff --git a/WardrobeManager.Presentation/Identity/CookieAuthenticationStateProvider.cs b/WardrobeManager.Presentation/Identity/CookieAuthenticationStateProvider.cs index d8115bd..5a9da25 100644 --- a/WardrobeManager.Presentation/Identity/CookieAuthenticationStateProvider.cs +++ b/WardrobeManager.Presentation/Identity/CookieAuthenticationStateProvider.cs @@ -164,7 +164,6 @@ public override async Task GetAuthenticationStateAsync() // default to not authenticated var user = Unauthenticated; - try { // the user info endpoint is secured, so if the user isn't logged in this will fail diff --git a/WardrobeManager.Presentation/Layout/MainLayout.razor b/WardrobeManager.Presentation/Layout/MainLayout.razor index 45e3d29..b9814e6 100644 --- a/WardrobeManager.Presentation/Layout/MainLayout.razor +++ b/WardrobeManager.Presentation/Layout/MainLayout.razor @@ -11,7 +11,7 @@ @{ // fixlater: In the future, we should maybe not display raw exceptions to the user - _notificationService.AddNotification(ex.Message, NotificationType.Error); + _notificationService.AddNotification($"Unhandled Exception: {ex.Message}", NotificationType.Error); }
diff --git a/WardrobeManager.Presentation/Pages/Public/Onboarding.razor b/WardrobeManager.Presentation/Pages/Public/Onboarding.razor index 50b0b87..fa795e4 100644 --- a/WardrobeManager.Presentation/Pages/Public/Onboarding.razor +++ b/WardrobeManager.Presentation/Pages/Public/Onboarding.razor @@ -53,7 +53,7 @@
From a88d7a603a2d786d0c7264eaf9b0954f7e918eeb Mon Sep 17 00:00:00 2001 From: Musa Ahmed Date: Wed, 4 Mar 2026 10:44:57 -0500 Subject: [PATCH 11/18] US-002 - Make two folders for ViewModels (pages, components) and modifiy Notifications.razor to use a ViewModel --- .../Services/ClothingServiceTests.cs | 1 + WardrobeManager.Api/Program.cs | 1 + .../Implementation/ClothingService.cs | 1 + .../AddClothingItemViewModelTests.cs | 2 + .../ViewModels/DashboardViewModelTests.cs | 1 + .../ViewModels/HomeViewModelTests.cs | 1 + .../ViewModels/LoginViewModelTests.cs | 1 + .../ViewModels/NavBarViewModelTests.cs | 2 + .../ViewModels/SignupViewModelTests.cs | 1 + .../ViewModels/WardrobeViewModelTests.cs | 1 + .../Components/Shared/Notifications.razor | 82 ++--------------- .../Layout/MainLayout.razor | 2 +- .../Layout/NavMenu.razor | 2 +- .../Pages/Authenticated/AddClothingItem.razor | 2 +- .../Pages/Authenticated/Dashboard.razor | 2 +- .../Pages/Authenticated/Wardrobe.razor | 4 +- .../Pages/Public/Home.razor | 2 +- .../Pages/Public/Login.razor | 2 +- .../Pages/Public/Onboarding.razor | 3 +- .../Pages/Public/Signup.razor | 2 +- WardrobeManager.Presentation/Program.cs | 1 + .../{ => Components}/NavMenuViewModel.cs | 4 +- .../Components/NotificationsViewModel.cs | 88 +++++++++++++++++++ .../ViewModels/DashboardViewModel.cs | 20 ----- .../ViewModels/HomeViewModel.cs | 20 ----- .../{ => Pages}/AddClothingItemViewModel.cs | 7 +- .../ViewModels/Pages/DashboardViewModel.cs | 10 +++ .../ViewModels/Pages/HomeViewModel.cs | 10 +++ .../ViewModels/{ => Pages}/LoginViewModel.cs | 5 +- .../{ => Pages}/MainLayoutViewModel.cs | 3 +- .../{ => Pages}/OnboardingViewModel.cs | 11 +-- .../ViewModels/{ => Pages}/SignupViewModel.cs | 5 +- .../{ => Pages}/WardrobeViewModel.cs | 7 +- WardrobeManager.Presentation/_Imports.razor | 3 +- .../StaticResources/MiscMethodsTests.cs | 1 + .../Services/IMiscMethods.cs | 2 +- .../Services/MiscMethods.cs | 4 +- 37 files changed, 155 insertions(+), 161 deletions(-) rename WardrobeManager.Presentation/ViewModels/{ => Components}/NavMenuViewModel.cs (90%) create mode 100644 WardrobeManager.Presentation/ViewModels/Components/NotificationsViewModel.cs delete mode 100644 WardrobeManager.Presentation/ViewModels/DashboardViewModel.cs delete mode 100644 WardrobeManager.Presentation/ViewModels/HomeViewModel.cs rename WardrobeManager.Presentation/ViewModels/{ => Pages}/AddClothingItemViewModel.cs (93%) create mode 100644 WardrobeManager.Presentation/ViewModels/Pages/DashboardViewModel.cs create mode 100644 WardrobeManager.Presentation/ViewModels/Pages/HomeViewModel.cs rename WardrobeManager.Presentation/ViewModels/{ => Pages}/LoginViewModel.cs (89%) rename WardrobeManager.Presentation/ViewModels/{ => Pages}/MainLayoutViewModel.cs (94%) rename WardrobeManager.Presentation/ViewModels/{ => Pages}/OnboardingViewModel.cs (89%) rename WardrobeManager.Presentation/ViewModels/{ => Pages}/SignupViewModel.cs (92%) rename WardrobeManager.Presentation/ViewModels/{ => Pages}/WardrobeViewModel.cs (92%) diff --git a/WardrobeManager.Api.Tests/Services/ClothingServiceTests.cs b/WardrobeManager.Api.Tests/Services/ClothingServiceTests.cs index 9ecfab6..d56d102 100644 --- a/WardrobeManager.Api.Tests/Services/ClothingServiceTests.cs +++ b/WardrobeManager.Api.Tests/Services/ClothingServiceTests.cs @@ -11,6 +11,7 @@ using WardrobeManager.Api.Services.Interfaces; using WardrobeManager.Shared.DTOs; using WardrobeManager.Shared.Enums; +using WardrobeManager.Shared.Services; using WardrobeManager.Shared.StaticResources; namespace WardrobeManager.Api.Tests.Services; diff --git a/WardrobeManager.Api/Program.cs b/WardrobeManager.Api/Program.cs index 936fed3..5f2f047 100644 --- a/WardrobeManager.Api/Program.cs +++ b/WardrobeManager.Api/Program.cs @@ -13,6 +13,7 @@ using WardrobeManager.Api.Services.Implementation; using WardrobeManager.Api.Services.Interfaces; using WardrobeManager.Shared.DTOs; +using WardrobeManager.Shared.Services; using WardrobeManager.Shared.StaticResources; #endregion diff --git a/WardrobeManager.Api/Services/Implementation/ClothingService.cs b/WardrobeManager.Api/Services/Implementation/ClothingService.cs index 153d2df..3ed8347 100644 --- a/WardrobeManager.Api/Services/Implementation/ClothingService.cs +++ b/WardrobeManager.Api/Services/Implementation/ClothingService.cs @@ -11,6 +11,7 @@ using WardrobeManager.Shared.DTOs; using WardrobeManager.Shared.Enums; using WardrobeManager.Shared.Models; +using WardrobeManager.Shared.Services; using WardrobeManager.Shared.StaticResources; #endregion diff --git a/WardrobeManager.Presentation.Tests/ViewModels/AddClothingItemViewModelTests.cs b/WardrobeManager.Presentation.Tests/ViewModels/AddClothingItemViewModelTests.cs index ac8f055..bb6177a 100644 --- a/WardrobeManager.Presentation.Tests/ViewModels/AddClothingItemViewModelTests.cs +++ b/WardrobeManager.Presentation.Tests/ViewModels/AddClothingItemViewModelTests.cs @@ -8,6 +8,8 @@ using WardrobeManager.Shared.StaticResources; using Blazing.Mvvm.Components; using Microsoft.Extensions.Configuration; +using WardrobeManager.Presentation.ViewModels.Pages; +using WardrobeManager.Shared.Services; namespace WardrobeManager.Presentation.Tests.ViewModels; diff --git a/WardrobeManager.Presentation.Tests/ViewModels/DashboardViewModelTests.cs b/WardrobeManager.Presentation.Tests/ViewModels/DashboardViewModelTests.cs index 5d773d0..b18a7f6 100644 --- a/WardrobeManager.Presentation.Tests/ViewModels/DashboardViewModelTests.cs +++ b/WardrobeManager.Presentation.Tests/ViewModels/DashboardViewModelTests.cs @@ -1,5 +1,6 @@ using FluentAssertions; using WardrobeManager.Presentation.ViewModels; +using WardrobeManager.Presentation.ViewModels.Pages; namespace WardrobeManager.Presentation.Tests.ViewModels; diff --git a/WardrobeManager.Presentation.Tests/ViewModels/HomeViewModelTests.cs b/WardrobeManager.Presentation.Tests/ViewModels/HomeViewModelTests.cs index 57b4046..35b1f91 100644 --- a/WardrobeManager.Presentation.Tests/ViewModels/HomeViewModelTests.cs +++ b/WardrobeManager.Presentation.Tests/ViewModels/HomeViewModelTests.cs @@ -1,5 +1,6 @@ using FluentAssertions; using WardrobeManager.Presentation.ViewModels; +using WardrobeManager.Presentation.ViewModels.Pages; namespace WardrobeManager.Presentation.Tests.ViewModels; diff --git a/WardrobeManager.Presentation.Tests/ViewModels/LoginViewModelTests.cs b/WardrobeManager.Presentation.Tests/ViewModels/LoginViewModelTests.cs index 8779bb3..884eea0 100644 --- a/WardrobeManager.Presentation.Tests/ViewModels/LoginViewModelTests.cs +++ b/WardrobeManager.Presentation.Tests/ViewModels/LoginViewModelTests.cs @@ -11,6 +11,7 @@ using WardrobeManager.Shared.Models; using Microsoft.AspNetCore.Components.Authorization; using System.Security.Claims; +using WardrobeManager.Presentation.ViewModels.Pages; namespace WardrobeManager.Presentation.Tests.ViewModels; diff --git a/WardrobeManager.Presentation.Tests/ViewModels/NavBarViewModelTests.cs b/WardrobeManager.Presentation.Tests/ViewModels/NavBarViewModelTests.cs index 957ef5e..3044803 100644 --- a/WardrobeManager.Presentation.Tests/ViewModels/NavBarViewModelTests.cs +++ b/WardrobeManager.Presentation.Tests/ViewModels/NavBarViewModelTests.cs @@ -7,6 +7,8 @@ using WardrobeManager.Presentation.ViewModels; using WardrobeManager.Presentation.Tests.Helpers; using Microsoft.AspNetCore.Components.Authorization; +using WardrobeManager.Presentation.ViewModels.Components; +using WardrobeManager.Presentation.ViewModels.Pages; namespace WardrobeManager.Presentation.Tests.ViewModels; diff --git a/WardrobeManager.Presentation.Tests/ViewModels/SignupViewModelTests.cs b/WardrobeManager.Presentation.Tests/ViewModels/SignupViewModelTests.cs index 722d1b7..22de8ba 100644 --- a/WardrobeManager.Presentation.Tests/ViewModels/SignupViewModelTests.cs +++ b/WardrobeManager.Presentation.Tests/ViewModels/SignupViewModelTests.cs @@ -7,6 +7,7 @@ using WardrobeManager.Presentation.Identity.Models; using WardrobeManager.Presentation.Services.Interfaces; using WardrobeManager.Presentation.ViewModels; +using WardrobeManager.Presentation.ViewModels.Pages; using WardrobeManager.Shared.Enums; using WardrobeManager.Shared.Models; diff --git a/WardrobeManager.Presentation.Tests/ViewModels/WardrobeViewModelTests.cs b/WardrobeManager.Presentation.Tests/ViewModels/WardrobeViewModelTests.cs index fadc699..c0fae7a 100644 --- a/WardrobeManager.Presentation.Tests/ViewModels/WardrobeViewModelTests.cs +++ b/WardrobeManager.Presentation.Tests/ViewModels/WardrobeViewModelTests.cs @@ -6,6 +6,7 @@ using WardrobeManager.Presentation.Tests.Helpers; using WardrobeManager.Shared.DTOs; using Blazing.Mvvm.Components; +using WardrobeManager.Presentation.ViewModels.Pages; namespace WardrobeManager.Presentation.Tests.ViewModels; diff --git a/WardrobeManager.Presentation/Components/Shared/Notifications.razor b/WardrobeManager.Presentation/Components/Shared/Notifications.razor index e9f8cd2..5295370 100644 --- a/WardrobeManager.Presentation/Components/Shared/Notifications.razor +++ b/WardrobeManager.Presentation/Components/Shared/Notifications.razor @@ -1,25 +1,24 @@ @namespace WardrobeManager.Presentation.Components.Shared -@inject INotificationService _notificationService - +@inherits MvvmComponentBase
@if (_notificationService.Notifications.Count > 5) { -
@@ -47,76 +46,5 @@ @code { - protected override async Task OnInitializedAsync() - { - _notificationService.OnChange += StateHasChanged; - // this runs the callback method supplied every 5 seconds. it does not wait for the last - // call to the method to finish. this can cause race conditions. it should be fine though - var _timer = new Timer(TryToClearNotifications, null, TimeSpan.Zero, TimeSpan.FromSeconds(5)); - } - - // Go through all notifications and try to remove the non-critical ones - private void TryToClearNotifications(object? state) - { - var notifications = _notificationService.Notifications; - - foreach (var notification in notifications) - { - TimeSpan difference = DateTime.UtcNow - notification.CreationDate; - - if (difference.TotalSeconds > 10 && notification.Type != NotificationType.Warning && notification.Type != NotificationType.Error) - { - _notificationService.RemoveNotification(notification); - } - } - } - - private void ClearAllNotifications() - { - foreach (var notification in _notificationService.Notifications) - { - _notificationService.RemoveNotification(notification); - } - } - - private void Dismiss(NotificationMessage notification) - { - _notificationService.RemoveNotification(notification); - } - - public void Dispose() - { - _notificationService.OnChange -= StateHasChanged; - } - - public ButtonType GetNotificationButtonType(NotificationType type) - { - return type switch - { - NotificationType.Error => ButtonType.Destructive, - _ => ButtonType.Outline - }; - } - - public string GetNotificationCss(NotificationType type) - { - return type switch - { - NotificationType.Success => "text-[#28a745]", - NotificationType.Warning => "text-[#ffc107]", - NotificationType.Error => "text-[#dc3545]", - _ => "text-[#007bff]", // default is 'info' colour - }; - } - - private string GetTruncatedMessage(NotificationMessage notification) - { - if (notification.Message.Length >= 40) - { - return notification.Message.Substring(0, 36) + "..."; - } - - return notification.Message; - } } diff --git a/WardrobeManager.Presentation/Layout/MainLayout.razor b/WardrobeManager.Presentation/Layout/MainLayout.razor index b9814e6..8811cf6 100644 --- a/WardrobeManager.Presentation/Layout/MainLayout.razor +++ b/WardrobeManager.Presentation/Layout/MainLayout.razor @@ -1,4 +1,4 @@ -@inherits MvvmLayoutComponentBase +@inherits MvvmLayoutComponentBase diff --git a/WardrobeManager.Presentation/Layout/NavMenu.razor b/WardrobeManager.Presentation/Layout/NavMenu.razor index db2961e..3cad421 100644 --- a/WardrobeManager.Presentation/Layout/NavMenu.razor +++ b/WardrobeManager.Presentation/Layout/NavMenu.razor @@ -3,7 +3,7 @@ @inject NavigationManager Navigation @inject IJSRuntime JsRuntime -@inherits MvvmComponentBase +@inherits MvvmComponentBase