fix(login): resolve session persistence and UI state after successful login
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 <noreply@anthropic.com>
This commit is contained in:
parent
a99070ba6d
commit
844b15af4d
@ -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) {
|
||||
|
||||
@ -34,6 +34,46 @@ export default function Navbar({ language, user, pathname = '/' }: NavbarProps)
|
||||
const searchValue = useSignal('')
|
||||
const navRef = useRef<HTMLElement>(null)
|
||||
|
||||
// Use provided user from server, but try to fetch fresh session on client
|
||||
const currentUser = useSignal<User | null>(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)
|
||||
</button>
|
||||
</form>
|
||||
|
||||
<UserMenu user={user} language={language} />
|
||||
<UserMenu user={currentUser.value} language={language} />
|
||||
|
||||
{/* Mail Icon */}
|
||||
<a
|
||||
@ -309,7 +349,7 @@ export default function Navbar({ language, user, pathname = '/' }: NavbarProps)
|
||||
</div>
|
||||
|
||||
<div onClick={() => (menuOpen.value = false)}>
|
||||
<UserMenu user={user} language={language} />
|
||||
<UserMenu user={currentUser.value} language={language} />
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col gap-2">
|
||||
|
||||
Loading…
Reference in New Issue
Block a user