'use client';
import React, { useState, useEffect, useRef, useCallback, memo } from 'react';
import { useAtom } from 'jotai';
import Image from 'next/image';
import {
ArrowLeft,
Send,
Mic,
Smile,
Info,
Phone,
Video,
X,
Image as ImageIcon,
BotMessageSquare,
} from 'lucide-react';
import { cn } from './utils';
import { ChatMessage, ChatUser } from './types';
import { isMobileAtom, chatDetailOpenAtom } from './store';
// Mock messages for demonstration
const mockMessages: ChatMessage[] = [
{
id: '1',
content: 'Hello, how are you doing today?',
senderId: 'other',
timestamp: '10:30 AM',
},
{
id: '2',
content: "I'm doing well, thanks for asking! How about you?",
senderId: 'me',
timestamp: '10:31 AM',
},
{
id: '3',
content:
'Pretty good. I was wondering if you had time to catch up on the project later today?',
senderId: 'other',
timestamp: '10:32 AM',
},
{
id: '4',
content: "Sure, I'm free after 3 PM. Would that work for you?",
senderId: 'me',
timestamp: '10:33 AM',
},
{
id: '5',
content: "That sounds perfect. Let's meet at the usual place?",
senderId: 'other',
timestamp: '10:35 AM',
},
];
// Memoized individual message component
const MessageItem = memo(
({ message, user }: { message: ChatMessage; user: ChatUser }) => {
const isFromMe = message.senderId === 'me';
return (
{!isFromMe && (
{user.avatar ? (
) : (
{user.name.charAt(0)}
)}
)}
{message.content}
{message.timestamp}
);
}
);
MessageItem.displayName = 'MessageItem';
// Chat details sidebar component
const ChatDetailsSidebar = memo(
({ user, onClose }: { user: ChatUser; onClose: () => void }) => {
return (
Details
Members
{user.avatar ? (
) : (
{user.name.charAt(0)}
)}
{user.name}
{user.name.toLowerCase().replace(/\s/g, '')}
);
}
);
ChatDetailsSidebar.displayName = 'ChatDetailsSidebar';
interface ChatDetailProps {
user: ChatUser;
onBack: () => void;
}
const ChatDetail: React.FC = ({ user, onBack }) => {
const [isMobile] = useAtom(isMobileAtom);
const [, setChatDetailOpen] = useAtom(chatDetailOpenAtom);
const [messages, setMessages] = useState(mockMessages);
const [inputValue, setInputValue] = useState('');
const [isDetailSidebarOpen, setIsDetailSidebarOpen] = useState(false);
const messagesEndRef = useRef(null);
const messageContainerRef = useRef(null);
// Scroll to bottom when messages change
useEffect(() => {
if (messagesEndRef.current) {
messagesEndRef.current.scrollIntoView({ behavior: 'smooth' });
}
}, [messages]);
// Add message handler
const addMessage = useCallback((message: ChatMessage) => {
setMessages((prev) => [...prev, message]);
}, []);
// Send message handler
const handleSend = useCallback(() => {
if (inputValue.trim()) {
const newMessage: ChatMessage = {
id: `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,
content: inputValue,
senderId: 'me',
timestamp: new Date().toLocaleTimeString([], {
hour: '2-digit',
minute: '2-digit',
}),
};
addMessage(newMessage);
setInputValue('');
// Simulate response after a delay
setTimeout(() => {
const responseMessage: ChatMessage = {
id: `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,
content: "Thanks for your message. I'll get back to you soon!",
senderId: 'other',
timestamp: new Date().toLocaleTimeString([], {
hour: '2-digit',
minute: '2-digit',
}),
};
addMessage(responseMessage);
}, 1000);
}
}, [inputValue, addMessage]);
// Back button handler
const handleBack = useCallback(() => {
setChatDetailOpen(false);
onBack();
}, [setChatDetailOpen, onBack]);
// Handle enter key press in input field
const handleKeyDown = useCallback(
(e: React.KeyboardEvent) => {
if (e.key === 'Enter' && !e.shiftKey) {
e.preventDefault();
handleSend();
}
},
[handleSend]
);
// Toggle details sidebar
const toggleDetailSidebar = useCallback(() => {
setIsDetailSidebarOpen((prev) => !prev);
}, []);
return (
{/* Main Chat Area */}
{/* Header */}
{user.avatar ? (
) : (
{user.name.charAt(0)}
)}
{user.name}
Active 5h ago
{/* Messages */}
{messages.map((message) => (
))}
{/* Input */}
{/* Detail Sidebar */}
{isDetailSidebarOpen && (
)}
);
};
export default memo(ChatDetail);