import React, { useEffect, useState } from 'react'; import { useChatStore } from '../store/chatStore'; import { useAuthStore } from '@/features/auth/store/authStore'; import { apiClient } from '@/services/api/client'; import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'; import { cn } from '@/lib/utils'; import { Loader2, Plus, Trash2, LogOut } from 'lucide-react'; import { CreateRoomDialog } from './CreateRoomDialog'; import { useToast } from '@/hooks/useToast'; import { Button } from '@/components/ui/button'; import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, } from '@/components/ui/dropdown-menu'; import { MoreVertical } from 'lucide-react'; import { ConfirmationDialog } from '@/components/ui/confirmation-dialog'; // FE-PAGE-005: Complete Chat page implementation - Room Management interface ConversationItemProps { conversation: { id: string; name: string; type: string }; onSelect: (id: string) => void; isSelected: boolean; } const ConversationItem: React.FC = ({ conversation, onSelect, isSelected, }) => { const { user } = useAuthStore(); const queryClient = useQueryClient(); const toast = useToast(); const { setCurrentConversation } = useChatStore(); const [showLeaveDialog, setShowLeaveDialog] = useState(false); const [showDeleteDialog, setShowDeleteDialog] = useState(false); const leaveRoomMutation = useMutation({ mutationFn: async (roomId: string) => { await apiClient.delete(`/conversations/${roomId}/participants/${user?.id}`); }, onSuccess: () => { queryClient.invalidateQueries({ queryKey: ['chatConversations', user?.id] }); toast.success('Left room successfully'); setCurrentConversation(null); setShowLeaveDialog(false); }, onError: (error: any) => { toast.error(error.response?.data?.error || 'Failed to leave room'); }, }); const deleteRoomMutation = useMutation({ mutationFn: async (roomId: string) => { await apiClient.delete(`/conversations/${roomId}`); }, onSuccess: () => { queryClient.invalidateQueries({ queryKey: ['chatConversations', user?.id] }); toast.success('Room deleted successfully'); setCurrentConversation(null); setShowDeleteDialog(false); }, onError: (error: any) => { toast.error(error.response?.data?.error || 'Failed to delete room'); }, }); const handleLeave = (e: React.MouseEvent) => { e.stopPropagation(); setShowLeaveDialog(true); }; const handleDelete = (e: React.MouseEvent) => { e.stopPropagation(); setShowDeleteDialog(true); }; const confirmLeave = () => { leaveRoomMutation.mutate(conversation.id); }; const confirmDelete = () => { deleteRoomMutation.mutate(conversation.id); }; return ( <>
onSelect(conversation.id)} className={cn( 'flex items-center justify-between p-3 rounded-lg cursor-pointer transition-colors group', isSelected ? 'bg-blue-100 text-blue-800' : 'hover:bg-gray-100', )} > {conversation.name || `Conversation ${conversation.id.substring(0, 8)}`} e.stopPropagation()}> Leave Room {conversation.type !== 'direct' && ( Delete Room )}
setShowLeaveDialog(false)} onConfirm={confirmLeave} title="Leave Room" description="Are you sure you want to leave this room? You will no longer receive messages from this conversation." confirmLabel="Leave" cancelLabel="Cancel" variant="default" isLoading={leaveRoomMutation.isPending} /> setShowDeleteDialog(false)} onConfirm={confirmDelete} title="Delete Room" description="Are you sure you want to delete this room? This action cannot be undone. All messages and participants will be removed." confirmLabel="Delete" cancelLabel="Cancel" variant="destructive" isLoading={deleteRoomMutation.isPending} /> ); }; export const ChatSidebar: React.FC = () => { const { user } = useAuthStore(); const userId = user?.id; const { conversations, currentConversationId, setCurrentConversation, addConversation, } = useChatStore(); const [isCreateDialogOpen, setIsCreateDialogOpen] = useState(false); // Fetch conversations from backend const { data, isLoading, error } = useQuery({ queryKey: ['chatConversations', userId], queryFn: async () => { if (!userId) return []; const response = await apiClient.get('/conversations'); return response.data.conversations; }, enabled: !!userId, }); useEffect(() => { if (data) { data.forEach((conv: any) => addConversation({ id: conv.id, name: conv.name, type: conv.type, participants: conv.participants, unread_count: 0, // Default for now }), ); } }, [data, addConversation]); if (isLoading) { return (
); } if (error) { return (
Erreur:{' '} {(error as any).message || 'Impossible de charger les conversations'}
); } return (

Conversations

{conversations.length === 0 ? (
Aucune conversation. Créez-en une !
) : ( conversations.map((conv) => ( )) )}
setIsCreateDialogOpen(false)} />
); };