forked from AcaMate/AcaMate_Web
[✨] 사이드 뷰 개발
This commit is contained in:
parent
3cbe24216d
commit
6342324108
|
@ -51,7 +51,8 @@ builder.Services.AddScoped<SecureService>();
|
|||
builder.Services.AddScoped<StorageService>();
|
||||
builder.Services.AddScoped<QueryParamService>();
|
||||
builder.Services.AddScoped<LoadingService>();
|
||||
builder.Services.AddScoped<UserStateService>();
|
||||
|
||||
builder.Services.AddSingleton<UserStateService>();
|
||||
|
||||
|
||||
// builder.Services.AddSingleton<LoggerService>(sp
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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<Models.SimpleAcademy>();
|
||||
|
||||
|
||||
|
@ -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<List<SimpleAcademy>>("/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);
|
||||
}
|
||||
}
|
|
@ -5,9 +5,9 @@
|
|||
</div>
|
||||
<div>
|
||||
<!-- 회원 이름이 오는 곳 -->
|
||||
<div class="text-gray-900 text-base font-medium">AcaMate</div>
|
||||
<div class="text-gray-900 text-base font-medium">@UserName</div>
|
||||
<!-- 회원 유형이 올 곳 -->
|
||||
<p class="text-gray-600 text-sm">Parent</p>
|
||||
<p class="text-gray-600 text-sm">@UserType</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,7 +1,13 @@
|
|||
using Front.Program.ViewModels;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
|
||||
namespace Front.Program.Views.Academy.Common;
|
||||
|
||||
public partial class LeftSideAcademy : ComponentBase
|
||||
{
|
||||
}
|
||||
[Inject]
|
||||
private UserStateService UserStateService { get; set; }
|
||||
|
||||
private string UserName => UserStateService.UserData?.Name ?? "AcaMate";
|
||||
private string UserType => UserStateService.UserData?.Type ?? "Parent";
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<div id="AcademyDrop" class="relative flex items-center gap-4 text-[#111418] flex-1">
|
||||
|
||||
<button class="flex items-center gap-2 hover:text-blue-600" @onclick="ToggleAcademyDropdown">
|
||||
<h2 class="hidden md:block text-text-title text-lg font-bold leading-tight tracking-[-0.015em]">AcaMate</h2>
|
||||
<h2 class="hidden md:block text-text-title text-lg font-bold leading-tight tracking-[-0.015em]">@currentAcademyName</h2>
|
||||
<img src="Resources/Images/Icon/Down.png" alt="아래"
|
||||
class="w-6 h-6 object-cover transition-transform duration-200 @(isAcademyDropdownOpen ? "rotate-180" : "")" />
|
||||
</button>
|
||||
|
@ -10,15 +10,12 @@
|
|||
@if (isAcademyDropdownOpen)
|
||||
{
|
||||
<div class="absolute top-full left-0 mt-2 w-64 bg-white rounded-lg shadow-lg py-2 z-50">
|
||||
<div class="px-4 py-2 border-b border-gray-200">
|
||||
<h3 class="font-semibold text-gray-900">학원 정보</h3>
|
||||
</div>
|
||||
<div class="max-h-60 overflow-y-auto">
|
||||
@foreach (var academy in academyItems)
|
||||
{
|
||||
<a href="/am/@academy.bid" class="block px-4 py-2 text-text-title hover:bg-gray-100">
|
||||
<div @onclick="() => SelectAcademy(academy)" class="cursor-pointer block px-4 py-2 text-text-title hover:bg-gray-100">
|
||||
@academy.name
|
||||
</a>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
@ -45,4 +42,4 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
|
@ -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<Models.SimpleAcademy>();
|
||||
|
||||
// 계산된 속성으로 변경
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user