/** * @file components/chat/ChatItem.tsx * @description Single message row component with support for user avatars, metadata, and deletion handling. */ "use client"; import type { Message, Member, User } from "@/db/schema"; import { UserAvatar } from "../ui/UserAvatar"; import { useState } from "react"; import { useRouter } from "next/navigation"; import { Trash2 } from "lucide-react"; /** * Composite message type extending base database Message with populated member and user relation. * * @interface MessageWithMember * @property {string} id - The unique identifier of the message. * @property {string} content - The text content of the message. * @property {string} createdAt - The timestamp when the message was created. * @property {Member & { user: User }} member - The associated member and user relational data. */ export type MessageWithMember = Message & { member: Member & { user: User; }; }; /** * Props for the ChatItem component. * * @interface ChatItemProps * @property {MessageWithMember} message - The message object containing member and user relational data. * @property {string} [currentUserId] - The unique identifier of the currently logged-in user. */ interface ChatItemProps { message: MessageWithMember; currentUserId?: string; } /** * Renders an individual chat message row displaying user avatar, sender name, timestamp, and text content. * * @async * @param {ChatItemProps} props - The component props. * @param {MessageWithMember} props.message - The message object containing member and user relational data. * @param {string} [props.currentUserId] - The unique identifier of the currently logged-in user. * @returns {JSX.Element} The rendered single chat message item. */ export function ChatItem({ message, currentUserId }: ChatItemProps) { const router = useRouter(); const [isDeleting, setIsDeleting] = useState(false); const user = message.member?.user; const fullName = user ? user.username.trim() : "Deleted Member"; const isOwner = user?.id === currentUserId; const formattedTime = new Date(message.createdAt).toLocaleTimeString( "de-DE", { hour: "2-digit", minute: "2-digit", }, ); /** * Handles the asynchronous deletion of the chat message. * * @async * @function handleDelete * @returns {Promise} Resolves when the deletion process completes or fails. */ const handleDelete = async () => { if (isDeleting) return; try { setIsDeleting(true); const response = await fetch(`/api/messages/${message.id}`, { method: "DELETE", }); if (!response.ok) { throw new Error("Error while deleting"); } router.refresh(); } catch (error) { console.error("Error deleting the message:", error); } finally { setIsDeleting(false); } }; return (
{/* Avatar Component */} {/* Message Content & Top Bar */}
{fullName} {formattedTime}
{/* Delete Button */} {isOwner && ( )}

{message.content}

); }