source: reactapp/src/Components/OpinionTree.js@ 8d83180

main
Last change on this file since 8d83180 was cae16b5, checked in by unknown <mlviktor23@…>, 2 years ago

implemented registration in react

  • Property mode set to 100644
File size: 8.7 KB
RevLine 
[f5d4792]1import {
2 OpinionCard,
3 OpinionCardContent,
4 OpinionCardContentTime,
5 OpinionCardContentTitle,
6 OpinionReplyCard,
7 OpinionReplyCardContent,
8 OpinionReplyCardContentTime,
9 StyledFontAwesomeIcon,
[62b653f]10 VoteCount,
[3e98cea]11} from "./Styled/OpinionCard.style";
12import { solid } from "@fortawesome/fontawesome-svg-core/import.macro";
[5347491]13import { dateConverter } from "../Util/dateConverter";
[6221ab6]14import AuthApi from "../api/AuthApi";
15import { useNavigate } from "react-router-dom";
16import { useContext, useState } from "react";
17import {
18 Modal,
19 ModalContent,
20 ModalClose,
21 ModalHeader,
22 ModalBody,
23 ModalTextarea,
24 ModalFooter,
25} from "../Components/Styled/Modal.style";
26import axios from "../api/axios";
[e958037]27
[6221ab6]28function OpinionTree({ professor, user, userLoaded }) {
[2998dc4]29 var renderedOpinionIds = [];
30 var postCount; // za da ne go pokazuva ispod postot
31
[6221ab6]32 let navigate = useNavigate();
33 const { auth, setAuth } = useContext(AuthApi);
34
35 let [replyModalDisplay, setReplyModalDisplay] = useState("none");
36 const [replyContent, setReplyContent] = useState("");
37
[2fcbde4]38 const [postForModal, setPostForModal] = useState(null);
39
[62b653f]40 const handleLike = async (post) => {
41 if (
42 auth &&
43 userLoaded &&
44 !post.likes.some((e) => e.id === user.user.id) &&
45 !post.dislikes.some((e) => e.id === user.user.id)
46 ) {
47 const response = await axios(
48 `http://192.168.0.17:8080/secure/professor/${professor.professorId}/upvoteOpinion/${post.postId}`,
49 {
50 method: "get",
51 withCredentials: true,
52 }
53 );
54
55 window.location.reload(false);
[6221ab6]56 } else {
[62b653f]57 return;
[6221ab6]58 }
59 };
60
[62b653f]61 const handleDislike = async (post) => {
62 if (
63 auth &&
64 auth &&
65 userLoaded &&
66 !post.likes.some((e) => e.id === user.user.id) &&
67 !post.dislikes.some((e) => e.id === user.user.id)
68 ) {
69 const response = await axios(
70 `http://192.168.0.17:8080/secure/professor/${professor.professorId}/downvoteOpinion/${post.postId}`,
71 {
72 method: "get",
73 withCredentials: true,
74 }
75 );
76
77 window.location.reload(false);
[6221ab6]78 } else {
[62b653f]79 return;
[6221ab6]80 }
81 };
82
[2fcbde4]83 const handleReply = (opinion) => {
[6221ab6]84 if (auth) {
85 setReplyModalDisplay("block");
[2fcbde4]86 setPostForModal(opinion);
[6221ab6]87 } else {
88 navigate("/login");
89 }
90 };
91
92 const handleModalCloseClick = () => {
93 setReplyModalDisplay("none");
94 };
95
96 const handleContentChange = (e) => {
97 setReplyContent(e.target.value);
98 };
99
100 const handleReplySubmit = async (e, postId) => {
101 e.preventDefault();
102
103 const response = await axios(
[62b653f]104 `http://192.168.0.17:8080/secure/professor/${professor.professorId}/replyToOpinion/${postId}`,
[6221ab6]105 {
106 method: "post",
[cae16b5]107 body: {
[6221ab6]108 content: replyContent,
109 },
110 withCredentials: true,
111 }
112 );
113
114 window.location.reload(false);
115 //console.log(response);
116 };
117
[5347491]118 function displayChildPosts(child, parentPostAuthorUsername, replyIndent) {
[2998dc4]119 if (child == null) return;
120 postCount = renderedOpinionIds.push(child.postId);
[3a44163]121 return (
[2998dc4]122 <div key={child.postId}>
[5347491]123 <OpinionReplyCard indent={replyIndent + "px"}>
[f5d4792]124 <OpinionReplyCardContent>
125 <p>
126 <a href="#">{child.author.username}</a> му реплицирал на{" "}
127 {parentPostAuthorUsername}
128 </p>
129 <p>{child.content}</p>
130 <OpinionReplyCardContentTime>
131 {dateConverter(
132 new Date(child.timePosted).toString().slice(4, -43)
133 )}
134 </OpinionReplyCardContentTime>
[6221ab6]135 {auth && userLoaded && user.user.id !== child.author.id && (
136 <>
137 <StyledFontAwesomeIcon
138 icon={solid("thumbs-up")}
139 right={50 + "px"}
[62b653f]140 color={
141 child.likes.some((e) => e.id === user.user.id)
142 ? "greenyellow"
143 : "darkgrey"
144 }
145 onClick={() => handleLike(child)}
[6221ab6]146 />
[62b653f]147 <VoteCount right={50 + "px"}>{child.likes.length}</VoteCount>
[6221ab6]148 <StyledFontAwesomeIcon
149 icon={solid("thumbs-down")}
150 right={10 + "px"}
[62b653f]151 color={
152 child.dislikes.some((e) => e.id === user.user.id)
153 ? "indianred"
154 : "darkgrey"
155 }
156 onClick={() => handleDislike(child)}
[6221ab6]157 />
[62b653f]158 <VoteCount right={10 + "px"}>{child.dislikes.length}</VoteCount>
[6221ab6]159 <StyledFontAwesomeIcon
160 icon={solid("reply")}
161 right={90 + "px"}
[62b653f]162 color="darkgrey"
[2fcbde4]163 onClick={() => handleReply(child)}
[6221ab6]164 />
165 </>
166 )}
[f5d4792]167 </OpinionReplyCardContent>
168 {child.children.map((childOfChild) =>
169 displayChildPosts(
170 childOfChild,
171 child.author.username,
172 replyIndent + 30
173 )
174 )}
[5347491]175 </OpinionReplyCard>
[3a44163]176 </div>
177 );
178 }
179
180 return (
181 <div className="opinionTree">
182 {professor.relatedOpinions.map((opinion) => {
[2998dc4]183 if (!renderedOpinionIds.includes(opinion.postId)) {
184 postCount = renderedOpinionIds.push(opinion.postId);
[3a44163]185 return (
186 <div key={opinion.postId}>
[e958037]187 <OpinionCard>
[f5d4792]188 <OpinionCardContent>
189 <p>
190 <a href="#">{opinion.author.username}</a> напишал
191 </p>
192 <OpinionCardContentTitle>
193 {opinion.title}
194 </OpinionCardContentTitle>
195 <p>{opinion.content}</p>
196 <OpinionCardContentTime>
197 {dateConverter(
198 new Date(opinion.timePosted).toString().slice(4, -43)
199 )}
200 </OpinionCardContentTime>
[6221ab6]201 {auth && userLoaded && user.user.id !== opinion.author.id && (
202 <>
203 <StyledFontAwesomeIcon
204 icon={solid("thumbs-up")}
205 right={50 + "px"}
[62b653f]206 color={
207 opinion.likes.some((e) => e.id === user.user.id)
208 ? "greenyellow"
209 : "darkgrey"
210 }
211 onClick={() => handleLike(opinion)}
[6221ab6]212 />
[62b653f]213 <VoteCount right={50 + "px"}>
214 {opinion.likes.length}
215 </VoteCount>
[6221ab6]216 <StyledFontAwesomeIcon
217 icon={solid("thumbs-down")}
218 right={10 + "px"}
[62b653f]219 color={
220 opinion.dislikes.some((e) => e.id === user.user.id)
221 ? "indianred"
222 : "darkgrey"
223 }
224 onClick={() => handleDislike(opinion)}
[6221ab6]225 />
[62b653f]226 <VoteCount right={10 + "px"}>
227 {opinion.dislikes.length}
228 </VoteCount>
[6221ab6]229 <StyledFontAwesomeIcon
230 icon={solid("reply")}
231 right={90 + "px"}
[62b653f]232 color="darkgrey"
[2fcbde4]233 onClick={() => handleReply(opinion)}
[6221ab6]234 />
235 </>
236 )}
[f5d4792]237 </OpinionCardContent>
238 {opinion.children.map((child) =>
239 displayChildPosts(child, opinion.author.username, 30)
240 )}
[e958037]241 </OpinionCard>
[3a44163]242 </div>
243 );
244 }
245 })}
[2fcbde4]246 {postForModal && (
247 <Modal display={replyModalDisplay}>
248 <ModalContent>
249 <ModalHeader>
250 <ModalClose onClick={handleModalCloseClick}>&times;</ModalClose>
251 <h3 style={{ marginTop: "5px" }}>
252 Реплика на {postForModal.author.username}
253 </h3>
254 </ModalHeader>
255 <form onSubmit={(e) => handleReplySubmit(e, postForModal.postId)}>
256 <ModalBody>
257 <label htmlFor="content">
258 <b>Содржина</b>:
259 <ModalTextarea
260 id="content"
261 rows="8"
262 cols="100"
263 value={replyContent}
264 onChange={handleContentChange}
265 />
266 </label>
267 </ModalBody>
268 <ModalFooter type="submit">РЕПЛИЦИРАЈ</ModalFooter>
269 </form>
270 </ModalContent>
271 </Modal>
272 )}
[3a44163]273 </div>
274 );
275}
276
277export default OpinionTree;
Note: See TracBrowser for help on using the repository browser.