diff --git a/Front.csproj b/Front.csproj index 2548224..08512f3 100644 --- a/Front.csproj +++ b/Front.csproj @@ -27,6 +27,8 @@ + + diff --git a/Program.cs b/Program.cs index e7ddd79..8b29c5e 100644 --- a/Program.cs +++ b/Program.cs @@ -37,11 +37,8 @@ builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); -// builder.Services.AddRazorPages(); -// builder.Services.AddServerSideBlazor(); -builder.Services.AddScoped(); -builder.Services.AddScoped(); -builder.Services.AddScoped(); +builder.Services.AddScoped(); +builder.Services.AddScoped(); await builder.Build().RunAsync(); diff --git a/Program/Layout/MainLayout.razor b/Program/Layout/MainLayout.razor index fe1c403..03b549c 100644 --- a/Program/Layout/MainLayout.razor +++ b/Program/Layout/MainLayout.razor @@ -9,18 +9,26 @@ @if(isAcademy) {
- - -
-
- + @if (!isIntro && UserStateService.isLogin) + { + -
+
+
+ +
+
+ @Body +
+
+ } + else + { +
@Body -
-
+ + }
} else diff --git a/Program/Layout/MainLayout.razor.cs b/Program/Layout/MainLayout.razor.cs index 71f7924..56b053c 100644 --- a/Program/Layout/MainLayout.razor.cs +++ b/Program/Layout/MainLayout.razor.cs @@ -4,26 +4,24 @@ using Microsoft.AspNetCore.Components.Routing; using Front.Program.Views.Project; using Front.Program.Views.Academy; using Front.Program.Services; +using Front.Program.ViewModels; namespace Front.Program.Layout; public partial class MainLayout : LayoutComponentBase, IDisposable { - [Inject] - NavigationManager Navigation { get; set; } = default!; - - [Inject] - LoadingService LoadingService { get; set; } = default!; - - [Inject] - StorageService StorageService { get; set; } = default!; + [Inject] NavigationManager Navigation { get; set; } = default!; + [Inject] LoadingService LoadingService { get; set; } = default!; + [Inject] UserStateService UserStateService { get; set; } = default!; // 경로의 시작 부분 // protected bool isHidePrjTop => Navigation.ToBaseRelativePath(Navigation.Uri).StartsWith("auth", StringComparison.OrdinalIgnoreCase); - // 경로의 끝 부분 protected bool isHidePrjTop => Navigation.ToBaseRelativePath(Navigation.Uri).EndsWith("auth", StringComparison.OrdinalIgnoreCase); protected bool isAcademy => Navigation.ToBaseRelativePath(Navigation.Uri).StartsWith("am", StringComparison.OrdinalIgnoreCase); + + // 경로 일치 + protected bool isIntro => Navigation.ToBaseRelativePath(Navigation.Uri).Equals("am/intro", StringComparison.OrdinalIgnoreCase); protected override void OnInitialized() { @@ -36,37 +34,6 @@ public partial class MainLayout : LayoutComponentBase, IDisposable private async void HandleLocationChanged(object? sender, LocationChangedEventArgs e) { LoadingService.HideNavigationLoading(); - // - // var uri = Navigation.ToAbsoluteUri(Navigation.Uri); - // Console.WriteLine($"리다이렉트된 URI: {uri}"); - // - // if (uri.Query.Contains("auth=")) - // { - // var query = uri.Query.TrimStart('?'); - // var parameters = query.Split('&') - // .Select(p => p.Split('=')) - // .Where(p => p.Length == 2) - // .ToDictionary(p => p[0], p => p[1]); - // - // if (parameters.TryGetValue("auth", out var auth)) - // { - // Console.WriteLine($"auth 파라미터 값: {auth}"); - // if (auth == "true") - // { - // await StorageService.SetItemAsync("IsLogin", "true"); - // Console.WriteLine("로그인 상태를 true로 설정했습니다."); - // } - // else - // { - // await StorageService.RemoveItemAsync("IsLogin"); - // Console.WriteLine("로그인 상태를 제거했습니다."); - // } - // - // // 파라미터를 제거하고 리다이렉트 - // var baseUri = uri.GetLeftPart(UriPartial.Path); - // Navigation.NavigateTo(baseUri, forceLoad: false); - // } - // } } public void Dispose() diff --git a/Program/Models/AcademyModels.cs b/Program/Models/AcademyModels.cs new file mode 100644 index 0000000..3623fa1 --- /dev/null +++ b/Program/Models/AcademyModels.cs @@ -0,0 +1,22 @@ +using System.ComponentModel.DataAnnotations; + +namespace Front.Program.Models; + +public class Academy +{ + public required string bid { get; set; } + public string business_name { get; set; } = string.Empty; + public string business_owner { get; set; } = string.Empty; + public string businessOwnerUID { get; set; } = string.Empty; + public string business_number { get; set; } = string.Empty; + public DateTime business_date { get; set; } + public string business_address { get; set; } = string.Empty; + public string business_contact { get; set; } = string.Empty; + public string uid { get; set; } = string.Empty; +} + +public class SimpleAcademy +{ + public required string bid { get; set; } + public string business_name { get; set; } = string.Empty; +} \ No newline at end of file diff --git a/Program/Services/LoadingService.cs b/Program/Services/LoadingService.cs index 2e55f18..07e8a2c 100644 --- a/Program/Services/LoadingService.cs +++ b/Program/Services/LoadingService.cs @@ -1,20 +1,21 @@ -using Front.Program.Views.Project; +// using Front.Program.Views.Project.Common; + +using Front.Program.Models; using Microsoft.AspNetCore.Components; namespace Front.Program.Services; +// 뷰를 참조 안하고도 로딩 상태를 알 수 있게 바꾸기 public class LoadingService { public bool IsLoading { get; private set; } - public IndicateType CurrentType { get; private set; } = IndicateType.Page; private bool isNavigationLoading { get; set; } public event Action? OnChange; - public void ShowLoading(IndicateType type = IndicateType.Page, bool isNavigation = false) + public void ShowLoading(bool isNavigation = false) { IsLoading = true; - CurrentType = type; isNavigationLoading = isNavigation; NotifyStateChanged(); } diff --git a/Program/Services/UserService.cs b/Program/Services/UserService.cs deleted file mode 100644 index 6fef32d..0000000 --- a/Program/Services/UserService.cs +++ /dev/null @@ -1,123 +0,0 @@ -using System.Text.Json; -using Front.Program.Models; -using Microsoft.JSInterop; - -namespace Front.Program.Services; - -public class UserService -{ - private readonly StorageService _storageService; - private readonly SecureService _secureService; - private readonly IJSRuntime _js; - private readonly ILogger _logger; - - public UserService( - StorageService storageService, - SecureService secureService, - IJSRuntime js, - ILogger logger) - { - _storageService = storageService; - _secureService = secureService; - _js = js; - _logger = logger; - } - - - public async Task<(bool success, UserData? userData)> GetUserData() - { - try - { - // 1. 먼저 저장된 데이터 확인 - var encryptedUserData = await _storageService.GetItemAsync("USER_DATA"); - if (!string.IsNullOrEmpty(encryptedUserData)) - { - try - { - var decryptedUserData = await _secureService.DecryptAsync(encryptedUserData); - var userData = JsonSerializer.Deserialize(decryptedUserData); - if (userData != null && !string.IsNullOrEmpty(userData.Name)) - { - _logger.LogInformation("저장된 사용자 데이터 로드 성공"); - return (true, userData); - } - } - catch (Exception ex) - { - _logger.LogWarning($"저장된 사용자 데이터 복호화 실패: {ex.Message}"); - await _storageService.RemoveItemAsync("USER_DATA"); - } - } - - // 2. API 호출 - var headerValue = await _storageService.GetItemAsync("Web_AM_Connect_Key"); - if (string.IsNullOrEmpty(headerValue)) - { - _logger.LogWarning("연결 키가 없습니다"); - return (false, null); - } - - _logger.LogInformation("세션 API 호출 시작"); - var response = await _js.InvokeAsync("fetchWithHeaderAndReturnUrl", - "/api/v1/in/user/auth/session", - "GET", - "Web_AM_Connect_Key", - headerValue); - - if (response.TryGetProperty("data", out var dataElement)) - { - try - { - // 전체 데이터 암호화 저장 - var userDataJson = dataElement.ToString(); - var userData = JsonSerializer.Deserialize(userDataJson); - - if (userData != null && !string.IsNullOrEmpty(userData.Name)) - { - var encryptedData = await _secureService.EncryptAsync(userDataJson); - await _storageService.SetItemAsync("USER_DATA", encryptedData); - await _storageService.SetItemAsync("Web_AM_Connect_Key", headerValue); - - _logger.LogInformation($"사용자 데이터 저장 성공: {userData.Name}"); - return (true, userData); - } - else - { - _logger.LogWarning("사용자 데이터에 필수 정보가 없습니다"); - return (false, null); - } - } - catch (Exception ex) - { - _logger.LogError($"사용자 데이터 처리 중 오류: {ex.Message}"); - return (false, null); - } - } - - _logger.LogWarning("사용자 데이터를 찾을 수 없습니다"); - return (false, null); - } - catch (Exception ex) - { - _logger.LogError($"사용자 데이터 조회 중 오류: {ex.Message}"); - return (false, null); - } - } - - public async Task ClearUserData() - { - try - { - await _storageService.RemoveItemAsync("USER_DATA"); - await _storageService.RemoveItemAsync("USER"); - await _storageService.RemoveItemAsync("Web_AM_Connect_Key"); - _logger.LogInformation("사용자 데이터 삭제 성공"); - return true; - } - catch (Exception ex) - { - _logger.LogError($"사용자 데이터 삭제 중 오류: {ex.Message}"); - return false; - } - } -} \ No newline at end of file diff --git a/Program/ViewModels/UserViewModel.cs b/Program/Services/UserStateService.cs similarity index 73% rename from Program/ViewModels/UserViewModel.cs rename to Program/Services/UserStateService.cs index 91388fd..e209bef 100644 --- a/Program/ViewModels/UserViewModel.cs +++ b/Program/Services/UserStateService.cs @@ -5,12 +5,14 @@ using Microsoft.JSInterop; namespace Front.Program.ViewModels; -public class UserViewModel(StorageService _storageService,SecureService _secureService, IJSRuntime _js) +public class UserStateService(StorageService _storageService,SecureService _secureService, IJSRuntime _js) { public UserData UserData { get; set; } = new UserData(); + public bool isFirstCheck { get; set; } = false; public bool isLogin { get; set; } = false; + public async Task<(bool success, UserData? userData)> GetUserDataFromStorageAsync() { try @@ -101,41 +103,48 @@ public class UserViewModel(StorageService _storageService,SecureService _secureS public async Task GetUserDataAsync() { - Console.WriteLine("GetUserDataAsync 호출됨"); - // 로그인 상태가 아니라면 애초에 할 필요 없음 - if (await _storageService.GetItemAsync("IsLogin") != "true") + try { - isLogin = false; - return false; - } - - var userDataForm = await GetUserDataFromStorageAsync(); - - if (userDataForm.success && userDataForm.userData != null) - { - // 사용자 데이터가 성공적으로 로드되었을 때의 로직 - UserData = userDataForm.userData; - isLogin = true; - return true; - } - else - { - var userDataFromServer = await GetUserDataFromServerAsync(); - if (userDataFromServer.success && userDataFromServer.userData != null) + Console.WriteLine("GetUserDataAsync 호출됨"); + // 로그인 상태가 아니라면 애초에 할 필요 없음 + if (await _storageService.GetItemAsync("IsLogin") != "true") { - // 서버에서 사용자 데이터를 성공적으로 로드했을 때의 로직 - UserData = userDataFromServer.userData; + isLogin = false; + return false; + } + + var userDataForm = await GetUserDataFromStorageAsync(); + + if (userDataForm.success && userDataForm.userData != null) + { + // 사용자 데이터가 성공적으로 로드되었을 때의 로직 + UserData = userDataForm.userData; isLogin = true; return true; } else { - // 사용자 데이터를 로드하지 못했을 때의 로직 - Console.WriteLine("사용자 데이터를 로드하지 못했습니다."); - isLogin = false; - return false; + var userDataFromServer = await GetUserDataFromServerAsync(); + if (userDataFromServer.success && userDataFromServer.userData != null) + { + // 서버에서 사용자 데이터를 성공적으로 로드했을 때의 로직 + UserData = userDataFromServer.userData; + isLogin = true; + return true; + } + else + { + // 사용자 데이터를 로드하지 못했을 때의 로직 + Console.WriteLine("사용자 데이터를 로드하지 못했습니다."); + isLogin = false; + return false; + } } } + finally + { + if (!isFirstCheck) isFirstCheck = true; + } } public async Task ClearUserData() diff --git a/Program/Views/Academy/AcademyIntro.razor b/Program/Views/Academy/AcademyIntro.razor index 1a0ef2b..b52829e 100644 --- a/Program/Views/Academy/AcademyIntro.razor +++ b/Program/Views/Academy/AcademyIntro.razor @@ -1,29 +1,67 @@ @page "/am/intro" -
+
-
+
-
-
-
-
+
+
+
+
-

학원을 위한 통합 플랫폼

-
- + + @if (!UserStateService.isLogin) + { +

+ 학원을 위한 통합 플랫폼 +

+ +
+ +
+ } + else + { +
+

+ @UserStateService.UserData.Name 님, 안녕하세요!
+ 학원을 선택해주세요.
+

+
+ @foreach (var academy in academyItems) + { + +
+ @academy.business_name + + + +
+
+ } +
+
+ } + + @*
*@ +
+ -
-

Terms of Service · Privacy Policy · Contact Us

-

© 2024 AcaMate. All rights reserved.

+ +

+ © 2024 AcaMate. All rights reserved. +

diff --git a/Program/Views/Academy/AcademyIntro.razor.cs b/Program/Views/Academy/AcademyIntro.razor.cs index d123ded..3f99336 100644 --- a/Program/Views/Academy/AcademyIntro.razor.cs +++ b/Program/Views/Academy/AcademyIntro.razor.cs @@ -1,7 +1,88 @@ +using Front.Program.Models; +using Front.Program.Services; +using Front.Program.ViewModels; using Microsoft.AspNetCore.Components; +using Microsoft.AspNetCore.Components.Routing; namespace Front.Program.Views.Academy; -public partial class AcademyIntro : ComponentBase +public partial class AcademyIntro : ComponentBase, IDisposable { + [Inject] NavigationManager Navigation { get; set; } = default!; + [Inject] StorageService StorageService { get; set; } = default!; + [Inject] QueryParamService QueryParamService { get; set; } = default!; + [Inject] UserStateService UserStateService { get; set; } = default!; + + private bool _isProcessing = false; + + + protected Models.SimpleAcademy[] academyItems = Array.Empty(); + + protected override async void OnInitialized() + { + Navigation.LocationChanged += HandleLocationChanged; + HandleLocationChanged(this, new LocationChangedEventArgs(Navigation.Uri, false)); + if (!UserStateService.isFirstCheck) await UserStateService.GetUserDataAsync(); + + academyItems = new[] + { + new SimpleAcademy{ bid = "AA0000", business_name = "테스트 학원1"}, + new SimpleAcademy{ bid = "AA0001", business_name = "테스트 학원2"}, + new SimpleAcademy{ bid = "AA0002", business_name = "테스트 학원3"}, + new SimpleAcademy{ bid = "AA0003", business_name = "테스트 학원4"}, + new SimpleAcademy{ bid = "AA0004", business_name = "테스트 학원5"}, + new SimpleAcademy{ bid = "AA0005", business_name = "테스트 학원6"}, + new SimpleAcademy{ bid = "AA0006", business_name = "테스트 학원7"}, + + }; + + await InvokeAsync(StateHasChanged); + } + + public void Dispose() + { + Navigation.LocationChanged -= HandleLocationChanged; + } + + private async void HandleLocationChanged(object? sender, LocationChangedEventArgs e) + { + try + { + // 다중 실행 방지 + if (_isProcessing) return; + _isProcessing = true; + + var uri = Navigation.ToAbsoluteUri(Navigation.Uri); + Console.WriteLine($"리다이렉트된 URI: {uri}"); + + // 쿼리 파라미터가 있는 경우에만 처리 + if (!string.IsNullOrEmpty(uri.Query)) + { + var queryParam = QueryParamService.ParseQueryParam(uri); + await QueryParamService.AuthCheck(queryParam, StorageService); + + // 유저 정보 확인하는거 (로그인 했으니 값 가져와야지) + await UserStateService.GetUserDataAsync(); + + // 쿼리 파라미터를 제거한 기본 URI로 리다이렉트 + var baseUri = uri.GetLeftPart(UriPartial.Path); + Console.WriteLine($"리다이렉트할 URI: {baseUri}"); + await InvokeAsync(StateHasChanged); // StateHasChanged를 호출하여 UI 업데이트 + Navigation.NavigateTo(baseUri, forceLoad: false); + } + } + catch (Exception ex) + { + Console.WriteLine($"Error in HandleLocationChanged: {ex.Message}"); + } + finally + { + _isProcessing = false; + } + } + + protected void OnClickLogin() + { + Navigation.NavigateTo("/am/auth"); + } } \ No newline at end of file diff --git a/Program/Views/Academy/TopNavAcademy.razor b/Program/Views/Academy/TopNavAcademy.razor index 405f9e3..0d18900 100644 --- a/Program/Views/Academy/TopNavAcademy.razor +++ b/Program/Views/Academy/TopNavAcademy.razor @@ -1,13 +1,36 @@
-
- +
+ + + @if (isAcademyDropdownOpen) + { +
+
+

학원 정보

+
+
+ @foreach (var academy in academyItems) + { + + @academy.business_name + + } +
+
+ }
- \ No newline at end of file +
diff --git a/Program/Views/Academy/TopNavAcademy.razor.cs b/Program/Views/Academy/TopNavAcademy.razor.cs index 43f1486..5dfce84 100644 --- a/Program/Views/Academy/TopNavAcademy.razor.cs +++ b/Program/Views/Academy/TopNavAcademy.razor.cs @@ -1,22 +1,27 @@ using Front.Program.ViewModels; +using Front.Program.Services; using Microsoft.AspNetCore.Components; +using System.Net.Http.Json; +using System.Runtime.InteropServices.JavaScript; +using System.Text.Json; +using Front.Program.Models; namespace Front.Program.Views.Academy; public partial class TopNavAcademy : ComponentBase { - [Inject] UserViewModel UserViewModel { get; set; } = default!; + [Inject] UserStateService UserStateService { get; set; } = default!; - protected bool isOpen = false; + protected bool isAcademyDropdownOpen = false; + protected Models.SimpleAcademy[] academyItems = Array.Empty(); protected override async Task OnInitializedAsync() { Console.WriteLine("TOPNAV_OnInitializedAsync"); - - if (string.IsNullOrEmpty(UserViewModel.UserData.Name)) - { - await UserViewModel.GetUserDataAsync(); - } + } + + protected void ToggleAcademyDropdown() { + isAcademyDropdownOpen = !isAcademyDropdownOpen; } } \ No newline at end of file diff --git a/Program/Views/Project/About.razor.cs b/Program/Views/Project/About.razor.cs index 087f938..6c5e0df 100644 --- a/Program/Views/Project/About.razor.cs +++ b/Program/Views/Project/About.razor.cs @@ -17,7 +17,7 @@ public partial class About : ComponentBase, IDisposable [Inject] QueryParamService QueryParamService { get; set; } = default!; - [Inject] UserViewModel UserViewModel { get; set; } = default!; + [Inject] UserStateService UserStateService { get; set; } = default!; private bool _isProcessing = false; @@ -32,12 +32,6 @@ public partial class About : ComponentBase, IDisposable Navigation.LocationChanged -= HandleLocationChanged; } - private async Task OnClickEvent() - { - // NavigationManager.NavigateTo("/redirectpage"); - Console.WriteLine("Redirecting to redirect page"); - } - private async void HandleLocationChanged(object? sender, LocationChangedEventArgs e) { try @@ -56,7 +50,7 @@ public partial class About : ComponentBase, IDisposable await QueryParamService.AuthCheck(queryParam, StorageService); // 유저 정보 확인하는거 (로그인 했으니 값 가져와야지) - await UserViewModel.GetUserDataAsync(); + await UserStateService.GetUserDataAsync(); // 쿼리 파라미터를 제거한 기본 URI로 리다이렉트 var baseUri = uri.GetLeftPart(UriPartial.Path); diff --git a/Program/Views/Project/Common/PageIndicator.razor b/Program/Views/Project/Common/PageIndicator.razor new file mode 100644 index 0000000..0d4fb88 --- /dev/null +++ b/Program/Views/Project/Common/PageIndicator.razor @@ -0,0 +1,5 @@ +
+
+
+
+
\ No newline at end of file diff --git a/Program/Views/Project/Common/PageIndicator.razor.cs b/Program/Views/Project/Common/PageIndicator.razor.cs new file mode 100644 index 0000000..3669762 --- /dev/null +++ b/Program/Views/Project/Common/PageIndicator.razor.cs @@ -0,0 +1,7 @@ +using Front.Program.Models; +using Microsoft.AspNetCore.Components; + +namespace Front.Program.Views.Project.Common; + +public partial class PageIndicator : ComponentBase +{ } diff --git a/Program/Views/Project/RedirectPage.razor b/Program/Views/Project/Common/RedirectPage.razor similarity index 100% rename from Program/Views/Project/RedirectPage.razor rename to Program/Views/Project/Common/RedirectPage.razor diff --git a/Program/Views/Project/RedirectPage.razor.cs b/Program/Views/Project/Common/RedirectPage.razor.cs similarity index 86% rename from Program/Views/Project/RedirectPage.razor.cs rename to Program/Views/Project/Common/RedirectPage.razor.cs index 94f9f91..2f79166 100644 --- a/Program/Views/Project/RedirectPage.razor.cs +++ b/Program/Views/Project/Common/RedirectPage.razor.cs @@ -1,6 +1,6 @@ using Microsoft.AspNetCore.Components; -namespace Front.Program.Views.Project; +namespace Front.Program.Views.Project.Common; public partial class RedirectPage : ComponentBase { diff --git a/Program/Views/Project/TopBanner.razor b/Program/Views/Project/Common/TopBanner.razor similarity index 100% rename from Program/Views/Project/TopBanner.razor rename to Program/Views/Project/Common/TopBanner.razor diff --git a/Program/Views/Project/TopBanner.razor.cs b/Program/Views/Project/Common/TopBanner.razor.cs similarity index 66% rename from Program/Views/Project/TopBanner.razor.cs rename to Program/Views/Project/Common/TopBanner.razor.cs index e677b5a..3cf6671 100644 --- a/Program/Views/Project/TopBanner.razor.cs +++ b/Program/Views/Project/Common/TopBanner.razor.cs @@ -1,6 +1,6 @@ using Microsoft.AspNetCore.Components; -namespace Front.Program.Views.Project; +namespace Front.Program.Views.Project.Common; public partial class TopBanner : ComponentBase { diff --git a/Program/Views/Project/TopProjectNav.razor b/Program/Views/Project/Common/TopProjectNav.razor similarity index 97% rename from Program/Views/Project/TopProjectNav.razor rename to Program/Views/Project/Common/TopProjectNav.razor index 9332365..b3636f3 100644 --- a/Program/Views/Project/TopProjectNav.razor +++ b/Program/Views/Project/Common/TopProjectNav.razor @@ -11,7 +11,7 @@ Join What's New
- @if (!UserViewModel.isLogin) + @if (!UserStateService.isLogin) {