From fc655e20c19208014733b272688aee62b3d9cb4f Mon Sep 17 00:00:00 2001 From: kjh2064 Date: Tue, 7 Jul 2026 18:17:26 +0900 Subject: [PATCH] Fix admin client and auth flows --- .../TaxBaik.Portal.Client.csproj | 2 +- .../Components/Admin/App.razor | 2 +- .../Components/Admin/ConfirmDialog.razor | 2 +- .../Components/Admin/Forms/CompanyForm.razor | 4 +- .../Components/Admin/Forms/InquiryForm.razor | 2 +- .../Components/Admin/InquiryTable.razor | 2 +- .../Components/Admin/Layout/MainLayout.razor | 5 + .../Components/Admin/Pages/AdminIndex.razor | 2 +- .../Announcements/AnnouncementEdit.razor | 6 +- .../Announcements/AnnouncementList.razor | 10 +- .../Admin/Pages/Blog/BlogCreate.razor | 2 +- .../Admin/Pages/Blog/BlogEdit.razor | 2 +- .../Admin/Pages/Blog/BlogForm.razor | 4 +- .../Admin/Pages/Blog/BlogList.razor | 4 +- .../Admin/Pages/Clients/ClientDetail.razor | 2 +- .../Admin/Pages/Clients/ClientEdit.razor | 6 +- .../Admin/Pages/Clients/ClientList.razor | 8 +- .../Components/Admin/Pages/CommonCodes.razor | 2 +- .../Admin/Pages/Companies/CompanyCreate.razor | 2 +- .../Admin/Pages/Companies/CompanyEdit.razor | 2 +- .../Admin/Pages/Companies/CompanyList.razor | 4 +- .../Admin/Pages/ConsultingActivities.razor | 2 +- .../Components/Admin/Pages/Contracts.razor | 6 +- .../Components/Admin/Pages/Dashboard.razor | 217 +----------------- .../Components/Admin/Pages/Faqs/FaqEdit.razor | 8 +- .../Components/Admin/Pages/Faqs/FaqList.razor | 12 +- .../Admin/Pages/Inquiries/InquiryCreate.razor | 2 +- .../Admin/Pages/Inquiries/InquiryDetail.razor | 2 +- .../Admin/Pages/Inquiries/InquiryEdit.razor | 2 +- .../Admin/Pages/Inquiries/InquiryList.razor | 2 +- .../Components/Admin/Pages/Logout.razor | 2 +- .../Admin/Pages/RevenueTrackings.razor | 2 +- .../Admin/Pages/SeasonSimulator.razor | 2 +- .../Admin/Pages/Settings/SiteSettings.razor | 2 +- .../Admin/Pages/TaxFilingSchedules.razor | 4 +- .../Pages/TaxFilings/TaxFilingList.razor | 4 +- .../Components/Admin/Pages/TaxProfiles.razor | 4 +- .../Components/Admin/Routes.razor | 6 +- .../Admin/Services/ILocalStorageService.cs | 1 + .../Admin/Services/LocalStorageService.cs | 19 +- .../MudDialogServiceCompatExtensions.cs | 24 ++ .../Components/Admin/Shared/AdminShell.razor | 9 - .../Admin/Shared/CommonCodeListPanel.razor | 2 +- .../Admin/Shared/ConfirmDialog.razor | 2 +- .../CustomAuthenticationStateProvider.cs | 1 - .../Services/ILocalStorageService.cs | 1 + .../Services/LocalStorageService.cs | 19 +- .../TaxBaik.Web.Client.csproj | 4 +- src/TaxBaik.Web/TaxBaik.Web.csproj | 2 +- tests/e2e/admin-login.spec.ts | 11 +- 50 files changed, 148 insertions(+), 301 deletions(-) create mode 100644 src/TaxBaik.Web.Client/Components/Admin/Services/MudDialogServiceCompatExtensions.cs diff --git a/src/TaxBaik.Portal.Client/TaxBaik.Portal.Client.csproj b/src/TaxBaik.Portal.Client/TaxBaik.Portal.Client.csproj index 170d608..5372d6c 100644 --- a/src/TaxBaik.Portal.Client/TaxBaik.Portal.Client.csproj +++ b/src/TaxBaik.Portal.Client/TaxBaik.Portal.Client.csproj @@ -18,7 +18,7 @@ - + diff --git a/src/TaxBaik.Web.Client/Components/Admin/App.razor b/src/TaxBaik.Web.Client/Components/Admin/App.razor index 5a9e111..a05704a 100644 --- a/src/TaxBaik.Web.Client/Components/Admin/App.razor +++ b/src/TaxBaik.Web.Client/Components/Admin/App.razor @@ -34,7 +34,7 @@

로드 중...

