diff --git a/TaxBaik.Web/Components/Admin/App.razor b/TaxBaik.Web/Components/Admin/App.razor
index 35b8075..8fbde11 100644
--- a/TaxBaik.Web/Components/Admin/App.razor
+++ b/TaxBaik.Web/Components/Admin/App.razor
@@ -24,6 +24,12 @@
배포 또는 서버 재시작 중이면 잠시 후 자동으로 새로고침됩니다.
+
diff --git a/TaxBaik.Web/wwwroot/css/admin.css b/TaxBaik.Web/wwwroot/css/admin.css
index 72aa5c6..b61a6ec 100644
--- a/TaxBaik.Web/wwwroot/css/admin.css
+++ b/TaxBaik.Web/wwwroot/css/admin.css
@@ -1370,3 +1370,61 @@ textarea:focus-visible {
break-inside: avoid;
}
}
+
+/* ============================================================================
+ Blazor Loading Indicator
+ ============================================================================ */
+
+#blazor-loading {
+ display: none;
+ position: fixed;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ background: rgba(255, 255, 255, 0.95);
+ backdrop-filter: blur(4px);
+ z-index: 9999;
+ align-items: center;
+ justify-content: center;
+}
+
+#blazor-loading.show {
+ display: flex;
+}
+
+.blazor-loading-overlay {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: 100%;
+ height: 100%;
+}
+
+.blazor-loading-spinner {
+ text-align: center;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: 1.5rem;
+}
+
+.blazor-loading-spinner p {
+ margin: 0;
+ font-size: 1rem;
+ color: var(--text-primary);
+ font-weight: 500;
+}
+
+.spinner {
+ width: 48px;
+ height: 48px;
+ border: 4px solid var(--bg-tertiary);
+ border-top-color: var(--primary-color);
+ border-radius: 50%;
+ animation: spin 1s linear infinite;
+}
+
+@keyframes spin {
+ to { transform: rotate(360deg); }
+}
diff --git a/TaxBaik.Web/wwwroot/js/admin-session.js b/TaxBaik.Web/wwwroot/js/admin-session.js
index 3a135f9..43ae8ba 100644
--- a/TaxBaik.Web/wwwroot/js/admin-session.js
+++ b/TaxBaik.Web/wwwroot/js/admin-session.js
@@ -15,6 +15,18 @@ window.taxbaikAdminSession = {
window.taxbaikAdminSession.syncRouteClass();
window.addEventListener('popstate', window.taxbaikAdminSession.syncRouteClass);
+ // Show loading indicator on page load (hide when Blazor circuit connects)
+ const loadingOverlay = document.getElementById('blazor-loading');
+ if (loadingOverlay) {
+ loadingOverlay.classList.add('show');
+ // Hide loading when Blazor is ready
+ Blazor.start().then(() => {
+ if (loadingOverlay) {
+ loadingOverlay.classList.remove('show');
+ }
+ });
+ }
+
const modal = document.getElementById('components-reconnect-modal');
if (!modal) {
return;