Skip to content

Commit

Permalink
Added backend api for both answered and unanswered question
Browse files Browse the repository at this point in the history
  • Loading branch information
Sawan-Kushwah committed Nov 8, 2024
1 parent c10ec6a commit 35c231b
Show file tree
Hide file tree
Showing 6 changed files with 208 additions and 191 deletions.
2 changes: 2 additions & 0 deletions backend/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import ratingRoutes from "./routes/ratingRoutes.js";
import getInTouch from "./routes/getInTouchRoutes.js";
import addBlog from "./routes/addBlogRoutes.js";
import subscribe from "./routes/subscribeRoutes.js";
import discussion from "./routes/discussionRoutes.js";
import cors from "cors";
import path from "path"; // Import path module
import { fileURLToPath } from "url"; // Import fileURLToPath
Expand Down Expand Up @@ -37,6 +38,7 @@ app.use("/api/contact", contactRoutes);
app.use("/api/getInTouch", getInTouch);
app.use("/api/addBlog", addBlog);
app.use("/api/newsletter", subscribe);
app.use("/api/discussion", discussion);

const PORT = process.env.PORT || 5000;
app.listen(PORT, () => {
Expand Down
49 changes: 49 additions & 0 deletions backend/controllers/discussionController.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import Question from '../models/discussion.js';

export 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
export 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' });
}
};

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


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' });
}
};
21 changes: 21 additions & 0 deletions backend/models/discussion.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import mongoose from '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);

export default Question;
12 changes: 12 additions & 0 deletions backend/routes/discussionRoutes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import express from 'express';
const router = express.Router();

import { getQuestions, saveQuestion, addAnswerToQuestion } from '../controllers/discussionController.js';

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

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

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

