"use client" import { useState, useRef, useCallback, useEffect } from "react" import { cn } from "@/lib/utils" import { Button } from "@/components/ui/button" import { Input } from "@/components/ui/input" import { Avatar, AvatarImage, AvatarFallback } from "@/components/ui/avatar" import { ScrollArea } from "@/components/ui/scroll-area" import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger, } from "@/components/ui/dropdown-menu" import { conversations as conversationsData } from "@/data/chats" import { Search, Send, Phone, Video, MoreHorizontal, Paperclip, Smile, Flag, Ban, Trash2, Image, File, X, } from "lucide-react" import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, DialogFooter, DialogClose, } from "@/components/ui/dialog" import { Label } from "@/components/ui/label" import { Textarea } from "@/components/ui/textarea" import { useTheme } from "next-themes" import { useUser } from "@/providers/user-provider" import { toast } from "sonner" import data from "@emoji-mart/data" import Picker from "@emoji-mart/react" export default function ChatsPage() { const { theme } = useTheme() const { user } = useUser() const [activeChat, setActiveChat] = useState(conversationsData[0]?.id ?? null) const [messageInput, setMessageInput] = useState("") const [showEmojiPicker, setShowEmojiPicker] = useState(false) const [attachments, setAttachments] = useState([]) const [panelWidth, setPanelWidth] = useState(320) const [isResizing, setIsResizing] = useState(false) const [reportDialogOpen, setReportDialogOpen] = useState(false) const [reportReason, setReportReason] = useState("") const fileInputRef = useRef(null) const emojiPickerRef = useRef(null) const resizeStartRef = useRef({ x: 0, width: 0 }) const [conversations, setConversations] = useState(conversationsData) if (!user) return null const conversation = conversations.find((c) => c.id === activeChat) const otherParticipant = (conv: typeof conversationsData[0]) => conv.participants.find((p) => p.id !== "user1") ?? conv.participants[0] useEffect(() => { const handleClickOutside = (e: MouseEvent) => { if (emojiPickerRef.current && !emojiPickerRef.current.contains(e.target as Node)) { setShowEmojiPicker(false) } } document.addEventListener("mousedown", handleClickOutside) return () => document.removeEventListener("mousedown", handleClickOutside) }, []) const handleResizeStart = useCallback((e: React.MouseEvent) => { e.preventDefault() setIsResizing(true) resizeStartRef.current = { x: e.clientX, width: panelWidth } }, [panelWidth]) useEffect(() => { if (!isResizing) return const handleMouseMove = (e: MouseEvent) => { const delta = e.clientX - resizeStartRef.current.x const newWidth = Math.max(240, Math.min(560, resizeStartRef.current.width + delta)) setPanelWidth(newWidth) } const handleMouseUp = () => setIsResizing(false) document.addEventListener("mousemove", handleMouseMove) document.addEventListener("mouseup", handleMouseUp) return () => { document.removeEventListener("mousemove", handleMouseMove) document.removeEventListener("mouseup", handleMouseUp) } }, [isResizing]) const handleEmojiSelect = (emoji: { native: string }) => { setMessageInput((prev) => prev + emoji.native) setShowEmojiPicker(false) } const handleFileSelect = (e: React.ChangeEvent) => { const files = Array.from(e.target.files ?? []) setAttachments((prev) => [...prev, ...files]) if (e.target) e.target.value = "" } const removeAttachment = (index: number) => { setAttachments((prev) => prev.filter((_, i) => i !== index)) } const handleSend = (e: React.FormEvent) => { e.preventDefault() if (!messageInput.trim() && attachments.length === 0) return const newMessage = { id: crypto.randomUUID(), conversationId: activeChat!, senderId: "user1", senderName: "Sarah Chen", senderAvatar: "SC", content: messageInput.trim(), timestamp: new Date().toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" }), } setConversations((prev) => prev.map((conv) => conv.id === activeChat ? { ...conv, messages: [...conv.messages, newMessage], lastMessage: newMessage.content, lastMessageTime: "Just now", unread: 0, } : conv ) ) setMessageInput("") setAttachments([]) } const formatFileSize = (bytes: number) => { if (bytes < 1024) return bytes + " B" if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(1) + " KB" return (bytes / (1024 * 1024)).toFixed(1) + " MB" } const isImageFile = (file: File) => file.type.startsWith("image/") return (
{/* Conversations list - left panel */}

Chats

{conversations.map((conv) => { const person = otherParticipant(conv) const isActive = conv.id === activeChat return ( ) })}
{/* Resize handle */}
{/* Chat area - right panel */} {conversation ? (
{/* Chat header */}
{otherParticipant(conversation).avatar}

{otherParticipant(conversation).name}

{otherParticipant(conversation).role}

Actions setReportDialogOpen(true)}> Report toast.info("Blocked")}> Block toast.info("Conversation deleted")} > Delete
{/* Messages */}
{conversation.messages.map((msg) => { const isMe = msg.senderId === "user1" return (
{isMe ? : null} {msg.senderAvatar}
{msg.content}
{msg.timestamp}
) })}
{/* Input */}
{attachments.length > 0 && (
{attachments.map((file, i) => (
{isImageFile(file) ? ( ) : ( )} {file.name} {formatFileSize(file.size)}
))}
)}
setMessageInput(e.target.value)} placeholder="Type a message..." className="h-9 w-full pr-9" />
{showEmojiPicker && (
)}
) : (

Select a conversation to start chatting

)} {/* Resize overlay */} {isResizing &&
} {/* Report dialog */} Report {conversation ? otherParticipant(conversation).name : "User"} Let us know why you're reporting this conversation.