From 153007fc473cd811bdb7b9f20d1f7d22cea6b0e6 Mon Sep 17 00:00:00 2001 From: ShivaniYadav07 Date: Sun, 25 Aug 2024 00:31:33 +0530 Subject: [PATCH 1/4] update multi select for topic and added subtopic for topics in profileHead --- controller/quesController.js | 86 ++++++++++++++++++++++++++--------- controller/topicController.js | 22 ++++++--- 2 files changed, 80 insertions(+), 28 deletions(-) diff --git a/controller/quesController.js b/controller/quesController.js index 41d50d9..9cd9ed1 100644 --- a/controller/quesController.js +++ b/controller/quesController.js @@ -143,27 +143,49 @@ export const getAllQuestion = async (req, res) => { try { const queryObject = {}; + // 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; + // 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()); + + if (topics.length === 1) { + // If single topic, use direct equality + queryObject.topics = topics[0]; + } else { + // If multiple topics, use $in + queryObject.topics = { $in: topics }; + } + } + + // 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 +202,7 @@ export const getAllQuestion = async (req, res) => { formattedQuestions = questions.map(question => ({ ...question.toObject(), - nestedSubTopic: question.nestedSubTopic || "" + nestedSubTopic: question.nestedSubTopic || "" })); } @@ -258,6 +280,9 @@ export const getAllQuestion = async (req, res) => { } }; + + + export const getTotalQuestions = async (req, res) => { try { const queryObject = {}; @@ -265,11 +290,24 @@ export const getTotalQuestions = async (req, res) => { 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 // If it's already an array, use it directly + : req.query.chapter.split(',').map(chapter => chapter.trim()); + queryObject.chapter = { $in: chapters }; // Matches any of the chapters + } + + // Handle multiple topics + if (req.query.topic) { + const topics = Array.isArray(req.query.topic) + ? req.query.topic // If it's already an array, use it directly + : req.query.topic.split(',').map(topic => topic.trim()); + queryObject.topics = { $in: topics }; // Matches any of the topics + } + + if (req.query.createdBy) queryObject.createdBy = req.query.createdBy; if (req.query.search) { const searchTerms = req.query.search.split(' ').filter(term => term !== ''); @@ -290,29 +328,31 @@ export const getTotalQuestions = async (req, res) => { console.log(queryObject); + // Get the total count of questions matching the query const totalQuestions = await Ques.countDocuments(queryObject); let myQuestions, questionsLength, fixedTotalQuestions, totalMyQuestions, totalMyPages, totalPages; - // 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); - + // Get the count of questions created by the user + const queryObjects = { ...queryObject, createdBy: userId }; + myQuestions = await Ques.find(queryObjects); + questionsLength = myQuestions.length; - // const totalMyQuestions = await Ques.countDocuments({ createdBy: userId }); - fixedTotalQuestions = await Ques.countDocuments({}); + totalMyQuestions = await Ques.countDocuments({ createdBy: userId }); + + // Calculate total pages for the user's questions and total questions + totalMyPages = Math.ceil(totalMyQuestions / req.query.questionsPerPage); + fixedTotalQuestions = await Ques.countDocuments({}); // Total questions in the collection totalPages = Math.ceil(totalQuestions / req.query.questionsPerPage); return res.status(200).json({ success: true, totalQuestions: totalQuestions, questionsLength: questionsLength, - // totalSearchQuestions: totalSearchQuestions, fixedTotalQuestions: fixedTotalQuestions, totalMyQuestions: totalMyQuestions, + totalPages: totalPages, + totalMyPages: totalMyPages, }); } catch (error) { return res.status(500).json({ @@ -322,6 +362,8 @@ export const getTotalQuestions = async (req, res) => { } }; + + export const getMyQuestions = async (req, res) => { try { const userId = req.user._id; 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; From e7a209d701b3bf8fc65405cc178ae233b7ef9caf Mon Sep 17 00:00:00 2001 From: ShivaniYadav07 Date: Mon, 26 Aug 2024 02:20:10 +0530 Subject: [PATCH 2/4] fixed subtopic render for profileHead --- controller/quesController.js | 80 +++++++++++++++++++++----------- controller/subtopicController.js | 24 +++++----- 2 files changed, 65 insertions(+), 39 deletions(-) diff --git a/controller/quesController.js b/controller/quesController.js index 9cd9ed1..22d22ce 100644 --- a/controller/quesController.js +++ b/controller/quesController.js @@ -139,11 +139,12 @@ export const deleteQuestion = async (req, res) => { } }; + export const getAllQuestion = async (req, res) => { try { const queryObject = {}; - // Handle standard and subject queries + // 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.createdBy) queryObject.createdBy = req.query.createdBy; @@ -161,14 +162,15 @@ export const getAllQuestion = async (req, res) => { const topics = Array.isArray(req.query.topic) ? req.query.topic : req.query.topic.split(',').map(tp => tp.trim()); + queryObject.topics = { $in: topics }; + } - if (topics.length === 1) { - // If single topic, use direct equality - queryObject.topics = topics[0]; - } else { - // If multiple topics, use $in - 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 @@ -273,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", @@ -288,73 +291,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; // Handle multiple chapters if (req.query.chapter) { const chapters = Array.isArray(req.query.chapter) - ? req.query.chapter // If it's already an array, use it directly + ? req.query.chapter : req.query.chapter.split(',').map(chapter => chapter.trim()); - queryObject.chapter = { $in: chapters }; // Matches any of the chapters + queryObject.chapter = { $in: chapters }; } - // Handle multiple topics + // Handle single or multiple topics if (req.query.topic) { const topics = Array.isArray(req.query.topic) - ? req.query.topic // If it's already an array, use it directly + ? req.query.topic : req.query.topic.split(',').map(topic => topic.trim()); - queryObject.topics = { $in: topics }; // Matches any of the topics + 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 queryObjects = { ...queryObject, createdBy: userId }; - myQuestions = await Ques.find(queryObjects); - questionsLength = myQuestions.length; + const myQuestionsQueryObject = { ...queryObject, createdBy: userId }; + const totalMyQuestions = await Ques.countDocuments(myQuestionsQueryObject); - totalMyQuestions = await Ques.countDocuments({ createdBy: userId }); + // 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); - // Calculate total pages for the user's questions and total questions - totalMyPages = Math.ceil(totalMyQuestions / req.query.questionsPerPage); - fixedTotalQuestions = await Ques.countDocuments({}); // Total questions in the collection - 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, - 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", @@ -362,6 +374,18 @@ export const getTotalQuestions = async (req, res) => { } }; +// Function to convert subtopic names to IDs +const convertSubtopicNamesToIds = async (subtopicNames) => { + try { + const subtopics = await Subtopic.find({ name: { $in: subtopicNames } }); + return subtopics.map(subtopic => subtopic._id); + } catch (error) { + console.error("Error converting subtopic names to IDs:", error); + throw new Error("Error converting subtopic names to IDs"); + } +}; + + export const getMyQuestions = async (req, res) => { 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', From 53d886b084b4a90f26bf0e49a2e1486a5bc8f88b Mon Sep 17 00:00:00 2001 From: ShivaniYadav07 Date: Wed, 28 Aug 2024 01:19:39 +0530 Subject: [PATCH 3/4] fixin frontend ... --- controller/quesController.js | 48 +++++++++++++++++++++++------------- routes/questionRoutes.js | 2 ++ 2 files changed, 33 insertions(+), 17 deletions(-) diff --git a/controller/quesController.js b/controller/quesController.js index 22d22ce..0635b88 100644 --- a/controller/quesController.js +++ b/controller/quesController.js @@ -283,9 +283,6 @@ queryObject.subtopics = {$in: subtopics} } }; - - - export const getTotalQuestions = async (req, res) => { try { const queryObject = {}; @@ -374,20 +371,6 @@ export const getTotalQuestions = async (req, res) => { } }; -// Function to convert subtopic names to IDs -const convertSubtopicNamesToIds = async (subtopicNames) => { - try { - const subtopics = await Subtopic.find({ name: { $in: subtopicNames } }); - return subtopics.map(subtopic => subtopic._id); - } catch (error) { - console.error("Error converting subtopic names to IDs:", error); - throw new Error("Error converting subtopic names to IDs"); - } -}; - - - - export const getMyQuestions = async (req, res) => { try { const userId = req.user._id; @@ -609,3 +592,34 @@ export const updateQuestionDetails = async (req, res) => { } }; +export const updateQuestionTopics = async (req, res) => { + try { + const { questionIds, subtopic, topic } = req.body; + + if (!questionIds || questionIds.length === 0) { + return res.status(400).json({ message: 'No question IDs provided.' }); + } + + // Check if subtopic is provided for updating + if (subtopic) { + // Update the subtopic of the questions + await Ques.updateMany( + { _id: { $in: questionIds }, subtopic: { $exists: true } }, + { $set: { subtopic: subtopic } } + ); + res.status(200).json({ message: 'Subtopics updated successfully.' }); + } else if (topic) { + // If no subtopic, update the topic + await Ques.updateMany( + { _id: { $in: questionIds }, subtopic: { $exists: false } }, + { $set: { topic: topic } } + ); + res.status(200).json({ message: 'Topics updated successfully.' }); + } else { + res.status(400).json({ message: 'No subtopic or topic provided for update.' }); + } + } catch (error) { + console.error('Error updating questions:', error); + res.status(500).json({ message: 'An error occurred while updating questions.' }); + } +}; \ No newline at end of file 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; From bd3feebdbe79ca0ea5d6660e7fd338f20c4a212b Mon Sep 17 00:00:00 2001 From: ShivaniYadav07 Date: Fri, 30 Aug 2024 01:25:02 +0530 Subject: [PATCH 4/4] update --- controller/quesController.js | 60 +++++++++++++++++++++++++----------- 1 file changed, 42 insertions(+), 18 deletions(-) diff --git a/controller/quesController.js b/controller/quesController.js index 0635b88..b235e63 100644 --- a/controller/quesController.js +++ b/controller/quesController.js @@ -596,30 +596,54 @@ export const updateQuestionTopics = async (req, res) => { try { const { questionIds, subtopic, topic } = req.body; - if (!questionIds || questionIds.length === 0) { + // 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.' }); } - // Check if subtopic is provided for updating - if (subtopic) { - // Update the subtopic of the questions - await Ques.updateMany( - { _id: { $in: questionIds }, subtopic: { $exists: true } }, - { $set: { subtopic: subtopic } } - ); - res.status(200).json({ message: 'Subtopics updated successfully.' }); - } else if (topic) { - // If no subtopic, update the topic - await Ques.updateMany( - { _id: { $in: questionIds }, subtopic: { $exists: false } }, - { $set: { topic: topic } } - ); - res.status(200).json({ message: 'Topics updated successfully.' }); + // 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 { - res.status(400).json({ message: 'No subtopic or topic provided for update.' }); + 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.' }); } -}; \ No newline at end of file +}; + +