diff --git a/Program.cs b/Program.cs index 68d1a9d..7a9cf60 100644 --- a/Program.cs +++ b/Program.cs @@ -51,7 +51,8 @@ builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); -builder.Services.AddScoped(); + +builder.Services.AddSingleton(); // builder.Services.AddSingleton(sp diff --git a/Program/Layout/MainLayout.razor.cs b/Program/Layout/MainLayout.razor.cs index 573f2a6..6f80ede 100644 --- a/Program/Layout/MainLayout.razor.cs +++ b/Program/Layout/MainLayout.razor.cs @@ -13,6 +13,9 @@ public partial class MainLayout : LayoutComponentBase, IDisposable [Inject] NavigationManager Navigation { get; set; } = default!; [Inject] LoadingService LoadingService { get; set; } = default!; [Inject] UserStateService UserStateService { get; set; } = default!; + + + private bool _isLoading = false; // 경로의 시작 부분 // protected bool isHidePrjTop => Navigation.ToBaseRelativePath(Navigation.Uri).StartsWith("auth", StringComparison.OrdinalIgnoreCase); @@ -28,23 +31,50 @@ public partial class MainLayout : LayoutComponentBase, IDisposable protected override async Task OnInitializedAsync() { + LoggerService.Write("MainLayout OnInitializedAsync 시작"); LoadingService.OnChange += StateHasChanged; Navigation.LocationChanged += HandleLocationChanged; HandleLocationChanged(this, new LocationChangedEventArgs(Navigation.Uri, false)); + + LoggerService.Write("MainLayout: UserStateService.GetUserDataAsync 호출 전"); + await UserStateService.GetUserDataAsync(); + LoggerService.Write($"MainLayout: UserStateService.isLogin 상태: {UserStateService.isLogin}"); + + // 학원 정보 로드 및 실패 시 처리 + var academyResult = await UserStateService.GetAcademy(); + LoadingService.ShowLoading(); + if (academyResult.success) + { + if (academyResult.simpleAcademy != null && academyResult.simpleAcademy.Any()) + { + UserStateService.academyItems = academyResult.simpleAcademy.ToArray(); + LoggerService.Write($"MainLayout: academyItems 로드 성공. {UserStateService.academyItems.Length}개"); + } + else + { + LoggerService.Write("MainLayout: 로드된 학원 정보가 없습니다."); + } + } + else + { + LoggerService.Write("MainLayout: 서버 세션에서 학원 정보 불러오기 실패. 사용자 상태 초기화."); + await UserStateService.ClearUserStateAsnyc(); + } + if (isAcademy) { if(!UserStateService.isLogin || UserStateService.UserData == null) { LoggerService.Write("로그인 상태가 아닙니다. 초기로 돌립니다."); - if (isIntro) - { - } //await UserStateService.ClearUserStateAsnyc(); + if (isIntro) { } else { await UserStateService.ClearUserStateAsnyc(); + LoadingService.HideLoading(); Navigation.NavigateTo("/"); } } + LoadingService.HideLoading(); } } diff --git a/Program/Services/UserStateService.cs b/Program/Services/UserStateService.cs index 01ec74a..223668c 100644 --- a/Program/Services/UserStateService.cs +++ b/Program/Services/UserStateService.cs @@ -2,16 +2,40 @@ using System.Text.Json; using Front.Program.Services; using Front.Program.Models; using Microsoft.JSInterop; +using System.ComponentModel; // INotifyPropertyChanged를 위해 추가 +using System.Runtime.CompilerServices; // CallerMemberName을 위해 추가 namespace Front.Program.ViewModels; public class UserStateService(StorageService _storageService, SecureService _secureService, APIService _APIService, - IJSRuntime _js) + IJSRuntime _js) : INotifyPropertyChanged { + public event PropertyChangedEventHandler? PropertyChanged; + + protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + } + + private Models.SimpleAcademy? _currentAcademy; + public Models.SimpleAcademy? CurrentAcademy + { + get => _currentAcademy; + set + { + if (_currentAcademy != value) + { + _currentAcademy = value; + OnPropertyChanged(); + } + } + } + public UserData UserData { get; set; } = new UserData(); public bool isFirstCheck { get; set; } = false; public bool isLogin { get; set; } = false; + public Models.SimpleAcademy[] academyItems = Array.Empty(); @@ -52,12 +76,17 @@ public class UserStateService(StorageService _storageService, SecureService _sec try { LoggerService.Write("GetUserDataAsync 호출됨"); - // 로그인 상태가 아니라면 애초에 할 필요 없음 - if (await _storageService.GetItemAsync("IsLogin") != "true") + var isLoginFromStorage = await _storageService.GetItemAsync("IsLogin"); + LoggerService.Write($"Storage에서 읽은 IsLogin 값: {isLoginFromStorage ?? "null"}"); + + // 로그인 상태가 아니라면 애초에 할 필요 없음 + if (isLoginFromStorage != "true") { isLogin = false; return false; } + + isLogin = true; var userDataForm = await GetUserDataFromStorageAsync(); @@ -65,7 +94,6 @@ public class UserStateService(StorageService _storageService, SecureService _sec { // 사용자 데이터가 성공적으로 로드되었을 때의 로직 UserData = userDataForm.userData; - isLogin = true; return true; } else @@ -75,7 +103,6 @@ public class UserStateService(StorageService _storageService, SecureService _sec { // 서버에서 사용자 데이터를 성공적으로 로드했을 때의 로직 UserData = userDataFromServer.userData; - isLogin = true; return true; } else @@ -130,7 +157,14 @@ public class UserStateService(StorageService _storageService, SecureService _sec { var data = await _APIService.GetConnectServerAsnyc>("/api/v1/in/user/academy"); if (data is { success: true, json: not null }) + { await _storageService.SetItemAsync("UsAcDt", data.json); + if (data.data != null && data.data.Any()) + { + academyItems = data.data.ToArray(); + CurrentAcademy = data.data.First(); // 첫 번째 학원을 현재 학원으로 설정 + } + } return (data.success, data.data); } } \ No newline at end of file diff --git a/Program/Views/Academy/Common/LeftSideAcademy.razor b/Program/Views/Academy/Common/LeftSideAcademy.razor index 30f4a05..3468244 100644 --- a/Program/Views/Academy/Common/LeftSideAcademy.razor +++ b/Program/Views/Academy/Common/LeftSideAcademy.razor @@ -5,9 +5,9 @@
-
AcaMate
+
@UserName
-

