로드 중...
diff --git a/TaxBaik.Web/Components/Admin/InquiryTable.razor b/TaxBaik.Web/Components/Admin/InquiryTable.razor
index a5aed76..b375b8b 100644
--- a/TaxBaik.Web/Components/Admin/InquiryTable.razor
+++ b/TaxBaik.Web/Components/Admin/InquiryTable.razor
@@ -1,6 +1,3 @@
-@using TaxBaik.Web.Services
-@inject IInquiryBrowserClient InquiryClient
-
@@ -37,24 +34,19 @@
@code {
+ [Parameter, EditorRequired]
+ public IReadOnlyList Inquiries { get; set; } = [];
+
[Parameter]
public string Status { get; set; } = "";
- private List inquiries = [];
- private List filteredInquiries = [];
+ private IReadOnlyList filteredInquiries = [];
- protected override async Task OnInitializedAsync()
- {
- var (items, _) = await InquiryClient.GetPagedAsync(1, 100);
- inquiries = items.ToList();
- FilterInquiries();
- }
-
- private void FilterInquiries()
+ protected override void OnParametersSet()
{
filteredInquiries = string.IsNullOrEmpty(Status)
- ? inquiries
- : inquiries.Where(x => x.Status == Status).ToList();
+ ? Inquiries
+ : Inquiries.Where(x => x.Status == Status).ToList();
}
private static string GetPreview(string message)
@@ -77,9 +69,4 @@
};
private static string GetStatusLabel(string status) => InquiryStatusMapper.Labels.GetValueOrDefault(status, status);
-
- protected override async Task OnParametersSetAsync()
- {
- FilterInquiries();
- }
}
diff --git a/TaxBaik.Web/Components/Admin/Layout/MainLayout.razor b/TaxBaik.Web/Components/Admin/Layout/MainLayout.razor
index 29a67ee..592f0e6 100644
--- a/TaxBaik.Web/Components/Admin/Layout/MainLayout.razor
+++ b/TaxBaik.Web/Components/Admin/Layout/MainLayout.razor
@@ -1,4 +1,7 @@
@inherits LayoutComponentBase
+@inject NavigationManager Navigation
+@inject IJSRuntime JS
+@implements IDisposable
@@ -73,8 +76,23 @@
private bool expandedCustomerGroup = true;
private bool expandedWebsiteGroup = false;
+ protected override void OnInitialized()
+ {
+ Navigation.LocationChanged += OnLocationChanged;
+ }
+
+ private void OnLocationChanged(object? sender, LocationChangedEventArgs args)
+ {
+ _ = InvokeAsync(() => JS.InvokeVoidAsync("taxbaikAdminSession.showLoading"));
+ }
+
private void ToggleDrawer()
{
drawerOpen = !drawerOpen;
}
+
+ public void Dispose()
+ {
+ Navigation.LocationChanged -= OnLocationChanged;
+ }
}
diff --git a/TaxBaik.Web/Components/Admin/Pages/Inquiries/InquiryList.razor b/TaxBaik.Web/Components/Admin/Pages/Inquiries/InquiryList.razor
index 549492e..0235a32 100644
--- a/TaxBaik.Web/Components/Admin/Pages/Inquiries/InquiryList.razor
+++ b/TaxBaik.Web/Components/Admin/Pages/Inquiries/InquiryList.razor
@@ -1,7 +1,7 @@
@page "/admin/inquiries"
@attribute [Authorize]
-@using TaxBaik.Domain.Interfaces
-@inject IInquiryRepository InquiryRepository
+@using TaxBaik.Web.Services
+@inject IInquiryBrowserClient InquiryClient
문의 관리
@@ -13,25 +13,44 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+@if (isLoading)
+{
+
+}
+else
+{
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+}
+
+@code {
+ private bool isLoading = true;
+ private IReadOnlyList allInquiries = [];
+
+ protected override async Task OnInitializedAsync()
+ {
+ var (items, _) = await InquiryClient.GetPagedAsync(1, 200);
+ allInquiries = items.ToList();
+ isLoading = false;
+ }
+}
diff --git a/TaxBaik.Web/wwwroot/css/admin.css b/TaxBaik.Web/wwwroot/css/admin.css
index b61a6ec..2eab28a 100644
--- a/TaxBaik.Web/wwwroot/css/admin.css
+++ b/TaxBaik.Web/wwwroot/css/admin.css
@@ -1391,6 +1391,23 @@ textarea:focus-visible {
#blazor-loading.show {
display: flex;
+ animation: overlayFadeIn 0.15s ease-out;
+}
+
+@keyframes overlayFadeIn {
+ from { opacity: 0; }
+ to { opacity: 1; }
+}
+
+/* Page content fade-in on each route mount */
+.admin-page-hero,
+.admin-login-page {
+ animation: adminPageIn 0.25s ease-out;
+}
+
+@keyframes adminPageIn {
+ from { opacity: 0; transform: translateY(6px); }
+ to { opacity: 1; transform: translateY(0); }
}
.blazor-loading-overlay {
diff --git a/TaxBaik.Web/wwwroot/js/admin-session.js b/TaxBaik.Web/wwwroot/js/admin-session.js
index cc87b6a..5373775 100644
--- a/TaxBaik.Web/wwwroot/js/admin-session.js
+++ b/TaxBaik.Web/wwwroot/js/admin-session.js
@@ -4,6 +4,7 @@ window.taxbaikAdminSession = {
'admin-login-route',
window.location.pathname.toLowerCase().endsWith('/admin/login'));
},
+
clearAuthToken: function () {
try {
localStorage.removeItem('auth_token');
@@ -11,54 +12,73 @@ window.taxbaikAdminSession = {
// Ignore storage errors; redirect still recovers the session.
}
},
+
+ showLoading: function () {
+ const overlay = document.getElementById('blazor-loading');
+ if (!overlay) return;
+
+ // Start observer FIRST so it catches the mutation that brings new content in.
+ if (window._taxbaikLoadingObserver) {
+ window._taxbaikLoadingObserver.disconnect();
+ }
+ window._taxbaikLoadingObserver = new MutationObserver(function () {
+ const pageReady =
+ document.querySelector('.admin-page-hero') !== null ||
+ document.querySelector('.admin-login-page') !== null;
+ if (pageReady) {
+ window.taxbaikAdminSession.hideLoading();
+ }
+ });
+ window._taxbaikLoadingObserver.observe(document.body, {
+ childList: true,
+ subtree: true
+ });
+
+ // Show overlay after observer is active.
+ overlay.classList.add('show');
+
+ // Safety fallback: hide after 3 seconds regardless.
+ if (window._taxbaikLoadingTimeout) {
+ clearTimeout(window._taxbaikLoadingTimeout);
+ }
+ window._taxbaikLoadingTimeout = setTimeout(function () {
+ window.taxbaikAdminSession.hideLoading();
+ }, 3000);
+ },
+
+ hideLoading: function () {
+ const overlay = document.getElementById('blazor-loading');
+ if (overlay) {
+ overlay.classList.remove('show');
+ }
+
+ if (window._taxbaikLoadingTimeout) {
+ clearTimeout(window._taxbaikLoadingTimeout);
+ window._taxbaikLoadingTimeout = null;
+ }
+
+ if (window._taxbaikLoadingObserver) {
+ window._taxbaikLoadingObserver.disconnect();
+ window._taxbaikLoadingObserver = null;
+ }
+ },
+
watchReconnect: function () {
window.taxbaikAdminSession.syncRouteClass();
window.addEventListener('popstate', window.taxbaikAdminSession.syncRouteClass);
- // Hide loading indicator after Blazor initializes
- const loadingOverlay = document.getElementById('blazor-loading');
- if (loadingOverlay) {
- const hideLoading = () => {
- if (loadingOverlay.classList.contains('show')) {
- loadingOverlay.classList.remove('show');
- }
- };
-
- // Method 1: Hide after 3 seconds (guaranteed timeout)
- setTimeout(hideLoading, 3000);
-
- // Method 2: Hide when Blazor components appear (faster if available)
- const observer = new MutationObserver(() => {
- const mudElements = document.querySelectorAll('[class*="mud-"]').length;
- if (mudElements > 10) {
- hideLoading();
- observer.disconnect();
- }
- });
- observer.observe(document.body, {
- childList: true,
- subtree: true,
- attributes: true
- });
-
- // Method 3: Hide when page is interactive
- document.addEventListener('readystatechange', () => {
- if (document.readyState === 'interactive' || document.readyState === 'complete') {
- setTimeout(hideLoading, 500);
- }
- });
- }
+ // Show loading on initial page load — overlay has 'show' from HTML,
+ // but we still need to set up the observer to detect when to hide it.
+ window.taxbaikAdminSession.showLoading();
const modal = document.getElementById('components-reconnect-modal');
- if (!modal) {
- return;
- }
+ if (!modal) return;
- const reloadOnRejectedCircuit = () => {
+ const reloadOnRejectedCircuit = function () {
const className = modal.className || '';
if (className.includes('components-reconnect-failed') ||
className.includes('components-reconnect-rejected')) {
- window.setTimeout(() => window.location.reload(), 1500);
+ window.setTimeout(function () { window.location.reload(); }, 1500);
}
};