- {(!avatar || !avatarLoaded || isPlaceholder) && (
+
+ {isPlaceholder ? (
+
+
+
+ ) : !avatarLoaded ? (
- )}
+ ) : null}
{avatar && !isPlaceholder && (
![]()
{ if (el?.complete && el.naturalWidth > 0) setAvatarLoaded(true); }}
diff --git a/src/app/contact/page.tsx b/src/app/contact/page.tsx
index 93874ac..9beae7b 100644
--- a/src/app/contact/page.tsx
+++ b/src/app/contact/page.tsx
@@ -3,6 +3,7 @@
import Image from 'next/image';
import Link from 'next/link';
import { useState, useEffect } from 'react';
+import { useSession } from 'next-auth/react';
import { CommonHeader } from '@/components/layout/CommonHeader';
import { Footer } from '@/components/layout/Footer';
import { cmsService } from '@/services/cms.service';
@@ -47,6 +48,9 @@ const defaultCta: ContactCta = {
};
export default function ContactPage() {
+ const { data: session } = useSession();
+ const isAgent = (session?.user as any)?.role === 'AGENT';
+
const [formData, setFormData] = useState({
name: '',
phone: '',
@@ -345,21 +349,21 @@ export default function ContactPage() {
- {/* CTA Section - Ready to find an agent */}
+ {/* CTA Section */}
- {cta.title}
+ {isAgent ? 'Manage your profile' : cta.title}
- {cta.description}
+ {isAgent ? 'Keep your profile updated and connect with potential clients.' : cta.description}
- {cta.buttonText}
+ {isAgent ? 'Go to Dashboard' : cta.buttonText}
diff --git a/src/components/message/MessagingPage.tsx b/src/components/message/MessagingPage.tsx
index 9dc05cf..5377945 100644
--- a/src/components/message/MessagingPage.tsx
+++ b/src/components/message/MessagingPage.tsx
@@ -825,7 +825,13 @@ export function MessagingPage({ initialConversationId }: { initialConversationId
)}
- {conversation.lastMessageText || 'No messages yet'}
+ {conversation.lastMessageText
+ ? /giphy\.com|\.gif(\?|$)/i.test(conversation.lastMessageText)
+ ? 'GIF 🎬'
+ : /\.(jpg|jpeg|png|webp|svg)(\?|$)/i.test(conversation.lastMessageText) && conversation.lastMessageText.startsWith('http')
+ ? 'Image 📷'
+ : conversation.lastMessageText
+ : 'No messages yet'}
diff --git a/src/hooks/useMessaging.ts b/src/hooks/useMessaging.ts
index c9bf62d..edc0e84 100644
--- a/src/hooks/useMessaging.ts
+++ b/src/hooks/useMessaging.ts
@@ -480,6 +480,17 @@ export function useMessaging(options: UseMessagingOptions = {}): UseMessagingRet
if (prev.some((m) => m.id === message.id)) return prev;
return [...prev, message];
});
+
+ // Auto-mark as read if user is currently viewing this conversation
+ // (the other user sent a message while we're looking at the chat)
+ const currentUserId = (session?.user as any)?.id;
+ if (message.senderId !== currentUserId) {
+ if (isConnected) {
+ socketService.markAsRead(message.conversationId);
+ } else {
+ messagesService.markAsRead(message.conversationId).catch(() => {});
+ }
+ }
}
// Update conversation list
@@ -536,13 +547,15 @@ export function useMessaging(options: UseMessagingOptions = {}): UseMessagingRet
const unsubscribeRead = socketService.onMessagesRead(
(data: MessagesReadEvent) => {
if (data.conversationId === currentConversationIdRef.current) {
- // Update message statuses
+ const currentUserId = (session?.user as any)?.id;
+ // Only update status on messages SENT by current user (not received ones)
setMessages((prev) =>
- prev.map((m) => ({
- ...m,
- status: 'READ' as MessageStatus,
- readAt: data.readAt,
- }))
+ prev.map((m) => {
+ if (m.senderId === currentUserId && m.status !== 'READ') {
+ return { ...m, status: 'READ' as MessageStatus, readAt: data.readAt };
+ }
+ return m;
+ })
);
}
}