diff --git a/app/protected/messages/page.tsx b/app/protected/messages/page.tsx index eaf4c8b8..8e4ee619 100644 --- a/app/protected/messages/page.tsx +++ b/app/protected/messages/page.tsx @@ -103,12 +103,14 @@ export default function MessagesPage() {

{conversationName}

- {!selectedConversation.is_group && selectedConversation.other_user && ( + {!selectedConversation.is_group && selectedConversation.other_user && selectedConversation.other_user.id ? ( + ) : !selectedConversation.is_group && ( + No user data )}
diff --git a/components/messages/ConversationList.tsx b/components/messages/ConversationList.tsx index 9b0b1669..67fe22c1 100644 --- a/components/messages/ConversationList.tsx +++ b/components/messages/ConversationList.tsx @@ -18,6 +18,20 @@ interface ConversationListProps { } export function ConversationList({ conversations, selectedId, onSelect, loading }: ConversationListProps) { + // Debug: Log conversations data (must be before any returns) + React.useEffect(() => { + if (!loading && conversations.length > 0) { + console.log('ConversationList conversations:', conversations.map(c => ({ + id: c.id, + is_group: c.is_group, + other_user: c.other_user ? { + id: c.other_user.id, + username: c.other_user.username + } : null + }))) + } + }, [conversations, loading]) + if (loading) { return (
@@ -85,11 +99,14 @@ export function ConversationList({ conversations, selectedId, onSelect, loading {initials} - {!conversation.is_group && otherUser && ( + {!conversation.is_group && otherUser && otherUser.id && (
)} + {!conversation.is_group && !otherUser && ( +
+ )}
diff --git a/components/messages/UserStatusIndicator.tsx b/components/messages/UserStatusIndicator.tsx index 3549b21c..6177e6dc 100644 --- a/components/messages/UserStatusIndicator.tsx +++ b/components/messages/UserStatusIndicator.tsx @@ -17,7 +17,26 @@ export function UserStatusIndicator({ }: UserStatusIndicatorProps) { const { presence, loading } = useUserPresence(userId) - if (loading || !presence) return null + // Debug logging + React.useEffect(() => { + if (presence) { + console.log('UserStatusIndicator for', userId, ':', { + isOnline: presence.isOnline, + lastSeen: presence.lastSeen, + loading + }) + } + }, [presence, userId, loading]) + + if (loading) { + console.log('UserStatusIndicator loading for', userId) + return null + } + + if (!presence) { + console.log('UserStatusIndicator no presence data for', userId) + return null + } const sizeClasses = { sm: 'w-2 h-2', diff --git a/hooks/useUserPresence.ts b/hooks/useUserPresence.ts index 52a170d1..4a853a6e 100644 --- a/hooks/useUserPresence.ts +++ b/hooks/useUserPresence.ts @@ -26,19 +26,35 @@ export function useUserPresence(userId: string | null) { .from('user_presence') .select('*') .eq('user_id', userId) - .single() + .maybeSingle() // Use maybeSingle instead of single to handle no results + + if (error) { + console.error('Error fetching presence:', error) + } if (data) { + console.log('Fetched presence for user:', userId, data) setPresence({ userId: data.user_id, isOnline: data.is_online, lastSeen: data.last_seen }) + } else { + // No presence record yet - user is offline + console.log('No presence record for user:', userId) + setPresence({ + userId: userId, + isOnline: false, + lastSeen: null + }) } setLoading(false) } fetchPresence() + + // Refresh presence every 10 seconds to catch updates + const refreshInterval = setInterval(fetchPresence, 10000) // Subscribe to presence changes const subscription = supabase @@ -52,9 +68,15 @@ export function useUserPresence(userId: string | null) { filter: `user_id=eq.${userId}` }, (payload) => { + console.log('🔔 Presence update received for', userId, payload) // eslint-disable-next-line @typescript-eslint/no-explicit-any const newData = payload.new as any if (newData) { + console.log('📡 Updating presence state:', { + userId: newData.user_id, + isOnline: newData.is_online, + lastSeen: newData.last_seen + }) setPresence({ userId: newData.user_id, isOnline: newData.is_online, @@ -63,10 +85,13 @@ export function useUserPresence(userId: string | null) { } } ) - .subscribe() + .subscribe((status) => { + console.log('Subscription status for', userId, ':', status) + }) return () => { subscription.unsubscribe() + clearInterval(refreshInterval) } }, [userId]) @@ -85,37 +110,65 @@ export function useMyPresence() { // Set user as online const setOnline = async () => { - await supabase + const { error } = await supabase .from('user_presence') - .upsert({ - user_id: user.id, - is_online: true, - last_seen: new Date().toISOString() - }) + .upsert( + { + user_id: user.id, + is_online: true, + last_seen: new Date().toISOString(), + updated_at: new Date().toISOString() + }, + { + onConflict: 'user_id' + } + ) + + if (error) { + console.error('Error setting online:', error) + } else { + console.log('✅ Set user online:', user.id) + } } // Set user as offline const setOffline = async () => { - await supabase + const { error } = await supabase .from('user_presence') - .upsert({ - user_id: user.id, - is_online: false, - last_seen: new Date().toISOString() - }) + .upsert( + { + user_id: user.id, + is_online: false, + last_seen: new Date().toISOString(), + updated_at: new Date().toISOString() + }, + { + onConflict: 'user_id' + } + ) + + if (error) { + console.error('Error setting offline:', error) + } else { + console.log('❌ Set user offline:', user.id) + } } // Update presence every 30 seconds + // More frequent updates ensure status is current const updatePresence = async () => { if (document.visibilityState === 'visible') { await setOnline() } } - // Set online on mount + // Set online immediately on mount setOnline() + + // Also set online after a short delay to ensure it's registered + setTimeout(setOnline, 1000) - // Update presence periodically + // Update presence periodically (every 30 seconds) const interval = setInterval(updatePresence, 30000) // Handle visibility change