|
| 1 | +import { useEffect, useState, useRef } from "react"; |
| 2 | +import { useParams } from "react-router-dom"; |
| 3 | +import { useAuth } from "../../../auth/AuthProvider"; |
| 4 | +import { ChatMessage, getGroupChatMessages, sendChatMessage, deleteGroupChat } from "../../../services/groupApi"; |
| 5 | +import { useGroup } from "../../home/components/GroupProvider"; |
| 6 | +import "./group_chat.css"; |
| 7 | + |
| 8 | +export const Chat = () => { |
| 9 | + const { groupId } = useParams<{ groupId: string }>(); |
| 10 | + const { user, token } = useAuth(); |
| 11 | + const { currentGroup } = useGroup(); |
| 12 | + const [messages, setMessages] = useState<ChatMessage[]>([]); |
| 13 | + const [newMessage, setNewMessage] = useState(""); |
| 14 | + const [error, setError] = useState<string | null>(null); |
| 15 | + const messagesEndRef = useRef<HTMLDivElement>(null); |
| 16 | + |
| 17 | + const scrollToBottom = () => { |
| 18 | + messagesEndRef.current?.scrollIntoView({ behavior: "smooth" }); |
| 19 | + }; |
| 20 | + |
| 21 | + useEffect(() => { |
| 22 | + if (groupId && token) { |
| 23 | + getGroupChatMessages(groupId, token) |
| 24 | + .then(setMessages) |
| 25 | + .catch(() => setError("Failed to load messages.")); |
| 26 | + } |
| 27 | + }, [groupId, token]); |
| 28 | + |
| 29 | + useEffect(scrollToBottom, [messages]); |
| 30 | + |
| 31 | + const handleSendMessage = async (e: React.FormEvent) => { |
| 32 | + e.preventDefault(); |
| 33 | + if (!newMessage.trim() || !groupId || !token) return; |
| 34 | + |
| 35 | + try { |
| 36 | + const sentMessage = await sendChatMessage(groupId, newMessage, token); |
| 37 | + setMessages([...messages, sentMessage]); |
| 38 | + setNewMessage(""); |
| 39 | + } catch { |
| 40 | + setError("Failed to send message."); |
| 41 | + } |
| 42 | + }; |
| 43 | + |
| 44 | + const handleDeleteChat = async () => { |
| 45 | + if (!groupId || !token) return; |
| 46 | + |
| 47 | + if (window.confirm("Are you sure you want to delete the entire chat history for this group? This cannot be undone.")) { |
| 48 | + try { |
| 49 | + await deleteGroupChat(groupId, token); |
| 50 | + setMessages([]); |
| 51 | + } catch { |
| 52 | + setError("Failed to delete chat."); |
| 53 | + } |
| 54 | + } |
| 55 | + }; |
| 56 | + |
| 57 | + return ( |
| 58 | + <div className="chat-container"> |
| 59 | + <h3>Group Chat</h3> |
| 60 | + {error && <p className="error-message">{error}</p>} |
| 61 | + <div className="messages-list"> |
| 62 | + {messages.map((msg) => ( |
| 63 | + <div key={msg.id} className={`message-item ${msg.username === user ? "sent" : "received"}`}> |
| 64 | + <div className="message-content"> |
| 65 | + <strong>{msg.username}</strong> |
| 66 | + <p>{msg.content}</p> |
| 67 | + <span className="timestamp">{new Date(msg.timestamp).toLocaleTimeString()}</span> |
| 68 | + </div> |
| 69 | + </div> |
| 70 | + ))} |
| 71 | + <div ref={messagesEndRef} /> |
| 72 | + </div> |
| 73 | + <form onSubmit={handleSendMessage} className="message-form"> |
| 74 | + <input |
| 75 | + type="text" |
| 76 | + value={newMessage} |
| 77 | + onChange={(e) => setNewMessage(e.target.value)} |
| 78 | + placeholder="Type a message..." |
| 79 | + /> |
| 80 | + <button type="submit">Send</button> |
| 81 | + </form> |
| 82 | + {currentGroup?.ownerUsername === user && ( |
| 83 | + <button onClick={handleDeleteChat} className="delete-chat-btn"> |
| 84 | + Delete Chat History |
| 85 | + </button> |
| 86 | + )} |
| 87 | + </div> |
| 88 | + ); |
| 89 | +}; |
0 commit comments