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 (
+
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[] = [
{