[c68150f] | 1 | import React, { useEffect, useState, useContext } from "react";
|
---|
[702ca77] | 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";
|
---|
[c68150f] | 12 | import axios from "../api/axios";
|
---|
| 13 | import JSOG from "jsog";
|
---|
| 14 | import AuthApi from "../api/AuthApi";
|
---|
[3b6962d] | 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";
|
---|
[c68150f] | 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);
|
---|
[702ca77] | 32 |
|
---|
[3b6962d] | 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 |
|
---|
[702ca77] | 68 | useEffect(() => {
|
---|
[3b6962d] | 69 | const url1 = `http://192.168.0.19:8080/secure/currentUser`;
|
---|
| 70 | const url2 = `http://192.168.0.19:8080/secure/getAllPostReports`;
|
---|
[c68150f] | 71 |
|
---|
| 72 | const fetchUser = async () => {
|
---|
| 73 | try {
|
---|
[3b6962d] | 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});
|
---|
[c68150f] | 91 | var cyclicGraph = await response.data;
|
---|
| 92 | var jsogStructure = JSOG.encode(cyclicGraph);
|
---|
| 93 | cyclicGraph = JSOG.decode(jsogStructure);
|
---|
[3b6962d] | 94 | setPostReports(cyclicGraph);
|
---|
| 95 | setLoadedPostReports(true);
|
---|
[c68150f] | 96 | } catch (error) {
|
---|
| 97 | setFetchError(true);
|
---|
| 98 | }
|
---|
| 99 | };
|
---|
| 100 |
|
---|
| 101 | if (auth) fetchUser();
|
---|
[3b6962d] | 102 |
|
---|
| 103 | }, [user]);
|
---|
[702ca77] | 104 |
|
---|
[c68150f] | 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 |
|
---|
[3b6962d] | 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 |
|
---|
[c68150f] | 157 | return loadedUser ? (
|
---|
[702ca77] | 158 | <>
|
---|
| 159 | <h3>Кориснички податоци:</h3>
|
---|
| 160 | <UserDetailsCard>
|
---|
[cae16b5] | 161 | {user.fullName && (
|
---|
| 162 | <UserDetailsCardContent>
|
---|
| 163 | <b>Име:</b> {user.fullName}{" "}
|
---|
| 164 | </UserDetailsCardContent>
|
---|
| 165 | )}
|
---|
[702ca77] | 166 | <UserDetailsCardContent>
|
---|
| 167 | <b>Корисничко име:</b> {user.username}{" "}
|
---|
| 168 | </UserDetailsCardContent>
|
---|
| 169 | <UserDetailsCardContent>
|
---|
| 170 | <b>E-mail:</b> {user.email}
|
---|
| 171 | </UserDetailsCardContent>
|
---|
| 172 | <UserDetailsCardContent>
|
---|
[3b6962d] | 173 | <b>Карма:</b>{" "}
|
---|
| 174 | <span style={{ color: user.karma < 0 ? "indianred" : "green" }}>
|
---|
| 175 | {user.karma}
|
---|
| 176 | </span>
|
---|
[702ca77] | 177 | </UserDetailsCardContent>
|
---|
| 178 | </UserDetailsCard>
|
---|
[3b6962d] | 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>
|
---|
[702ca77] | 195 | {user.authoredPosts.length > 0 ? (
|
---|
[3b6962d] | 196 | <h3 style={{ marginBottom: "10px", marginTop:"30px" }}>Ваши мислења:</h3>
|
---|
[702ca77] | 197 | ) : (
|
---|
[3b6962d] | 198 | <h3 style={{ marginBottom: "10px" }}>Немате објавени мислења</h3>
|
---|
[702ca77] | 199 | )}
|
---|
| 200 | {user.authoredPosts.map((post) => {
|
---|
| 201 | return (
|
---|
| 202 | <div key={post.postId}>
|
---|
| 203 | <OpinionCard>
|
---|
| 204 | <OpinionCardContent>
|
---|
[c68150f] | 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 | )}
|
---|
[702ca77] | 222 | </p>
|
---|
[c68150f] | 223 | <p style={{ marginBottom: "10px" }}>{post.content}</p>
|
---|
[702ca77] | 224 | <OpinionCardContentTime>
|
---|
| 225 | {dateConverter(
|
---|
| 226 | new Date(post.timePosted).toString().slice(4, -43)
|
---|
| 227 | )}
|
---|
| 228 | </OpinionCardContentTime>
|
---|
| 229 | </OpinionCardContent>
|
---|
| 230 | </OpinionCard>
|
---|
| 231 | </div>
|
---|
| 232 | );
|
---|
| 233 | })}
|
---|
[3b6962d] | 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 | )}
|
---|
[702ca77] | 412 | </>
|
---|
| 413 | ) : (
|
---|
| 414 | <>се вчитува...</>
|
---|
| 415 | );
|
---|
| 416 | }
|
---|
| 417 |
|
---|
| 418 | export default UserDashboard;
|
---|