source: reactapp/src/Pages/UserDashboard.js

main
Last change on this file was 8dffe02, checked in by unknown <mlviktor23@…>, 18 months ago

prefinal reproducible

  • Property mode set to 100644
File size: 32.7 KB
Line 
1/* eslint-disable no-unused-vars */
2// noinspection JSUnresolvedVariable,ES6ConvertVarToLetConst,JSUnresolvedFunction,SpellCheckingInspection,JSUnusedLocalSymbols
3
4import React, { useEffect, useState, useContext } from "react";
5import {
6 OpinionCard,
7 OpinionCardContent,
8 OpinionCardContentTime,
9} from "../Components/Styled/OpinionCard.style";
10import {
11 UserDetailsCard,
12 UserDetailsCardContent,
13} from "../Components/Styled/UserDetails.style";
14import { dateConverter } from "../Util/dateConverter";
15import axios from "../api/axios";
16import JSOG from "jsog";
17import AuthApi from "../api/AuthApi";
18import {EntityLi, EntityTypeSelector, EntityUl} from "../Components/Styled/EntityList.style";
19import {
20 AddOpinionButton,
21 Modal,
22 ModalBody,
23 ModalClose,
24 ModalContent, ModalFooter,
25 ModalHeader, ModalTextarea,
26 ModalInput
27} from "../Components/Styled/Modal.style";
28import LoadingSpinner from "../Components/Styled/LoadingSpinner.style";
29import {findParentThread} from "../Util/findParentThread";
30
31function UserDashboard() {
32 const { auth, setAuth } = useContext(AuthApi);
33
34 const [user, setUser] = useState(null);
35 const [loadedUser, setLoadedUser] = useState(false);
36 const [authoredPosts, setAuthoredPosts] = useState(null);
37 const [loadedAuthoredPosts, setLoadedAuthoredPosts] = useState(false);
38
39 const [fetchError, setFetchError] = useState(false);
40
41 const [postReports, setPostReports] = useState(null);
42 const [loadedPostReports, setLoadedPostReports] = useState(false);
43
44 const [reportModalDisplay, setReportModalDisplay] = useState("none");
45 const [reportForModal, setReportForModal] = useState(null);
46
47 const [actionType, setActionType] = useState(0);
48
49 const [newPostContent, setNewPostContent] = useState("");
50 const [newOpinionTargetProfessorId, setNewOpinionTargetProfessorId] = useState("");
51 const [newParentPostId, setNewParentPostId] = useState("-1");
52
53 const [newThreadTitle, setNewThreadTitle] = useState("");
54 const [newParentThreadId,setNewParentThreadId] = useState("-1");
55 const [newTargetSubjectId, setNewTargetSubjectId] = useState("");
56
57
58 const [markResolved, setMarkResolved] = useState(false);
59
60 const [errMsg, setErrMsg] = useState("");
61
62 const handleModalCloseClick = () => {
63 setReportForModal(null);
64 setReportModalDisplay("none");
65 document.body.style.overflowY = "auto";
66 };
67
68 const handleViewReportButtonClick = (e,report) => {
69 e.preventDefault();
70 setReportForModal(report);
71 }
72
73 useEffect(() => {
74 if(reportForModal!==null) {
75 if (reportForModal.post !== null) {
76 setNewPostContent(reportForModal.post.content);
77 if(reportForModal.post.title !== null) setNewThreadTitle(reportForModal.post.title);
78 if(reportForModal.post.targetProfessor !== undefined) setNewOpinionTargetProfessorId(reportForModal.post.targetProfessor.professorId); //prvicnoto
79 if(reportForModal.post.targetProfessor === undefined) setNewTargetSubjectId(reportForModal.post.targetSubject.subjectId); //prvicnoto
80 }
81 setReportModalDisplay("block");
82 document.body.style.overflowY = "hidden";
83 }
84 }, [reportForModal]);
85
86 const [newOpinionTargetProfessor, setNewOpinionTargetProfessor] = useState(null);
87 const [loadedNewProfessor,setLoadedNewProfessor] = useState(false);
88 const [newProfessorRelatedOpinions, setNewProfessorRelatedOpinions] = useState(null);
89 const [loadedNewProfessorRelatedOpinions, setLoadedNewProfessorRelatedOpinions] = useState(false);
90 const [loadingProf, setLoadingProf] = useState(false);
91
92 const handleNewTargetProfessorChange = async (e) => {
93 setLoadingProf(true);
94 e.preventDefault();
95 if (newOpinionTargetProfessorId!=="") {
96 try {
97 Promise.all([fetch(`http://192.168.1.108:8080/public/professor/${newOpinionTargetProfessorId}`),
98 fetch(`http://192.168.1.108:8080/public/professor/${newOpinionTargetProfessorId}/relatedOpinions`)])
99 .then(([resNewOpinionTargetProfessor, resNewProfessorRelatedOpinions]) => Promise.all([resNewOpinionTargetProfessor.json(), resNewProfessorRelatedOpinions.json()]))
100 .then(([dataNewOpinionTargetProfessor, dataNewProfessorRelatedOpinions]) => {
101 let cyclicGraph1 = dataNewOpinionTargetProfessor;
102 var jsogStructure1 = JSOG.encode(cyclicGraph1);
103 cyclicGraph1 = JSOG.decode(jsogStructure1);
104 setNewOpinionTargetProfessor(cyclicGraph1);
105 setLoadedNewProfessor(true);
106
107 let cyclicGraph2 = dataNewProfessorRelatedOpinions;
108 var jsogStructure2 = JSOG.encode(cyclicGraph2);
109 cyclicGraph2 = JSOG.decode(jsogStructure2);
110 setNewProfessorRelatedOpinions(cyclicGraph2);
111 setLoadedNewProfessorRelatedOpinions(true);
112
113 setLoadingProf(false);
114 })
115 } catch (error) {
116 setFetchError(true);
117 }
118 }
119 }
120
121 const [newTargetSubject, setNewTargetSubject] = useState(null);
122 const [loadedNewSubject, setLoadedNewSubject] = useState(false);
123 const [newTargetSubjectThreads, setNewTargetSubjectThreads] = useState(null);
124 const [loadedNewSubjectThreads, setLoadedNewSubjectThreads] = useState(false);
125 const [loadingSubj, setLoadingSubj] = useState(false);
126
127 const handleNewTargetSubjectChange = async (e) => {
128 e.preventDefault();
129 setLoadingSubj(true);
130 if (newTargetSubjectId!=="") {
131 try {
132 Promise.all([fetch(`http://192.168.1.108:8080/public/subject/${newTargetSubjectId}`),
133 fetch(`http://192.168.1.108:8080/public/subject/${newTargetSubjectId}/threads`)])
134 .then(([resNewTargetSubject, resNewTargetSubjectThreads]) => Promise.all([resNewTargetSubject.json(), resNewTargetSubjectThreads.json()]))
135 .then(([dataNewTargetSubject, dataNewTargetSubjectThreads]) => {
136 let cyclicGraph1 = dataNewTargetSubject;
137 var jsogStructure1 = JSOG.encode(cyclicGraph1);
138 cyclicGraph1 = JSOG.decode(jsogStructure1);
139 setNewTargetSubject(cyclicGraph1);
140 setLoadedNewSubject(true);
141
142 let cyclicGraph2 = dataNewTargetSubjectThreads;
143 var jsogStructure2 = JSOG.encode(cyclicGraph2);
144 cyclicGraph2 = JSOG.decode(jsogStructure2);
145 setNewTargetSubjectThreads(cyclicGraph2);
146 setLoadedNewSubjectThreads(true);
147
148 setLoadingSubj(false);
149 })
150 } catch (error) {
151 setFetchError(true);
152 }
153 }
154 }
155
156 useEffect(() => {
157 const fetchUser = () => {
158 try {
159 if(!loadedUser) {
160 Promise.all([axios.get(`http://192.168.1.108:8080/secure/currentUser`, {withCredentials:true}),
161 axios.get(`http://192.168.1.108:8080/secure/currentUser/posts`, {withCredentials:true})])
162 .then(([resUser, resAuthoredPosts]) => Promise.all([resUser.data, resAuthoredPosts.data]))
163 .then(([dataUser, dataAuthoredPosts]) => {
164 let cyclicGraph1 = dataUser;
165 let jsogStructure1 = JSOG.encode(cyclicGraph1);
166 cyclicGraph1 = JSOG.decode(jsogStructure1);
167 setUser(cyclicGraph1);
168 setLoadedUser(true);
169
170 let cyclicGraph2 = dataAuthoredPosts;
171 let jsogStructure2 = JSOG.encode(cyclicGraph2);
172 cyclicGraph2 = JSOG.decode(jsogStructure2);
173 setAuthoredPosts(cyclicGraph2);
174 setLoadedAuthoredPosts(true);
175 })
176 }
177 if(user.userRole==='MODERATOR') fetchPostReports();
178 } catch (error) {
179 setFetchError(true);
180 }
181 };
182
183 const fetchPostReports = async () => {
184 try {
185 const response = await axios.get(`http://192.168.1.108:8080/secure/getAllPostReports`, {withCredentials: true});
186 var cyclicGraph = await response.data;
187 var jsogStructure = JSOG.encode(cyclicGraph);
188 cyclicGraph = JSOG.decode(jsogStructure);
189 setPostReports(cyclicGraph);
190 setLoadedPostReports(true);
191 } catch (error) {
192 setFetchError(true);
193 }
194 };
195
196 if (auth) fetchUser();
197
198 }, [user]);
199
200 const handleEdit = async (e) => {
201 e.preventDefault();
202 try {
203 if(reportForModal.post !== null && reportForModal.post.targetProfessor !== undefined) {
204 await axios(`http://192.168.1.108:8080/secure/updateOpinion/${reportForModal.post.postId}`,
205 {
206 method: "put",
207 data: {
208 newContent: newPostContent,
209 newTargetProfessorId: reportForModal.post.targetProfessor.professorId,
210 newParentPostId: reportForModal.post.parent !== null ? reportForModal.post.parent.postId : "-1"
211 },
212 withCredentials: true,
213 })
214 await axios(`http://192.168.1.108:8080/secure/markReportResolved/${reportForModal.postReportId}/${markResolved ? `resolve` : `open`}`,{
215 method: "get",
216 withCredentials: true
217 })
218 } else if(reportForModal.post !== null && reportForModal.post.targetProfessor === undefined) {
219 await axios(`http://192.168.1.108:8080/secure/updateThread/${reportForModal.post.postId}`,
220 {
221 method: "put",
222 data: {
223 newTitle: newThreadTitle,
224 newContent: newPostContent,
225 newTargetSubjectId: reportForModal.post.targetSubject.subjectId,
226 newParentThreadId: reportForModal.post.parent !== null ? reportForModal.post.parent.postId : "-1"
227 },
228 withCredentials: true,
229 })
230 }
231 await axios(`http://192.168.1.108:8080/secure/markReportResolved/${reportForModal.postReportId}/${markResolved ? `resolve` : `open`}`,{
232 method: "get",
233 withCredentials: true
234 })
235 } catch (error) {
236 setFetchError(true);
237 }
238 window.location.reload();
239 }
240
241 const handleRelocate = async (e) => {
242 e.preventDefault();
243 try {
244 if(reportForModal.post !== null && reportForModal.post.targetProfessor !== undefined) {
245 var response = await axios(`http://192.168.1.108:8080/secure/updateOpinion/${reportForModal.post.postId}`,
246 {
247 method: "put",
248 data: {
249 newContent: reportForModal.post.content,
250 newTargetProfessorId: newOpinionTargetProfessorId,
251 newParentPostId: newParentPostId==="Постави како самостојно мислење" ? "-1" : newParentPostId //:)
252 },
253 withCredentials: true,
254 })
255 await axios(`http://192.168.1.108:8080/secure/markReportResolved/${reportForModal.postReportId}/${markResolved ? `resolve` : `open`}`,{
256 method: "get",
257 withCredentials: true
258 })
259 } else if(reportForModal.post !== null && reportForModal.post.targetProfessor === undefined) {
260 var response = await axios(`http://192.168.1.108:8080/secure/updateThread/${reportForModal.post.postId}`,
261 {
262 method: "put",
263 data: {
264 newTitle: newThreadTitle,
265 newContent: reportForModal.post.content,
266 newTargetSubjectId: newTargetSubjectId,
267 newParentThreadId: newParentThreadId==="Постави како самостојно мислење (нова тема)" ? "-1" : newParentThreadId //:)
268 },
269 withCredentials: true,
270 })
271 }
272 await axios(`http://192.168.1.108:8080/secure/markReportResolved/${reportForModal.postReportId}/${markResolved ? `resolve` : `open`}`,{
273 method: "get",
274 withCredentials: true
275 })
276 } catch (error) {
277 setFetchError(true);
278 }
279 setErrMsg(response.data);
280 if (response.data==="") window.location.reload();
281 }
282
283 const handleDelete = async (e) => {
284 e.preventDefault();
285 try {
286 if(reportForModal.post !== null && reportForModal.post.targetProfessor !== undefined) {
287 await axios(`http://192.168.1.108:8080/secure/deleteOpinion/${reportForModal.post.postId}`,
288 {
289 method: "delete",
290 withCredentials: true,
291 })
292 window.location.reload();
293 } else if(reportForModal.post !== null && reportForModal.post.targetProfessor === undefined) {
294 await axios(`http://192.168.1.108:8080/secure/deleteThread/${reportForModal.post.postId}`,
295 {
296 method: "delete",
297 withCredentials: true,
298 })
299 }
300 } catch (error) {
301 setFetchError(true);
302 }
303 window.location.reload();
304 }
305
306 const handleMarkResolved = () => {
307 if (actionType !== 1) setMarkResolved(!markResolved);
308 }
309
310 return loadedUser ? (
311 <>
312 <h3>Кориснички податоци:</h3>
313 <UserDetailsCard>
314 {user.fullName && (
315 <UserDetailsCardContent>
316 <b>Име:</b> {user.fullName}{" "}
317 </UserDetailsCardContent>
318 )}
319 <UserDetailsCardContent>
320 <b>Корисничко име:</b> {user.username}{" "}
321 </UserDetailsCardContent>
322 <UserDetailsCardContent>
323 <b>E-mail:</b> {user.email}
324 </UserDetailsCardContent>
325 <UserDetailsCardContent>
326 <b>Карма:</b>{" "}
327 <span style={{ color: user.karma < 0 ? "indianred" : "green" }}>
328 {user.karma}
329 </span>
330 </UserDetailsCardContent>
331 </UserDetailsCard>
332 {loadedPostReports ? postReports.length > 0 ? (
333 <h3 style={{ marginBottom: "10px" }}>Пријави за мислења:</h3>
334 ) : (
335 <h3>Нема пријавени мислења</h3>
336 ) : loadedUser && user.userRole==='MODERATOR' ? <LoadingSpinner/> : ""}
337 <EntityUl style={{marginTop:"25px"}}>
338 {loadedPostReports && postReports.map((postReport) => {
339 return <EntityLi bgcolor="cornsilk" key={postReport.postReportId} style={{padding:"15px"}}>
340 <p style={{color: postReport.resolved ? "grey" : "black"}}><span style={{fontSize:"14px", fontStyle:"italic", fontWeight:"normal"}}>{dateConverter(
341 new Date(postReport.time).toString().slice(4, -43)
342 )}</span><br/>{postReport.description.substring(0,45 )}{postReport.description.length >= 45 ? ("...") : ("")} {postReport.resolved ? <span style={{fontStyle:"italic"}}>(разрешено)</span> : ""}
343 </p>
344 <AddOpinionButton onClick={(e)=>handleViewReportButtonClick(e,postReport)} style={{height:"30px", padding:"5px", fontSize:"14px", position:"absolute", top:"30%", right:"20px" }}>Разгледај</AddOpinionButton>
345 </EntityLi>;
346 })}
347 </EntityUl>
348 {authoredPosts.length > 0 ? (
349 <h3 style={{ marginBottom: "10px", marginTop:"30px" }}>Ваши мислења:</h3>
350 ) : (
351 <h3 style={{ marginBottom: "10px" }}>Немате објавени мислења</h3>
352 )}
353 {authoredPosts.map((post) => {
354 return (
355 <div key={post.postId}>
356 <OpinionCard>
357 <OpinionCardContent>
358 <p style={{ fontStyle: "italic", marginBottom: "10px" }}>
359 во дискусија за{" "}
360 {post.targetProfessor !== undefined ? (
361 <a href={"/professor/" + post.targetProfessor.professorId}>
362 {post.targetProfessor.professorName}
363 </a>
364 ) : (
365 <a
366 href={
367 post.parent === null
368 ? "/topic/" + post.postId
369 : "/topic/" + findParentThread(post).postId
370 }
371 >
372 {post.targetSubject.subjectName}
373 </a>
374 )}
375 </p>
376 <p style={{ marginBottom: "10px" }}>{post.content}</p>
377 <OpinionCardContentTime>
378 {dateConverter(
379 new Date(post.timePosted).toString().slice(4, -43)
380 )} <span style={{fontStyle:"normal",color:"blue"}}>#{post.postId}</span>
381 </OpinionCardContentTime>
382 </OpinionCardContent>
383 </OpinionCard>
384 </div>
385 );
386 })}
387 {reportForModal && (
388 <Modal display={reportModalDisplay}>
389 <ModalContent>
390 <ModalHeader>
391 <ModalClose onClick={handleModalCloseClick}>&times;</ModalClose>
392 <h3 style={{ marginTop: "5px" }}>
393 Преглед на пријава за мислење
394 </h3>
395 </ModalHeader>
396 <ModalBody>
397 <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>
398 <p style={{fontWeight:"bold",marginBottom:"15px"}}>Време на пријава: <span style={{fontWeight:"normal"}}>{dateConverter(
399 new Date(reportForModal.time).toString().slice(4, -43)
400 )}</span></p>
401 <p style={{fontWeight:"bold",marginBottom:"15px"}}>Образложение: </p> <p style={{marginBottom:"15px"}}>{reportForModal.description}</p>
402 <p style={{fontWeight:"bold", marginBottom:"15px"}}>Информации за пријавеното мислење:</p>
403 {reportForModal.post !== null ?
404 <OpinionCard>
405 <OpinionCardContent>
406 <p style={{fontStyle: "italic", marginBottom: "10px"}}>
407 во дискусија за{" "}
408 {reportForModal.post.targetProfessor !== undefined ? (
409 <a href={"/professor/" + reportForModal.post.targetProfessor.professorId}>
410 {reportForModal.post.targetProfessor.professorName}
411 </a>
412 ) : (
413 <a
414 href={
415 reportForModal.post.parent === null
416 ? "/topic/" + reportForModal.post.postId
417 : "/topic/" + findParentThread(reportForModal.post).postId
418 }
419 >
420 {reportForModal.post.targetSubject.subjectName}
421 </a>
422 )}
423 </p>
424 {reportForModal.post.title === null ?
425 <p style={{ fontStyle: "italic", marginBottom: "10px" }}>
426 <a href={"/user/" + reportForModal.post.author.id}>
427 {reportForModal.post.author.username}
428 </a>{" "}
429 напишал
430 </p> :
431 <p style={{ fontStyle: "italic", marginBottom: "10px" }}>
432 <a href={"/user/" + reportForModal.post.author.id}>
433 {reportForModal.post.author.username}
434 </a>{" "}
435 отворил тема со наслов <span style={{fontWeight:"bold"}}>{reportForModal.post.title}</span>
436 </p>
437 }
438 <p style={{marginBottom: "10px"}}>{reportForModal.post.content}</p>
439 <OpinionCardContentTime>
440 {dateConverter(
441 new Date(reportForModal.post.timePosted).toString().slice(4, -43)
442 )} <span style={{fontStyle:"normal",color:"blue"}}>#{reportForModal.post.postId}</span>
443 </OpinionCardContentTime>
444 </OpinionCardContent>
445 </OpinionCard>
446 : "Пријавеното мислење или неговиот автор се избришани"}
447
448 {reportForModal.post !== null &&
449 <div style={{ display: "flex" }}>
450 {actionType===0 ? <EntityTypeSelector
451 backgroundcolor="rgba(0, 102, 204, 1)"
452 color="white"
453 boxshadow="none"
454 boxshadowhover="none"
455 opacityhover="0.6"
456 cursor="auto"
457 >
458 Измени содржина или наслов
459 </EntityTypeSelector> : <EntityTypeSelector
460 boxshadow="2px 2px 5px #aaaaaa"
461 cursor="pointer"
462 boxshadowhover="2px 2px 10px #aaaaaa"
463 opacityhover="1"
464 onClick={() => setActionType(0)}
465 >
466 Измени содржина или наслов
467 </EntityTypeSelector>}
468 {actionType===1 ? <EntityTypeSelector
469 backgroundcolor="rgba(0, 102, 204, 1)"
470 color="white"
471 boxshadow="none"
472 boxshadowhover="none"
473 opacityhover="0.6"
474 cursor="auto"
475 >
476 Избриши
477 </EntityTypeSelector> : <EntityTypeSelector
478 boxshadow="2px 2px 5px #aaaaaa"
479 cursor="pointer"
480 boxshadowhover="2px 2px 10px #aaaaaa"
481 opacityhover="1"
482 onClick={() => {setActionType(1); setMarkResolved(true)}}
483 >
484 Избриши
485 </EntityTypeSelector>}
486 {actionType===2 ? <EntityTypeSelector
487 backgroundcolor="rgba(0, 102, 204, 1)"
488 color="white"
489 boxshadow="none"
490 boxshadowhover="none"
491 opacityhover="0.6"
492 cursor="auto"
493 >
494 Премести
495 </EntityTypeSelector> : <EntityTypeSelector
496 boxshadow="2px 2px 5px #aaaaaa"
497 cursor="pointer"
498 boxshadowhover="2px 2px 10px #aaaaaa"
499 opacityhover="1"
500 onClick={() => setActionType(2)}
501 >
502 Премести
503 </EntityTypeSelector>}
504 </div>}
505 {reportForModal.post !== null ?
506 actionType === 0 ?
507 (<form onSubmit={e => handleEdit(e)}>
508 {reportForModal.post.title !== null &&
509 <label>
510 <b>Нов наслов на тема:</b>
511 <ModalInput
512 value={newThreadTitle}
513 onChange={e => setNewThreadTitle(e.target.value)}
514 id="title"
515 spellCheck={false}
516 style={{marginTop:"10px"}}
517 />
518 </label>}
519 <label>
520 <b>Нова содржина:</b>
521 <ModalTextarea
522 value={newPostContent}
523 onChange={e => setNewPostContent(e.target.value)}
524 id="content"
525 rows="8"
526 cols="100"
527 spellCheck={false}
528 style={{marginTop:"10px"}}
529 />
530 </label>
531 <div style={{marginTop:"15px"}}>
532 <label>
533 <input
534 type="checkbox"
535 onChange={handleMarkResolved}
536 />
537 <span style={{marginLeft:"10px", fontWeight:"bold"}}>Означи како разрешено</span>
538 </label>
539 </div>
540 <ModalFooter type="submit">ПОТВРДИ</ModalFooter>
541 </form>)
542 : actionType === 1 ?
543 (<form onSubmit={e => handleDelete(e)}>
544 <p style={{color:"red", display:"flex", justifyContent:"space-around"}}>Избриши го мислењето? (оваа акција е иреверзибилна)</p>
545 <div style={{marginTop:"15px"}}>
546 <label>
547 <input
548 type="checkbox"
549 checked={markResolved}
550 onChange={handleMarkResolved}
551 />
552 <span style={{marginLeft:"10px", fontWeight:"bold"}}>Означи како разрешено</span>
553 </label>
554 </div>
555 <ModalFooter type="submit">ПОТВРДИ</ModalFooter>
556 </form>)
557 :
558 (reportForModal.post.targetProfessor !== undefined ?
559 (<form onSubmit={e => handleRelocate(e)}>
560 <p style={{color:"black"}}>Внеси <span style={{fontWeight:"bold"}}>ID</span> на секцијата за дискусија (за <span style={{fontWeight:"bold"}}>професор</span>)
561 во која треба да биде преместено мислењето:</p>
562 <div style={{marginTop:"15px"}}>
563 <ModalInput
564 value={newOpinionTargetProfessorId}
565 onChange={e => {e.preventDefault();setNewOpinionTargetProfessorId(e.target.value)}}
566 id="newOpinionTargetProfessorId"
567 spellCheck={false}
568 style={{marginTop:"10px", marginBottom:"10px", width:"90px"}}
569 />
570 <button onClick={async (e) => {await handleNewTargetProfessorChange(e);}} style={{marginBottom:"10px", padding:"5px", fontFamily: "Roboto Mono, monospace"}}>Зачувај</button>
571 {newOpinionTargetProfessor!==null && !loadingProf ? <p style={{color:"black", marginBottom:"20px", opacity:"50%"}}>Мислењето ќе се премести во секцијата за професорот со <span style={{fontWeight:"bold"}}>ID=
572 {newOpinionTargetProfessor.professorId}</span> (<span style={{fontWeight:"bold"}}>{newOpinionTargetProfessor.professorName}</span>)</p> : loadingProf ? <LoadingSpinner style={{marginBottom:"15px", marginTop:"15px"}}/> : null}
573 {newOpinionTargetProfessor && <p style={{color:"black", marginBottom:"10px"}}>Постави како дете на мислење со ID:</p>}
574 {newOpinionTargetProfessor &&
575 <select value={newParentPostId} onChange={e => setNewParentPostId(e.target.value)} style={{width:"280px", display:"block", padding:"5px",marginBottom:"5px", fontFamily: "Roboto Mono, monospace"}}>
576 <option value="-1">Постави како самостојно мислење</option>
577 {newProfessorRelatedOpinions.filter((opinion)=>opinion.postId!==reportForModal.post.postId).map((opinion) => {
578 return <option key={opinion.postId} value={opinion.postId}>{opinion.postId}</option>})
579 }
580 </select>}
581 <br/>
582 <label>
583 <input
584 type="checkbox"
585 onChange={handleMarkResolved}
586 />
587 <span style={{marginLeft:"10px", fontWeight:"bold"}}>Означи како разрешено</span>
588 </label>
589 </div>
590 {errMsg!=="" && <p style={{color:"red", display:"flex", justifyContent:"space-around"}}>{errMsg}</p>}
591 <ModalFooter type="submit">ПОТВРДИ</ModalFooter>
592 </form>) :
593 //THREAD CASE
594 (<form onSubmit={e => handleRelocate(e)}>
595 <p style={{color:"black"}}>Внеси <span style={{fontWeight:"bold"}}>ID</span> на секцијата за дискусија (за <span style={{fontWeight:"bold"}}>предмет</span>)
596 во која треба да биде преместено мислењето:</p>
597 <div style={{marginTop:"15px"}}>
598 <label>
599 <ModalInput
600 value={newTargetSubjectId}
601 onChange={e => {e.preventDefault();setNewTargetSubjectId(e.target.value)}}
602 id="newTargetSubjectId"
603 spellCheck={false}
604 style={{marginTop:"10px", marginBottom:"10px", width:"90px"}}
605 />
606 <button onClick={async (e) => {await handleNewTargetSubjectChange(e);}} style={{marginBottom:"10px", padding:"5px", fontFamily: "Roboto Mono, monospace"}}>Зачувај</button>
607 {newTargetSubject!==null && !loadingSubj ? <p style={{color:"black", marginBottom:"20px", opacity:"50%"}}>Мислењето ќе се премести во секцијата за предметот со <span style={{fontWeight:"bold"}}>ID=
608 {newTargetSubject.subjectId}</span> (<span style={{fontWeight:"bold"}}>{newTargetSubject.subjectName}</span>)</p> : loadingSubj ? <LoadingSpinner style={{marginBottom:"15px", marginTop:"15px"}}/> : null}
609 {newTargetSubject && <p style={{color:"black", marginBottom:"10px"}}>Постави како дете на мислење со ID:</p>}
610 {newTargetSubject &&
611 <select value={newParentThreadId} onChange={e => setNewParentThreadId(e.target.value)} style={{width:"370px", display:"block", padding:"5px",marginBottom:"5px", fontFamily: "Roboto Mono, monospace"}}>
612 <option value="-1">Постави како самостојно мислење (нова тема)</option>
613 {newTargetSubjectThreads.filter((thread)=>thread.postId!==reportForModal.post.postId).map((thread) => {
614 return <option key={thread.postId} value={thread.postId}>{thread.postId}</option>})
615 }
616 </select>}
617 {newParentThreadId==="-1" && loadedNewSubject &&
618 <>
619 <p style={{marginTop:"10px"}}>Наслов на нова тема:</p>
620 <ModalInput
621 value={newThreadTitle}
622 onChange={e => setNewThreadTitle(e.target.value)}
623 id="titleChangeRelocate"
624 spellCheck={false}
625 style={{marginTop:"10px"}}
626 />
627 </>}
628 <br/>
629 <input
630 type="checkbox"
631 defaultChecked={reportForModal.resolved}
632 onChange={handleMarkResolved}
633 />
634 <span style={{marginLeft:"10px", fontWeight:"bold"}}>Означи како разрешено</span>
635 </label>
636 </div>
637 {errMsg!=="" && <p style={{color:"red", display:"flex", justifyContent:"space-around"}}>{errMsg}</p>}
638 <ModalFooter type="submit">ПОТВРДИ</ModalFooter>
639 </form>))
640 : null
641 }
642 </ModalBody>
643 </ModalContent>
644 </Modal>
645 )}
646 </>
647 ) : (
648 <LoadingSpinner/>
649 );
650}
651
652export default UserDashboard;
Note: See TracBrowser for help on using the repository browser.