From a2eeefd0d13acd1385c6fd2d6feb819ab7888da3 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 23 Nov 2025 16:33:33 +0000 Subject: [PATCH 1/3] Initial plan From f44abc5e514958ab44a11cb52165b66b799f935c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 23 Nov 2025 16:40:21 +0000 Subject: [PATCH 2/3] Complete discussion section CRUD operations with frontend and backend fixes Co-authored-by: shivamxverma <171797924+shivamxverma@users.noreply.github.com> --- Frontend/src/api/api.js | 12 +- Frontend/src/components/NavBar.jsx | 1 + Frontend/src/pages/DiscussionPage.jsx | 361 ++++++++++++++---- .../src/controllers/discussion.controller.js | 6 +- backend/src/routes/discussion.route.js | 6 +- 5 files changed, 306 insertions(+), 80 deletions(-) diff --git a/Frontend/src/api/api.js b/Frontend/src/api/api.js index 28d631a..05ea5d8 100644 --- a/Frontend/src/api/api.js +++ b/Frontend/src/api/api.js @@ -141,15 +141,21 @@ export const createDiscussion = (payload) => { } export const likeDiscussion = (discussionId) => { - return axios.get(`${BASE}/${discussionId}/like`, { withCredentials: true }); + return axios.post(`${BASE}/discussion/${discussionId}/like`, {}, { + withCredentials: true, + headers: { Authorization: `Bearer ${accessToken}` } + }); } export const dislikeDiscussion = (discussionId) => { - return axios.get(`${BASE}/${discussionId}/dislike`, { withCredentials: true }); + return axios.post(`${BASE}/discussion/${discussionId}/dislike`, {}, { + withCredentials: true, + headers: { Authorization: `Bearer ${accessToken}` } + }); } export const createComment = (discussionId, comment) => { - return axios.post(`${BASE}/${discussionId}/comment`, comment, { + return axios.post(`${BASE}/discussion/${discussionId}/comment`, comment, { withCredentials: true, headers: { Authorization: `Bearer ${accessToken}` } }) diff --git a/Frontend/src/components/NavBar.jsx b/Frontend/src/components/NavBar.jsx index 5606716..b164b4e 100644 --- a/Frontend/src/components/NavBar.jsx +++ b/Frontend/src/components/NavBar.jsx @@ -54,6 +54,7 @@ export default function NewNav() { const navItems = [ { to: "/", label: "Home" }, { to: "/problems", label: "Problems" }, + { to: "/discussion", label: "Discussions" }, ...(userRole === "author" || userRole === "admin" ? [{ to: "/newproblem", label: "Create Problem" }] : []), diff --git a/Frontend/src/pages/DiscussionPage.jsx b/Frontend/src/pages/DiscussionPage.jsx index cd11097..3aaed9b 100644 --- a/Frontend/src/pages/DiscussionPage.jsx +++ b/Frontend/src/pages/DiscussionPage.jsx @@ -1,82 +1,301 @@ -import React, { useEffect , useState } from 'react'; -import {getAllDiscussion} from '@/api/api'; +import React, { useEffect, useState } from 'react'; +import { getAllDiscussion, createDiscussion, likeDiscussion, dislikeDiscussion, createComment } from '@/api/api'; +import { useAuth } from '@/auth/AuthContext'; const DiscussionPage = () => { - const [discussion,setDiscussion] = useState([{ - _id : 1,content : "your name is shivam",like : 1,dislike : 3 - }]); - const [formData,setFormData] = useState({ - title : "", - description : "", - tags : "" - }) - - const Field = ({ label, hint, children }) => ( -
-
- - {hint && {hint}} -
- {children} -
- ); + const { user } = useAuth(); + const [discussions, setDiscussions] = useState([]); + const [loading, setLoading] = useState(true); + const [error, setError] = useState(''); + const [showCreateForm, setShowCreateForm] = useState(false); + const [formData, setFormData] = useState({ + title: '', + content: '', + tags: '' + }); + const [commentData, setCommentData] = useState({}); + const [showComments, setShowComments] = useState({}); + + useEffect(() => { + fetchDiscussions(); + }, []); + + const fetchDiscussions = async () => { + try { + setLoading(true); + setError(''); + const response = await getAllDiscussion(); + setDiscussions(Array.isArray(response.data.data) ? response.data.data : []); + } catch (err) { + setError('Failed to load discussions. Please try again.'); + console.error(err); + } finally { + setLoading(false); + } + }; + + const handleCreateDiscussion = async (e) => { + e.preventDefault(); + if (!user) { + setError('Please login to create a discussion'); + return; + } - // useEffect(()=> { - // async function fetchDiscussion(){ - // try{ - // const response = await getAllDiscussion(); - // setDiscussion(response.data.message); - // }catch(error){ - // console.error(error); - // } - // } - // fetchDiscussion(); - // },[]) + try { + const payload = { + title: formData.title, + content: formData.content, + tags: formData.tags ? formData.tags.split(',').map(tag => tag.trim()) : [] + }; + + await createDiscussion(payload); + setFormData({ title: '', content: '', tags: '' }); + setShowCreateForm(false); + fetchDiscussions(); + } catch (err) { + setError('Failed to create discussion. Please try again.'); + console.error(err); + } + }; - const handleDiscussionCreation = () => { + const handleLike = async (discussionId) => { + if (!user) { + setError('Please login to like discussions'); + return; + } + try { + await likeDiscussion(discussionId); + fetchDiscussions(); + } catch (err) { + console.error('Failed to like discussion:', err); + } + }; - } + const handleDislike = async (discussionId) => { + if (!user) { + setError('Please login to dislike discussions'); + return; + } + try { + await dislikeDiscussion(discussionId); + fetchDiscussions(); + } catch (err) { + console.error('Failed to dislike discussion:', err); + } + }; + + const handleAddComment = async (discussionId) => { + if (!user) { + setError('Please login to comment'); + return; + } + const content = commentData[discussionId]; + if (!content || !content.trim()) return; + + try { + await createComment(discussionId, { content }); + setCommentData({ ...commentData, [discussionId]: '' }); + fetchDiscussions(); + } catch (err) { + console.error('Failed to add comment:', err); + } + }; + + const toggleComments = (discussionId) => { + setShowComments(prev => ({ ...prev, [discussionId]: !prev[discussionId] })); + }; return ( - <> - -
- - updateField("title",e.target.value)} - placeholder='Enter Title For Discussion' - required - /> - - - -