fix: implement Blazor-native login form to properly update authentication state
TaxBaik CI/CD / build-and-deploy (push) Successful in 2m26s
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:
@@ -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",
|
||||
"AI‑ready by design: pre‑written prompt instructions included",
|
||||
"An advanced, jQuery‑free Bootstrap 5 Admin Dashboard UI",
|
||||
"Built for the next generation of enterprise web applications",
|
||||
"Clean, scalable, and engineered for future‑forward 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');
|
||||
}
|
||||
Reference in New Issue
Block a user