import React, { useState } from "react"; import { base44 } from "@/api/base44Client"; import { useQuery } from "@tanstack/react-query"; import { MessageSquare, X, Send, Minimize2, Maximize2 } from "lucide-react"; import { Button } from "@/components/ui/button"; import { Card, CardHeader, CardTitle, CardContent } from "@/components/ui/card"; import { Input } from "@/components/ui/input"; import { Badge } from "@/components/ui/badge"; import { Avatar, AvatarFallback } from "@/components/ui/avatar"; import { ScrollArea } from "@/components/ui/scroll-area"; import { motion, AnimatePresence } from "framer-motion"; import { format } from "date-fns"; import { useNavigate } from "react-router-dom"; import { createPageUrl } from "@/utils"; export default function ChatBubble() { const [isOpen, setIsOpen] = useState(false); const [isMinimized, setIsMinimized] = useState(false); const [selectedConv, setSelectedConv] = useState(null); const [messageInput, setMessageInput] = useState(""); const navigate = useNavigate(); const { data: user } = useQuery({ queryKey: ['current-user'], queryFn: () => base44.auth.me(), }); const { data: conversations, refetch: refetchConversations } = useQuery({ queryKey: ['conversations-bubble'], queryFn: () => base44.entities.Conversation.list('-last_message_at', 5), initialData: [], refetchInterval: 10000, // Refresh every 10 seconds }); const { data: messages, refetch: refetchMessages } = useQuery({ queryKey: ['messages-bubble', selectedConv?.id], queryFn: () => base44.entities.Message.filter({ conversation_id: selectedConv?.id }), initialData: [], enabled: !!selectedConv?.id, refetchInterval: 5000, // Refresh every 5 seconds when viewing }); const totalUnread = conversations.reduce((sum, conv) => sum + (conv.unread_count || 0), 0); const handleSendMessage = async () => { if (!messageInput.trim() || !selectedConv) return; await base44.entities.Message.create({ conversation_id: selectedConv.id, sender_id: user.id, sender_name: user.full_name || user.email, sender_role: user.role || "admin", content: messageInput.trim(), read_by: [user.id] }); await base44.entities.Conversation.update(selectedConv.id, { last_message: messageInput.trim().substring(0, 100), last_message_at: new Date().toISOString() }); setMessageInput(""); refetchMessages(); refetchConversations(); }; const getRoleColor = (role) => { const colors = { client: "bg-purple-100 text-purple-700", vendor: "bg-amber-100 text-amber-700", staff: "bg-blue-100 text-blue-700", admin: "bg-slate-100 text-slate-700" }; return colors[role] || "bg-slate-100 text-slate-700"; }; return ( <> {/* Chat Bubble Button */} {!isOpen && ( )} {/* Chat Window */} {isOpen && ( {/* Header */}
{selectedConv ? selectedConv.subject : 'Messages'} {selectedConv && (

{selectedConv.is_group ? `${selectedConv.participants?.length || 0} members` : selectedConv.participants?.[1]?.name || 'Chat'}

)} {!selectedConv && (

{totalUnread > 0 ? `${totalUnread} unread` : 'Online'}

)}
{selectedConv && ( )}
{!isMinimized && ( {!selectedConv ? ( <> {/* Conversations List */}
{conversations.length === 0 ? (

No conversations yet

) : ( conversations.map((conv) => { const otherParticipant = conv.participants?.[1] || conv.participants?.[0] || {}; return ( setSelectedConv(conv)} >
{conv.is_group ? : otherParticipant.name?.charAt(0) || '?'}

{conv.is_group ? conv.group_name : (conv.subject || otherParticipant.name)}

{conv.unread_count > 0 && ( {conv.unread_count} )}

{conv.last_message || "No messages yet"}

{conv.last_message_at && (

{format(new Date(conv.last_message_at), "MMM d, h:mm a")}

)}
); }) )}
{/* Quick Action */}
) : ( <> {/* Messages Thread */}
{messages.map((message) => { const isOwnMessage = message.sender_id === user?.id || message.created_by === user?.id; return (
{message.sender_name?.charAt(0) || '?'}

{message.content}

{message.created_date && format(new Date(message.created_date), "h:mm a")}

); })}
{/* Message Input */}
setMessageInput(e.target.value)} onKeyPress={(e) => e.key === 'Enter' && handleSendMessage()} className="flex-1" />
)}
)}
)}
); }