Skip to content

Commit

Permalink
Added fully function backend API
Browse files Browse the repository at this point in the history
  • Loading branch information
Sawan-Kushwah committed Nov 9, 2024
1 parent c4d21f8 commit afcba5b
Show file tree
Hide file tree
Showing 5 changed files with 166 additions and 39 deletions.
115 changes: 76 additions & 39 deletions client/src/component/DiscussionForum.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,59 +3,95 @@ import { useState, useEffect } from 'react';
const DiscussionForum = (props) => {
const [questions, setQuestions] = useState([]);

// Fetch questions from localStorage
// Fetch questions from the backend API
useEffect(() => {
const storedQuestions = localStorage.getItem('questions');
if (storedQuestions) {
setQuestions(JSON.parse(storedQuestions));
}
}, []);
const fetchQuestions = async () => {
try {
const response = await fetch('http://localhost:5000/api/discussion/getQuestion');
if (response.ok) {
const data = await response.json();
setQuestions(data);
} else {
console.error('Failed to fetch questions');
}
} catch (error) {
console.error('Error fetching questions:', error);
}
};

// Save questions to localStorage
const saveQuestions = (updatedQuestions) => {
setQuestions(updatedQuestions);
localStorage.setItem('questions', JSON.stringify(updatedQuestions));
};
fetchQuestions();
}, []);

// Helper function to save a new question
const addQuestion = (content) => {
const addQuestion = async (content) => {
const newQuestion = {
id: Date.now().toString(),
content,
answered: false,
answer: '',
};

const updatedQuestions = [...questions, newQuestion];
saveQuestions(updatedQuestions);
try {
const response = await fetch('http://localhost:5000/api/discussion/postQuestion', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(newQuestion),
});

if (response.ok) {
const savedQuestion = await response.json();
setQuestions((prevQuestions) => [...prevQuestions, savedQuestion]);
} else {
console.error('Failed to add question');
}
} catch (error) {
console.error('Error adding question:', error);
}
};

// Helper function to add an answer to a question
const addAnswer = (questionId, answerContent) => {
const updatedQuestions = questions.map((question) =>
question.id === questionId
? { ...question, answered: true, answer: answerContent }
: question
);
saveQuestions(updatedQuestions);
const addAnswer = async (questionId, answerContent) => {
try {
const response = await fetch(`http://localhost:5000/api/discussion/${questionId}/answer`, {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ answer: answerContent }),
});

if (response.ok) {
const updatedQuestion = await response.json();
setQuestions((prevQuestions) =>
prevQuestions.map((question) =>
question._id === questionId ? { ...question, ...updatedQuestion } : question
)
);
} else {
console.error('Failed to add answer');
}
} catch (error) {
console.error('Error adding answer:', error);
}
};

