source: reactapp/src/Components/OpinionTree.js@ 2fcbde4

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

implemented replying to posts in react

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