diff --git a/client/src/components/MobileNavbar.jsx b/client/src/components/MobileNavbar.jsx
index 8e9be9a..01afb2f 100644
--- a/client/src/components/MobileNavbar.jsx
+++ b/client/src/components/MobileNavbar.jsx
@@ -40,6 +40,15 @@ export default function MobileNavbar({ logout, userData, open, setOpen, mode, se
Dashboard
+
+
+ {userData?.level}
+ {userData?.points}
+ {userData?.badgeCount?.gold}
+ /{userData?.badgeCount?.silver}
+ /{userData?.badgeCount?.bronze}
+
+
diff --git a/client/src/controllers/SearchBarController.js b/client/src/controllers/SearchBarController.js
index 2202691..b01a111 100644
--- a/client/src/controllers/SearchBarController.js
+++ b/client/src/controllers/SearchBarController.js
@@ -15,12 +15,12 @@ export default function SearchBarController() {
e.preventDefault();
if (location.pathname === '/questions/search') {
- setSearchParams({ title: search, text: search, creator: search }, { replace: true });
+ setSearchParams({ title: search }, { replace: true });
} else {
navigate({
pathname: '/questions/search',
search: `?${createSearchParams({
- title: search, text: search, creator: search
+ title: search,
})}`,
replace: true,
});
diff --git a/client/src/controllers/SearchResultsController.jsx b/client/src/controllers/SearchResultsController.jsx
index 196821f..85fe890 100644
--- a/client/src/controllers/SearchResultsController.jsx
+++ b/client/src/controllers/SearchResultsController.jsx
@@ -9,31 +9,26 @@ export default function SearchResultsController() {
const [searchParams] = useSearchParams();
const [loading, setLoading] = useState(true);
- const getData = async ({ question_id }) => {
- let match = {};
- const regexMatch = {};
- const time = {};
- let newdate = searchParams.get('createdAt');
+ const getData = async () => {
+ const creator = searchParams.get('creator');
+ const title = searchParams.get('title');
+ const text = searchParams.get('text');
+ let tags = searchParams.get('tags');
+ let time = searchParams.get('createdAt');
+ let createdAt = {};
- if (newdate) {
- newdate = new Date(newdate);
- time['$gte'] = parseInt(newdate.getTime());
- newdate.setDate(newdate.getDate() + 1);
- time['$lte'] = newdate.getTime();
- match = JSON.stringify({ createdAt: time });
+ if (time) {
+ time = new Date(time);
+ createdAt['$gte'] = parseInt(time.getTime());
+ time.setDate(time.getDate() + 1);
+ createdAt['$lte'] = time.getTime();
+ }
+ if (tags) {
+ tags = tags.split(' ');
}
- const creator = searchParams.get('creator');
- if (creator) regexMatch.creator = creator;
-
- const text = searchParams.get('text');
- if (text) regexMatch.text = text.replaceAll(' ', '|');
-
- const title = searchParams.get('title');
- if (title) regexMatch.title = title.replaceAll(' ', '|');
-
setLoading(() => true);
- const { questions } = await searchQuestions({ after: question_id, regexMatch, match });
+ const { questions } = await searchQuestions({ creator, title, text, tags, createdAt });
setLoading(() => false);
return questions;
diff --git a/client/src/services/fields.js b/client/src/services/fields.js
index f5db0c2..e99386f 100644
--- a/client/src/services/fields.js
+++ b/client/src/services/fields.js
@@ -22,6 +22,7 @@ const askQuestionFields = [
label: 'Text',
multiline: true,
},
+ { id: 'tags', label: 'Tags' },
];
const commentFields = [
@@ -127,6 +128,7 @@ const searchFields = [
id: 'creator',
label: 'Creator',
},
+ { id: 'tags', label: 'Tags (separated by spaces)' },
];
const generateEditFields =
diff --git a/client/src/services/questionsServices.js b/client/src/services/questionsServices.js
index 938ea83..bc3622a 100644
--- a/client/src/services/questionsServices.js
+++ b/client/src/services/questionsServices.js
@@ -2,7 +2,10 @@ import { createEndpoint } from './api';
const callQuestionsAPI = createEndpoint('/questions');
-const searchQuestions = async (sort) => callQuestionsAPI('get', `/search`, sort);
+const searchQuestions = async (sort) => {
+ console.log(sort);
+ return callQuestionsAPI('get', `/search`, sort);
+};
const postQuestion = async (data) => callQuestionsAPI('post', ``, data);
diff --git a/client/src/services/schemas.js b/client/src/services/schemas.js
index 0e81f86..d2be36a 100644
--- a/client/src/services/schemas.js
+++ b/client/src/services/schemas.js
@@ -21,6 +21,10 @@ const searchSchema = Yup.object({
text: Yup.string().max(300, 'Text must be at most 300 characters, try and use keywords only '),
// createdAt: Yup.string().max(11, 'Date must be at most 11 characters, make sure body is formatted correctly'),
creator: Yup.string().max(16, 'username must be at most 16 characters'),
+ tags: Yup.string().matches(
+ /^(?:\b\w+\b[\s\r\n]*){0,5}$/,
+ 'Tags should be separated by spaces and are limited to 5'
+ ),
});
const loginSchema = Yup.object({
@@ -71,17 +75,12 @@ const questionSchema = Yup.object({
text: Yup.string()
.max(3000, 'Body cannot be longer than 3000 characters')
.required('A body is required'),
+ tags: Yup.string().matches(
+ /^(?:\b\w+\b[\s\r\n]*){0,5}$/,
+ 'Tags should be separated by spaces and are limited to 5'
+ ),
});
-const editSchema = Yup.object({
- etitle: Yup.string()
- .max(150, 'Title cannot be longer then 150 characters.')
- .required('A title is required.'),
- etext: Yup.string()
- .max(3000, 'Body cannot be longer than 3000 characters')
- .required('A body is required'),
-})
-
const patchSchema = Yup.object().shape(
{
email: Yup.string()
diff --git a/server/db/models/User.js b/server/db/models/User.js
index a6b75e1..3eb6861 100644
--- a/server/db/models/User.js
+++ b/server/db/models/User.js
@@ -18,7 +18,6 @@ const User = mongoose.Schema(
User.post('findOneAndUpdate', async (doc) => {
const badges = calculateUserBadges(doc.points);
doc.badges = [...new Set([...doc.badges, ...badges])];
- console.log(doc.badges);
await doc.save();
});
diff --git a/server/routes/question/CreateQuestion.js b/server/routes/question/CreateQuestion.js
index 0aff3e2..decd845 100644
--- a/server/routes/question/CreateQuestion.js
+++ b/server/routes/question/CreateQuestion.js
@@ -9,7 +9,7 @@ async function CreateQuestion(req, res) {
if (!title || !text) return res.status(400).send(config.errorIncomplete);
- if (tags && tags.length > 5) {
+ if (tags && tags.split(' ').length > 5) {
return res.status(400).send(config.errorIncomplete);
}
@@ -21,7 +21,11 @@ async function CreateQuestion(req, res) {
if (!success) return res.status(500).send(config.errorGeneric);
- const newQuestion = await Question.create({ ...question, tags, _id: question.question_id });
+ const newQuestion = await Question.create({
+ ...question,
+ tags: tags.split(' '),
+ _id: question.question_id,
+ });
// Increment user points by 1
await createRequest('patch', `/users/${user.username}/points`, {
diff --git a/server/routes/question/Search.js b/server/routes/question/Search.js
index eb23464..058f3df 100644
--- a/server/routes/question/Search.js
+++ b/server/routes/question/Search.js
@@ -1,32 +1,36 @@
-const createRequest = require('server/utils/api');
const config = require('server/config.json');
const Question = require('server/db/models/Question');
async function Search(req, res) {
- const { success, questions } = await createRequest(
- 'get',
- `/questions/search`,
- req.query
- );
+ const { creator, title, text, tags, createdAt } = req.query;
- if (!success) return res.status(500).send(config.errorGeneric);
+ let searchQuery = {};
+ if (creator) {
+ searchQuery['creator'] = {
+ $regex: creator,
+ };
+ }
+ if (title) {
+ searchQuery['title'] = {
+ $regex: title,
+ };
+ }
+ if (text) {
+ searchQuery['text'] = {
+ $regex: text,
+ };
+ }
+ if (tags) {
+ searchQuery['tags'] = { $all: tags };
+ }
+ if (createdAt) {
+ searchQuery['createdAt'] = createdAt;
+ }
- // Patch search results to database
- const questionSet = await Promise.all(
- questions
- .map((question) => ({
- id: question.question_id,
- ...question,
- }))
- .map(async (question) => {
- return Question.findByIdAndUpdate(question.id, question, {
- upsert: true,
- });
- })
- );
+ const questions = await Question.find(searchQuery).sort({ createdAt: 'asc' });
- return res.send({ questions: questionSet.filter(question => question) });
+ return res.send({ questions });
}
module.exports = Search;