fix: implement Blazor-native login form to properly update authentication state
TaxBaik CI/CD / build-and-deploy (push) Successful in 2m26s

Problem: JavaScript login form saved tokens to localStorage but didn't notify
CustomAuthenticationStateProvider, causing [Authorize] pages to remain in
'loading' state indefinitely. The provider only reads tokens when:
1. GetAuthenticationStateAsync() is called (page load)
2. NotifyAuthenticationStateChanged() is triggered (UI updates)

But JavaScript login didn't trigger either, leaving the authentication state
stale.

Solution: Convert AdminLoginForm from HTML+JavaScript to pure Blazor component.
Now the login flow is:
1. User enters credentials in Blazor form
2. HttpClient POST to /api/auth/login
3. Save tokens to localStorage
4. Call CustomAuthenticationStateProvider.LoginAsync() directly
5. Blazor detects auth state change and re-evaluates [Authorize] pages
6. Dashboard [Authorize] page renders successfully

Result: Immediate authentication state update, no loading timeout on protected pages.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-07-03 13:03:53 +09:00
parent 041d3cae96
commit 40cffb3beb
326 changed files with 327714 additions and 47 deletions
@@ -0,0 +1,68 @@
VANTA.HALO({
el: "#net",
mouseControls: false,
touchControls: false,
gyroControls: false,
color: 0xfd3995,
size: 1.6,
scale: 0.75,
xOffset: 0.22,
scaleMobile: 0.50,
});
// Typewriter effect script (ES5)
var textElement = document.getElementById('typewriter-text'); // Element to display text
var messages = [
"The world's first Admin WebApp built with Artificial Intelligence",
"AIready by design: prewritten prompt instructions included",
"An advanced, jQueryfree Bootstrap 5 Admin Dashboard UI",
"Built for the next generation of enterprise web applications",
"Clean, scalable, and engineered for futureforward growth",
"Continuously updated by a team of expert developers",
"Enterprise-grade performance with beautiful design",
"One dashboard template, unlimited use cases",
"Modern, responsive UI built for serious development"
];
var currentMessageIndex = 0;
var isDeleting = false;
var typingSpeed = 15; // Speed of typing/deleting in milliseconds
var pauseSpeed = 3000; // Pause between cycles in milliseconds
function typeWrite() {
var fullText = messages[currentMessageIndex];
var currentText = textElement.textContent;
var isEndOfMessage = !isDeleting && currentText === fullText;
var isStartOfMessage = isDeleting && currentText === '';
if (isEndOfMessage) {
setTimeout(function () {
isDeleting = true;
typeWrite();
}, pauseSpeed);
return;
}
if (isStartOfMessage) {
isDeleting = false;
currentMessageIndex = (currentMessageIndex + 1) % messages.length;
typeWrite();
return;
}
if (isDeleting) {
currentText = currentText.slice(0, -1);
}
else {
currentText = fullText.slice(0, currentText.length + 1);
}
textElement.textContent = currentText;
setTimeout(typeWrite, typingSpeed);
}
// Start the typewriter effect
if (textElement) {
textElement.textContent = '';
typeWrite();
}
else {
console.error('Typewriter text element not found');
}