export default router;
155 changes: 70 additions & 85 deletions frontend/src/pages/DiscussionForum.js
Original file line number Diff line number Diff line change
@@ -1,32 +1,54 @@
export async function renderDiscussionForum(container) {
// Initialize questions data
let questions = JSON.parse(localStorage.getItem('questions')) || [];

// Helper function to save questions to localStorage
const saveQuestions = () => {
localStorage.setItem('questions', JSON.stringify(questions));
// Fetch questions data from the backend
const fetchQuestions = async () => {
try {
const response = await fetch('http://localhost:5000/api/discussion/getQuestion');
const data = await response.json();
return data;
} catch (error) {
console.error('Error fetching questions:', error);
return [];
}
};

// Function to handle adding a new question
const addQuestion = (content) => {
// Helper function to save a new question to the backend
const addQuestion = async (content) => {
const newQuestion = {
id: Date.now(),
content: content,
answered: false,
answer: '',
};
questions.push(newQuestion);
saveQuestions();
render();
try {
const response = await fetch('http://localhost:5000/api/discussion/postQuestion', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(newQuestion),
});
const savedQuestion = await response.json();
window.location.reload()
} catch (error) {
console.error('Error adding question:', error);
}
};

// Function to handle adding an answer to a question
const addAnswer = (questionId, answerContent) => {
questions = questions.map(q =>
q.id === questionId ? { ...q, answered: true, answer: answerContent } : q
);
saveQuestions();
render();
// Helper function to add an answer to a question
const addAnswer = async (questionId, answerContent) => {
const answer = { answer: answerContent };
try {
const response = await fetch(`http://localhost:5000/api/discussion/${questionId}/answer`, {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(answer),
});
const updatedQuestion = await response.json();
window.location.reload()
} catch (error) {
console.error('Error adding answer:', error);
}
};

// Function to render the Question Card
Expand Down Expand Up @@ -55,12 +77,13 @@ export async function renderDiscussionForum(container) {
answerSection.appendChild(answerText);
card.appendChild(answerSection);
} else {
const answerForm = renderAnswerForm(question.id);
const answerForm = renderAnswerForm(question._id);
card.appendChild(answerForm);
}

return card;
};

// Function to render the Question Form
const renderQuestionForm = () => {
const formContainer = document.createElement('div');
Expand Down Expand Up @@ -117,93 +140,55 @@ export async function renderDiscussionForum(container) {
return formContainer;
};



// Function to render the list of questions
const renderQuestionList = () => {
// Create container divs for unanswered and answered sections
const renderQuestionList = async () => {
const questions = await fetchQuestions();

// Create containers for unanswered and answered sections
const unansweredContainer = document.createElement('div');
const answeredContainer = document.createElement('div');

// Create titles for unanswered and answered questions
const unansweredTitleContainer = document.createElement('div');
const unansweredTitle = document.createElement('h2');
unansweredTitle.textContent = 'Unanswered Questions';
unansweredTitle.classList.add('text-2xl', 'font-semibold', 'mb-4', 'text-gray-800', 'dark:text-white');

const answeredTitleContainer = document.createElement('div');
const answeredTitle = document.createElement('h2');
answeredTitle.textContent = 'Answered Questions';
answeredTitle.classList.add('text-2xl', 'font-semibold', 'mb-4', 'text-gray-800', 'dark:text-white', 'mt-8');

// Append the titles to their respective containers
unansweredContainer.appendChild(unansweredTitle);
answeredContainer.appendChild(answeredTitle);
unansweredTitleContainer.appendChild(unansweredTitle);
answeredTitleContainer.appendChild(answeredTitle);

// Filter questions into answered and unanswered arrays
const unansweredQuestions = questions.filter(q => !q.answered);
const answeredQuestions = questions.filter(q => q.answered);

// Create a wrapper div for unanswered questions
// Create containers for the question cards
const unansweredCardsContainer = document.createElement('div');
unansweredCardsContainer.classList.add('flex', 'gap-9', 'flex-wrap'); // Add space between cards

// Handle unanswered questions
if (unansweredQuestions.length === 0) {
const noUnansweredMessage = document.createElement('p');
noUnansweredMessage.textContent = 'No unanswered questions yet.';
unansweredCardsContainer.appendChild(noUnansweredMessage);
} else {
unansweredQuestions.forEach(q => {
const questionCard = renderQuestionCard(q);
unansweredCardsContainer.appendChild(questionCard);
});
}

// Create a wrapper div for answered questions
const answeredCardsContainer = document.createElement('div');
answeredCardsContainer.classList.add('flex', 'gap-9', 'flex-wrap'); // Add space between cards
answeredCardsContainer.classList.add('flex', 'flex-wrap', 'gap-5')
unansweredCardsContainer.classList.add('flex', 'flex-wrap', 'gap-5')

// Handle answered questions
if (answeredQuestions.length === 0) {
const noAnsweredMessage = document.createElement('p');
noAnsweredMessage.textContent = 'No answered questions yet.';
answeredCardsContainer.appendChild(noAnsweredMessage);
} else {
answeredQuestions.forEach(q => {
const questionCard = renderQuestionCard(q);
questions.forEach((question) => {
const questionCard = renderQuestionCard(question);
if (question.answered) {
answeredCardsContainer.appendChild(questionCard);
});
}

// Append the card containers to their respective sections
unansweredContainer.appendChild(unansweredCardsContainer);
answeredContainer.appendChild(answeredCardsContainer);

// Append both sections to the container
container.appendChild(unansweredContainer);
container.appendChild(answeredContainer);
};



const render = () => {
container.innerHTML = ''; // Clear the container

// Create the heading for the forum
const heading = document.createElement('h1');
heading.textContent = 'Wordwise Discussion Forum';
heading.classList.add('text-3xl', 'font-bold', 'mb-6', 'text-gray-800', 'dark:text-white');
container.appendChild(heading);
} else {
unansweredCardsContainer.appendChild(questionCard);
}
});

// First, append the question form at the top
const questionForm = renderQuestionForm();
container.appendChild(questionForm);
// Clear previous content
container.innerHTML = '';

// Then, append the question list (answered and unanswered)
const questionList = renderQuestionList();
container.appendChild(questionList);
// Append new content
container.appendChild(renderQuestionForm());
container.appendChild(unansweredTitleContainer);
container.appendChild(unansweredCardsContainer);
container.appendChild(answeredTitleContainer);
container.appendChild(answeredCardsContainer);
};



render(); // Initial render
renderQuestionList();
}
Loading

0 comments on commit 35c231b

Please sign in to comment.