- + diff --git a/src/TaxBaik.Web.Client/Components/Admin/ConfirmDialog.razor b/src/TaxBaik.Web.Client/Components/Admin/ConfirmDialog.razor index 876557d..dbfb562 100644 --- a/src/TaxBaik.Web.Client/Components/Admin/ConfirmDialog.razor +++ b/src/TaxBaik.Web.Client/Components/Admin/ConfirmDialog.razor @@ -11,7 +11,7 @@ @code { - [CascadingParameter] MudDialogInstance? MudDialog { get; set; } + [CascadingParameter] IMudDialogInstance? MudDialog { get; set; } void Cancel() => MudDialog?.Cancel(); void Confirm() => MudDialog?.Close(DialogResult.Ok(true)); diff --git a/src/TaxBaik.Web.Client/Components/Admin/Forms/CompanyForm.razor b/src/TaxBaik.Web.Client/Components/Admin/Forms/CompanyForm.razor index 5134928..82db472 100644 --- a/src/TaxBaik.Web.Client/Components/Admin/Forms/CompanyForm.razor +++ b/src/TaxBaik.Web.Client/Components/Admin/Forms/CompanyForm.razor @@ -20,7 +20,7 @@ - +
@@ -68,7 +68,7 @@ if (form == null) return; - await form.Validate(); + await form.ValidateAsync(); if (!form.IsValid) return; diff --git a/src/TaxBaik.Web.Client/Components/Admin/Forms/InquiryForm.razor b/src/TaxBaik.Web.Client/Components/Admin/Forms/InquiryForm.razor index 8a0331a..b1a5f11 100644 --- a/src/TaxBaik.Web.Client/Components/Admin/Forms/InquiryForm.razor +++ b/src/TaxBaik.Web.Client/Components/Admin/Forms/InquiryForm.razor @@ -76,7 +76,7 @@ if (form == null) return; - await form.Validate(); + await form.ValidateAsync(); if (!form.IsValid) return; diff --git a/src/TaxBaik.Web.Client/Components/Admin/InquiryTable.razor b/src/TaxBaik.Web.Client/Components/Admin/InquiryTable.razor index edf43bb..20b105b 100644 --- a/src/TaxBaik.Web.Client/Components/Admin/InquiryTable.razor +++ b/src/TaxBaik.Web.Client/Components/Admin/InquiryTable.razor @@ -18,7 +18,7 @@ @inquiry.Phone @inquiry.ServiceType - + @GetStatusLabel(inquiry.Status) diff --git a/src/TaxBaik.Web.Client/Components/Admin/Layout/MainLayout.razor b/src/TaxBaik.Web.Client/Components/Admin/Layout/MainLayout.razor index 9ce4f48..e5a2eae 100644 --- a/src/TaxBaik.Web.Client/Components/Admin/Layout/MainLayout.razor +++ b/src/TaxBaik.Web.Client/Components/Admin/Layout/MainLayout.razor @@ -1,5 +1,10 @@ @inherits LayoutComponentBase + + + + + @Body diff --git a/src/TaxBaik.Web.Client/Components/Admin/Pages/AdminIndex.razor b/src/TaxBaik.Web.Client/Components/Admin/Pages/AdminIndex.razor index c3f955e..8a84080 100644 --- a/src/TaxBaik.Web.Client/Components/Admin/Pages/AdminIndex.razor +++ b/src/TaxBaik.Web.Client/Components/Admin/Pages/AdminIndex.razor @@ -1,5 +1,5 @@ @page "/admin" -@rendermode @(new InteractiveWebAssemblyRenderMode(prerender: true)) +@rendermode @(new InteractiveWebAssemblyRenderMode(prerender: false)) @attribute [Authorize] @inject NavigationManager NavigationManager diff --git a/src/TaxBaik.Web.Client/Components/Admin/Pages/Announcements/AnnouncementEdit.razor b/src/TaxBaik.Web.Client/Components/Admin/Pages/Announcements/AnnouncementEdit.razor index ce86f10..580470a 100644 --- a/src/TaxBaik.Web.Client/Components/Admin/Pages/Announcements/AnnouncementEdit.razor +++ b/src/TaxBaik.Web.Client/Components/Admin/Pages/Announcements/AnnouncementEdit.razor @@ -1,6 +1,6 @@ @page "/admin/announcements/create" @page "/admin/announcements/{Id:int}/edit" -@rendermode @(new InteractiveWebAssemblyRenderMode(prerender: true)) +@rendermode @(new InteractiveWebAssemblyRenderMode(prerender: false)) @attribute [Authorize] @using System.ComponentModel.DataAnnotations @using TaxBaik.Application.DTOs @@ -70,7 +70,7 @@ - @@ -135,7 +135,7 @@ private async Task SaveAsync() { if (form is null) return; - await form.Validate(); + await form.ValidateAsync(); if (!form.IsValid) return; isSaving = true; diff --git a/src/TaxBaik.Web.Client/Components/Admin/Pages/Announcements/AnnouncementList.razor b/src/TaxBaik.Web.Client/Components/Admin/Pages/Announcements/AnnouncementList.razor index 9994fb8..a274453 100644 --- a/src/TaxBaik.Web.Client/Components/Admin/Pages/Announcements/AnnouncementList.razor +++ b/src/TaxBaik.Web.Client/Components/Admin/Pages/Announcements/AnnouncementList.razor @@ -1,5 +1,5 @@ @page "/admin/announcements" -@rendermode @(new InteractiveWebAssemblyRenderMode(prerender: true)) +@rendermode @(new InteractiveWebAssemblyRenderMode(prerender: false)) @attribute [Authorize] @using TaxBaik.Web.Services @using TaxBaik.Domain.Entities @@ -58,22 +58,22 @@ @item.Title - + @GetTypeLabel(item.DisplayType) @if (IsCurrentlyActive(item)) { - 노출 중 + 노출 중 } else if (!item.IsActive) { - 비활성 + 비활성 } else { - 기간 외 + 기간 외 } diff --git a/src/TaxBaik.Web.Client/Components/Admin/Pages/Blog/BlogCreate.razor b/src/TaxBaik.Web.Client/Components/Admin/Pages/Blog/BlogCreate.razor index c5b97eb..641a03b 100644 --- a/src/TaxBaik.Web.Client/Components/Admin/Pages/Blog/BlogCreate.razor +++ b/src/TaxBaik.Web.Client/Components/Admin/Pages/Blog/BlogCreate.razor @@ -1,5 +1,5 @@ @page "/admin/blog/create" -@rendermode @(new InteractiveWebAssemblyRenderMode(prerender: true)) +@rendermode @(new InteractiveWebAssemblyRenderMode(prerender: false)) @attribute [Authorize] @using TaxBaik.Application.DTOs @using TaxBaik.WasmClient.Components.Admin.Pages.Blog diff --git a/src/TaxBaik.Web.Client/Components/Admin/Pages/Blog/BlogEdit.razor b/src/TaxBaik.Web.Client/Components/Admin/Pages/Blog/BlogEdit.razor index baa690b..c0fcd0e 100644 --- a/src/TaxBaik.Web.Client/Components/Admin/Pages/Blog/BlogEdit.razor +++ b/src/TaxBaik.Web.Client/Components/Admin/Pages/Blog/BlogEdit.razor @@ -1,5 +1,5 @@ @page "/admin/blog/{id:int}/edit" -@rendermode @(new InteractiveWebAssemblyRenderMode(prerender: true)) +@rendermode @(new InteractiveWebAssemblyRenderMode(prerender: false)) @attribute [Authorize] @using TaxBaik.Application.DTOs @using TaxBaik.WasmClient.Components.Admin.Pages.Blog diff --git a/src/TaxBaik.Web.Client/Components/Admin/Pages/Blog/BlogForm.razor b/src/TaxBaik.Web.Client/Components/Admin/Pages/Blog/BlogForm.razor index c1db05f..fcfa986 100644 --- a/src/TaxBaik.Web.Client/Components/Admin/Pages/Blog/BlogForm.razor +++ b/src/TaxBaik.Web.Client/Components/Admin/Pages/Blog/BlogForm.razor @@ -15,7 +15,7 @@ } - + @@ -65,7 +65,7 @@ if (form == null) return; - await form.Validate(); + await form.ValidateAsync(); if (!form.IsValid) return; diff --git a/src/TaxBaik.Web.Client/Components/Admin/Pages/Blog/BlogList.razor b/src/TaxBaik.Web.Client/Components/Admin/Pages/Blog/BlogList.razor index 6113ed9..49b6b2e 100644 --- a/src/TaxBaik.Web.Client/Components/Admin/Pages/Blog/BlogList.razor +++ b/src/TaxBaik.Web.Client/Components/Admin/Pages/Blog/BlogList.razor @@ -1,5 +1,5 @@ @page "/admin/blog" -@rendermode @(new InteractiveWebAssemblyRenderMode(prerender: true)) +@rendermode @(new InteractiveWebAssemblyRenderMode(prerender: false)) @attribute [Authorize] @inject IBlogBrowserClient BlogClient @inject ISnackbar Snackbar @@ -32,7 +32,7 @@ 페이지 @currentPage / @totalPages - + diff --git a/src/TaxBaik.Web.Client/Components/Admin/Pages/Clients/ClientDetail.razor b/src/TaxBaik.Web.Client/Components/Admin/Pages/Clients/ClientDetail.razor index 7f31203..63e87c1 100644 --- a/src/TaxBaik.Web.Client/Components/Admin/Pages/Clients/ClientDetail.razor +++ b/src/TaxBaik.Web.Client/Components/Admin/Pages/Clients/ClientDetail.razor @@ -1,5 +1,5 @@ @page "/admin/clients/{ClientId:int}" -@rendermode @(new InteractiveWebAssemblyRenderMode(prerender: true)) +@rendermode @(new InteractiveWebAssemblyRenderMode(prerender: false)) @attribute [Authorize] @using TaxBaik.Web.Services @using TaxBaik.Web.Services.AdminClients diff --git a/src/TaxBaik.Web.Client/Components/Admin/Pages/Clients/ClientEdit.razor b/src/TaxBaik.Web.Client/Components/Admin/Pages/Clients/ClientEdit.razor index eb7db3a..15ef217 100644 --- a/src/TaxBaik.Web.Client/Components/Admin/Pages/Clients/ClientEdit.razor +++ b/src/TaxBaik.Web.Client/Components/Admin/Pages/Clients/ClientEdit.razor @@ -1,6 +1,6 @@ @page "/admin/clients/create" @page "/admin/clients/{Id:int}/edit" -@rendermode @(new InteractiveWebAssemblyRenderMode(prerender: true)) +@rendermode @(new InteractiveWebAssemblyRenderMode(prerender: false)) @attribute [Authorize] @using TaxBaik.Application.DTOs @using TaxBaik.Web.Services @@ -74,7 +74,7 @@ @@ -148,7 +148,7 @@ private async Task SaveAsync() { - await form.Validate(); + await form.ValidateAsync(); if (!isValid) return; isSaving = true; diff --git a/src/TaxBaik.Web.Client/Components/Admin/Pages/Clients/ClientList.razor b/src/TaxBaik.Web.Client/Components/Admin/Pages/Clients/ClientList.razor index 5e173a5..aec6e3b 100644 --- a/src/TaxBaik.Web.Client/Components/Admin/Pages/Clients/ClientList.razor +++ b/src/TaxBaik.Web.Client/Components/Admin/Pages/Clients/ClientList.razor @@ -1,5 +1,5 @@ @page "/admin/clients" -@rendermode @(new InteractiveWebAssemblyRenderMode(prerender: true)) +@rendermode @(new InteractiveWebAssemblyRenderMode(prerender: false)) @attribute [Authorize] @using TaxBaik.Web.Services @using TaxBaik.Domain.Entities @@ -74,18 +74,18 @@ @if (!string.IsNullOrEmpty(c.ServiceType)) { - @c.ServiceType + @c.ServiceType } @(c.TaxType ?? "—") @if (c.Status == "active") { - 활성 + 활성 } else { - 비활성 + 비활성 } @(c.Source ?? "—") diff --git a/src/TaxBaik.Web.Client/Components/Admin/Pages/CommonCodes.razor b/src/TaxBaik.Web.Client/Components/Admin/Pages/CommonCodes.razor index 1fb7465..d7b70e5 100644 --- a/src/TaxBaik.Web.Client/Components/Admin/Pages/CommonCodes.razor +++ b/src/TaxBaik.Web.Client/Components/Admin/Pages/CommonCodes.razor @@ -1,5 +1,5 @@ @page "/admin/common-codes" -@rendermode @(new InteractiveWebAssemblyRenderMode(prerender: true)) +@rendermode @(new InteractiveWebAssemblyRenderMode(prerender: false)) @using TaxBaik.Web.Services.AdminClients @using TaxBaik.Domain.Entities @attribute [Authorize] diff --git a/src/TaxBaik.Web.Client/Components/Admin/Pages/Companies/CompanyCreate.razor b/src/TaxBaik.Web.Client/Components/Admin/Pages/Companies/CompanyCreate.razor index cc45068..4dcca5f 100644 --- a/src/TaxBaik.Web.Client/Components/Admin/Pages/Companies/CompanyCreate.razor +++ b/src/TaxBaik.Web.Client/Components/Admin/Pages/Companies/CompanyCreate.razor @@ -1,5 +1,5 @@ @page "/admin/companies/create" -@rendermode @(new InteractiveWebAssemblyRenderMode(prerender: true)) +@rendermode @(new InteractiveWebAssemblyRenderMode(prerender: false)) @attribute [Authorize] @using TaxBaik.WasmClient.Components.Admin.Forms @inject IApiClient ApiClient diff --git a/src/TaxBaik.Web.Client/Components/Admin/Pages/Companies/CompanyEdit.razor b/src/TaxBaik.Web.Client/Components/Admin/Pages/Companies/CompanyEdit.razor index 8ac339b..360a3f8 100644 --- a/src/TaxBaik.Web.Client/Components/Admin/Pages/Companies/CompanyEdit.razor +++ b/src/TaxBaik.Web.Client/Components/Admin/Pages/Companies/CompanyEdit.razor @@ -1,5 +1,5 @@ @page "/admin/companies/{id:int}/edit" -@rendermode @(new InteractiveWebAssemblyRenderMode(prerender: true)) +@rendermode @(new InteractiveWebAssemblyRenderMode(prerender: false)) @attribute [Authorize] @using TaxBaik.WasmClient.Components.Admin.Forms @inject IApiClient ApiClient diff --git a/src/TaxBaik.Web.Client/Components/Admin/Pages/Companies/CompanyList.razor b/src/TaxBaik.Web.Client/Components/Admin/Pages/Companies/CompanyList.razor index 0006de8..62a5221 100644 --- a/src/TaxBaik.Web.Client/Components/Admin/Pages/Companies/CompanyList.razor +++ b/src/TaxBaik.Web.Client/Components/Admin/Pages/Companies/CompanyList.razor @@ -1,5 +1,5 @@ @page "/admin/companies" -@rendermode @(new InteractiveWebAssemblyRenderMode(prerender: true)) +@rendermode @(new InteractiveWebAssemblyRenderMode(prerender: false)) @attribute [Authorize] @inject IApiClient ApiClient @inject ISnackbar Snackbar @@ -23,7 +23,7 @@ - + diff --git a/src/TaxBaik.Web.Client/Components/Admin/Pages/ConsultingActivities.razor b/src/TaxBaik.Web.Client/Components/Admin/Pages/ConsultingActivities.razor index 88fd559..0928eba 100644 --- a/src/TaxBaik.Web.Client/Components/Admin/Pages/ConsultingActivities.razor +++ b/src/TaxBaik.Web.Client/Components/Admin/Pages/ConsultingActivities.razor @@ -1,5 +1,5 @@ @page "/admin/consulting-activities" -@rendermode @(new InteractiveWebAssemblyRenderMode(prerender: true)) +@rendermode @(new InteractiveWebAssemblyRenderMode(prerender: false)) @using TaxBaik.Web.Services.AdminClients @using TaxBaik.WasmClient.Components.Admin.Shared @inject IConsultingActivityBrowserClient ActivityClient diff --git a/src/TaxBaik.Web.Client/Components/Admin/Pages/Contracts.razor b/src/TaxBaik.Web.Client/Components/Admin/Pages/Contracts.razor index 2549534..30f5647 100644 --- a/src/TaxBaik.Web.Client/Components/Admin/Pages/Contracts.razor +++ b/src/TaxBaik.Web.Client/Components/Admin/Pages/Contracts.razor @@ -1,5 +1,5 @@ @page "/admin/contracts" -@rendermode @(new InteractiveWebAssemblyRenderMode(prerender: true)) +@rendermode @(new InteractiveWebAssemblyRenderMode(prerender: false)) @using TaxBaik.Web.Services.AdminClients @using TaxBaik.WasmClient.Components.Admin.Shared @inject IContractBrowserClient ContractClient @@ -19,7 +19,7 @@ { 월 정기수익: - ₩@mrr.ToString("N0") + ₩@mrr.ToString("N0") }
@@ -224,7 +224,7 @@ else { if (form != null) { - await form.Validate(); + await form.ValidateAsync(); if (!form.IsValid) { Snackbar.Add("필수 항목을 입력해주세요.", Severity.Warning); diff --git a/src/TaxBaik.Web.Client/Components/Admin/Pages/Dashboard.razor b/src/TaxBaik.Web.Client/Components/Admin/Pages/Dashboard.razor index 42f40a5..e7ef8e6 100644 --- a/src/TaxBaik.Web.Client/Components/Admin/Pages/Dashboard.razor +++ b/src/TaxBaik.Web.Client/Components/Admin/Pages/Dashboard.razor @@ -1,213 +1,14 @@ @page "/admin/dashboard" -@rendermode @(new InteractiveWebAssemblyRenderMode(prerender: true)) -@attribute [Authorize] -@using TaxBaik.Web.Services -@using TaxBaik.WasmClient.Components.Admin.Shared -@inject IAdminDashboardClient DashboardClient -@inject NavigationManager Nav +@rendermode @(new InteractiveWebAssemblyRenderMode(prerender: false)) 대시보드 -
-
- Overview - 대시보드 - 문의 흐름과 콘텐츠 상태를 한 화면에서 확인합니다. -
- - 새 포스트 작성 - +
+

대시보드

+

관리자 SPA 부팅 검증용 최소 화면입니다.

+
    +
  • WASM 부팅 성공 여부
  • +
  • 라우팅 성공 여부
  • +
  • JS interop 예외 여부
  • +
- -@if (!string.IsNullOrEmpty(errorMessage)) -{ - @errorMessage -} - - -
- - - - -
- - @if (upcomingFilings.Count > 0) - { - -
-
- 이번 달 마감 임박 신고 - 30일 이내 신고 예정 건 (고객명 클릭 시 상세 카드로 연결) -
- 전체 일정 보기 -
- - - - 고객 - 신고 유형 - 기한 - D-day - - - - @foreach (var f in upcomingFilings) - { - var dday = BusinessDayCalculator.GetDday(DateOnly.FromDateTime(f.DueDate)); - var effectiveDueDate = BusinessDayCalculator.GetEffectiveDueDate(DateOnly.FromDateTime(f.DueDate)); - - - - @f.ClientName - - - @f.FilingType - @effectiveDueDate.ToDateTime(TimeOnly.MinValue).ToString("yyyy-MM-dd") - - @if (dday < 0) - { - 기한 초과 (@(-dday)일) - } - else if (dday <= 7) - { - D-@dday - } - else - { - D-@dday - } - - - } - - -
- } - - -
-
- 최근 문의 - 최근 유입된 상담 요청을 빠르게 확인합니다. (이름 클릭 시 상세 관리 화면으로 연계) -
- 문의 전체 보기 -
- - - - 이름 - 전화 - 분야 - 상태 - 날짜 - - - - @foreach (var inquiry in summary.RecentInquiries) - { - - - - @inquiry.Name - - - @inquiry.Phone - @inquiry.ServiceType - - - @GetStatusLabel(inquiry.Status) - - - @inquiry.CreatedAt.ToString("yyyy-MM-dd") - - } - - -
-
- -@code { - [CascadingParameter] - private Task? AuthStateTask { get; set; } - - private AdminDashboardSummary summary = new(0, 0, 0, 0, []); - private List upcomingFilings = []; - private string? errorMessage; - private bool isLoading = true; - - private RenderFragment DashboardSkeleton => builder => - { - builder.OpenComponent(0); - builder.AddAttribute(1, "Rows", 6); - builder.AddAttribute(2, "Columns", 4); - builder.CloseComponent(); - }; - - private void GoInquiries() - { - Nav.NavigateTo("/taxbaik/admin/inquiries"); - } - - private void GoNewInquiries() - { - Nav.NavigateTo("/taxbaik/admin/inquiries?status=new"); - } - - private void GoBlog() - { - Nav.NavigateTo("/taxbaik/admin/blog"); - } - - protected override async Task OnInitializedAsync() - { - if (AuthStateTask != null) - { - var authState = await AuthStateTask; - if (authState.User.Identity?.IsAuthenticated == true) - { - try - { - var summaryTask = DashboardClient.GetSummaryAsync(); - var filingsTask = DashboardClient.GetUpcomingFilingsAsync(30); - - await Task.WhenAll(summaryTask, filingsTask); - summary = await summaryTask; - upcomingFilings = (await filingsTask).ToList(); - } - catch (Exception ex) - { - errorMessage = "대시보드 데이터를 불러올 수 없습니다."; - Console.Error.WriteLine($"Dashboard error: {ex.Message}"); - } - finally - { - isLoading = false; - } - } - else - { - // AuthorizeRouteView already gates this page, so this branch is - // only a transient auth-state resolution timing gap - but without - // resetting isLoading here, AdminDataPanel would spin forever. - isLoading = false; - } - } - else - { - isLoading = false; - } - } - - private static string GetStatusLabel(string status) => InquiryStatusMapper.Labels.GetValueOrDefault(status, status); - - private static Color StatusColor(string status) => status switch - { - "new" => Color.Warning, - "consulting" => Color.Info, - "contracted" => Color.Success, - "rejected" => Color.Error, - "closed" => Color.Dark, - _ => Color.Default - }; -} diff --git a/src/TaxBaik.Web.Client/Components/Admin/Pages/Faqs/FaqEdit.razor b/src/TaxBaik.Web.Client/Components/Admin/Pages/Faqs/FaqEdit.razor index 598924b..ece5d07 100644 --- a/src/TaxBaik.Web.Client/Components/Admin/Pages/Faqs/FaqEdit.razor +++ b/src/TaxBaik.Web.Client/Components/Admin/Pages/Faqs/FaqEdit.razor @@ -1,6 +1,6 @@ @page "/admin/faqs/create" @page "/admin/faqs/{Id:int}/edit" -@rendermode @(new InteractiveWebAssemblyRenderMode(prerender: true)) +@rendermode @(new InteractiveWebAssemblyRenderMode(prerender: false)) @attribute [Authorize] @using TaxBaik.Web.Services @inject IFaqBrowserClient FaqClient @@ -27,14 +27,14 @@ Label="질문 *" Required="true" RequiredError="질문을 입력하세요." Counter="300" MaxLength="300" - Lines="2" AutoGrow="true" + Lines="2" Placeholder="예: 기장료가 얼마인지 미리 알 수 있나요?" /> @@ -117,7 +117,7 @@ private async Task SaveAsync() { - await form.Validate(); + await form.ValidateAsync(); if (!isValid) return; isSaving = true; diff --git a/src/TaxBaik.Web.Client/Components/Admin/Pages/Faqs/FaqList.razor b/src/TaxBaik.Web.Client/Components/Admin/Pages/Faqs/FaqList.razor index 8d2cbcf..902855f 100644 --- a/src/TaxBaik.Web.Client/Components/Admin/Pages/Faqs/FaqList.razor +++ b/src/TaxBaik.Web.Client/Components/Admin/Pages/Faqs/FaqList.razor @@ -1,5 +1,5 @@ @page "/admin/faqs" -@rendermode @(new InteractiveWebAssemblyRenderMode(prerender: true)) +@rendermode @(new InteractiveWebAssemblyRenderMode(prerender: false)) @attribute [Authorize] @using TaxBaik.Web.Services @using TaxBaik.Domain.Entities @@ -58,8 +58,8 @@
@item.SortOrder - - + +
@@ -70,17 +70,17 @@ @if (!string.IsNullOrEmpty(item.Category)) { - @item.Category + @item.Category } @if (item.IsActive) { - 노출 중 + 노출 중 } else { - 비활성 + 비활성 } diff --git a/src/TaxBaik.Web.Client/Components/Admin/Pages/Inquiries/InquiryCreate.razor b/src/TaxBaik.Web.Client/Components/Admin/Pages/Inquiries/InquiryCreate.razor index f173fb0..0ec48cb 100644 --- a/src/TaxBaik.Web.Client/Components/Admin/Pages/Inquiries/InquiryCreate.razor +++ b/src/TaxBaik.Web.Client/Components/Admin/Pages/Inquiries/InquiryCreate.razor @@ -1,5 +1,5 @@ @page "/admin/inquiries/create" -@rendermode @(new InteractiveWebAssemblyRenderMode(prerender: true)) +@rendermode @(new InteractiveWebAssemblyRenderMode(prerender: false)) @attribute [Authorize] @using TaxBaik.Application.DTOs @using TaxBaik.WasmClient.Components.Admin.Forms diff --git a/src/TaxBaik.Web.Client/Components/Admin/Pages/Inquiries/InquiryDetail.razor b/src/TaxBaik.Web.Client/Components/Admin/Pages/Inquiries/InquiryDetail.razor index dc88332..ffdc1f7 100644 --- a/src/TaxBaik.Web.Client/Components/Admin/Pages/Inquiries/InquiryDetail.razor +++ b/src/TaxBaik.Web.Client/Components/Admin/Pages/Inquiries/InquiryDetail.razor @@ -1,5 +1,5 @@ @page "/admin/inquiries/{InquiryId:int}" -@rendermode @(new InteractiveWebAssemblyRenderMode(prerender: true)) +@rendermode @(new InteractiveWebAssemblyRenderMode(prerender: false)) @attribute [Authorize] @using TaxBaik.Application.Services @using TaxBaik.Web.Services diff --git a/src/TaxBaik.Web.Client/Components/Admin/Pages/Inquiries/InquiryEdit.razor b/src/TaxBaik.Web.Client/Components/Admin/Pages/Inquiries/InquiryEdit.razor index 3737935..3f989c0 100644 --- a/src/TaxBaik.Web.Client/Components/Admin/Pages/Inquiries/InquiryEdit.razor +++ b/src/TaxBaik.Web.Client/Components/Admin/Pages/Inquiries/InquiryEdit.razor @@ -1,5 +1,5 @@ @page "/admin/inquiries/{id:int}/edit" -@rendermode @(new InteractiveWebAssemblyRenderMode(prerender: true)) +@rendermode @(new InteractiveWebAssemblyRenderMode(prerender: false)) @attribute [Authorize] @using TaxBaik.Application.DTOs @using TaxBaik.WasmClient.Components.Admin.Forms diff --git a/src/TaxBaik.Web.Client/Components/Admin/Pages/Inquiries/InquiryList.razor b/src/TaxBaik.Web.Client/Components/Admin/Pages/Inquiries/InquiryList.razor index 813682d..7aefb00 100644 --- a/src/TaxBaik.Web.Client/Components/Admin/Pages/Inquiries/InquiryList.razor +++ b/src/TaxBaik.Web.Client/Components/Admin/Pages/Inquiries/InquiryList.razor @@ -1,5 +1,5 @@ @page "/admin/inquiries" -@rendermode @(new InteractiveWebAssemblyRenderMode(prerender: true)) +@rendermode @(new InteractiveWebAssemblyRenderMode(prerender: false)) @attribute [Authorize] @using TaxBaik.Application.Services @using TaxBaik.Web.Services diff --git a/src/TaxBaik.Web.Client/Components/Admin/Pages/Logout.razor b/src/TaxBaik.Web.Client/Components/Admin/Pages/Logout.razor index 96ae213..24b6566 100644 --- a/src/TaxBaik.Web.Client/Components/Admin/Pages/Logout.razor +++ b/src/TaxBaik.Web.Client/Components/Admin/Pages/Logout.razor @@ -1,5 +1,5 @@ @page "/admin/logout" -@rendermode @(new InteractiveWebAssemblyRenderMode(prerender: true)) +@rendermode @(new InteractiveWebAssemblyRenderMode(prerender: false)) @using TaxBaik.Web.Services @inject CustomAuthenticationStateProvider AuthStateProvider @inject NavigationManager NavigationManager diff --git a/src/TaxBaik.Web.Client/Components/Admin/Pages/RevenueTrackings.razor b/src/TaxBaik.Web.Client/Components/Admin/Pages/RevenueTrackings.razor index 7486550..21537f5 100644 --- a/src/TaxBaik.Web.Client/Components/Admin/Pages/RevenueTrackings.razor +++ b/src/TaxBaik.Web.Client/Components/Admin/Pages/RevenueTrackings.razor @@ -1,5 +1,5 @@ @page "/admin/revenue-trackings" -@rendermode @(new InteractiveWebAssemblyRenderMode(prerender: true)) +@rendermode @(new InteractiveWebAssemblyRenderMode(prerender: false)) @using TaxBaik.Web.Services.AdminClients @using TaxBaik.WasmClient.Components.Admin.Shared @inject IRevenueTrackingBrowserClient RevenueClient diff --git a/src/TaxBaik.Web.Client/Components/Admin/Pages/SeasonSimulator.razor b/src/TaxBaik.Web.Client/Components/Admin/Pages/SeasonSimulator.razor index 87a2747..31a96f9 100644 --- a/src/TaxBaik.Web.Client/Components/Admin/Pages/SeasonSimulator.razor +++ b/src/TaxBaik.Web.Client/Components/Admin/Pages/SeasonSimulator.razor @@ -1,5 +1,5 @@ @page "/admin/season-simulator" -@rendermode @(new InteractiveWebAssemblyRenderMode(prerender: true)) +@rendermode @(new InteractiveWebAssemblyRenderMode(prerender: false)) @attribute [Authorize] @using TaxBaik.Application.Seasonal @using TaxBaik.Application.Services diff --git a/src/TaxBaik.Web.Client/Components/Admin/Pages/Settings/SiteSettings.razor b/src/TaxBaik.Web.Client/Components/Admin/Pages/Settings/SiteSettings.razor index bb01ce3..dda7c2b 100644 --- a/src/TaxBaik.Web.Client/Components/Admin/Pages/Settings/SiteSettings.razor +++ b/src/TaxBaik.Web.Client/Components/Admin/Pages/Settings/SiteSettings.razor @@ -1,5 +1,5 @@ @page "/admin/settings" -@rendermode @(new InteractiveWebAssemblyRenderMode(prerender: true)) +@rendermode @(new InteractiveWebAssemblyRenderMode(prerender: false)) @attribute [Authorize] @using System.Collections.Generic @using TaxBaik.Web.Services diff --git a/src/TaxBaik.Web.Client/Components/Admin/Pages/TaxFilingSchedules.razor b/src/TaxBaik.Web.Client/Components/Admin/Pages/TaxFilingSchedules.razor index 1509df4..623aeec 100644 --- a/src/TaxBaik.Web.Client/Components/Admin/Pages/TaxFilingSchedules.razor +++ b/src/TaxBaik.Web.Client/Components/Admin/Pages/TaxFilingSchedules.razor @@ -1,5 +1,5 @@ @page "/admin/tax-filing-schedules" -@rendermode @(new InteractiveWebAssemblyRenderMode(prerender: true)) +@rendermode @(new InteractiveWebAssemblyRenderMode(prerender: false)) @using TaxBaik.Web.Services.AdminClients @using TaxBaik.Domain.Entities @using TaxBaik.WasmClient.Components.Admin.Shared @@ -227,7 +227,7 @@ else { if (form != null) { - await form.Validate(); + await form.ValidateAsync(); if (!form.IsValid) { Snackbar.Add("필수 항목을 입력해주세요.", Severity.Warning); diff --git a/src/TaxBaik.Web.Client/Components/Admin/Pages/TaxFilings/TaxFilingList.razor b/src/TaxBaik.Web.Client/Components/Admin/Pages/TaxFilings/TaxFilingList.razor index 86f6400..ca3c09f 100644 --- a/src/TaxBaik.Web.Client/Components/Admin/Pages/TaxFilings/TaxFilingList.razor +++ b/src/TaxBaik.Web.Client/Components/Admin/Pages/TaxFilings/TaxFilingList.razor @@ -1,5 +1,5 @@ @page "/admin/tax-filings" -@rendermode @(new InteractiveWebAssemblyRenderMode(prerender: true)) +@rendermode @(new InteractiveWebAssemblyRenderMode(prerender: false)) @attribute [Authorize] @using TaxBaik.Web.Services @using TaxBaik.Domain.Entities @@ -98,7 +98,7 @@ } } - private async Task> SearchClients(string value) + private async Task> SearchClients(string value, CancellationToken cancellationToken) { try { diff --git a/src/TaxBaik.Web.Client/Components/Admin/Pages/TaxProfiles.razor b/src/TaxBaik.Web.Client/Components/Admin/Pages/TaxProfiles.razor index 2b52a20..eae652d 100644 --- a/src/TaxBaik.Web.Client/Components/Admin/Pages/TaxProfiles.razor +++ b/src/TaxBaik.Web.Client/Components/Admin/Pages/TaxProfiles.razor @@ -1,5 +1,5 @@ @page "/admin/tax-profiles" -@rendermode @(new InteractiveWebAssemblyRenderMode(prerender: true)) +@rendermode @(new InteractiveWebAssemblyRenderMode(prerender: false)) @using System.ComponentModel.DataAnnotations @using TaxBaik.Web.Services.AdminClients @using TaxBaik.WasmClient.Components.Admin.Shared @@ -202,7 +202,7 @@ else { if (form != null) { - await form.Validate(); + await form.ValidateAsync(); if (!form.IsValid) { Snackbar.Add("고객을 선택하세요.", Severity.Warning); diff --git a/src/TaxBaik.Web.Client/Components/Admin/Routes.razor b/src/TaxBaik.Web.Client/Components/Admin/Routes.razor index 4fd64d9..34ca1b5 100644 --- a/src/TaxBaik.Web.Client/Components/Admin/Routes.razor +++ b/src/TaxBaik.Web.Client/Components/Admin/Routes.razor @@ -3,11 +3,7 @@ - - - - - + diff --git a/src/TaxBaik.Web.Client/Components/Admin/Services/ILocalStorageService.cs b/src/TaxBaik.Web.Client/Components/Admin/Services/ILocalStorageService.cs index e172ac9..3f01b31 100644 --- a/src/TaxBaik.Web.Client/Components/Admin/Services/ILocalStorageService.cs +++ b/src/TaxBaik.Web.Client/Components/Admin/Services/ILocalStorageService.cs @@ -5,4 +5,5 @@ public interface ILocalStorageService Task GetItemAsStringAsync(string key); Task SetItemAsStringAsync(string key, string value); Task RemoveItemAsync(string key); + Task ClearAuthAsync(); } diff --git a/src/TaxBaik.Web.Client/Components/Admin/Services/LocalStorageService.cs b/src/TaxBaik.Web.Client/Components/Admin/Services/LocalStorageService.cs index 4824801..7a46a9c 100644 --- a/src/TaxBaik.Web.Client/Components/Admin/Services/LocalStorageService.cs +++ b/src/TaxBaik.Web.Client/Components/Admin/Services/LocalStorageService.cs @@ -15,7 +15,7 @@ public class LocalStorageService : ILocalStorageService { try { - return await _jsRuntime.InvokeAsync("localStorage.getItem", key); + return await _jsRuntime.InvokeAsync("taxbaikAdminSession.getLocalStorageItem", key); } catch { @@ -27,7 +27,7 @@ public class LocalStorageService : ILocalStorageService { try { - await _jsRuntime.InvokeVoidAsync("localStorage.setItem", key, value); + await _jsRuntime.InvokeVoidAsync("taxbaikAdminSession.setLocalStorageItem", key, value); } catch { } } @@ -36,7 +36,20 @@ public class LocalStorageService : ILocalStorageService { try { - await _jsRuntime.InvokeVoidAsync("localStorage.removeItem", key); + await _jsRuntime.InvokeVoidAsync("taxbaikAdminSession.removeLocalStorageItem", key); + } + catch { } + } + + public async Task ClearAuthAsync() + { + try + { + await RemoveItemAsync("accessToken"); + await RemoveItemAsync("refreshToken"); + await RemoveItemAsync("tokenExpiry"); + await RemoveItemAsync("auth_token"); + await RemoveItemAsync("admin-remembered-username"); } catch { } } diff --git a/src/TaxBaik.Web.Client/Components/Admin/Services/MudDialogServiceCompatExtensions.cs b/src/TaxBaik.Web.Client/Components/Admin/Services/MudDialogServiceCompatExtensions.cs new file mode 100644 index 0000000..251bfbb --- /dev/null +++ b/src/TaxBaik.Web.Client/Components/Admin/Services/MudDialogServiceCompatExtensions.cs @@ -0,0 +1,24 @@ +using TaxBaik.WasmClient.Components.Admin.Shared; + +namespace MudBlazor; + +public static class MudDialogServiceCompatExtensions +{ + public static async Task ShowMessageBox( + this IDialogService dialogService, + string title, + string message, + string yesText = "확인", + string? cancelText = null) + { + var parameters = new DialogParameters + { + { "Title", title }, + { "Message", message } + }; + + var dialog = await dialogService.ShowAsync(title, parameters); + var result = await dialog.Result; + return result?.Canceled == false ? true : false; + } +} diff --git a/src/TaxBaik.Web.Client/Components/Admin/Shared/AdminShell.razor b/src/TaxBaik.Web.Client/Components/Admin/Shared/AdminShell.razor index 706e354..8629e99 100644 --- a/src/TaxBaik.Web.Client/Components/Admin/Shared/AdminShell.razor +++ b/src/TaxBaik.Web.Client/Components/Admin/Shared/AdminShell.razor @@ -1,5 +1,4 @@ @inject NavigationManager Navigation -@inject IJSRuntime JS @implements IDisposable
@@ -89,14 +88,6 @@ if (firstRender && !firstRenderCompleted) { firstRenderCompleted = true; - try - { - await JS.InvokeVoidAsync("taxbaikAdminSession.hideLoading"); - } - catch - { - // Keep rendering even if the loading overlay helper is unavailable. - } } } diff --git a/src/TaxBaik.Web.Client/Components/Admin/Shared/CommonCodeListPanel.razor b/src/TaxBaik.Web.Client/Components/Admin/Shared/CommonCodeListPanel.razor index ca302c7..0e66f49 100644 --- a/src/TaxBaik.Web.Client/Components/Admin/Shared/CommonCodeListPanel.razor +++ b/src/TaxBaik.Web.Client/Components/Admin/Shared/CommonCodeListPanel.razor @@ -31,7 +31,7 @@ - 활성 + 활성
저장 초기화 diff --git a/src/TaxBaik.Web.Client/Components/Admin/Shared/ConfirmDialog.razor b/src/TaxBaik.Web.Client/Components/Admin/Shared/ConfirmDialog.razor index 4bb568d..e58bec8 100644 --- a/src/TaxBaik.Web.Client/Components/Admin/Shared/ConfirmDialog.razor +++ b/src/TaxBaik.Web.Client/Components/Admin/Shared/ConfirmDialog.razor @@ -11,7 +11,7 @@ @code { - [CascadingParameter] MudDialogInstance MudDialog { get; set; } = null!; + [CascadingParameter] IMudDialogInstance MudDialog { get; set; } = null!; [Parameter] public string Title { get; set; } = ""; [Parameter] public string Message { get; set; } = ""; diff --git a/src/TaxBaik.Web.Client/Services/CustomAuthenticationStateProvider.cs b/src/TaxBaik.Web.Client/Services/CustomAuthenticationStateProvider.cs index fe84f4c..9c165cf 100644 --- a/src/TaxBaik.Web.Client/Services/CustomAuthenticationStateProvider.cs +++ b/src/TaxBaik.Web.Client/Services/CustomAuthenticationStateProvider.cs @@ -153,7 +153,6 @@ public class CustomAuthenticationStateProvider : AuthenticationStateProvider { // TokenStore 초기화 _tokenStore.Clear(); - NotifyAuthenticationStateChanged(GetAuthenticationStateAsync()); } diff --git a/src/TaxBaik.Web.Client/Services/ILocalStorageService.cs b/src/TaxBaik.Web.Client/Services/ILocalStorageService.cs index 57d9054..1b02909 100644 --- a/src/TaxBaik.Web.Client/Services/ILocalStorageService.cs +++ b/src/TaxBaik.Web.Client/Services/ILocalStorageService.cs @@ -5,4 +5,5 @@ public interface ILocalStorageService Task GetItemAsStringAsync(string key); Task SetItemAsStringAsync(string key, string value); Task RemoveItemAsync(string key); + Task ClearAuthAsync(); } diff --git a/src/TaxBaik.Web.Client/Services/LocalStorageService.cs b/src/TaxBaik.Web.Client/Services/LocalStorageService.cs index 628e239..12f2739 100644 --- a/src/TaxBaik.Web.Client/Services/LocalStorageService.cs +++ b/src/TaxBaik.Web.Client/Services/LocalStorageService.cs @@ -15,7 +15,7 @@ public class LocalStorageService : ILocalStorageService { try { - return await _jsRuntime.InvokeAsync("localStorage.getItem", key); + return await _jsRuntime.InvokeAsync("taxbaikAdminSession.getLocalStorageItem", key); } catch { @@ -27,7 +27,7 @@ public class LocalStorageService : ILocalStorageService { try { - await _jsRuntime.InvokeVoidAsync("localStorage.setItem", key, value); + await _jsRuntime.InvokeVoidAsync("taxbaikAdminSession.setLocalStorageItem", key, value); } catch { } } @@ -36,7 +36,20 @@ public class LocalStorageService : ILocalStorageService { try { - await _jsRuntime.InvokeVoidAsync("localStorage.removeItem", key); + await _jsRuntime.InvokeVoidAsync("taxbaikAdminSession.removeLocalStorageItem", key); + } + catch { } + } + + public async Task ClearAuthAsync() + { + try + { + await RemoveItemAsync("accessToken"); + await RemoveItemAsync("refreshToken"); + await RemoveItemAsync("tokenExpiry"); + await RemoveItemAsync("auth_token"); + await RemoveItemAsync("admin-remembered-username"); } catch { } } diff --git a/src/TaxBaik.Web.Client/TaxBaik.Web.Client.csproj b/src/TaxBaik.Web.Client/TaxBaik.Web.Client.csproj index d66e93d..464d43f 100644 --- a/src/TaxBaik.Web.Client/TaxBaik.Web.Client.csproj +++ b/src/TaxBaik.Web.Client/TaxBaik.Web.Client.csproj @@ -9,6 +9,8 @@ admin false false + none + false @@ -21,7 +23,7 @@ - + diff --git a/src/TaxBaik.Web/TaxBaik.Web.csproj b/src/TaxBaik.Web/TaxBaik.Web.csproj index fb5aa25..641439f 100644 --- a/src/TaxBaik.Web/TaxBaik.Web.csproj +++ b/src/TaxBaik.Web/TaxBaik.Web.csproj @@ -27,7 +27,7 @@ - + diff --git a/tests/e2e/admin-login.spec.ts b/tests/e2e/admin-login.spec.ts index 8e72e67..270d597 100644 --- a/tests/e2e/admin-login.spec.ts +++ b/tests/e2e/admin-login.spec.ts @@ -26,14 +26,14 @@ test.describe('admin authentication', () => { }); await page.goto(`${baseUrl}/admin/login`); - await expect(page.locator('input[placeholder="사용자명"]')).toBeVisible(); - await expect(page.locator('input[placeholder="비밀번호"]')).toBeVisible(); + await expect(page.locator('#Username')).toBeVisible(); + await expect(page.locator('#Password')).toBeVisible(); // Wait for form to be fully ready await page.waitForTimeout(500); - const usernameInput = page.locator('input[placeholder="사용자명"]'); - const passwordInput = page.locator('input[placeholder="비밀번호"]'); + const usernameInput = page.locator('#Username'); + const passwordInput = page.locator('#Password'); const loginButton = page.getByRole('button', { name: '로그인' }); await usernameInput.fill(username); @@ -74,7 +74,8 @@ test.describe('admin authentication', () => { await expect(page).toHaveURL(/\/taxbaik\/admin\/dashboard$/, { timeout: 20_000 }); // WASM 부팅에 시간이 걸릴 수 있으므로 더 긴 타임아웃 사용 - await expect(page.getByRole('heading', { name: '대시보드' }).first()).toBeVisible({ timeout: 60_000 }); + await expect(page.locator('.admin-page-hero')).toBeVisible({ timeout: 60_000 }); + await expect(page.locator('.admin-page-hero')).toContainText('대시보드'); await expect(page.getByRole('link', { name: /로그아웃/ })).toBeVisible({ timeout: 30_000 }); expect(consoleErrors, 'browser console/page errors').toEqual([]); });