From eefc4bcd7899cb754eef74fdcc348171903f7df5 Mon Sep 17 00:00:00 2001 From: pradeepkumar Date: Mon, 9 Feb 2026 00:03:45 +0530 Subject: [PATCH] feat: Redirect authenticated users from auth pages and enable event-driven profile data refresh in the settings sidebar. --- src/app/(auth)/layout.tsx | 56 ++++++++++++ .../settings/ProfileSettingsForm.tsx | 20 +---- src/components/settings/SettingsSidebar.tsx | 87 +++++++++++-------- 3 files changed, 109 insertions(+), 54 deletions(-) diff --git a/src/app/(auth)/layout.tsx b/src/app/(auth)/layout.tsx index 08da1e6..d0cf22e 100644 --- a/src/app/(auth)/layout.tsx +++ b/src/app/(auth)/layout.tsx @@ -1,8 +1,64 @@ +'use client'; + +import { useSession } from 'next-auth/react'; +import { useRouter } from 'next/navigation'; +import { useEffect } from 'react'; + export default function AuthLayout({ children, }: { children: React.ReactNode; }) { + const { data: session, status } = useSession(); + const router = useRouter(); + + useEffect(() => { + if (status === 'loading') return; + + // Redirect authenticated users away from auth pages + if (session) { + const userRole = (session.user as any)?.role; + if (userRole === 'AGENT') { + router.replace('/agent/dashboard'); + } else { + router.replace('/user/dashboard'); + } + } + }, [session, status, router]); + + // Show loading spinner while checking authentication + if (status === 'loading') { + return ( +
+
+ RE-Quest +
+
+
+ ); + } + + // Show loading while redirecting authenticated users + if (session) { + return ( +
+
+ RE-Quest +
+
+
+ ); + } + + // Only render auth pages for unauthenticated users return (
diff --git a/src/components/settings/ProfileSettingsForm.tsx b/src/components/settings/ProfileSettingsForm.tsx index dc8f462..66d84a1 100644 --- a/src/components/settings/ProfileSettingsForm.tsx +++ b/src/components/settings/ProfileSettingsForm.tsx @@ -189,20 +189,13 @@ export function ProfileSettingsForm({ // Clean up local preview URL only after successful presigned URL URL.revokeObjectURL(localPreviewUrl); - // Update the session to reflect the new avatar - await updateSession({ - ...session, - user: { - ...session?.user, - image: presignedUrl, - }, - }); - // Dispatch event to notify header to refresh profile data window.dispatchEvent(new Event('profile-updated')); } catch { // If presigned URL fails, keep the local preview (don't revoke it) console.warn('Could not get presigned URL, using local preview'); + // Still dispatch event to refresh header + window.dispatchEvent(new Event('profile-updated')); } setSuccessMessage('Profile picture updated successfully!'); @@ -254,15 +247,6 @@ export function ProfileSettingsForm({ } setAvatarUrl(null); - // Update session - await updateSession({ - ...session, - user: { - ...session?.user, - image: null, - }, - }); - // Dispatch event to notify header to refresh profile data window.dispatchEvent(new Event('profile-updated')); diff --git a/src/components/settings/SettingsSidebar.tsx b/src/components/settings/SettingsSidebar.tsx index 1f31963..b77d9a6 100644 --- a/src/components/settings/SettingsSidebar.tsx +++ b/src/components/settings/SettingsSidebar.tsx @@ -1,6 +1,6 @@ 'use client'; -import { useState, useEffect } from 'react'; +import { useState, useEffect, useCallback } from 'react'; import Image from 'next/image'; import Link from 'next/link'; import { usePathname } from 'next/navigation'; @@ -31,51 +31,66 @@ export function SettingsSidebar({ avatarUrl: session?.user?.image || null, }); - useEffect(() => { - const fetchProfile = async () => { - try { - const role = (session?.user as any)?.role; - let avatarUrl = session?.user?.image || null; - let name = session?.user?.name || 'User'; - let title = 'User'; + const fetchProfile = useCallback(async () => { + try { + const role = (session?.user as any)?.role; + let avatarUrl: string | null = null; + let name = session?.user?.name || 'User'; + let title = 'User'; - if (role === 'AGENT') { - const profile = await agentsService.getMyProfile(); - name = `${profile.firstName || ''} ${profile.lastName || ''}`.trim() || name; - title = profile.agentType?.name || 'Real Estate Agent'; + if (role === 'AGENT') { + const profile = await agentsService.getMyProfile(); + name = `${profile.firstName || ''} ${profile.lastName || ''}`.trim() || name; + title = profile.agentType?.name || 'Real Estate Agent'; - if (profile.avatar) { - try { - avatarUrl = await uploadService.getPresignedDownloadUrl(profile.avatar); - } catch { - avatarUrl = profile.avatar; - } - } - } else if (role === 'USER') { - const profile = await usersService.getMyProfile(); - name = `${profile.firstName || ''} ${profile.lastName || ''}`.trim() || name; - title = 'Member'; - - if (profile.avatar) { - try { - avatarUrl = await uploadService.getPresignedDownloadUrl(profile.avatar); - } catch { - avatarUrl = profile.avatar; - } + if (profile.avatar) { + try { + avatarUrl = await uploadService.getPresignedDownloadUrl(profile.avatar); + } catch { + avatarUrl = profile.avatar; } } + } else if (role === 'USER') { + const profile = await usersService.getMyProfile(); + name = `${profile.firstName || ''} ${profile.lastName || ''}`.trim() || name; + title = 'Member'; - setProfileData({ name, title, avatarUrl }); - } catch (err) { - console.error('Failed to fetch profile for sidebar:', err); - // Keep session data as fallback + if (profile.avatar) { + try { + avatarUrl = await uploadService.getPresignedDownloadUrl(profile.avatar); + } catch { + avatarUrl = profile.avatar; + } + } } - }; + setProfileData({ name, title, avatarUrl }); + } catch (err) { + console.error('Failed to fetch profile for sidebar:', err); + // Keep session data as fallback + } + }, [session]); + + // Fetch profile on mount + useEffect(() => { if (session) { fetchProfile(); } - }, [session]); + }, [session, fetchProfile]); + + // Listen for profile update events to refresh the sidebar + useEffect(() => { + const handleProfileUpdate = () => { + if (session) { + fetchProfile(); + } + }; + + window.addEventListener('profile-updated', handleProfileUpdate); + return () => { + window.removeEventListener('profile-updated', handleProfileUpdate); + }; + }, [session, fetchProfile]); const navItems: NavItem[] = [ {