diff --git a/controller/quesController.js b/controller/quesController.js index 41d50d9..b235e63 100644 --- a/controller/quesController.js +++ b/controller/quesController.js @@ -139,31 +139,55 @@ export const deleteQuestion = async (req, res) => { } }; + export const getAllQuestion = async (req, res) => { try { const queryObject = {}; + // Handle standard, subject, and createdBy queries if (req.query.standard) queryObject.standard = req.query.standard; if (req.query.subject) queryObject.subject = req.query.subject; - if (req.query.chapter) queryObject.chapter = req.query.chapter; - if (req.query.topic) queryObject.topics = req.query.topic; if (req.query.createdBy) queryObject.createdBy = req.query.createdBy; + // Handle multiple chapters + if (req.query.chapter) { + const chapters = Array.isArray(req.query.chapter) + ? req.query.chapter + : req.query.chapter.split(',').map(ch => ch.trim()); + queryObject.chapter = { $in: chapters }; + } + + // Handle single or multiple topics + if (req.query.topic) { + const topics = Array.isArray(req.query.topic) + ? req.query.topic + : req.query.topic.split(',').map(tp => tp.trim()); + queryObject.topics = { $in: topics }; + } + + // Handle subtopics + if (req.query.subtopic) { + const subtopics = Array.isArray(req.query.subtopic) + ? req.query.subtopic + : req.query.subtopic.split(',').map(st => st.trim()); +queryObject.subtopics = {$in: subtopics} + } + + // Handle search query if (req.query.search) { const searchTerms = req.query.search.split(' ').filter(term => term !== ''); - const searchRegex = searchTerms.map(term => new RegExp(term, 'i')); - queryObject.$and = [ { $or: searchRegex.map(regex => ({ question: regex })) } ]; } - console.log(queryObject); + console.log(queryObject); // For debugging purposes + + let formattedQuestions = []; - let formattedQuestions = [] if (req.user.role === "admin") { - let questionsData = Ques.find(queryObject).sort({ createdAt: -1 }); + let questionsData = Ques.find(queryObject).sort({ createdAt: -1 }); let page = req.query.page || 1; let limit = req.query.limit || 50; @@ -180,7 +204,7 @@ export const getAllQuestion = async (req, res) => { formattedQuestions = questions.map(question => ({ ...question.toObject(), - nestedSubTopic: question.nestedSubTopic || "" + nestedSubTopic: question.nestedSubTopic || "" })); } @@ -251,6 +275,7 @@ export const getAllQuestion = async (req, res) => { }, }); } catch (error) { + console.error("Error in getAllQuestion:", error); return res.status(500).json({ success: false, message: error.message || "Internal Server Error", @@ -263,58 +288,82 @@ export const getTotalQuestions = async (req, res) => { const queryObject = {}; const userId = req.user._id; + // Handle standard and subject queries if (req.query.standard) queryObject.standard = req.query.standard; if (req.query.subject) queryObject.subject = req.query.subject; - if (req.query.chapter) queryObject.chapter = req.query.chapter; - if (req.query.topic) queryObject.topics = req.query.topic; - if (req.query.createdBy) queryObject.createdBy = req.query.createdBy; - // const myquestion = req.query.createdBy ? true : false; + // Handle multiple chapters + if (req.query.chapter) { + const chapters = Array.isArray(req.query.chapter) + ? req.query.chapter + : req.query.chapter.split(',').map(chapter => chapter.trim()); + queryObject.chapter = { $in: chapters }; + } + // Handle single or multiple topics + if (req.query.topic) { + const topics = Array.isArray(req.query.topic) + ? req.query.topic + : req.query.topic.split(',').map(topic => topic.trim()); + queryObject.topics = { $in: topics }; + } + + // Handle subtopics + if (req.query.subtopic) { + const subtopics = Array.isArray(req.query.subtopic) + ? req.query.subtopic + : req.query.subtopic.split(',').map(subtopic => subtopic.trim()); + + queryObject.subtopics = { $in: subtopics }; + } + + // Handle createdBy query + if (req.query.createdBy) queryObject.createdBy = req.query.createdBy; + + // Handle search query if (req.query.search) { const searchTerms = req.query.search.split(' ').filter(term => term !== ''); const searchRegex = searchTerms.map(term => new RegExp(term, 'i')); - queryObject.$and = [{ $or: searchRegex.map(regex => ({ question: regex })) }]; } + // Handle mySearch query to search within user's created questions if (req.query.mySearch) { const searchTerms = req.query.mySearch.split(' ').filter(term => term !== ''); const searchRegex = searchTerms.map(term => new RegExp(term, 'i')); - queryObject.$and = [ { $or: searchRegex.map(regex => ({ question: regex })) }, { createdBy: userId }, ]; } - console.log(queryObject); + console.log(queryObject); // For debugging purposes + // Get the total count of questions matching the query const totalQuestions = await Ques.countDocuments(queryObject); - let myQuestions, questionsLength, fixedTotalQuestions, totalMyQuestions, totalMyPages, totalPages; + // Get the count of questions created by the user + const myQuestionsQueryObject = { ...queryObject, createdBy: userId }; + const totalMyQuestions = await Ques.countDocuments(myQuestionsQueryObject); - // if (myquestion) { - const queryObjects = { ...queryObject, createdBy: userId }; - myQuestions = await Ques.find(queryObjects); - questionsLength = myQuestions.length; - totalMyQuestions = await Ques.countDocuments({ createdBy: userId }); - totalMyPages = Math.ceil(totalMyQuestions / req.query.questionsPerPage); - + // Calculate total pages + const questionsPerPage = parseInt(req.query.questionsPerPage) || 10; // Set a default value if not provided + const totalPages = Math.ceil(totalQuestions / questionsPerPage); + const totalMyPages = Math.ceil(totalMyQuestions / questionsPerPage); - // const totalMyQuestions = await Ques.countDocuments({ createdBy: userId }); - fixedTotalQuestions = await Ques.countDocuments({}); - totalPages = Math.ceil(totalQuestions / req.query.questionsPerPage); + // Get the total count of all questions in the collection + const fixedTotalQuestions = await Ques.countDocuments({}); return res.status(200).json({ success: true, totalQuestions: totalQuestions, - questionsLength: questionsLength, - // totalSearchQuestions: totalSearchQuestions, - fixedTotalQuestions: fixedTotalQuestions, totalMyQuestions: totalMyQuestions, + fixedTotalQuestions: fixedTotalQuestions, + totalPages: totalPages, + totalMyPages: totalMyPages, }); } catch (error) { + console.error("Error in getTotalQuestions:", error); // Added logging for debugging return res.status(500).json({ success: false, message: error.message || "Internal Server Error", @@ -543,3 +592,58 @@ export const updateQuestionDetails = async (req, res) => { } }; +export const updateQuestionTopics = async (req, res) => { + try { + const { questionIds, subtopic, topic } = req.body; + + // Ensure questionIds is an array + const ids = Array.isArray(questionIds) ? questionIds : [questionIds]; + + if (ids.length === 0) { + return res.status(400).json({ message: 'No question IDs provided.' }); + } + + // Find questions with the provided IDs + const existingQuestions = await Ques.find({ _id: { $in: ids } }); + if (existingQuestions.length === 0) { + return res.status(404).json({ message: 'No questions found with the provided IDs.' }); + } + + const updateFields = {}; + + // Handle topic update + if (topic && topic.length > 0) { + updateFields.topics = topic; // Set topics to the provided value + updateFields.subtopics = []; // Clear subtopics if topics are being updated + } + + // Handle subtopic update + if (subtopic && subtopic.length > 0) { + updateFields.subtopics = subtopic; // Update subtopics + } + + console.log('Update fields:', updateFields); // Log update fields for debugging + + // Perform the update + const result = await Ques.updateMany( + { _id: { $in: ids } }, + { $set: updateFields } + ); + + // Check if any documents were matched and modified + if (result.matchedCount === 0) { + return res.status(404).json({ message: 'No questions found with the provided IDs.' }); + } + + if (result.modifiedCount > 0) { + return res.status(200).json({ message: 'Questions updated successfully.' }); + } else { + return res.status(200).json({ message: 'Questions found but nothing was updated because the data was the same.' }); + } + } catch (error) { + console.error('Error updating questions:', error); + res.status(500).json({ message: 'An error occurred while updating questions.' }); + } +}; + + diff --git a/controller/subtopicController.js b/controller/subtopicController.js index b3055ab..3f5df3a 100644 --- a/controller/subtopicController.js +++ b/controller/subtopicController.js @@ -107,6 +107,7 @@ export const getSubtopics = async (req, res) => { const chapterNameArray = chapterName.split(',').map(name => name.trim()); const topicNameArray = topicName.split(',').map(name => name.trim()); + // Fetch the subject and populate chapters, topics, and subtopics const subject = await Subject.findOne({ name: subjectName, standard, @@ -116,37 +117,38 @@ export const getSubtopics = async (req, res) => { populate: { path: 'topics', match: { name: { $in: topicNameArray } }, - populate: 'subtopics' + populate: { + path: 'subtopics', // Ensure this path includes subtopic names + select: 'name', // Select fields you need + } } }); if (!subject) { - return res.status(400).json({ success: false, message: "Subject not found" }); + return res.status(404).json({ success: false, message: "Subject not found" }); } let subtopics = []; + // Flatten and collect all subtopics from the populated data subject.chapters.forEach(chapter => { chapter.topics.forEach(topic => { subtopics.push(...topic.subtopics); }); }); - for (let i = 0; i < subtopics.length; i++) { - const subtopic = subtopics[i]; - if (subtopic.subtopics && subtopic.subtopics.length > 0) { - const nestedSubtopicIds = subtopic.subtopics; - const nestedSubtopics = await Subtopic.find({ _id: { $in: nestedSubtopicIds } }); - subtopics[i].subtopics = nestedSubtopics; - } - } + // Map subtopics with their names + subtopics = subtopics.map(subtopic => ({ + _id: subtopic._id, + name: subtopic.name, // Use the name directly + })); res.status(200).json({ success: true, subtopics, }); } catch (error) { - console.error('Error in getSubTopic:', error); + console.error('Error in getSubtopics:', error); res.status(500).json({ success: false, message: error.message || 'Internal Server Error', diff --git a/controller/topicController.js b/controller/topicController.js index 2f1b0fc..cb7924c 100644 --- a/controller/topicController.js +++ b/controller/topicController.js @@ -139,16 +139,25 @@ export const getTopic = async (req, res) => { let filter = {}; - if (subjectName) filter.subjectName = subjectName; - if (standard) filter.standard = standard; - if (chapterName) filter.chapterName = chapterName; + if (subjectName) { + filter.subjectName = subjectName; + } - const topics = await Topic.find(filter); + if (standard) { + filter.standard = standard; + } - if (topics.length === 0) { - return res.status(404).json({ success: false, message: 'No topics found' }); + if (chapterName) { + // Split chapterName by commas to handle multiple values, trimming spaces + const chaptersArray = chapterName.split(',').map(chapter => chapter.trim()); + + // Use MongoDB $in operator for filtering by multiple chapters + filter.chapterName = { $in: chaptersArray }; } + const topics = await Topic.find(filter); + + return res.status(200).json({ success: true, topics }); } catch (error) { console.error('Error in getTopic:', error); @@ -156,6 +165,7 @@ export const getTopic = async (req, res) => { } }; + export const getTopicById = async (req, res) => { try { const { id } = req.params; diff --git a/routes/questionRoutes.js b/routes/questionRoutes.js index faede2c..cbfb7e7 100644 --- a/routes/questionRoutes.js +++ b/routes/questionRoutes.js @@ -9,6 +9,7 @@ import { getTotalQuestions, updateOption, updateQuestionDetails, + updateQuestionTopics, // toggleOptionTag, } from "../controller/quesController.js"; import isAuthenticated from "../middlewares/auth.js"; @@ -31,5 +32,6 @@ router.get("/get/myquestion", isAuthenticated, getMyQuestions) router.get("/get/users", isAuthenticated, allUser); router.get("/get/totalquestion", isAuthenticated, getTotalQuestions); router.put('/updatequestion/:questionId', updateQuestionDetails); +router.put('/updatequestiontopic', updateQuestionTopics) export default router;