diff --git a/client/src/components/fakestackoverflow.tsx b/client/src/components/fakestackoverflow.tsx index c73dca6..e4f834f 100644 --- a/client/src/components/fakestackoverflow.tsx +++ b/client/src/components/fakestackoverflow.tsx @@ -63,7 +63,7 @@ const FakeStackOverflow = ({ socket }: { socket: FakeSOSocket | null }) => { }> } /> {/* should become community */} - } /> + } /> } /> } /> } /> diff --git a/client/src/components/main/chat/index.css b/client/src/components/main/chat/index.css index ba62a68..0d37ac1 100644 --- a/client/src/components/main/chat/index.css +++ b/client/src/components/main/chat/index.css @@ -1,127 +1,127 @@ .chat-container { - display: flex; - flex-direction: column; - justify-content: space-between; - align-items: center; - width: 100%; - min-height: 90vh; - background-color: #FFFCF5; - overflow-y: scroll; - } - - .scrollable-container { - width: 100%; - height: 200px; - overflow-y: scroll; - } - - .ruled-paper { - background-size: 100% 3em; - background-color: #FFFCF5; - flex-grow: 1; - width: 100%; - padding-top: 0.2rem; - line-height: 1.2; - } - - - .carrot { - display: flex; - flex-direction: column; - align-items: flex-start; - padding: 20px; - } - - .community-title { - margin: 0 auto; /* Horizontally center */ - background: #6D89B0; - text-align: start; - padding: 10px; - border-radius: 5px; - color: white; - font-size: 24px; - font-weight: bold; - } - - .chat-title { - padding: 20px; - font-size: 24px; - font-weight: bold; - } - - .chat-header { - background-color: #466694; - color: #FFFFFF; - display: flex; - flex-direction: row; - align-items: center; - justify-content: space-between; - width: 100%; - } - - .chat-footer { - background-color: #466694; - color: #FFFFFF; - display: flex; - flex-direction: row; - align-items: center; - justify-content: space-between; - width: 100%; - } - - .chat-text-user, .chat-text-me { - display: inline-block; - font-size: 24px; - max-width: 100%; - white-space: nowrap; - margin-bottom: 5px; - } - - .chat-text-user { - text-align: left !important; - padding: 3px 15px; - background: #f1f1f1; - color: #000 !important; - border-radius: 20px 20px 20px 3px; - } - - .chat-text-me { - float: right; - padding: 3px 15px; - background: #DFAEA1; - color: #fff !important; - border-radius: 30px 20px 3px 30px; - margin-bottom: 10px; - clear: both; - } - - .username { - background: #6D89B0; - color: white; - font-size: 24px; - max-width: 975px; - font-weight: bold; - } - - .username::placeholder { - color: white; - } - - .message { - display: block; - width: 100%; - } - - .send { - background: #BABDE2; - border-radius: 10px; - padding: 5px; - color: white; - margin-right: 20px; - font-size: 24px; - font-weight: bold; - } - - .send:hover { - background-color: #9498B5; - } \ No newline at end of file + display: flex; + flex-direction: column; + justify-content: space-between; + align-items: center; + width: 100%; + min-height: 90vh; + background-color: #FFFCF5; + overflow-y: scroll; +} + +.scrollable-container { + width: 100%; + height: 200px; + overflow-y: scroll; +} + +.ruled-paper { + background-size: 100% 3em; + background-color: #FFFCF5; + flex-grow: 1; + width: 100%; + padding-top: 0.2rem; + line-height: 1.2; +} + + +.carrot { + display: flex; + flex-direction: column; + align-items: flex-start; + padding: 20px; +} + +.community-title { + margin: 0 auto; /* Horizontally center */ + background: #6D89B0; + text-align: start; + padding: 10px; + border-radius: 5px; + color: white; + font-size: 24px; + font-weight: bold; +} + +.chat-title { + padding: 20px; + font-size: 24px; + font-weight: bold; +} + +.chat-header { + background-color: #466694; + color: #FFFFFF; + display: flex; + flex-direction: row; + align-items: center; + justify-content: space-between; + width: 100%; +} + +.chat-footer { + background-color: #466694; + color: #FFFFFF; + display: flex; + flex-direction: row; + align-items: center; + justify-content: space-between; + width: 100%; +} + +.chat-text-user, .chat-text-me { + display: inline-block; + font-size: 24px; + max-width: 100%; + white-space: nowrap; + margin-bottom: 5px; +} + +.chat-text-user { + text-align: left !important; + padding: 3px 15px; + background: #f1f1f1; + color: #000 !important; + border-radius: 20px 20px 20px 3px; +} + +.chat-text-me { + float: right; + padding: 3px 15px; + background: #DFAEA1; + color: #fff !important; + border-radius: 30px 20px 3px 30px; + margin-bottom: 10px; + clear: both; +} + +.username { + background: #6D89B0; + color: white; + font-size: 24px; + max-width: 975px; + font-weight: bold; +} + +.username::placeholder { + color: white; +} + +.message { + display: block; + width: 100%; +} + +.send { + background: #BABDE2; + border-radius: 10px; + padding: 5px; + color: white; + margin-right: 20px; + font-size: 24px; + font-weight: bold; +} + +.send:hover { + background-color: #9498B5; +} \ No newline at end of file diff --git a/client/src/components/main/chat/index.tsx b/client/src/components/main/chat/index.tsx index 7ece429..083b53e 100644 --- a/client/src/components/main/chat/index.tsx +++ b/client/src/components/main/chat/index.tsx @@ -1,11 +1,13 @@ import './index.css'; import { FaCaretUp, FaCaretDown } from 'react-icons/fa'; -import { useLocation } from 'react-router-dom'; +import { useLocation, useParams } from 'react-router-dom'; import Message from './Message'; import useChat from '../../../hooks/useChat'; const ChatPage = () => { const { pathname } = useLocation(); + const { community } = useParams(); + const { currentMessage, messages, @@ -22,7 +24,7 @@ const ChatPage = () => {
{pathname.includes('community') ? ( - chatting now: community + chatting now: {community} ) : ( <> diff --git a/client/src/components/main/homePage/community/index.tsx b/client/src/components/main/homePage/community/index.tsx index b02dcbb..e40db50 100644 --- a/client/src/components/main/homePage/community/index.tsx +++ b/client/src/components/main/homePage/community/index.tsx @@ -1,6 +1,7 @@ import './index.css'; import React from 'react'; // import { Link } from 'react-router-dom'; +import { Link } from 'react-router-dom'; import MembersSidebar from './membersSideBar'; import useQuestionPage from '../../../../hooks/useQuestionPage'; import QuestionView from './questions'; @@ -11,7 +12,7 @@ import QuestionView from './questions'; */ const CommunityHomePage = () => { // Use the custom hook to manage the state and fetch community-specific questions - const { titleText, qlist } = useQuestionPage(); + const { titleText, qlist, userCommunity } = useQuestionPage(); return (
@@ -22,7 +23,9 @@ const CommunityHomePage = () => { {/* Sidebar for members */} {/* Button to chat with the community */} - + + Chat with Community + {/* Display questions related to the community */}
diff --git a/client/src/hooks/useChat.ts b/client/src/hooks/useChat.ts index cb3deee..e564ff2 100644 --- a/client/src/hooks/useChat.ts +++ b/client/src/hooks/useChat.ts @@ -1,10 +1,13 @@ /* eslint-disable no-console */ import { useEffect, useState } from 'react'; import { addDoc, collection, onSnapshot, orderBy, query } from 'firebase/firestore'; +import { useLocation, useParams } from 'react-router-dom'; import useUserContext from './useUserContext'; import { db } from '../firebaseConfig'; const useChat = () => { + const { pathname } = useLocation(); + const { community } = useParams(); const { user } = useUserContext(); const [currentMessage, setCurrentMessage] = useState(''); const [messages, setMessages] = useState<{ message: string; username: string; sendTo: string }[]>( @@ -13,6 +16,12 @@ const useChat = () => { const [send, setSend] = useState(''); const messageContainer = document.querySelector('.scrollable-container'); + useEffect(() => { + if (pathname.includes('community')) { + setSend(community || ''); + } + }, [community, pathname, setSend]); + const handleSendTo = (e: React.ChangeEvent) => { setSend(e.target.value); }; @@ -22,6 +31,7 @@ const useChat = () => { }; const saveMessagesToUserAccount = async (message: string, sendTo: string) => { + console.log('in save messages'); try { if (user && user.username) { await addDoc(collection(db, 'messages'), { @@ -45,6 +55,24 @@ const useChat = () => { // Query to retrieve messages where the current user is either the sender (username) or receiver (sendTo) const q = query(collection(db, 'messages'), orderBy('timestamp', 'asc')); + if (pathname.includes('community') && community) { + const unsubscribe = onSnapshot(q, querySnapshot => { + const loadedMessages = querySnapshot.docs + // eslint-disable-next-line @typescript-eslint/no-shadow + .map(doc => ({ + message: doc.data().message, + username: doc.data().username, + sendTo: doc.data().sendTo, + timestamp: doc.data().timestamp, + })) + .filter(msg => msg.sendTo === community); + setMessages(loadedMessages); + }); + + // eslint-disable-next-line consistent-return + return () => unsubscribe(); + } + const unsubscribe = onSnapshot(q, querySnapshot => { const loadedMessages = querySnapshot.docs // eslint-disable-next-line @typescript-eslint/no-shadow @@ -62,10 +90,9 @@ const useChat = () => { setMessages(loadedMessages); }); - // Cleanup the snapshot listener on component unmount // eslint-disable-next-line consistent-return return () => unsubscribe(); - }, [user, send]); + }, [user, send, pathname, community]); const scrollUp = () => { messageContainer?.scrollBy(0, -100); diff --git a/client/src/hooks/useQuestionPage.ts b/client/src/hooks/useQuestionPage.ts index a5cd437..9940a06 100644 --- a/client/src/hooks/useQuestionPage.ts +++ b/client/src/hooks/useQuestionPage.ts @@ -1,8 +1,10 @@ +/* eslint-disable no-console */ import { useSearchParams } from 'react-router-dom'; import { useEffect, useState } from 'react'; import useUserContext from './useUserContext'; import { Answer, OrderType, Question } from '../types'; import { getQuestionsByFilter } from '../services/questionService'; +import { getUser } from '../services/userService'; /** * Custom hook for managing the question page state, filtering, and real-time updates. @@ -12,13 +14,14 @@ import { getQuestionsByFilter } from '../services/questionService'; * @returns setQuestionOrder - Function to set the sorting order of questions (e.g., newest, oldest). */ const useQuestionPage = () => { - const { socket } = useUserContext(); + const { socket, user } = useUserContext(); const [searchParams] = useSearchParams(); const [titleText, setTitleText] = useState('All Questions'); const [search, setSearch] = useState(''); const [questionOrder, setQuestionOrder] = useState('newest'); const [qlist, setQlist] = useState([]); + const [userCommunity, setUserCommunity] = useState(''); useEffect(() => { let pageTitle = 'All Questions'; @@ -105,7 +108,22 @@ const useQuestionPage = () => { }; }, [questionOrder, search, socket]); - return { titleText, qlist, setQuestionOrder }; + useEffect(() => { + const fetchUserCommunity = async () => { + if (!user?.username) return; + + try { + const data = await getUser(user.username); // Fetch user data from MongoDB + setUserCommunity(data.community || ''); + } catch (error) { + console.error('Error fetching community:', error); + } + }; + + fetchUserCommunity(); + }, [user]); + + return { titleText, qlist, setQuestionOrder, userCommunity }; }; export default useQuestionPage;