Files
pagodera/components/chat/ChatModal.tsx
T
Evandro Fonseca Junior 7f42def478 feat(market): add Minha Intenções tab with panel, hook, and badge
- Introduced "Minhas Intenções" tab visible only to logged-in users.
- Integrated MyPurchaseIntentionsPanel and useMyPurchaseIntentions hook.
- Added tab badge showing count of pending intentions.
- Extended session API to include user’s main character for downstream features.
2025-11-07 17:25:51 -03:00

148 lines
3.9 KiB
TypeScript

"use client";
import { useState, useEffect } from "react";
import {
Dialog,
DialogContent,
DialogDescription,
DialogHeader,
DialogTitle,
} from "@/components/ui/dialog";
import { ChatHeader } from "./ChatHeader";
import { MessageList } from "./MessageList";
import { MessageInput } from "./MessageInput";
import { useChat } from "@/lib/hooks/use-chat";
import { useSession } from "@/lib/hooks/use-session";
import { Skeleton } from "@/components/ui/skeleton";
interface ChatModalProps {
open: boolean;
onOpenChange: (open: boolean) => void;
listingId?: number | null;
chatId?: string | null;
initialMessage?: string;
}
export function ChatModal({
open,
onOpenChange,
listingId,
chatId: initialChatId,
initialMessage,
}: ChatModalProps) {
const { user } = useSession();
const [chatId, setChatId] = useState<string | null>(initialChatId || null);
const [isCreatingChat, setIsCreatingChat] = useState(false);
const {
chat,
messages,
isLoading,
isSending,
sendMessage,
loadMoreMessages,
hasMore,
otherUserTyping,
} = useChat(chatId);
// Se chatId for fornecido diretamente, usar ele
useEffect(() => {
if (initialChatId) {
setChatId(initialChatId);
return;
}
}, [initialChatId]);
// Criar ou buscar chat quando modal abrir (apenas se não tiver chatId)
useEffect(() => {
if (!open || !user || !listingId || initialChatId) {
if (!initialChatId && !listingId) {
setChatId(null);
}
return;
}
const createOrGetChat = async () => {
setIsCreatingChat(true);
try {
const res = await fetch("/api/chats", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
credentials: "include",
body: JSON.stringify({
listing_id: listingId,
buyer_message: initialMessage,
}),
});
if (!res.ok) {
throw new Error("Erro ao criar chat");
}
const data = await res.json();
setChatId(data.chat.chat_id);
// Se houver mensagem inicial, já foi enviada no backend
} catch (error) {
console.error("Erro ao criar/buscar chat:", error);
} finally {
setIsCreatingChat(false);
}
};
createOrGetChat();
}, [open, user, listingId, initialMessage, initialChatId]);
if (!user) {
return null;
}
return (
<Dialog open={open} onOpenChange={onOpenChange}>
<DialogContent className="max-w-2xl h-[80vh] flex flex-col p-0 gap-0">
<DialogHeader className="sr-only">
<DialogTitle>Chat com vendedor</DialogTitle>
<DialogDescription>
Conversa sobre o anúncio
</DialogDescription>
</DialogHeader>
{isCreatingChat || (isLoading && !chat) ? (
<div className="flex-1 flex items-center justify-center">
<div className="space-y-4 w-full px-4">
<Skeleton className="h-24 w-full" />
<Skeleton className="h-64 w-full" />
<Skeleton className="h-20 w-full" />
</div>
</div>
) : chat ? (
<>
<ChatHeader chat={chat} currentUserId={user.userId} />
<MessageList
messages={messages}
currentUserId={user.userId}
isLoading={isLoading}
onLoadMore={loadMoreMessages}
hasMore={hasMore}
otherUserTyping={otherUserTyping}
/>
<MessageInput
onSend={sendMessage}
isSending={isSending}
disabled={!chat.is_active}
chatId={chatId}
/>
</>
) : (
<div className="flex-1 flex items-center justify-center text-center text-muted-foreground">
<p>Erro ao carregar chat</p>
</div>
)}
</DialogContent>
</Dialog>
);
}