1 | import React, { useEffect, useState, useContext } from "react";
|
---|
2 | import {
|
---|
3 | OpinionCard,
|
---|
4 | OpinionCardContent,
|
---|
5 | OpinionCardContentTime,
|
---|
6 | } from "../Components/Styled/OpinionCard.style";
|
---|
7 | import {
|
---|
8 | UserDetailsCard,
|
---|
9 | UserDetailsCardContent,
|
---|
10 | } from "../Components/Styled/UserDetails.style";
|
---|
11 | import { dateConverter } from "../Util/dateConverter";
|
---|
12 | import axios from "../api/axios";
|
---|
13 | import JSOG from "jsog";
|
---|
14 | import AuthApi from "../api/AuthApi";
|
---|
15 | import {EntityLi, EntityTypeSelector, EntityUl} from "../Components/Styled/EntityList.style";
|
---|
16 | import {
|
---|
17 | AddOpinionButton,
|
---|
18 | Modal,
|
---|
19 | ModalBody,
|
---|
20 | ModalClose,
|
---|
21 | ModalContent, ModalFooter,
|
---|
22 | ModalHeader, ModalTextarea,
|
---|
23 | ModalInput
|
---|
24 | } from "../Components/Styled/Modal.style";
|
---|
25 |
|
---|
26 | function UserDashboard() {
|
---|
27 | const { auth, setAuth } = useContext(AuthApi);
|
---|
28 |
|
---|
29 | const [user, setUser] = useState(null);
|
---|
30 | const [loadedUser, setLoadedUser] = useState(false);
|
---|
31 | const [fetchError, setFetchError] = useState(false);
|
---|
32 |
|
---|
33 | const [postReports, setPostReports] = useState(null);
|
---|
34 | const [loadedPostReports, setLoadedPostReports] = useState(false);
|
---|
35 |
|
---|
36 | const [reportModalDisplay, setReportModalDisplay] = useState("none");
|
---|
37 | const [reportForModal, setReportForModal] = useState(null);
|
---|
38 |
|
---|
39 | const [actionType, setActionType] = useState(0);
|
---|
40 |
|
---|
41 | const [newPostContent, setNewPostContent] = useState("");
|
---|
42 | const [newPostTitle, setNewPostTitle] = useState("");
|
---|
43 |
|
---|
44 | const [markResolved, setMarkResolved] = useState(false);
|
---|
45 |
|
---|
46 | const handleModalCloseClick = () => {
|
---|
47 | setReportForModal(null);
|
---|
48 | setReportModalDisplay("none");
|
---|
49 | document.body.style.overflowY = "auto";
|
---|
50 | };
|
---|
51 |
|
---|
52 | const handleViewReportButtonClick = (e,report) => {
|
---|
53 | e.preventDefault();
|
---|
54 | setReportForModal(report);
|
---|
55 | }
|
---|
56 |
|
---|
57 | useEffect(() => {
|
---|
58 | if(reportForModal!==null) {
|
---|
59 | if (reportForModal.post !== null) {
|
---|
60 | setNewPostContent(reportForModal.post.content);
|
---|
61 | if(reportForModal.post.title !== null) setNewPostTitle(reportForModal.post.title);
|
---|
62 | }
|
---|
63 | setReportModalDisplay("block");
|
---|
64 | document.body.style.overflowY = "hidden";
|
---|
65 | }
|
---|
66 | }, [reportForModal]);
|
---|
67 |
|
---|
68 | useEffect(() => {
|
---|
69 | const url1 = `http://192.168.0.19:8080/secure/currentUser`;
|
---|
70 | const url2 = `http://192.168.0.19:8080/secure/getAllPostReports`;
|
---|
71 |
|
---|
72 | const fetchUser = async () => {
|
---|
73 | try {
|
---|
74 | if(!loadedUser) {
|
---|
75 | const response = await axios.get(url1, {withCredentials: true});
|
---|
76 | let cyclicGraph = await response.data;
|
---|
77 | var jsogStructure = JSOG.encode(cyclicGraph);
|
---|
78 | cyclicGraph = JSOG.decode(jsogStructure);
|
---|
79 | setUser(cyclicGraph);
|
---|
80 | setLoadedUser(true);
|
---|
81 | }
|
---|
82 | if(user.userRole==='MODERATOR')fetchPostReports();
|
---|
83 | } catch (error) {
|
---|
84 | setFetchError(true);
|
---|
85 | }
|
---|
86 | };
|
---|
87 |
|
---|
88 | const fetchPostReports = async () => {
|
---|
89 | try {
|
---|
90 | const response = await axios.get(url2, {withCredentials: true});
|
---|
91 | var cyclicGraph = await response.data;
|
---|
92 | var jsogStructure = JSOG.encode(cyclicGraph);
|
---|
93 | cyclicGraph = JSOG.decode(jsogStructure);
|
---|
94 | setPostReports(cyclicGraph);
|
---|
95 | setLoadedPostReports(true);
|
---|
96 | } catch (error) {
|
---|
97 | setFetchError(true);
|
---|
98 | }
|
---|
99 | };
|
---|
100 |
|
---|
101 | if (auth) fetchUser();
|
---|
102 |
|
---|
103 | }, [user]);
|
---|
104 |
|
---|
105 | // useEffect(() => {
|
---|
106 | // const timer = setTimeout(() => {
|
---|
107 | // if (user === null) window.location.reload(false); <---- :-)
|
---|
108 | // }, 3000);
|
---|
109 | // return () => clearTimeout(timer);
|
---|
110 | // }, []);
|
---|
111 |
|
---|
112 | function findParentThread(post) {
|
---|
113 | if (post.parent === null) return post;
|
---|
114 | return findParentThread(post.parent);
|
---|
115 | }
|
---|
116 |
|
---|
117 | const handleEdit = async (e) => {
|
---|
118 | e.preventDefault();
|
---|
119 | try {
|
---|
120 | if(reportForModal.post !== null && reportForModal.post.targetProfessor !== undefined) {
|
---|
121 | await axios(`http://192.168.0.19:8080/secure/updateOpinion/${reportForModal.post.postId}`,
|
---|
122 | {
|
---|
123 | method: "put",
|
---|
124 | data: {
|
---|
125 | newContent: newPostContent,
|
---|
126 | newTargetProfessorId: reportForModal.post.targetProfessor.professorId,
|
---|
127 | },
|
---|
128 | withCredentials: true,
|
---|
129 | })
|
---|
130 | window.location.reload(false);
|
---|
131 | } else if(reportForModal.post !== null && reportForModal.post.targetProfessor === undefined) {
|
---|
132 | await axios(`http://192.168.0.19:8080/secure/updateThread/${reportForModal.post.postId}`,
|
---|
133 | {
|
---|
134 | method: "put",
|
---|
135 | data: {
|
---|
136 | newTitle: newPostTitle,
|
---|
137 | newContent: newPostContent,
|
---|
138 | newTargetSubjectId: reportForModal.post.targetSubject.subjectId
|
---|
139 | },
|
---|
140 | withCredentials: true,
|
---|
141 | })
|
---|
142 | window.location.reload(false);
|
---|
143 | }
|
---|
144 | } catch (error) {
|
---|
145 | setFetchError(true);
|
---|
146 | }
|
---|
147 | }
|
---|
148 |
|
---|
149 | const handleDelete = (e) => {
|
---|
150 | e.preventDefault();
|
---|
151 | }
|
---|
152 |
|
---|
153 | const handleMarkResolved = () => {
|
---|
154 | if (actionType !== 1) setMarkResolved(!markResolved);
|
---|
155 | }
|
---|
156 |
|
---|
157 | return loadedUser ? (
|
---|
158 | <>
|
---|
159 | <h3>Кориснички податоци:</h3>
|
---|
160 | <UserDetailsCard>
|
---|
161 | {user.fullName && (
|
---|
162 | <UserDetailsCardContent>
|
---|
163 | <b>Име:</b> {user.fullName}{" "}
|
---|
164 | </UserDetailsCardContent>
|
---|
165 | )}
|
---|
166 | <UserDetailsCardContent>
|
---|
167 | <b>Корисничко име:</b> {user.username}{" "}
|
---|
168 | </UserDetailsCardContent>
|
---|
169 | <UserDetailsCardContent>
|
---|
170 | <b>E-mail:</b> {user.email}
|
---|
171 | </UserDetailsCardContent>
|
---|
172 | <UserDetailsCardContent>
|
---|
173 | <b>Карма:</b>{" "}
|
---|
174 | <span style={{ color: user.karma < 0 ? "indianred" : "green" }}>
|
---|
175 | {user.karma}
|
---|
176 | </span>
|
---|
177 | </UserDetailsCardContent>
|
---|
178 | </UserDetailsCard>
|
---|
179 | {loadedPostReports ? postReports.length > 0 ? (
|
---|
180 | <h3 style={{ marginBottom: "10px" }}>Пријави за мислења:</h3>
|
---|
181 | ) : (
|
---|
182 | <h3>Нема пријавени мислења</h3>
|
---|
183 | ) : loadedUser && user.userRole==='MODERATOR' ? "се вчитува..." : ""}
|
---|
184 | <EntityUl style={{marginTop:"25px"}}>
|
---|
185 | {loadedPostReports && postReports.map((postReport) => {
|
---|
186 | return <EntityLi bgcolor="cornsilk" key={postReport.postReportId} style={{padding:"15px"}}>
|
---|
187 | <p style={{color: postReport.resolved ? "grey" : "black"}}><span style={{fontSize:"14px", fontStyle:"italic", fontWeight:"normal"}}>{dateConverter(
|
---|
188 | new Date(postReport.time).toString().slice(4, -43)
|
---|
189 | )}</span><br/>{postReport.description.substring(0,45 )}{postReport.description.length >= 45 ? ("...") : ("")} {postReport.resolved ? <span style={{fontStyle:"italic"}}>(разрешено)</span> : ""}
|
---|
190 | </p>
|
---|
191 | <AddOpinionButton onClick={(e)=>handleViewReportButtonClick(e,postReport)} style={{height:"30px", padding:"5px", fontSize:"14px", position:"absolute", top:"30%", right:"20px" }}>Разгледај</AddOpinionButton>
|
---|
192 | </EntityLi>;
|
---|
193 | })}
|
---|
194 | </EntityUl>
|
---|
195 | {user.authoredPosts.length > 0 ? (
|
---|
196 | <h3 style={{ marginBottom: "10px", marginTop:"30px" }}>Ваши мислења:</h3>
|
---|
197 | ) : (
|
---|
198 | <h3 style={{ marginBottom: "10px" }}>Немате објавени мислења</h3>
|
---|
199 | )}
|
---|
200 | {user.authoredPosts.map((post) => {
|
---|
201 | return (
|
---|
202 | <div key={post.postId}>
|
---|
203 | <OpinionCard>
|
---|
204 | <OpinionCardContent>
|
---|
205 | <p style={{ fontStyle: "italic", marginBottom: "10px" }}>
|
---|
206 | во дискусија за{" "}
|
---|
207 | {post.targetProfessor !== undefined ? (
|
---|
208 | <a href={"/professor/" + post.targetProfessor.professorId}>
|
---|
209 | {post.targetProfessor.professorName}
|
---|
210 | </a>
|
---|
211 | ) : (
|
---|
212 | <a
|
---|
213 | href={
|
---|
214 | post.parent === null
|
---|
215 | ? "/topic/" + post.postId
|
---|
216 | : "/topic/" + findParentThread(post).postId
|
---|
217 | }
|
---|
218 | >
|
---|
219 | {post.targetSubject.subjectName}
|
---|
220 | </a>
|
---|
221 | )}
|
---|
222 | </p>
|
---|
223 | <p style={{ marginBottom: "10px" }}>{post.content}</p>
|
---|
224 | <OpinionCardContentTime>
|
---|
225 | {dateConverter(
|
---|
226 | new Date(post.timePosted).toString().slice(4, -43)
|
---|
227 | )}
|
---|
228 | </OpinionCardContentTime>
|
---|
229 | </OpinionCardContent>
|
---|
230 | </OpinionCard>
|
---|
231 | </div>
|
---|
232 | );
|
---|
233 | })}
|
---|
234 | {reportForModal && (
|
---|
235 | <Modal display={reportModalDisplay}>
|
---|
236 | <ModalContent>
|
---|
237 | <ModalHeader>
|
---|
238 | <ModalClose onClick={handleModalCloseClick}>×</ModalClose>
|
---|
239 | <h3 style={{ marginTop: "5px" }}>
|
---|
240 | Преглед на пријава за мислење
|
---|
241 | </h3>
|
---|
242 | </ModalHeader>
|
---|
243 | <ModalBody>
|
---|
244 | <p style={{fontWeight:"bold",marginBottom:"15px"}}>Пријавил: <span style={{fontWeight:"normal"}}>{reportForModal.user !== null ? <a href={"/user/"+reportForModal.user.id}>{reportForModal.user.username}</a> : "(избришан корисник)"}</span></p>
|
---|
245 | <p style={{fontWeight:"bold",marginBottom:"15px"}}>Време на пријава: <span style={{fontWeight:"normal"}}>{dateConverter(
|
---|
246 | new Date(reportForModal.time).toString().slice(4, -43)
|
---|
247 | )}</span></p>
|
---|
248 | <p style={{fontWeight:"bold",marginBottom:"15px"}}>Образложение: </p> <p style={{marginBottom:"15px"}}>{reportForModal.description}</p>
|
---|
249 | <p style={{fontWeight:"bold", marginBottom:"15px"}}>Информации за пријавеното мислење:</p>
|
---|
250 | {reportForModal.post !== null ?
|
---|
251 | <OpinionCard>
|
---|
252 | <OpinionCardContent>
|
---|
253 | <p style={{fontStyle: "italic", marginBottom: "10px"}}>
|
---|
254 | во дискусија за{" "}
|
---|
255 | {reportForModal.post.targetProfessor !== undefined ? (
|
---|
256 | <a href={"/professor/" + reportForModal.post.targetProfessor.professorId}>
|
---|
257 | {reportForModal.post.targetProfessor.professorName}
|
---|
258 | </a>
|
---|
259 | ) : (
|
---|
260 | <a
|
---|
261 | href={
|
---|
262 | reportForModal.post.parent === null
|
---|
263 | ? "/topic/" + reportForModal.post.postId
|
---|
264 | : "/topic/" + findParentThread(reportForModal.post).postId
|
---|
265 | }
|
---|
266 | >
|
---|
267 | {reportForModal.post.targetSubject.subjectName}
|
---|
268 | </a>
|
---|
269 | )}
|
---|
270 | </p>
|
---|
271 | {reportForModal.post.title === null ?
|
---|
272 | <p style={{ fontStyle: "italic", marginBottom: "10px" }}>
|
---|
273 | <a href={"/user/" + reportForModal.post.author.id}>
|
---|
274 | {reportForModal.post.author.username}
|
---|
275 | </a>{" "}
|
---|
276 | напишал
|
---|
277 | </p> :
|
---|
278 | <p style={{ fontStyle: "italic", marginBottom: "10px" }}>
|
---|
279 | <a href={"/user/" + reportForModal.post.author.id}>
|
---|
280 | {reportForModal.post.author.username}
|
---|
281 | </a>{" "}
|
---|
282 | отворил тема со наслов <span style={{fontWeight:"bold"}}>{reportForModal.post.title}</span>
|
---|
283 | </p>
|
---|
284 | }
|
---|
285 | <p style={{marginBottom: "10px"}}>{reportForModal.post.content}</p>
|
---|
286 | <OpinionCardContentTime>
|
---|
287 | {dateConverter(
|
---|
288 | new Date(reportForModal.post.timePosted).toString().slice(4, -43)
|
---|
289 | )}
|
---|
290 | </OpinionCardContentTime>
|
---|
291 | </OpinionCardContent>
|
---|
292 | </OpinionCard>
|
---|
293 | : "Пријавеното мислење или неговиот автор се избришани"}
|
---|
294 |
|
---|
295 | {reportForModal.post !== null &&
|
---|
296 | <div style={{ display: "flex" }}>
|
---|
297 | {actionType===0 ? <EntityTypeSelector
|
---|
298 | backgroundcolor="rgba(0, 102, 204, 1)"
|
---|
299 | color="white"
|
---|
300 | boxshadow="none"
|
---|
301 | boxshadowhover="none"
|
---|
302 | opacityhover="0.6"
|
---|
303 | cursor="auto"
|
---|
304 | >
|
---|
305 | Измени содржина или наслов
|
---|
306 | </EntityTypeSelector> : <EntityTypeSelector
|
---|
307 | boxshadow="2px 2px 5px #aaaaaa"
|
---|
308 | cursor="pointer"
|
---|
309 | boxshadowhover="2px 2px 10px #aaaaaa"
|
---|
310 | opacityhover="1"
|
---|
311 | onClick={() => setActionType(0)}
|
---|
312 | >
|
---|
313 | Измени содржина или наслов
|
---|
314 | </EntityTypeSelector>}
|
---|
315 | {actionType===1 ? <EntityTypeSelector
|
---|
316 | backgroundcolor="rgba(0, 102, 204, 1)"
|
---|
317 | color="white"
|
---|
318 | boxshadow="none"
|
---|
319 | boxshadowhover="none"
|
---|
320 | opacityhover="0.6"
|
---|
321 | cursor="auto"
|
---|
322 | >
|
---|
323 | Избриши
|
---|
324 | </EntityTypeSelector> : <EntityTypeSelector
|
---|
325 | boxshadow="2px 2px 5px #aaaaaa"
|
---|
326 | cursor="pointer"
|
---|
327 | boxshadowhover="2px 2px 10px #aaaaaa"
|
---|
328 | opacityhover="1"
|
---|
329 | onClick={() => {setActionType(1); setMarkResolved(true)}}
|
---|
330 | >
|
---|
331 | Избриши
|
---|
332 | </EntityTypeSelector>}
|
---|
333 | {actionType===2 ? <EntityTypeSelector
|
---|
334 | backgroundcolor="rgba(0, 102, 204, 1)"
|
---|
335 | color="white"
|
---|
336 | boxshadow="none"
|
---|
337 | boxshadowhover="none"
|
---|
338 | opacityhover="0.6"
|
---|
339 | cursor="auto"
|
---|
340 | >
|
---|
341 | Премести
|
---|
342 | </EntityTypeSelector> : <EntityTypeSelector
|
---|
343 | boxshadow="2px 2px 5px #aaaaaa"
|
---|
344 | cursor="pointer"
|
---|
345 | boxshadowhover="2px 2px 10px #aaaaaa"
|
---|
346 | opacityhover="1"
|
---|
347 | onClick={() => setActionType(2)}
|
---|
348 | >
|
---|
349 | Премести
|
---|
350 | </EntityTypeSelector>}
|
---|
351 | </div>}
|
---|
352 | {reportForModal.post !== null ?
|
---|
353 | actionType === 0 ?
|
---|
354 | (<form onSubmit={e => handleEdit(e)}>
|
---|
355 | {reportForModal.post.title !== null && <label>
|
---|
356 | <b>Нов наслов на тема:</b>
|
---|
357 | <ModalInput
|
---|
358 | value={newPostTitle}
|
---|
359 | onChange={e => setNewPostTitle(e.target.value)}
|
---|
360 | id="title"
|
---|
361 | spellCheck={false}
|
---|
362 | style={{marginTop:"10px"}}
|
---|
363 | />
|
---|
364 | </label>}
|
---|
365 | <label>
|
---|
366 | <b>Нова содржина:</b>
|
---|
367 | <ModalTextarea
|
---|
368 | value={newPostContent}
|
---|
369 | onChange={e => setNewPostContent(e.target.value)}
|
---|
370 | id="content"
|
---|
371 | rows="8"
|
---|
372 | cols="100"
|
---|
373 | spellCheck={false}
|
---|
374 | style={{marginTop:"10px"}}
|
---|
375 | />
|
---|
376 | </label>
|
---|
377 | <div style={{marginTop:"15px"}}>
|
---|
378 | <label>
|
---|
379 | <input
|
---|
380 | type="checkbox"
|
---|
381 | checked={markResolved}
|
---|
382 | onChange={handleMarkResolved}
|
---|
383 | />
|
---|
384 | <span style={{marginLeft:"10px", fontWeight:"bold"}}>Означи како разрешено</span>
|
---|
385 | </label>
|
---|
386 | </div>
|
---|
387 | <ModalFooter type="submit">ПОТВРДИ</ModalFooter>
|
---|
388 | </form>)
|
---|
389 | : actionType === 1 ?
|
---|
390 | (<form onSubmit={e => handleDelete(e)}>
|
---|
391 | <p style={{color:"red", display:"flex", justifyContent:"space-around"}}>Избриши го мислењето? (оваа акција е иреверзибилна)</p>
|
---|
392 | <div style={{marginTop:"15px"}}>
|
---|
393 | <label>
|
---|
394 | <input
|
---|
395 | type="checkbox"
|
---|
396 | checked={markResolved}
|
---|
397 | onChange={handleMarkResolved}
|
---|
398 | />
|
---|
399 | <span style={{marginLeft:"10px", fontWeight:"bold"}}>Означи како разрешено</span>
|
---|
400 | </label>
|
---|
401 | </div>
|
---|
402 | <ModalFooter type="submit">ПОТВРДИ</ModalFooter>
|
---|
403 | </form>)
|
---|
404 | :
|
---|
405 | ("123")
|
---|
406 | : null
|
---|
407 | }
|
---|
408 | </ModalBody>
|
---|
409 | </ModalContent>
|
---|
410 | </Modal>
|
---|
411 | )}
|
---|
412 | </>
|
---|
413 | ) : (
|
---|
414 | <>се вчитува...</>
|
---|
415 | );
|
---|
416 | }
|
---|
417 |
|
---|
418 | export default UserDashboard;
|
---|