Skip to content

Commit a6c886b

Browse files
committedSep 18, 2023
last edition of the favorite section
1 parent ca31c69 commit a6c886b

19 files changed

+387
-161
lines changed
 

‎client/src/components/Navbar-Components/NavbarBS.jsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import "../../App.css";
1919

2020
export default function NavbarBS() {
2121
const { user, isLoading, logout } = useContext(AuthContext);
22-
console.log(user);
22+
2323
return (
2424
<>
2525
<Navbar

‎client/src/components/communityQuestions/PostsList.jsx

+14-7
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ import Favourite from "../dashboard/tabs/Favourite";
1818
import { cols } from "../../colorSchema";
1919
import "./PostsList.css";
2020
import CommentsModal from "./CommentsModal";
21+
import OverlayTrigger from 'react-bootstrap/OverlayTrigger';
22+
import Tooltip from 'react-bootstrap/Tooltip';
2123

2224

2325

@@ -27,31 +29,33 @@ function PostsList({ posts, setPosts, comments, setComments,savedPosts }) {
2729
const [selectedPost, setSelectedPost] = useState(null);
2830
const [modalIsOpen, setModalIsOpen] = useState(false);
2931

30-
const filteredPosts = posts && posts.length > 0 ? posts.filter((post) => post.saves.includes(user._id)) : [];
31-
// console.log(filteredPosts);
32+
3233

3334

3435
const handleLikeClick = async (postId) => {
36+
3537
try {
3638
const response = await axiosClient.get(`/post/${postId}`);
3739
const currentLikers = response.data.likes;
3840
const flattenedLikers = currentLikers.flat();
3941

4042
if (flattenedLikers.includes(user._id)) {
4143
await axiosClient.put(`/post/${postId}`, {
42-
$pull: { likes: user._id },
44+
$pull: { likes: user._id }
4345
});
4446
} else {
4547
await axiosClient.put(`/post/${postId}`, {
4648
$push: { likes: user._id },
4749
});
4850
}
51+
4952
} catch (error) {
5053
console.error("Error while adding like:", error);
5154
}
5255
};
5356

5457

58+
5559
const handleSaveClick = async (postId) => {
5660
try {
5761
const response = await axiosClient.get(`/post/${postId}`);
@@ -67,9 +71,7 @@ function PostsList({ posts, setPosts, comments, setComments,savedPosts }) {
6771
$push: { saves: user._id },
6872
});
6973
}
70-
} else {
71-
console.error("Error: response.data.saves is not an array.");
72-
}
74+
}
7375

7476
} catch (error) {
7577
console.error("Error while saving Post:", error);
@@ -140,10 +142,15 @@ function PostsList({ posts, setPosts, comments, setComments,savedPosts }) {
140142
<Row className="likes_Comments_Counter">
141143
{post && post.likes.length > 0 ? (
142144
<Col className="likesCounter">
145+
<OverlayTrigger
146+
147+
overlay={<Tooltip >{post.likes.map((like)=>like.map((innerLike)=>innerLike.username)).join(", ")}</Tooltip>}
148+
>
143149
<FontAwesomeIcon
144150
icon={solidThumbsUp}
145151
className="likeIconCounter"
146-
/>{" "}
152+
/>
153+
</OverlayTrigger>{" "}
147154
{post.likes.length}
148155
</Col>
149156
) : (
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
2+
3+
.favorites{
4+
display: flex;
5+
flex-direction: column;
6+
height: 100%;
7+
justify-content: center;
8+
align-items: center;
9+
gap: 30px;
10+
margin-top: 100px;
11+
width: 100%;
12+
}
13+
14+
.savedQuestionsCarousel{
15+
width: 100%;
16+
padding: 50px;
17+
min-height: 600px;
18+
}
19+
.savedQuestionsCarousel .carousel-inner{
20+
min-height: 500px;
21+
}
22+
23+
24+
25+
.savedPostsCarousel {
26+
width: 100%;
27+
min-height: 750px;
28+
height: 750px;
29+
padding: 50px;
30+
margin-bottom: 100px;
31+
32+
}
33+
34+
.savedPostsCarousel .carousel-inner{
35+
36+
min-height: 750px;
37+
max-height: 750px;
38+
width: 80%;
39+
overflow: visible;
40+
margin-left: auto;
41+
display: flex;
42+
align-items: center;
43+
44+
45+
46+
}
47+
.carousel-indicators{
48+
margin-top: 2rem;
49+
}

‎client/src/components/dashboard/tabs/Favourite.jsx

+68-8
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,27 @@ import React, { useContext, useEffect, useState } from "react";
22
import { AuthContext } from "../../../context/AuthProvider";
33
import { axiosClient } from "../../../axiosClient";
44
import PostsList from "../../communityQuestions/PostsList";
5-
6-
5+
import QuestionsList from "../../interviewQuestions/QuestionsList";
6+
import Carousel from "react-bootstrap/Carousel";
7+
import "./Favourite.css";
78

89
export default function Favourite() {
910
const { user } = useContext(AuthContext);
1011
const [posts, setPosts] = useState([]);
1112
const [comments, setcomments] = useState([]);
12-
const [savedPosts, setSavedPosts]=useState([])
13+
const [savedPosts, setSavedPosts] = useState([]);
14+
const [savedQuest, setSavedQuest] = useState([]);
1315

16+
const showFilter = "filterHidden";
1417

15-
1618
useEffect(() => {
1719
const fetchData = async () => {
1820
try {
1921
const result = await axiosClient.get("/post");
2022
setPosts(result.data);
21-
setSavedPosts(posts.filter((post)=>JSON.stringify(post.saves).includes(user._id)))
23+
setSavedPosts(
24+
posts.filter((post) => JSON.stringify(post.saves).includes(user._id))
25+
);
2226
} catch (error) {
2327
console.log(error);
2428
}
@@ -38,11 +42,67 @@ export default function Favourite() {
3842
fetchData();
3943
}, [comments]);
4044

45+
const [data, setData] = useState([]);
46+
const [loading, setLoading] = useState(true);
47+
48+
const fetchData = async () => {
49+
try {
50+
const response = await axiosClient.get("/interviewQuestions");
51+
setData(response.data);
52+
setSavedQuest(
53+
response.data.filter((question) =>
54+
JSON.stringify(question.saves).includes(user._id)
55+
)
56+
);
57+
setLoading(false);
58+
} catch (error) {
59+
console.log(error);
60+
setLoading(false);
61+
}
62+
};
63+
useEffect(() => {
64+
fetchData();
65+
}, [data]);
4166

4267
return (
43-
<div className="col-12 mt-5 d-flex flex-column justify-content-center align-items-center">
44-
45-
<PostsList posts={savedPosts} comments={comments} setcomments={setcomments} />
68+
<div className="favorites">
69+
{
70+
savedQuest.length > 0?
71+
72+
<div className="savedQuestionsCarousel">
73+
<h4 style={{color:"white", marginBottom:"50px"}}>Saved Questions:</h4>
74+
<Carousel>
75+
{savedQuest.map((question, index) => (
76+
<Carousel.Item key={index}>
77+
<QuestionsList
78+
data={[question]}
79+
loading={loading}
80+
setLoading={setLoading}
81+
isFavoritesSection={true}
82+
83+
/>
84+
</Carousel.Item>
85+
))}
86+
</Carousel>
87+
</div>
88+
:
89+
<h4>No saved Questions</h4>
90+
}
91+
{savedPosts.length>0?
92+
<div className="savedPostsCarousel">
93+
<h4 style={{color:"white", marginBottom:"50px"}}>Saved Posts:</h4>
94+
<Carousel >
95+
{savedPosts.map((post, index) => (
96+
<Carousel.Item key={index}>
97+
<PostsList posts={[post]} comments={comments} setcomments={setcomments} />
98+
</Carousel.Item>
99+
))}
100+
</Carousel>
101+
</div>
102+
:
103+
<h4>No saved Posts</h4>
104+
}
46105
</div>
106+
47107
);
48108
}

‎client/src/components/dashboard/tabs/userfeed/PostsFeedTab.jsx

+12-3
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,17 @@ import CreatePostMask from "./CreatePostMask";
99
import { cols } from "../../../../colorSchema";
1010
import { faDisplay } from "@fortawesome/free-solid-svg-icons";
1111
import Favourite from "../Favourite";
12+
import { useContext } from "react";
13+
import { AuthContext } from "../../../../context/AuthProvider";
14+
import cookieParser from "cookie-parser";
15+
1216

1317

1418

1519
export default function PostsFeedTab() {
1620
const [posts, setPosts] = useState([]);
1721
const [comments, setcomments] = useState([]);
22+
const { user } = useContext(AuthContext);
1823

1924

2025

@@ -28,7 +33,8 @@ export default function PostsFeedTab() {
2833
}
2934
};
3035
fetchData();
31-
}, [posts]);
36+
},[posts]);
37+
3238

3339
useEffect(() => {
3440
const fetchData = async () => {
@@ -41,14 +47,17 @@ export default function PostsFeedTab() {
4147
};
4248
fetchData();
4349
}, [comments]);
44-
// console.log("postsfeedtabs",posts);
4550

51+
52+
53+
54+
4655
return (
4756
<Container style={{ backgroundColor: cols.black, display:"flex", justifyContent:"center", marginLeft:"2rem"}}>
4857
<Row className="col-lg-9 col-md-10 col-sm-12" >
4958
<Col>
5059
<CreatePostMask posts={posts} setPosts={setPosts}/>
51-
<PostsList posts={posts} setPosts={setPosts} comments={comments} setcomments={setcomments} />
60+
<PostsList posts={posts} setPosts={setPosts} comments={comments} setcomments={setcomments} user={user} />
5261
</Col>
5362
</Row>
5463
</Container>

‎client/src/components/interviewQuestions/InterviewQuestionsDashboard.jsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ function InterviewQuestionsDashboard() {
2424
};
2525
useEffect(() => {
2626
fetchData();
27-
}, []);
27+
}, [data]);
2828
const handleAddQuestion = (newQuestion) => {
2929
setData([...data, newQuestion]);
3030
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
import React, { useState } from "react";
2+
import Dropdown from "react-bootstrap/Dropdown";
3+
import { Button, ButtonGroup } from "react-bootstrap";
4+
5+
export default function QuestionsFilter({ data, setFilteredData, handleFilterQuestions,selectedTechnology, setSelectedTechnology }) {
6+
// const [selectedTechnology, setSelectedTechnology] = useState(null);
7+
const [isTechnical, setIsTechnical] = useState(null);
8+
9+
10+
11+
12+
let filteredData = data;
13+
if (selectedTechnology) {
14+
filteredData = data.filter((question) => {
15+
return (
16+
question.technology === selectedTechnology &&
17+
(isTechnical === null || question.isTechnical === isTechnical)
18+
);
19+
});
20+
} else if (isTechnical !== null) {
21+
filteredData = data.filter(
22+
(question) => question.isTechnical === isTechnical
23+
);
24+
}
25+
26+
return (
27+
<Dropdown className="filterDropDown" required>
28+
<Dropdown.Toggle variant="dark" id="dropDownType">
29+
Filter by
30+
</Dropdown.Toggle>
31+
<Dropdown.Menu>
32+
<Dropdown.Item onClick={() => handleFilterQuestions("all")}>
33+
all
34+
</Dropdown.Item>
35+
<Dropdown as={ButtonGroup}>
36+
<Button
37+
className="filterQuestionsBtn"
38+
variant="dark"
39+
onClick={() => handleFilterQuestions("technical")}
40+
>
41+
Technical
42+
</Button>
43+
44+
<Dropdown.Toggle
45+
split
46+
variant="success"
47+
id="dropdown-split-basic"
48+
/>
49+
50+
<Dropdown.Menu>
51+
<Dropdown.Item onClick={() => setSelectedTechnology(null)}>
52+
All
53+
</Dropdown.Item>
54+
<Dropdown.Item onClick={() => setSelectedTechnology("node")}>
55+
node
56+
</Dropdown.Item>
57+
<Dropdown.Item onClick={() => setSelectedTechnology("express")}>
58+
express
59+
</Dropdown.Item>
60+
<Dropdown.Item onClick={() => setSelectedTechnology("react")}>
61+
react
62+
</Dropdown.Item>
63+
<Dropdown.Item
64+
onClick={() => setSelectedTechnology("javascript")}
65+
>
66+
javascript
67+
</Dropdown.Item>
68+
<Dropdown.Item onClick={() => setSelectedTechnology("html")}>
69+
html
70+
</Dropdown.Item>
71+
<Dropdown.Item onClick={() => setSelectedTechnology("css")}>
72+
css
73+
</Dropdown.Item>
74+
<Dropdown.Item onClick={() => setSelectedTechnology("sql")}>
75+
sql
76+
</Dropdown.Item>
77+
<Dropdown.Item onClick={() => setSelectedTechnology("mysql")}>
78+
mysql
79+
</Dropdown.Item>
80+
<Dropdown.Item onClick={() => setSelectedTechnology("mongodb")}>
81+
mongodb
82+
</Dropdown.Item>
83+
<Dropdown.Item onClick={() => setSelectedTechnology("bootstrap")}>
84+
bootstrap
85+
</Dropdown.Item>
86+
<Dropdown.Item onClick={() => setSelectedTechnology("other")}>
87+
other
88+
</Dropdown.Item>
89+
</Dropdown.Menu>
90+
</Dropdown>
91+
92+
<Dropdown.Item onClick={() => handleFilterQuestions("non-technical")}>
93+
Non-Technical
94+
</Dropdown.Item>
95+
</Dropdown.Menu>
96+
</Dropdown>
97+
);
98+
}

‎client/src/components/interviewQuestions/QuestionsList.css

+7
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,13 @@
1414
background-color: rgb(255, 255, 255);
1515
}
1616

17+
.filterShowed{
18+
display: block;
19+
}
20+
.filterHidden{
21+
display: none;
22+
}
23+
1724
.questionRatingSection {
1825
display: flex;
1926
flex-direction: row;

‎client/src/components/interviewQuestions/QuestionsList.jsx

+83-124
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,51 @@
1-
import React, { useEffect, useState } from "react";
1+
import React, { useState, useEffect } from "react";
22
import { axiosClient } from "../../axiosClient";
33
import "./QuestionsList.css";
44
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
55
import { useContext } from "react";
66
import { AuthContext } from "../../context/AuthProvider.jsx";
7-
import {
8-
faCircleUp,
9-
faCircleDown,
10-
faCogs,
11-
faLightbulb,
12-
} from "@fortawesome/free-solid-svg-icons";
13-
import { faCheckCircle as mediumChecked } from "@fortawesome/free-regular-svg-icons";
14-
import {
15-
Container,
16-
Col,
17-
Row,
18-
Image,
19-
Button,
20-
ButtonGroup,
21-
} from "react-bootstrap";
22-
import { OverlayTrigger, Tooltip } from "react-bootstrap";
23-
import AnswerList from "./AnswerList";
7+
import { faCircleUp, faCircleDown } from "@fortawesome/free-solid-svg-icons";
8+
import { Container, Col, Row, Image, Button } from "react-bootstrap";
249
import QuestionModal from "./AnswerModal";
2510
import DateFormatter from "./DateFormatter";
26-
import Dropdown from "react-bootstrap/Dropdown";
27-
import { cols } from "../../colorSchema";
2811
import TurnedInIcon from "@mui/icons-material/TurnedIn";
2912
import TurnedInNotIcon from "@mui/icons-material/TurnedInNot";
13+
import QuestionsFilter from "../interviewQuestions/QuestionsFilter";
14+
import { json } from "react-router-dom";
3015

31-
function QuestionsList({ data, loading, setData }) {
16+
function QuestionsList({ data, loading, setData, isFavoritesSection,savedQuest }) {
3217
const { user } = useContext(AuthContext);
33-
3418
const [showModal, setShowModal] = useState(false);
3519
const [selectedQuestion, setSelectedQuestion] = useState(null);
3620
const [isTechnical, setIsTechnical] = useState(null);
3721
const [selectedTechnology, setSelectedTechnology] = useState(null);
38-
const [savedQuestion, setSavedQuestion] = useState(false);
3922
const [selectedQuestionId, setSelectedQuestionId] = useState(null);
23+
const [filteredData, setFilteredData] = useState(data);
24+
const [showFilter, setshowFilter] = useState("filterShowed");
25+
const [savedQuestions, setSavedQuestions]=useState([])
26+
27+
useEffect(() => {
28+
let filteredQuestions = [...data];
29+
30+
if (selectedTechnology) {
31+
filteredQuestions = filteredQuestions.filter(
32+
(question) =>
33+
question.technology === selectedTechnology &&
34+
(isTechnical === null || question.isTechnical === isTechnical)
35+
);
36+
} else if (isTechnical !== null) {
37+
filteredQuestions = filteredQuestions.filter(
38+
(question) => question.isTechnical === isTechnical
39+
);
40+
}
41+
42+
setFilteredData(filteredQuestions);
43+
}, [data, selectedTechnology, isTechnical]);
4044

4145
const handleVote = async (questionId, voteType) => {
4246
try {
4347
const userId = user._id;
4448

45-
4649
await axiosClient.patch(`/interviewQuestions/${questionId}/vote`, {
4750
voteType,
4851
userId,
@@ -73,6 +76,8 @@ function QuestionsList({ data, loading, setData }) {
7376
return <div>No questions found.</div>;
7477
}
7578

79+
80+
7681
const handleOpenModal = (question) => {
7782
setSelectedQuestionId(question._id);
7883
setSelectedQuestion(question);
@@ -84,18 +89,37 @@ function QuestionsList({ data, loading, setData }) {
8489
setShowModal(false);
8590
};
8691

87-
const handleSaveQuestion = (questionId) => {
88-
setSelectedQuestionId(questionId);
92+
93+
94+
const handleSaveQuestion = async (questionId) => {
95+
try {
96+
const response = await axiosClient.get(`/interviewQuestions/${questionId}`);
97+
const currentSavers = response.data.saves;
98+
99+
if (Array.isArray(currentSavers)) {
100+
const flattenedSavers = currentSavers.flat();
101+
if (flattenedSavers.includes(user._id)) {
102+
// User already saved the question, so unsave it
103+
await axiosClient.put(`/interviewQuestions/${questionId}`, {
104+
$pull: { saves: user._id },
105+
});
106+
107+
} else {
108+
// User hasn't saved the question, so save it
109+
await axiosClient.put(`/interviewQuestions/${questionId}`, {
110+
$push: { saves: user._id },
111+
});
112+
}
113+
114+
// Update the savedQuestions state after making the API call
115+
}
116+
} catch (error) {
117+
console.error("Error while saving Question:", error);
118+
}
89119
};
120+
90121

91-
const questionWithHighestVotes = data.reduce(
92-
(prevQuestion, currentQuestion) => {
93-
return currentQuestion.votes > prevQuestion.votes
94-
? currentQuestion
95-
: prevQuestion;
96-
},
97-
data[0]
98-
);
122+
99123

100124
const handleFilterQuestions = (option) => {
101125
switch (option) {
@@ -118,96 +142,31 @@ function QuestionsList({ data, loading, setData }) {
118142
}
119143
};
120144

121-
let filteredData = data;
122-
if (selectedTechnology) {
123-
filteredData = data.filter((question) => {
124-
return (
125-
question.technology === selectedTechnology &&
126-
(isTechnical === null || question.isTechnical === isTechnical)
127-
);
128-
});
129-
} else if (isTechnical !== null) {
130-
filteredData = data.filter(
131-
(question) => question.isTechnical === isTechnical
132-
);
133-
}
145+
const questionWithHighestVotes = data.reduce(
146+
(prevQuestion, currentQuestion) => {
147+
return currentQuestion.votes > prevQuestion.votes
148+
? currentQuestion
149+
: prevQuestion;
150+
},
151+
data[0]
152+
);
134153

135154
return (
136155
<div
137156
className="questionListSection"
138157
style={{ display: "flex", flexDirection: "column" }}
139158
>
140-
<Dropdown className="filterDropDown" required>
141-
<Dropdown.Toggle variant="dark" id="dropDownType">
142-
Filter by
143-
</Dropdown.Toggle>
144-
<Dropdown.Menu>
145-
<Dropdown.Item onClick={() => handleFilterQuestions("all")}>
146-
all
147-
</Dropdown.Item>
148-
<Dropdown as={ButtonGroup}>
149-
<Button
150-
className="filterQuestionsBtn"
151-
variant="dark"
152-
onClick={() => handleFilterQuestions("technical")}
153-
>
154-
Technical
155-
</Button>
156-
157-
<Dropdown.Toggle
158-
split
159-
variant="success"
160-
id="dropdown-split-basic"
161-
/>
162-
163-
<Dropdown.Menu>
164-
<Dropdown.Item onClick={() => setSelectedTechnology(null)}>
165-
All
166-
</Dropdown.Item>
167-
<Dropdown.Item onClick={() => setSelectedTechnology("node")}>
168-
node
169-
</Dropdown.Item>
170-
<Dropdown.Item onClick={() => setSelectedTechnology("express")}>
171-
express
172-
</Dropdown.Item>
173-
<Dropdown.Item onClick={() => setSelectedTechnology("react")}>
174-
react
175-
</Dropdown.Item>
176-
<Dropdown.Item
177-
onClick={() => setSelectedTechnology("javascript")}
178-
>
179-
javascript
180-
</Dropdown.Item>
181-
<Dropdown.Item onClick={() => setSelectedTechnology("html")}>
182-
html
183-
</Dropdown.Item>
184-
<Dropdown.Item onClick={() => setSelectedTechnology("css")}>
185-
css
186-
</Dropdown.Item>
187-
<Dropdown.Item onClick={() => setSelectedTechnology("sql")}>
188-
sql
189-
</Dropdown.Item>
190-
<Dropdown.Item onClick={() => setSelectedTechnology("mysql")}>
191-
mysql
192-
</Dropdown.Item>
193-
<Dropdown.Item onClick={() => setSelectedTechnology("mongodb")}>
194-
mongodb
195-
</Dropdown.Item>
196-
<Dropdown.Item onClick={() => setSelectedTechnology("bootstrap")}>
197-
bootstrap
198-
</Dropdown.Item>
199-
<Dropdown.Item onClick={() => setSelectedTechnology("other")}>
200-
other
201-
</Dropdown.Item>
202-
</Dropdown.Menu>
203-
</Dropdown>
204-
205-
<Dropdown.Item onClick={() => handleFilterQuestions("non-technical")}>
206-
Non-Technical
207-
</Dropdown.Item>
208-
</Dropdown.Menu>
209-
</Dropdown>
210-
159+
{!isFavoritesSection && (
160+
<div className={showFilter ? "filterShowed" : "filterHidden"}>
161+
<QuestionsFilter
162+
163+
data={data}
164+
setFilteredData={setFilteredData}
165+
handleFilterQuestions={handleFilterQuestions}
166+
setSelectedTechnology={setSelectedTechnology}
167+
/>
168+
</div>
169+
)}
211170
<Container className="interviewQuestionSection">
212171
<Row>
213172
{filteredData.map((question) => (
@@ -234,21 +193,21 @@ function QuestionsList({ data, loading, setData }) {
234193
: "Type: Non-Technical"}
235194
</Row>
236195
<Row className="cardHeaderRight">
237-
{question.technology !== "" && (
238-
<>Technology: {question.technology}</>
239-
)}
196+
{question.technology !== "" && (
197+
<>Technology: {question.technology}</>
198+
)}
240199
</Row>
241200
</Col>
242201
<Col xs={1}>
243202
<div
244203
onClick={() => handleSaveQuestion(question._id)}
245204
className="saveQuetionIcon"
246205
>
247-
{selectedQuestionId === question._id ? (
206+
{JSON.stringify(question.saves).includes(JSON.stringify(user._id)) ?
248207
<TurnedInIcon />
249-
) : (
208+
:
250209
<TurnedInNotIcon />
251-
)}
210+
}
252211
</div>
253212
</Col>
254213
</Row>

‎client/src/context/AuthProvider.jsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ export default function AuthProvider({ children }) {
2323
setIsLoading(false);
2424
console.log(err);
2525
});
26-
}, []);
26+
}, [user]);
2727

2828
const login = (data) => {
2929
axiosClient

‎controllers/interviewQuestion.js

+26-2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1+
const { default: mongoose } = require("mongoose");
12
const InterviewQuestion = require("../models/interviewQuestion");
23

34
const createQuestion=async (req,res)=>{
45
try{
56
const {id}=req.user
67
const {body:{content,author,isTechnical,technology}}=req
7-
const question=await InterviewQuestion.create({content,author,isTechnical,technology})
8+
const question=await InterviewQuestion.create({content,author,isTechnical,technology,saves:[]})
89
res.status(201).json(question)
910
}catch(error){
1011
res.status(500).send(error.message)
@@ -31,6 +32,17 @@ const getQuestions=async (req,res)=>{
3132
}
3233
}
3334

35+
36+
const getQuestionsById=async(req,res)=>{
37+
try {
38+
const id = req.params.id
39+
const question= await InterviewQuestion.findById(id)
40+
res.status(200).json(question)
41+
} catch (error) {
42+
res.status(500).send(error.message)
43+
}
44+
}
45+
3446
const updateQuestionsVotes = async (req, res) => {
3547
try {
3648
const questionId = req.params.id;
@@ -77,4 +89,16 @@ const updateQuestionsVotes = async (req, res) => {
7789
};
7890

7991

80-
module.exports={createQuestion,getQuestions,updateQuestionsVotes}
92+
const updateQuestionById=async(req,res)=>{
93+
try {
94+
const id=req.params.id
95+
const body = req.body
96+
97+
const question= await InterviewQuestion.findByIdAndUpdate(id,body,{new:true})
98+
res.status(202).json(question);
99+
} catch (error) {
100+
res.status(500).send(error.message);
101+
}
102+
}
103+
104+
module.exports={createQuestion,getQuestions,updateQuestionsVotes, updateQuestionById,getQuestionsById}

‎controllers/posts.js

+5-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,11 @@ const fs = require("fs");
33

44
const getPosts = async (req, res) => {
55
try {
6-
const posts = await Post.find().sort({ createdAt: -1 }).populate("author");
6+
const posts = await Post.find().sort({ createdAt: -1 }).populate("author").populate({
7+
path: "likes",
8+
model: "User",
9+
select: "username"
10+
});
711
res.status(200).json(posts);
812
} catch (error) {
913
res.status(500).send(error.message);

‎models/interviewQuestion.js

+18-12
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@ const questionSchema = new mongoose.Schema(
1717
type: Number,
1818
default: 0
1919
},
20-
upVotes:{
21-
type:[mongoose.Schema.Types.ObjectId],
22-
default:[]
20+
upVotes: {
21+
type: [mongoose.Schema.Types.ObjectId],
22+
default: []
2323
},
2424
downVotes: {
2525
type: [mongoose.Schema.Types.ObjectId],
@@ -29,21 +29,27 @@ const questionSchema = new mongoose.Schema(
2929
type: Date,
3030
default: Date.now,
3131
},
32-
isTechnical:{
32+
isTechnical: {
3333
type: Boolean
3434
},
3535
positionLevel: {
36-
type: String,
37-
enum: ["junior","senior"],
38-
36+
type: String,
37+
enum: ["junior", "senior"],
38+
3939
},
4040
technology: {
4141
type: String,
42-
enum: ["node", "express", "react", "javascript", "html", "css", "sql", "mysql", "mongodb","bootstrap","other",""],
43-
44-
45-
},
46-
updatedAt: { type: Date, default: Date.now }
42+
enum: ["node", "express", "react", "javascript", "html", "css", "sql", "mysql", "mongodb", "bootstrap", "other", ""],
43+
44+
45+
},
46+
updatedAt: { type: Date, default: Date.now },
47+
saves: [
48+
{
49+
type: [mongoose.Schema.Types.ObjectId],
50+
ref: "User"
51+
}
52+
]
4753
}
4854
)
4955

‎routes/interviewQuestion.js

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
11
const express = require('express');
2-
const {createQuestion,getQuestions,updateQuestionsVotes}=require("../controllers/interviewQuestion")
2+
const {createQuestion,getQuestions,getQuestionsById,updateQuestionsVotes,updateQuestionById}=require("../controllers/interviewQuestion")
33
const { verifyToken } = require("../middlewares/verifyToken");
44
const { authorize } = require("../middlewares/authorize");
55

66
const questionRouter=express.Router()
77

88

99
questionRouter.get("/",verifyToken, authorize("user"),getQuestions)
10+
questionRouter.get("/:id",verifyToken,authorize("user"),getQuestionsById)
1011
questionRouter.post("/newQuestion",verifyToken, authorize("user"),createQuestion)
1112
questionRouter.patch("/:id/vote",verifyToken, authorize("user"), updateQuestionsVotes);
13+
questionRouter.put("/:id", verifyToken,authorize("user"),updateQuestionById)
14+
1215

1316
module.exports=questionRouter
324 KB
Loading
324 KB
Loading
324 KB
Loading
62.8 KB
Loading
62.8 KB
Loading

0 commit comments

Comments
 (0)
Please sign in to comment.