From 844b15af4dbe6f34311f8394c1968848279ec4e6 Mon Sep 17 00:00:00 2001 From: Haitao Pan Date: Wed, 5 Nov 2025 16:34:39 +0800 Subject: [PATCH] fix(login): resolve session persistence and UI state after successful login MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixed three critical issues with the login flow: 1. LOGIN SUCCESSFUL REDIRECT - Changed redirect from '/' to '/panel' (user personal dashboard) - Users now land on their panel page after login instead of home page 2. SESSION PERSISTENCE - Navbar now fetches fresh session data on client-side after login - Added useEffect in Navbar to call /api/auth/session on component mount - UserMenu dynamically updates to show logged-in state - Session data is fetched with credentials: 'include' 3. DYNAMIC USER STATE - Created currentUser signal in Navbar to track real-time auth state - UserMenu now receives currentUser.value instead of static server prop - User information updates immediately after successful login - No page refresh needed to see user menu change CHANGES: - LoginForm.tsx: Redirect to /panel after successful login - Navbar.tsx: Added session fetching on client-side mount - UserMenu: Receives live user data via currentUser signal The user will now see: ✅ Immediate UI update (UserMenu shows avatar/dropdown) ✅ Redirect to /panel (user dashboard) ✅ Session persists across page navigation 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- dashboard-fresh/islands/LoginForm.tsx | 4 +-- dashboard-fresh/islands/Navbar.tsx | 44 +++++++++++++++++++++++++-- 2 files changed, 44 insertions(+), 4 deletions(-) diff --git a/dashboard-fresh/islands/LoginForm.tsx b/dashboard-fresh/islands/LoginForm.tsx index e8ae29d..fef41e5 100644 --- a/dashboard-fresh/islands/LoginForm.tsx +++ b/dashboard-fresh/islands/LoginForm.tsx @@ -258,9 +258,9 @@ export default function LoginForm({ language, initialEmail = '', onSuccess }: Lo if (onSuccess) { onSuccess() } else { - // Redirect to home after short delay + // Redirect to user panel after short delay setTimeout(() => { - globalThis.location.href = '/' + globalThis.location.href = '/panel' }, 1000) } } catch (submitError) { diff --git a/dashboard-fresh/islands/Navbar.tsx b/dashboard-fresh/islands/Navbar.tsx index db9d5e7..67d0f1f 100644 --- a/dashboard-fresh/islands/Navbar.tsx +++ b/dashboard-fresh/islands/Navbar.tsx @@ -34,6 +34,46 @@ export default function Navbar({ language, user, pathname = '/' }: NavbarProps) const searchValue = useSignal('') const navRef = useRef(null) + // Use provided user from server, but try to fetch fresh session on client + const currentUser = useSignal(user || null) + + // Fetch session on client-side to get fresh user info + useEffect(() => { + let isActive = true + + const fetchSession = async () => { + try { + const response = await fetch('/api/auth/session', { + credentials: 'include', + }) + + if (!isActive || !response.ok) { + return + } + + const data = (await response.json()) as { + user?: User + } + + if (isActive && data.user) { + currentUser.value = data.user + } + } catch (error) { + // Silently fail if session fetch fails + console.debug('Failed to fetch session:', error) + } + } + + // Only fetch on client side + if (typeof window !== 'undefined') { + fetchSession() + } + + return () => { + isActive = false + } + }, []) + const isHiddenRoute = pathname ? ['/login', '/register'].some((prefix) => pathname.startsWith(prefix)) : false // Generate language toggle URL that preserves current path and params @@ -190,7 +230,7 @@ export default function Navbar({ language, user, pathname = '/' }: NavbarProps) - + {/* Mail Icon */}
(menuOpen.value = false)}> - +