Parent

+

@UserType

diff --git a/Program/Views/Academy/Common/LeftSideAcademy.razor.cs b/Program/Views/Academy/Common/LeftSideAcademy.razor.cs index 93a0ce3..3cd0bb6 100644 --- a/Program/Views/Academy/Common/LeftSideAcademy.razor.cs +++ b/Program/Views/Academy/Common/LeftSideAcademy.razor.cs @@ -1,7 +1,13 @@ +using Front.Program.ViewModels; using Microsoft.AspNetCore.Components; namespace Front.Program.Views.Academy.Common; public partial class LeftSideAcademy : ComponentBase { -} \ No newline at end of file + [Inject] + private UserStateService UserStateService { get; set; } + + private string UserName => UserStateService.UserData?.Name ?? "AcaMate"; + private string UserType => UserStateService.UserData?.Type ?? "Parent"; +} diff --git a/Program/Views/Academy/Common/TopNavAcademy.razor b/Program/Views/Academy/Common/TopNavAcademy.razor index bb3923b..02ae2d7 100644 --- a/Program/Views/Academy/Common/TopNavAcademy.razor +++ b/Program/Views/Academy/Common/TopNavAcademy.razor @@ -2,7 +2,7 @@
@@ -10,15 +10,12 @@ @if (isAcademyDropdownOpen) {
-
-

학원 정보

-
@foreach (var academy in academyItems) { - + }
@@ -45,4 +42,4 @@
- + \ No newline at end of file diff --git a/Program/Views/Academy/Common/TopNavAcademy.razor.cs b/Program/Views/Academy/Common/TopNavAcademy.razor.cs index a2db69e..4f0f27f 100644 --- a/Program/Views/Academy/Common/TopNavAcademy.razor.cs +++ b/Program/Views/Academy/Common/TopNavAcademy.razor.cs @@ -1,3 +1,5 @@ + +using System.ComponentModel; using Front.Program.ViewModels; using Front.Program.Services; using Microsoft.AspNetCore.Components; @@ -8,26 +10,52 @@ using Front.Program.Models; namespace Front.Program.Views.Academy.Common; -public partial class TopNavAcademy : ComponentBase +public partial class TopNavAcademy : ComponentBase, IDisposable { [Inject] UserStateService UserStateService { get; set; } = default!; + [Inject] NavigationManager NavigationManager { get; set; } = default!; + protected bool isOpen = false; protected bool isAcademyDropdownOpen = false; - protected Models.SimpleAcademy[] academyItems = Array.Empty(); + + // 계산된 속성으로 변경 + protected Models.SimpleAcademy[] academyItems => UserStateService.academyItems; + protected string currentAcademyName => UserStateService.CurrentAcademy?.name ?? "학원을 선택하세요"; - protected override async Task OnInitializedAsync() + protected override void OnInitialized() { - LoggerService.Write("TOPNAV_OnInitializedAsync"); + UserStateService.PropertyChanged += OnUserStateServicePropertyChanged; + } + + public void Dispose() + { + UserStateService.PropertyChanged -= OnUserStateServicePropertyChanged; + } + + private void OnUserStateServicePropertyChanged(object? sender, PropertyChangedEventArgs e) + { + if (e.PropertyName == nameof(UserStateService.CurrentAcademy)) + { + StateHasChanged(); + } } protected void ToggleAcademyDropdown() { isAcademyDropdownOpen = !isAcademyDropdownOpen; } + private void SelectAcademy(SimpleAcademy academy) + { + UserStateService.CurrentAcademy = academy; // 현재 선택된 학원 업데이트 + isAcademyDropdownOpen = false; + NavigationManager.NavigateTo($"/am/main?bid={academy.bid}"); + + } + private void OnClickOutside() { if (isAcademyDropdownOpen) isAcademyDropdownOpen = false; StateHasChanged(); } -} \ No newline at end of file +}