// Function to render the Question Card
const renderQuestionCard = (question) => {
return (
<div
className={`${props.mode === 'dark' ? 'bg-gray-800 text-gray-200' : 'bg-white text-gray-800'
className={`${props.mode === 'dark' ? 'bg-gray-800 text-white' : 'bg-white text-gray-800'
} p-6 rounded-lg shadow-lg mb-6 w-full md:w-[48%] lg:w-[30%] transition-transform transform hover:scale-105`}
key={question.id}
key={question._id}
>
<p className="text-xl font-semibold">{question.content}</p>
{question.answered ? (
<div className={`mt-4 ${props.mode === 'dark' ? 'bg-gray-700' : 'bg-white'} p-4 rounded-md shadow-md`}>
<div className={`mt-4 p-4 rounded-md shadow-md ${props.mode === 'dark' ? 'bg-gray-700' : 'bg-white'}`}>
<h3 className="text-lg font-semibold">Answer:</h3>
<p>{question.answer}</p>
</div>
) : (
<AnswerForm questionId={question.id} />
<AnswerForm questionId={question._id} />
)}
</div>
);
Expand All @@ -74,17 +110,18 @@ const DiscussionForum = (props) => {
};

return (
<form onSubmit={handleSubmit} className={`${props.mode === 'dark' ? 'bg-gray-700' : 'bg-white'} p-4 rounded-md shadow-md mt-4`}>
<form onSubmit={handleSubmit} className={`p-4 rounded-md shadow-md mt-4 ${props.mode === 'dark' ? 'bg-gray-700' : 'bg-white'}`}>
<textarea
value={answer}
onChange={(e) => setAnswer(e.target.value)}
placeholder="Write your answer..."
className={`w-full p-4 border rounded-md ${props.mode === 'dark' ? 'bg-gray-600 text-gray-200' : 'bg-gray-100 text-gray-800'
} focus:outline-none focus:ring-2 focus:ring-gray-500 transition-all`}
className={`w-full p-4 border rounded-md ${props.mode === 'dark' ? 'bg-gray-900 text-white' : 'bg-gray-100 text-gray-800'
} focus:outline-none focus:ring-2 ${props.mode === 'dark' ? 'focus:ring-gray-400' : 'focus:ring-gray-500'} transition-all`}
/>
<button
type="submit"
className="mt-4 bg-gray-800 text-white px-6 py-2 rounded-md hover:bg-gray-600 focus:outline-none focus:ring-2 focus:ring-gray-500 transition-colors"
className={`mt-4 px-6 py-2 rounded-md ${props.mode === 'dark' ? 'bg-gray-600 text-white hover:bg-gray-500' : 'bg-gray-800 text-white hover:bg-gray-600'
} focus:outline-none focus:ring-2 ${props.mode === 'dark' ? 'focus:ring-gray-400' : 'focus:ring-gray-500'} transition-colors`}
>
Submit Answer
</button>
Expand All @@ -105,17 +142,18 @@ const DiscussionForum = (props) => {
};

return (
<div className={`p-6 rounded-lg shadow-lg mb-8 ${props.mode === 'dark' ? 'bg-gray-800 text-gray-200' : 'bg-white text-gray-800'}`}>
<div className={`p-6 rounded-lg shadow-lg mb-8 ${props.mode === 'dark' ? 'bg-gray-800 text-white' : 'bg-white text-gray-800'}`}>
<textarea
value={newQuestion}
onChange={(e) => setNewQuestion(e.target.value)}
placeholder="Ask your question..."
className={`w-full p-4 border rounded-md ${props.mode === 'dark' ? 'bg-gray-600 text-gray-200' : 'bg-gray-100 text-gray-800'
} focus:outline-none focus:ring-2 focus:ring-gray-500 transition-all`}
className={`w-full p-4 border rounded-md ${props.mode === 'dark' ? 'bg-gray-900 text-white' : 'bg-gray-100 text-gray-800'
} focus:outline-none focus:ring-2 ${props.mode === 'dark' ? 'focus:ring-gray-400' : 'focus:ring-gray-500'} transition-all`}
/>
<button
onClick={handleSubmit}
className="mt-4 bg-gray-800 text-white px-6 py-2 rounded-md hover:bg-gray-600 focus:outline-none focus:ring-2 focus:ring-gray-500 transition-colors"
className={`mt-4 px-6 py-2 rounded-md ${props.mode === 'dark' ? 'bg-gray-600 text-white hover:bg-gray-500' : 'bg-gray-800 text-white hover:bg-gray-600'
} focus:outline-none focus:ring-2 ${props.mode === 'dark' ? 'focus:ring-gray-400' : 'focus:ring-gray-500'} transition-colors`}
>
Ask Question
</button>
Expand All @@ -125,24 +163,23 @@ const DiscussionForum = (props) => {

return (
<div className="container mx-auto px-6 py-8 mt-20">
<h1 className="text-4xl font-bold text-center mb-8">
<h1 className={`text-4xl font-bold text-center mb-8 ${props.mode === 'dark' ? 'text-white' : 'text-gray-800'}`}>
BITBOX Discussion Forum
</h1>

<QuestionForm />

<div>
<h2 className="text-2xl font-semibold mb-6">Unanswered Questions</h2>
<h2 className={`text-2xl font-semibold mb-6 ${props.mode === 'dark' ? 'text-white' : 'text-gray-800'}`}>Unanswered Questions</h2>
<div className="flex flex-wrap gap-6">
{questions
.filter((question) => !question.answered)
.map((question) => renderQuestionCard(question))}
</div>
</div>
<div class="p-[1px] bg-blue-500 text-white rounded-md shadow">
</div>

<div>
<h2 className="text-2xl font-semibold mb-6 mt-8">Answered Questions</h2>
<h2 className={`text-2xl font-semibold mb-6 mt-8 ${props.mode === 'dark' ? 'text-white' : 'text-gray-800'}`}>Answered Questions</h2>
<div className="flex flex-wrap gap-6">
{questions
.filter((question) => question.answered)
Expand Down
56 changes: 56 additions & 0 deletions server/Controllers/discussionController.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
const Question = require('../Models/discussion.js');

const getQuestions = async (req, res) => {
try {
const questions = await Question.find();
res.json(questions);
} catch (error) {
res.status(500).json({ error: 'Failed to retrieve questions' });
}
};

// Save a new question to MongoDB
const saveQuestion = async (req, res) => {
try {
const { content } = req.body;

const newQuestion = new Question({
content,
});

await newQuestion.save();

res.status(201).json(newQuestion);
} catch (error) {
res.status(500).json({ error: 'Failed to save question' });
}
};

const addAnswerToQuestion = async (req, res) => {
try {
const questionId = req.params.id;
const { answer } = req.body;
console.log(questionId)
console.log(answer)

const updatedQuestion = await Question.findByIdAndUpdate(
questionId,
{ answered: true, answer },
{ new: true }
);

if (updatedQuestion) {
res.json(updatedQuestion);
} else {
res.status(404).json({ error: 'Question not found' });
}
} catch (error) {
res.status(500).json({ error: 'Failed to update question' });
}
};

module.exports = {
getQuestions,
saveQuestion,
addAnswerToQuestion
};
21 changes: 21 additions & 0 deletions server/Models/discussion.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
const mongoose = require('mongoose');

// Define the schema for a question
const discussionSchema = new mongoose.Schema({
content: {
type: String,
required: true,
},
answered: {
type: Boolean,
default: false,
},
answer: {
type: String,
default: '',
},
}, { timestamps: true });

const Question = mongoose.model('Question', discussionSchema);

module.exports = Question;
1 change: 1 addition & 0 deletions server/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ app.use("/api/contact", require("./routes/contact"));
app.use("/api/blog", require("./routes/blog"));
app.use("/api/visitor", require("./routes/visitor"));
app.use("/api/showcaseProjects", require("./routes/projectsRoute"));
app.use("/api/discussion", require("./routes/discussionRoutes"));

// Socket.io connection handling
const users = {};
Expand Down
12 changes: 12 additions & 0 deletions server/routes/discussionRoutes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
const express = require('express');
const router = express.Router();

const { getQuestions, saveQuestion, addAnswerToQuestion } = require('../Controllers/discussionController');

router.get('/getQuestion', getQuestions);

router.post('/postQuestion', saveQuestion);

router.put('/:id/answer', addAnswerToQuestion);

module.exports = router;

0 comments on commit afcba5b

Please sign in to comment.