From e044acea17b365044dab4c2b3acd36c55ae46c21 Mon Sep 17 00:00:00 2001 From: kjh2064 Date: Fri, 3 Jul 2026 11:19:55 +0900 Subject: [PATCH] feature: implement persistent login username and remember-me checkbox Problem: Login form showed remembered username from localStorage, but didn't restore the 'remember me' checkbox state. Users had to re-check the box on each login attempt, defeating the purpose of the remember feature. Solution: 1. AdminLoginForm: Add isRememberChecked field and RememberedCheckboxKey constant 2. OnInitializedAsync: Restore both username AND checkbox state from localStorage 3. admin-session.js bindLoginForm: Restore checkbox.checked from localStorage 4. admin-session.js submit handler: Save checkbox state alongside username Result: Complete round-trip persistence - when user checks 'remember me' and logs in, both username and checkbox state persist until explicitly cleared. Co-Authored-By: Claude Haiku 4.5 --- .../Components/Admin/Shared/AdminLoginForm.razor | 5 +++++ src/TaxBaik.Web/wwwroot/js/admin-session.js | 15 +++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/src/TaxBaik.Web.Client/Components/Admin/Shared/AdminLoginForm.razor b/src/TaxBaik.Web.Client/Components/Admin/Shared/AdminLoginForm.razor index 70a3d33..c1f2624 100644 --- a/src/TaxBaik.Web.Client/Components/Admin/Shared/AdminLoginForm.razor +++ b/src/TaxBaik.Web.Client/Components/Admin/Shared/AdminLoginForm.razor @@ -40,18 +40,23 @@ @code { private string rememberedUsername = ""; + private bool isRememberChecked = false; private bool isReady; private const string RememberedUsernameKey = "admin-remembered-username"; + private const string RememberedCheckboxKey = "admin-remember-checkbox"; protected override async Task OnInitializedAsync() { try { rememberedUsername = await LocalStorageService.GetItemAsStringAsync(RememberedUsernameKey) ?? ""; + var checkboxValue = await LocalStorageService.GetItemAsStringAsync(RememberedCheckboxKey) ?? "false"; + isRememberChecked = checkboxValue == "true" && !string.IsNullOrEmpty(rememberedUsername); } catch { rememberedUsername = ""; + isRememberChecked = false; } } diff --git a/src/TaxBaik.Web/wwwroot/js/admin-session.js b/src/TaxBaik.Web/wwwroot/js/admin-session.js index 1acdeec..5150959 100644 --- a/src/TaxBaik.Web/wwwroot/js/admin-session.js +++ b/src/TaxBaik.Web/wwwroot/js/admin-session.js @@ -277,6 +277,19 @@ window.taxbaikAdminSession = { if (label) label.textContent = '로그인'; } + // 체크박스 상태 복원 + const rememberCheckbox = form.querySelector('input[type="checkbox"]'); + if (rememberCheckbox) { + try { + const savedState = localStorage.getItem('admin-remember-checkbox'); + if (savedState === 'true') { + rememberCheckbox.checked = true; + } + } catch { + // localStorage access error + } + } + if (form.dataset.bound === '1') return; form.dataset.bound = '1'; window.taxbaikAdminSession.traceUiState('admin-login', 'bindLoginForm attached'); @@ -322,8 +335,10 @@ window.taxbaikAdminSession = { if (rememberMe) { localStorage.setItem('admin-remembered-username', username); + localStorage.setItem('admin-remember-checkbox', 'true'); } else { localStorage.removeItem('admin-remembered-username'); + localStorage.removeItem('admin-remember-checkbox'); } window.location.href = '/taxbaik/admin/dashboard';