import { Reply, MoreVertical, Trash2, Check } from "lucide-react"; import { Link } from "@remix-run/react"; import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, } from "../ui/dropdown-menu"; import { formatTime, formatDate2 } from "../../utils/helpers"; import { MessageList, ThreadParticipant } from "../../../src/api/types/models"; import { Dialog, DialogContent, DialogOverlay } from "../ui/dialog"; import { Button } from "../ui/button"; import { useState, useRef, useEffect } from "react"; // Message bubble component // // isCurrentUser: whether this message belongs to "our side" of the chat. // In seller-side threads that includes coworkers, not just yourself. // isCoworker: this message was written by a teammate (owner or staff) other // than the viewer. We still put it on the right side, but we surface the // sender's name so you can tell who typed it — and we don't offer to // delete it (backend only lets a user delete their own messages). export const MessageBubble = ({ message, isCurrentUser, isCoworker = false, onReply, onDelete, replyToMessageContent, onReplyClick, isHighlighted = false, otherParticipant, }: { message: MessageList; isCurrentUser: boolean; isCoworker?: boolean; onReply: (message: MessageList) => void; onDelete?: (messageId: string) => void; replyToMessageContent?: string | undefined; onReplyClick?: (replyToId: string) => void; isHighlighted?: boolean; otherParticipant: ThreadParticipant | undefined; }) => { const [showDeleteDialog, setShowDeleteDialog] = useState(false); const [showDropdownMenu, setShowDropdownMenu] = useState(false); const messageRef = useRef(null); useEffect(() => { if (isHighlighted && messageRef.current) { messageRef.current.classList.add("highlight-message"); // Remove highlight after animation completes const timeout = setTimeout(() => { if (messageRef.current) { messageRef.current.classList.remove("highlight-message"); } }, 1500); return () => clearTimeout(timeout); } }, [isHighlighted]); return ( <>
{isCoworker && message.senderUsername && (
{message.senderUsername}
)} {message.replyTo && (
onReplyClick?.(message.replyTo || "")} onKeyDown={(e) => { if (e.key === "Enter" || e.key === " ") { onReplyClick?.(message.replyTo || ""); } }} role="button" tabIndex={0} aria-label="پیام اصلی را نمایش بده" > {/* Display replied message content if available */} {replyToMessageContent || "پاسخ به پیام"}
)} {message.product && ( {message.product.primaryImage ? ( ) : (
)}

{message.product.title}

{message.product.basePrice && (

{parseInt(message.product.basePrice).toLocaleString("fa-IR")}{" "} تومان

)}
)} {message.imageUrl && ( window.open(message.imageUrl, "_blank")} /> )} {message.content &&

{message.content}

}
onReply(message)} className="cursor-pointer justify-end" > پاسخ {isCurrentUser && !isCoworker && ( { setShowDropdownMenu(false); setShowDeleteDialog(true); }} className="cursor-pointer text-red-500 justify-end" > حذف پیام )}

{formatTime(message.createdAt || "")}

{isCurrentUser && (
{new Date(message.createdAt || "").getTime() < new Date(otherParticipant?.lastReadAt || "").getTime() ? (
) : ( )}
)}
onDelete?.(message.id || "")} /> ); }; const DeleteConfirmBox = ({ showDeleteDialog, setShowDeleteDialog, confirmDelete, }: { showDeleteDialog: boolean; setShowDeleteDialog: (show: boolean) => void; confirmDelete: () => void; }) => { return (

حذف پیام

میخواهید این پیام را حذف کنید؟

); }; // Date separator component export const DateSeparator = ({ date }: { date: string }) => { return (
{formatDate2(date)}
); };