Changes in / [4abf55a:e49d1b6]
- Files:
-
- 1 added
- 14 deleted
- 19 edited
Legend:
- Unmodified
- Added
- Removed
-
reactapp/src/App.js
r4abf55a re49d1b6 14 14 import NotFound from "./Pages/NotFound"; 15 15 import Topic from "./Pages/Topic"; 16 import LoadingSpinner from "./Components/Styled/LoadingSpinner.style";17 16 18 17 export default function App() { … … 43 42 return children; 44 43 } else { 45 return < LoadingSpinner/>;44 return <div>се вчитува cookie...</div>; 46 45 } 47 46 }; -
reactapp/src/Components/OpinionTree.js
r4abf55a re49d1b6 42 42 43 43 useEffect(() => { 44 const url = `http://192.168.0. 29:8080/secure/currentUser`;44 const url = `http://192.168.0.19:8080/secure/currentUser`; 45 45 46 46 const fetchUser = async () => { … … 68 68 ) { 69 69 const response = await axios( 70 `http://192.168.0. 29:8080/secure/upvoteOpinion/${post.postId}`,70 `http://192.168.0.19:8080/secure/upvoteOpinion/${post.postId}`, 71 71 { 72 72 method: "get", … … 74 74 } 75 75 ); 76 window.location.reload( );76 window.location.reload(false); 77 77 } else { 78 78 return; … … 91 91 ) { 92 92 const response = await axios( 93 `http://192.168.0. 29:8080/secure/downvoteOpinion/${post.postId}`,93 `http://192.168.0.19:8080/secure/downvoteOpinion/${post.postId}`, 94 94 { 95 95 method: "get", … … 98 98 ); 99 99 100 window.location.reload( );100 window.location.reload(false); 101 101 } else { 102 102 return; … … 131 131 if (!replyContent.length < 1) { 132 132 const response = await axios( 133 `http://192.168.0. 29:8080/secure/professor/${professor.professorId}/replyToOpinion/${postId}`,133 `http://192.168.0.19:8080/secure/professor/${professor.professorId}/replyToOpinion/${postId}`, 134 134 { 135 135 method: "post", … … 141 141 ); 142 142 setErrorMessage(""); 143 window.location.reload( );143 window.location.reload(false); 144 144 } else { 145 145 setErrorMessage("Полето за содржина не смее да биде празно"); … … 161 161 {child.content} 162 162 </p> 163 { new Date(child.timePosted).setMilliseconds(0) === new Date(child.timeLastEdited).setMilliseconds(0)? (163 {child.timePosted === child.timeLastEdited ? ( 164 164 <OpinionCardContentTime> 165 165 {dateConverter( 166 166 new Date(child.timePosted).toString().slice(4, -43) 167 )} <span style={{fontStyle:"normal",color:"blue"}}>#{child.postId}</span>167 )} 168 168 </OpinionCardContentTime> 169 169 ) : ( … … 171 171 {dateConverter( 172 172 new Date(child.timeLastEdited).toString().slice(4, -43) 173 )}{" "} <span style={{fontStyle:"normal",color:"blue"}}>#{child.postId}</span>{" "}173 )}{" "} 174 174 (едитирано од модератор) 175 175 </OpinionCardContentTime> … … 260 260 {opinion.content} 261 261 </p> 262 { new Date(opinion.timePosted).setMilliseconds(0) === new Date(opinion.timeLastEdited).setMilliseconds(0)? (262 {opinion.timePosted === opinion.timeLastEdited ? ( 263 263 <OpinionCardContentTime> 264 264 {dateConverter( 265 265 new Date(opinion.timePosted).toString().slice(4, -43) 266 )} <span style={{fontStyle:"normal",color:"blue"}}>#{opinion.postId}</span>266 )} 267 267 </OpinionCardContentTime> 268 268 ) : ( … … 272 272 .toString() 273 273 .slice(4, -43) 274 )}{" "} <span style={{fontStyle:"normal",color:"blue"}}>#{opinion.postId}</span>{" "}274 )}{" "} 275 275 (едитирано од модератор) 276 276 </OpinionCardContentTime> -
reactapp/src/Components/Search.js
r4abf55a re49d1b6 15 15 16 16 useEffect(() => { 17 const url = `http://192.168.0. 29:8080/public/professors/nameContains/${transliterate(17 const url = `http://192.168.0.19:8080/public/professors/nameContains/${transliterate( 18 18 query 19 19 )}`; -
reactapp/src/Components/Styled/ProfessorCard.style.js
r4abf55a re49d1b6 2 2 3 3 export const ProfessorCard = styled.div` 4 background-color: cornsilk; 4 5 width: auto; 5 6 padding: 10px; -
reactapp/src/Components/UserHeader.js
r4abf55a re49d1b6 3 3 import axios from "../api/axios"; 4 4 import Logout from "./Logout"; 5 import LoadingSpinner from "./Styled/LoadingSpinner.style";6 5 7 6 function UserHeader({}) { … … 11 10 12 11 useEffect(() => { 13 const url = `http://192.168.0. 29:8080/secure/currentUser`;12 const url = `http://192.168.0.19:8080/secure/currentUser`; 14 13 15 14 const fetchUser = async () => { … … 35 34 ) : ( 36 35 <div style={{ float: "left", marginTop: 25, marginLeft: 60 }}> 37 <LoadingSpinner/>36 се вчитува... 38 37 </div> 39 38 ); -
reactapp/src/Pages/Faculty.js
r4abf55a re49d1b6 16 16 import SubjectsAccordion from "../Components/SubjectsAccordion"; 17 17 import { CurrentPageNav } from "../Components/Styled/Main.style"; 18 import LoadingSpinner from "../Components/Styled/LoadingSpinner.style";19 18 20 19 const Faculty = () => { … … 28 27 29 28 useEffect(() => { 30 const urlProfessors = `http://192.168.0. 29:8080/public/professors?facultyId=${params.facultyId}`;31 const urlStudyProgrammes = `http://192.168.0. 29:8080/public/study_programmes?facultyId=${params.facultyId}`;29 const urlProfessors = `http://192.168.0.19:8080/public/professors?facultyId=${params.facultyId}`; 30 const urlStudyProgrammes = `http://192.168.0.19:8080/public/study_programmes?facultyId=${params.facultyId}`; 32 31 33 32 const fetchDataProfessors = async () => { … … 225 224 ) : !fetchError && !loadedProfessors ? ( 226 225 <div> 227 < LoadingSpinner style={{ marginTop: "140px" }}/>226 <p style={{ marginTop: "140px" }}>се вчитува...</p> 228 227 <Outlet /> 229 228 </div> -
reactapp/src/Pages/Login.js
r4abf55a re49d1b6 17 17 18 18 useEffect(() => { 19 if (!auth)userRef.current.focus();19 userRef.current.focus(); 20 20 }, []); 21 21 -
reactapp/src/Pages/Professor.js
r4abf55a re49d1b6 24 24 import axios from "../api/axios"; 25 25 import { CurrentPageNav } from "../Components/Styled/Main.style"; 26 import LoadingSpinner from "../Components/Styled/LoadingSpinner.style";27 26 28 27 function Professor() { … … 40 39 41 40 useEffect(() => { 42 const url = `http://192.168.0. 29:8080/public/professor/${params.professorId}`;41 const url = `http://192.168.0.19:8080/public/professor/${params.professorId}`; 43 42 44 43 const fetchProfessor = async () => { … … 77 76 if (!postContent.length < 1) { 78 77 const response = await axios( 79 `http://192.168.0. 29:8080/secure/professor/${params.professorId}/addOpinion`,78 `http://192.168.0.19:8080/secure/professor/${params.professorId}/addOpinion`, 80 79 { 81 80 method: "post", … … 87 86 ); 88 87 setErrorMessage(""); 89 window.location.reload( );88 window.location.reload(false); 90 89 } else { 91 90 setErrorMessage("Полето за содржина не смее да биде празно"); … … 112 111 </CurrentPageNav> 113 112 <ProfessorCard> 114 <ProfessorCardName>{professor.professorName} <span style={{opacity:"50%", fontSize:"16px"}}>#{professor.professorId}</span></ProfessorCardName>113 <ProfessorCardName>{professor.professorName}</ProfessorCardName> 115 114 <ProfessorCardSeparator /> 116 115 <div style={{ marginTop: "10px" }}> … … 180 179 return ( 181 180 <div> 182 < LoadingSpinner style={{ marginTop: "140px" }}/>181 <p style={{ marginTop: "140px" }}>се вчитува...</p> 183 182 <Outlet /> 184 183 </div> -
reactapp/src/Pages/Subject.js
r4abf55a re49d1b6 28 28 } from "../Components/Styled/Modal.style"; 29 29 import axios from "../api/axios"; 30 import LoadingSpinner from "../Components/Styled/LoadingSpinner.style";31 30 32 31 const Subject = () => { … … 47 46 48 47 useEffect(() => { 49 const url = `http://192.168.0. 29:8080/public/subject/${params.subjectId}`;48 const url = `http://192.168.0.19:8080/public/subject/${params.subjectId}`; 50 49 51 50 const fetchData = async () => { … … 84 83 if (!topicTitle.length < 1 && !topicContent.length < 1) { 85 84 const response = await axios( 86 `http://192.168.0. 29:8080/secure/subject/${params.subjectId}/addThread`,85 `http://192.168.0.19:8080/secure/subject/${params.subjectId}/addThread`, 87 86 { 88 87 method: "post", … … 95 94 ); 96 95 setErrorMessage(""); 97 window.location.reload( );96 window.location.reload(false); 98 97 } else { 99 98 setErrorMessage("Полињата за наслов и содржина не смеат да бидат празни"); … … 128 127 </CurrentPageNav> 129 128 <ProfessorCard> 130 <ProfessorCardName>{subject.subjectName} <span style={{opacity:"50%", fontSize:"16px"}}>#{subject.subjectId}</span></ProfessorCardName>129 <ProfessorCardName>{subject.subjectName}</ProfessorCardName> 131 130 <ProfessorCardSeparator /> 132 131 <div style={{ marginTop: "10px" }}> … … 205 204 <div key={subject.subjectId}> 206 205 {topics.map((topic) => { 207 var numReplies = 0; 208 topic.children.map((c)=>numReplies += ++c.children.length); // ++c.children.length -> c + decata na c 206 var numReplies = topic.children.length; 209 207 return ( 210 208 <EntityUl key={topic.postId}> … … 270 268 ) : !fetchError ? ( 271 269 <div> 272 < LoadingSpinner style={{ marginTop: "140px" }}/>270 <p style={{ marginTop: "140px" }}>се вчитува...</p> 273 271 <Outlet /> 274 272 </div> -
reactapp/src/Pages/Topic.js
r4abf55a re49d1b6 28 28 } from "../Components/Styled/Modal.style"; 29 29 import axios from "../api/axios"; 30 import LoadingSpinner from "../Components/Styled/LoadingSpinner.style";31 30 32 31 const Topic = () => { … … 49 48 50 49 useEffect(() => { 51 const url1 = `http://192.168.0. 29:8080/public/thread/${params.topicId}`;52 const url2 = `http://192.168.0. 29:8080/secure/currentUser`;50 const url1 = `http://192.168.0.19:8080/public/thread/${params.topicId}`; 51 const url2 = `http://192.168.0.19:8080/secure/currentUser`; 53 52 54 53 const fetchTopic = async () => { … … 100 99 if (!replyContent.length < 1) { 101 100 const response = await axios( 102 `http://192.168.0. 29:8080/secure/subject/${thread.targetSubject.subjectId}/replyToThread/${postId}`,101 `http://192.168.0.19:8080/secure/subject/${thread.targetSubject.subjectId}/replyToThread/${postId}`, 103 102 { 104 103 method: "post", … … 110 109 ); 111 110 setErrorMessage(""); 112 window.location.reload( );111 window.location.reload(false); 113 112 } else { 114 113 setErrorMessage("Полето за содржина не смее да биде празно"); … … 129 128 if (!postContent.length < 1) { 130 129 const response = await axios( 131 `http://192.168.0. 29:8080/secure/subject/${thread.targetSubject.subjectId}/replyToThread/${params.topicId}`,130 `http://192.168.0.19:8080/secure/subject/${thread.targetSubject.subjectId}/replyToThread/${params.topicId}`, 132 131 { 133 132 method: "post", … … 139 138 ); 140 139 setErrorMessage(""); 141 window.location.reload( );140 window.location.reload(false); 142 141 } else { 143 142 setErrorMessage("Полето за содржина не смее да биде празно"); … … 161 160 ) { 162 161 const response = await axios( 163 `http://192.168.0. 29:8080/secure/upvoteThread/${post.postId}`,162 `http://192.168.0.19:8080/secure/upvoteThread/${post.postId}`, 164 163 { 165 164 method: "get", … … 167 166 } 168 167 ); 169 window.location.reload( );168 window.location.reload(false); 170 169 } else { 171 170 return; … … 184 183 ) { 185 184 const response = await axios( 186 `http://192.168.0. 29:8080/secure/downvoteThread/${post.postId}`,185 `http://192.168.0.19:8080/secure/downvoteThread/${post.postId}`, 187 186 { 188 187 method: "get", … … 191 190 ); 192 191 193 window.location.reload( );192 window.location.reload(false); 194 193 } else { 195 194 return; … … 214 213 {child.content} 215 214 </p> 216 { new Date(child.timePosted).setMilliseconds(0) === new Date(child.timeLastEdited).setMilliseconds(0)? (215 {thread.timePosted === thread.timeLastEdited ? ( 217 216 <OpinionCardContentTime> 218 217 {dateConverter( 219 new Date( child.timePosted).toString().slice(4, -43)220 )} <span style={{fontStyle:"normal",color:"blue"}}>#{child.postId}</span>218 new Date(thread.timePosted).toString().slice(4, -43) 219 )} 221 220 </OpinionCardContentTime> 222 221 ) : ( 223 222 <OpinionCardContentTime> 224 223 {dateConverter( 225 new Date( child.timeLastEdited).toString().slice(4, -43)226 )}{" "} <span style={{fontStyle:"normal",color:"blue"}}>#{child.postId}</span>{" "}224 new Date(thread.timeLastEdited).toString().slice(4, -43) 225 )}{" "} 227 226 (едитирано од модератор) 228 227 </OpinionCardContentTime> … … 271 270 /> 272 271 273 <VoteCount right={ 10 + "px"}>272 <VoteCount right={50 + "px"}> 274 273 {child.votes.filter((v) => v.vote === "DOWNVOTE").length} 275 274 </VoteCount> … … 325 324 </CurrentPageNav> 326 325 <div style={{ height: "20px", marginBottom: "50px", marginTop: "50px" }}> 327 <h3 style={{ float: "left" }}>{thread.title} <span style={{opacity:"50%", fontSize:"16px"}}>#{thread.postId}</span></h3>326 <h3 style={{ float: "left" }}>{thread.title}</h3> 328 327 {auth && ( 329 328 <AddOpinionButton onClick={handleAddOpinionButtonClick}> … … 370 369 {thread.content} 371 370 </p> 372 { new Date(thread.timePosted).setMilliseconds(0) === new Date(thread.timeLastEdited).setMilliseconds(0)? (371 {thread.timePosted === thread.timeLastEdited ? ( 373 372 <OpinionCardContentTime> 374 373 {dateConverter( 375 374 new Date(thread.timePosted).toString().slice(4, -43) 376 )} <span style={{fontStyle:"normal",color:"blue"}}>#{thread.postId}</span>375 )} 377 376 </OpinionCardContentTime> 378 377 ) : ( … … 380 379 {dateConverter( 381 380 new Date(thread.timeLastEdited).toString().slice(4, -43) 382 )}{" "} <span style={{fontStyle:"normal",color:"blue"}}>#{thread.postId}</span>{" "}381 )}{" "} 383 382 (едитирано од модератор) 384 383 </OpinionCardContentTime> … … 445 444 {directChild.content} 446 445 </p> 447 { new Date(directChild.timePosted).setMilliseconds(0) === new Date(directChild.timeLastEdited).setMilliseconds(0)? (446 {directChild.timePosted === directChild.timeLastEdited ? ( 448 447 <OpinionCardContentTime> 449 448 {dateConverter( 450 449 new Date(directChild.timePosted).toString().slice(4, -43) 451 )} <span style={{fontStyle:"normal",color:"blue"}}>#{directChild.postId}</span>450 )} 452 451 </OpinionCardContentTime> 453 452 ) : ( … … 457 456 .toString() 458 457 .slice(4, -43) 459 )}{" "} <span style={{fontStyle:"normal",color:"blue"}}>#{directChild.postId}</span>{" "}458 )}{" "} 460 459 (едитирано од модератор) 461 460 </OpinionCardContentTime> … … 560 559 ) : !fetchError && !loadedThread ? ( 561 560 <div> 562 < LoadingSpinner style={{ marginTop: "140px" }}/>561 <p style={{ marginTop: "140px" }}>се вчитува...</p> 563 562 <Outlet /> 564 563 </div> -
reactapp/src/Pages/University.js
r4abf55a re49d1b6 14 14 } from "../Components/Styled/EntityList.style"; 15 15 import { CurrentPageNav } from "../Components/Styled/Main.style"; 16 import LoadingSpinner from "../Components/Styled/LoadingSpinner.style";17 16 18 17 const University = () => { … … 23 22 24 23 useEffect(() => { 25 const url = `http://192.168.0. 29:8080/public/faculties?universityId=${params.universityId}`;24 const url = `http://192.168.0.19:8080/public/faculties?universityId=${params.universityId}`; 26 25 27 26 const fetchData = async () => { … … 106 105 ) : !fetchError && !loaded ? ( 107 106 <div> 108 < LoadingSpinner style={{ marginTop: "140px" }}/>107 <p style={{ marginTop: "140px" }}>се вчитува...</p> 109 108 <Outlet /> 110 109 </div> -
reactapp/src/Pages/UserDashboard.js
r4abf55a re49d1b6 1 /* eslint-disable no-unused-vars */2 // noinspection JSUnresolvedVariable,ES6ConvertVarToLetConst,JSUnresolvedFunction,SpellCheckingInspection,JSUnusedLocalSymbols3 4 1 import React, { useEffect, useState, useContext } from "react"; 5 2 import { … … 26 23 ModalInput 27 24 } from "../Components/Styled/Modal.style"; 28 import LoadingSpinner from "../Components/Styled/LoadingSpinner.style";29 25 30 26 function UserDashboard() { … … 44 40 45 41 const [newPostContent, setNewPostContent] = useState(""); 46 const [newOpinionTargetProfessorId, setNewOpinionTargetProfessorId] = useState(""); 47 const [newOpinionTargetProfessor, setNewOpinionTargetProfessor] = useState(null); 48 const [loadedNewProfessor,setLoadedNewProfessor] = useState(false); 49 const [newParentPostId, setNewParentPostId] = useState("-1"); 50 51 const [newThreadTitle, setNewThreadTitle] = useState(""); 52 const [newParentThreadId,setNewParentThreadId] = useState("-1"); 53 const [newTargetSubjectId, setNewTargetSubjectId] = useState(""); 54 const [newTargetSubject, setNewTargetSubject] = useState(null); 55 const [loadedNewSubject, setLoadedNewSubject] = useState(null); 42 const [newPostTitle, setNewPostTitle] = useState(""); 56 43 57 44 const [markResolved, setMarkResolved] = useState(false); 58 59 const [errMsg, setErrMsg] = useState("");60 45 61 46 const handleModalCloseClick = () => { … … 74 59 if (reportForModal.post !== null) { 75 60 setNewPostContent(reportForModal.post.content); 76 if(reportForModal.post.title !== null) setNewThreadTitle(reportForModal.post.title); 77 if(reportForModal.post.targetProfessor !== undefined) setNewOpinionTargetProfessorId(reportForModal.post.targetProfessor.professorId); //prvicnoto 78 if(reportForModal.post.targetProfessor === undefined) setNewTargetSubjectId(reportForModal.post.targetSubject.subjectId); //prvicnoto 61 if(reportForModal.post.title !== null) setNewPostTitle(reportForModal.post.title); 79 62 } 80 63 setReportModalDisplay("block"); … … 83 66 }, [reportForModal]); 84 67 85 const[loadingProf, setLoadingProf] = useState(false);86 87 const handleNewTargetProfessorChange = async (e) => {88 setLoadingProf(true);89 e.preventDefault();90 if (newOpinionTargetProfessorId!=="") {91 try {92 const response = await axios.get(`http://192.168.0.29:8080/public/professor/${newOpinionTargetProfessorId}`, {withCredentials: true});93 let cyclicGraph = await response.data;94 var jsogStructure = JSOG.encode(cyclicGraph);95 cyclicGraph = JSOG.decode(jsogStructure);96 setNewOpinionTargetProfessor(cyclicGraph);97 setLoadedNewProfessor(true);98 setLoadingProf(false);99 } catch (error) {100 setFetchError(true);101 }102 }103 }104 105 const[loadingSubj, setLoadingSubj] = useState(false);106 107 const handleNewTargetSubjectChange = async (e) => {108 e.preventDefault();109 setLoadingSubj(true);110 if (newTargetSubjectId!=="") {111 try {112 const response = await axios.get(`http://192.168.0.29:8080/public/subject/${newTargetSubjectId}`, {withCredentials: true});113 let cyclicGraph = await response.data;114 var jsogStructure = JSOG.encode(cyclicGraph);115 cyclicGraph = JSOG.decode(jsogStructure);116 setNewTargetSubject(cyclicGraph);117 setLoadedNewSubject(true);118 setLoadingSubj(false);119 } catch (error) {120 setFetchError(true);121 }122 }123 }124 125 68 useEffect(() => { 126 const url1 = `http://192.168.0. 29:8080/secure/currentUser`;127 const url2 = `http://192.168.0. 29:8080/secure/getAllPostReports`;69 const url1 = `http://192.168.0.19:8080/secure/currentUser`; 70 const url2 = `http://192.168.0.19:8080/secure/getAllPostReports`; 128 71 129 72 const fetchUser = async () => { … … 162 105 // useEffect(() => { 163 106 // const timer = setTimeout(() => { 164 // if (user === null) window.location.reload( ); <---- :-)107 // if (user === null) window.location.reload(false); <---- :-) 165 108 // }, 3000); 166 109 // return () => clearTimeout(timer); … … 176 119 try { 177 120 if(reportForModal.post !== null && reportForModal.post.targetProfessor !== undefined) { 178 await axios(`http://192.168.0. 29:8080/secure/updateOpinion/${reportForModal.post.postId}`,121 await axios(`http://192.168.0.19:8080/secure/updateOpinion/${reportForModal.post.postId}`, 179 122 { 180 123 method: "put", … … 182 125 newContent: newPostContent, 183 126 newTargetProfessorId: reportForModal.post.targetProfessor.professorId, 184 newParentPostId: reportForModal.post.parent !== null ? reportForModal.post.parent.postId : "-1"185 127 }, 186 128 withCredentials: true, 187 129 }) 130 window.location.reload(false); 188 131 } else if(reportForModal.post !== null && reportForModal.post.targetProfessor === undefined) { 189 await axios(`http://192.168.0. 29:8080/secure/updateThread/${reportForModal.post.postId}`,132 await axios(`http://192.168.0.19:8080/secure/updateThread/${reportForModal.post.postId}`, 190 133 { 191 134 method: "put", 192 135 data: { 193 newTitle: new ThreadTitle,136 newTitle: newPostTitle, 194 137 newContent: newPostContent, 195 newTargetSubjectId: reportForModal.post.targetSubject.subjectId, 196 newParentThreadId: reportForModal.post.parent !== null ? reportForModal.post.parent.postId : "-1" 138 newTargetSubjectId: reportForModal.post.targetSubject.subjectId 197 139 }, 198 140 withCredentials: true, 199 141 }) 200 } 201 await axios(`http://192.168.0.29:8080/secure/markReportResolved/${reportForModal.postReportId}/${markResolved ? `resolve` : `open`}`,{ 202 method: "get", 203 withCredentials: true 204 }) 205 } catch (error) { 206 setFetchError(true); 207 } 208 window.location.reload(); 209 } 210 211 const handleRelocate = async (e) => { 212 e.preventDefault(); 213 try { 214 if(reportForModal.post !== null && reportForModal.post.targetProfessor !== undefined) { 215 var response = await axios(`http://192.168.0.29:8080/secure/updateOpinion/${reportForModal.post.postId}`, 216 { 217 method: "put", 218 data: { 219 newContent: reportForModal.post.content, 220 newTargetProfessorId: newOpinionTargetProfessorId, 221 newParentPostId: newParentPostId==="Постави како самостојно мислење" ? "-1" : newParentPostId //:) 222 }, 223 withCredentials: true, 224 }) 225 } else if(reportForModal.post !== null && reportForModal.post.targetProfessor === undefined) { 226 var response = await axios(`http://192.168.0.29:8080/secure/updateThread/${reportForModal.post.postId}`, 227 { 228 method: "put", 229 data: { 230 newTitle: newThreadTitle, 231 newContent: reportForModal.post.content, 232 newTargetSubjectId: newTargetSubjectId, 233 newParentThreadId: newParentThreadId==="Постави како самостојно мислење (нова тема)" ? "-1" : newParentThreadId //:) 234 }, 235 withCredentials: true, 236 }) 237 } 238 await axios(`http://192.168.0.29:8080/secure/markReportResolved/${reportForModal.postReportId}/${markResolved ? `resolve` : `open`}`,{ 239 method: "get", 240 withCredentials: true 241 }) 242 } catch (error) { 243 setFetchError(true); 244 } 245 setErrMsg(response.data); 246 if (response.data==="") window.location.reload(); 247 } 248 249 const handleDelete = async (e) => { 250 e.preventDefault(); 251 try { 252 if(reportForModal.post !== null && reportForModal.post.targetProfessor !== undefined) { 253 await axios(`http://192.168.0.29:8080/secure/deleteOpinion/${reportForModal.post.postId}`, 254 { 255 method: "delete", 256 withCredentials: true, 257 }) 258 window.location.reload(); 259 } else if(reportForModal.post !== null && reportForModal.post.targetProfessor === undefined) { 260 await axios(`http://192.168.0.29:8080/secure/deleteThread/${reportForModal.post.postId}`, 261 { 262 method: "delete", 263 withCredentials: true, 264 }) 142 window.location.reload(false); 265 143 } 266 144 } catch (error) { 267 145 setFetchError(true); 268 146 } 269 window.location.reload(); 147 } 148 149 const handleDelete = (e) => { 150 e.preventDefault(); 270 151 } 271 152 … … 300 181 ) : ( 301 182 <h3>Нема пријавени мислења</h3> 302 ) : loadedUser && user.userRole==='MODERATOR' ? <LoadingSpinner/>: ""}183 ) : loadedUser && user.userRole==='MODERATOR' ? "се вчитува..." : ""} 303 184 <EntityUl style={{marginTop:"25px"}}> 304 185 {loadedPostReports && postReports.map((postReport) => { … … 344 225 {dateConverter( 345 226 new Date(post.timePosted).toString().slice(4, -43) 346 )} <span style={{fontStyle:"normal",color:"blue"}}>#{post.postId}</span>227 )} 347 228 </OpinionCardContentTime> 348 229 </OpinionCardContent> … … 406 287 {dateConverter( 407 288 new Date(reportForModal.post.timePosted).toString().slice(4, -43) 408 )} <span style={{fontStyle:"normal",color:"blue"}}>#{reportForModal.post.postId}</span>289 )} 409 290 </OpinionCardContentTime> 410 291 </OpinionCardContent> … … 472 353 actionType === 0 ? 473 354 (<form onSubmit={e => handleEdit(e)}> 474 {reportForModal.post.title !== null && 475 <label> 355 {reportForModal.post.title !== null && <label> 476 356 <b>Нов наслов на тема:</b> 477 357 <ModalInput 478 value={new ThreadTitle}479 onChange={e => setNew ThreadTitle(e.target.value)}358 value={newPostTitle} 359 onChange={e => setNewPostTitle(e.target.value)} 480 360 id="title" 481 361 spellCheck={false} … … 499 379 <input 500 380 type="checkbox" 381 checked={markResolved} 501 382 onChange={handleMarkResolved} 502 383 /> … … 522 403 </form>) 523 404 : 524 (reportForModal.post.targetProfessor !== undefined ? 525 (<form onSubmit={e => handleRelocate(e)}> 526 <p style={{color:"black"}}>Внеси <span style={{fontWeight:"bold"}}>ID</span> на секцијата за дискусија (за <span style={{fontWeight:"bold"}}>професор</span>) 527 во која треба да биде преместено мислењето:</p> 528 <div style={{marginTop:"15px"}}> 529 <label> 530 <ModalInput 531 value={newOpinionTargetProfessorId} 532 onChange={e => {e.preventDefault();setNewOpinionTargetProfessorId(e.target.value)}} 533 id="newOpinionTargetProfessorId" 534 spellCheck={false} 535 style={{marginTop:"10px", marginBottom:"10px", width:"90px"}} 536 /> 537 <button onClick={async (e) => {await handleNewTargetProfessorChange(e);}} style={{marginBottom:"10px", padding:"5px", fontFamily: "Roboto Mono, monospace"}}>Зачувај</button> 538 {newOpinionTargetProfessor!==null && !loadingProf ? <p style={{color:"black", marginBottom:"20px", opacity:"50%"}}>Мислењето ќе се премести во секцијата за професорот со <span style={{fontWeight:"bold"}}>ID= 539 {newOpinionTargetProfessor.professorId}</span> (<span style={{fontWeight:"bold"}}>{newOpinionTargetProfessor.professorName}</span>)</p> : loadingProf ? <LoadingSpinner style={{marginBottom:"15px", marginTop:"15px"}}/> : null} 540 {newOpinionTargetProfessor && <p style={{color:"black", marginBottom:"10px"}}>Постави како дете на мислење со ID:</p>} 541 {newOpinionTargetProfessor && 542 <select value={newParentPostId} onChange={e => setNewParentPostId(e.target.value)} style={{width:"280px", display:"block", padding:"5px",marginBottom:"5px", fontFamily: "Roboto Mono, monospace"}}> 543 <option value="-1">Постави како самостојно мислење</option> 544 {newOpinionTargetProfessor.relatedOpinions.filter((opinion)=>opinion.postId!==reportForModal.post.postId).map((opinion) => { 545 return <option key={opinion.postId} value={opinion.postId}>{opinion.postId}</option>}) 546 } 547 </select>} 548 <br/> 549 <input 550 type="checkbox" 551 defaultChecked={reportForModal.resolved} 552 onChange={handleMarkResolved} 553 /> 554 <span style={{marginLeft:"10px", fontWeight:"bold"}}>Означи како разрешено</span> 555 </label> 556 </div> 557 {errMsg!=="" && <p style={{color:"red", display:"flex", justifyContent:"space-around"}}>{errMsg}</p>} 558 <ModalFooter type="submit">ПОТВРДИ</ModalFooter> 559 </form>) : 560 //THREAD CASE 561 (<form onSubmit={e => handleRelocate(e)}> 562 <p style={{color:"black"}}>Внеси <span style={{fontWeight:"bold"}}>ID</span> на секцијата за дискусија (за <span style={{fontWeight:"bold"}}>предмет</span>) 563 во која треба да биде преместено мислењето:</p> 564 <div style={{marginTop:"15px"}}> 565 <label> 566 <ModalInput 567 value={newTargetSubjectId} 568 onChange={e => {e.preventDefault();setNewTargetSubjectId(e.target.value)}} 569 id="newTargetSubjectId" 570 spellCheck={false} 571 style={{marginTop:"10px", marginBottom:"10px", width:"90px"}} 572 /> 573 <button onClick={async (e) => {await handleNewTargetSubjectChange(e);}} style={{marginBottom:"10px", padding:"5px", fontFamily: "Roboto Mono, monospace"}}>Зачувај</button> 574 {newTargetSubject!==null && !loadingSubj ? <p style={{color:"black", marginBottom:"20px", opacity:"50%"}}>Мислењето ќе се премести во секцијата за предметот со <span style={{fontWeight:"bold"}}>ID= 575 {newTargetSubject.subjectId}</span> (<span style={{fontWeight:"bold"}}>{newTargetSubject.subjectName}</span>)</p> : loadingSubj ? <LoadingSpinner style={{marginBottom:"15px", marginTop:"15px"}}/> : null} 576 {newTargetSubject && <p style={{color:"black", marginBottom:"10px"}}>Постави како дете на мислење со ID:</p>} 577 {newTargetSubject && 578 <select value={newParentThreadId} onChange={e => setNewParentThreadId(e.target.value)} style={{width:"370px", display:"block", padding:"5px",marginBottom:"5px", fontFamily: "Roboto Mono, monospace"}}> 579 <option value="-1">Постави како самостојно мислење (нова тема)</option> 580 {newTargetSubject.threads.filter((thread)=>thread.postId!==reportForModal.post.postId).map((thread) => { 581 return <option key={thread.postId} value={thread.postId}>{thread.postId}</option>}) 582 } 583 </select>} 584 {newParentThreadId==="-1" && loadedNewSubject && 585 <> 586 <p style={{marginTop:"10px"}}>Наслов на нова тема:</p> 587 <ModalInput 588 value={newThreadTitle} 589 onChange={e => setNewThreadTitle(e.target.value)} 590 id="titleChangeRelocate" 591 spellCheck={false} 592 style={{marginTop:"10px"}} 593 /> 594 </>} 595 <br/> 596 <input 597 type="checkbox" 598 defaultChecked={reportForModal.resolved} 599 onChange={handleMarkResolved} 600 /> 601 <span style={{marginLeft:"10px", fontWeight:"bold"}}>Означи како разрешено</span> 602 </label> 603 </div> 604 {errMsg!=="" && <p style={{color:"red", display:"flex", justifyContent:"space-around"}}>{errMsg}</p>} 605 <ModalFooter type="submit">ПОТВРДИ</ModalFooter> 606 </form>)) 607 : null 405 ("123") 406 : null 608 407 } 609 408 </ModalBody> … … 613 412 </> 614 413 ) : ( 615 <LoadingSpinner/>414 <>се вчитува...</> 616 415 ); 617 416 } -
reactapp/src/api/axios.js
r4abf55a re49d1b6 2 2 3 3 export default axios.create({ 4 baseURL: "http://192.168.0. 29:8080",4 baseURL: "http://192.168.0.19:8080", 5 5 }); -
springapp/src/main/java/mk/profesori/springapp/Controller/PublicController.java
r4abf55a re49d1b6 25 25 @RestController 26 26 @RequestMapping("/public") 27 @CrossOrigin(origins = { "http://192.168.0. 29:3000", "http://192.168.0.28:3000" })27 @CrossOrigin(origins = { "http://192.168.0.19:3000", "http://192.168.0.39:3000" }) 28 28 public class PublicController { 29 29 -
springapp/src/main/java/mk/profesori/springapp/Controller/SecureController.java
r4abf55a re49d1b6 6 6 import mk.profesori.springapp.Model.UserRole; 7 7 import mk.profesori.springapp.Service.CustomUserDetailsService; 8 import mk.profesori.springapp.Service.DisallowedOperationException;9 import mk.profesori.springapp.Service.IncompatiblePostId;10 8 import mk.profesori.springapp.Service.MainService; 11 9 import org.apache.tomcat.websocket.AuthenticationException; … … 20 18 @RestController 21 19 @RequestMapping("/secure") 22 @CrossOrigin(origins = { "http://192.168.0. 29:3000", "http://192.168.0.28:3000" })20 @CrossOrigin(origins = { "http://192.168.0.19:3000", "http://192.168.0.39:3000" }) 23 21 public class SecureController { 24 22 … … 135 133 136 134 @RequestMapping(value = "/updateOpinion/{postId}", method = RequestMethod.PUT) 137 public StringupdateOpinion(@RequestBody ObjectNode objectNode, @PathVariable Long postId,135 public void updateOpinion(@RequestBody ObjectNode objectNode, @PathVariable Long postId, 138 136 @CurrentSecurityContext SecurityContext context) { 139 137 Authentication authentication = context.getAuthentication(); … … 142 140 String newContent = objectNode.get("newContent").asText(); 143 141 Long newTargetProfessorId = objectNode.get("newTargetProfessorId").asLong(); 144 Long newParentPostId = objectNode.get("newParentPostId").asLong(); 145 try { 146 mainService.updateOpinion(newContent, newTargetProfessorId, newParentPostId, postId); 147 } catch (IncompatiblePostId | DisallowedOperationException e) { 148 return e.getMessage(); 149 } 150 } 151 152 return null; 142 mainService.updateOpinion(newContent, newTargetProfessorId, postId); 143 } 153 144 } 154 145 155 146 @RequestMapping(value = "/updateThread/{postId}", method = RequestMethod.PUT) 156 public StringupdateThread(@RequestBody ObjectNode objectNode, @PathVariable Long postId,147 public void updateThread(@RequestBody ObjectNode objectNode, @PathVariable Long postId, 157 148 @CurrentSecurityContext SecurityContext context) { 158 149 Authentication authentication = context.getAuthentication(); … … 162 153 String newContent = objectNode.get("newContent").asText(); 163 154 Long newTargetSubjectId = objectNode.get("newTargetSubjectId").asLong(); 164 Long newParentThreadId = objectNode.get("newParentThreadId").asLong(); 165 try { 155 156 if (objectNode.has("newParentThreadId")) { 157 Long newParentThreadId = objectNode.get("newParentThreadId").asLong(); 166 158 mainService.update_Thread(newTitle, newContent, newTargetSubjectId, newParentThreadId, postId); 167 } catch (IncompatiblePostId | DisallowedOperationException e){168 return e.getMessage();159 } else { 160 mainService.update_Thread(newTitle, newContent, newTargetSubjectId, null, postId); 169 161 } 170 162 } 171 172 return null;173 163 } 174 164 … … 233 223 } 234 224 235 @RequestMapping(value = "/markReportResolved/{postReportId}/ {action}", method = RequestMethod.GET)225 @RequestMapping(value = "/markReportResolved/{postReportId}/", method = RequestMethod.GET) 236 226 public void markReportResolved(@PathVariable Long postReportId, @PathVariable String action, @CurrentSecurityContext SecurityContext context) { 237 227 Authentication authentication = context.getAuthentication(); 238 if (authentication != null && authentication.getPrincipal() instanceof CustomUserDetails currentUser && 239 currentUser.getUserRole().equals(UserRole.MODERATOR)) { 228 if (authentication != null && authentication.getPrincipal() instanceof CustomUserDetails currentUser) { 240 229 mainService.markReport(postReportId, action); 241 230 } -
springapp/src/main/java/mk/profesori/springapp/Security/SecurityConfiguration.java
r4abf55a re49d1b6 37 37 @Override 38 38 public void addCorsMappings(CorsRegistry registry) { 39 registry.addMapping("/**").allowedOrigins("http://192.168.0. 29:3000", "http://192.168.0.28:3000")39 registry.addMapping("/**").allowedOrigins("http://192.168.0.19:3000", "http://192.168.0.39:3000") 40 40 .allowCredentials(true); 41 41 } -
springapp/src/main/java/mk/profesori/springapp/Service/MainService.java
r4abf55a re49d1b6 141 141 public void addThread(String title, String content, Long subjectId, CustomUserDetails currentUser) { 142 142 Subject targetSubject = subjectRepository.findBySubjectId(subjectId); 143 String titleToSet = title.equals("") ? null : title; 144 145 _Thread _threadToAdd = new _Thread(titleToSet, content, currentUser, null, null, null, targetSubject); 143 144 _Thread _threadToAdd = new _Thread(title, content, currentUser, null, null, null, targetSubject); 146 145 _threadRepository.save(_threadToAdd); 147 146 } … … 200 199 public void delete_Thread(Long postId) {_threadRepository.deleteById(postId);} 201 200 202 public String updateOpinion(String newContent, Long newTargetProfessorId, Long newParentPostId, Long postId) {201 public void updateOpinion(String newContent, Long newTargetProfessorId, Long postId) { 203 202 Opinion opinionToUpdate = opinionRepository.findByPostId(postId); 204 203 … … 206 205 207 206 Professor newTargetProfessor = professorRepository.findByProfessorId(newTargetProfessorId); 208 opinionToUpdate.setTargetProfessor(newTargetProfessor); 209 210 Opinion newParentOpinion = null; 211 if (newParentPostId != -1) { 212 newParentOpinion = opinionRepository.findByPostId(newParentPostId); 213 if (!newParentOpinion.getTargetProfessor().equals(newTargetProfessor)) 214 throw new IncompatiblePostId("Мислењето не припаѓа во специфицираната секција за дискусија."); 215 if (opinionToUpdate.getChildren().contains(newParentOpinion)) 216 throw new DisallowedOperationException("Мислењето не може да се постави како дете на негово дете (бесконечна рекурзија)"); 217 } 218 opinionToUpdate.setParent(newParentOpinion); 219 207 opinionToUpdate.setTargetProfessor(newTargetProfessor); //opcijava da ja dava samo kaj postovi so parentPost==null 220 208 for(Post p : opinionToUpdate.getChildren()) { 221 209 Opinion o = (Opinion) p; … … 224 212 opinionToUpdate.setTimeLastEdited(LocalDateTime.now()); 225 213 opinionRepository.save(opinionToUpdate); 226 return null; 227 } 228 229 public String update_Thread(String newTitle, String newContent, Long newTargetSubjectId, Long newParentThreadId, Long postId) { 214 } 215 216 public void update_Thread(String newTitle, String newContent, Long newTargetSubjectId, Long newParentThreadId, Long postId) { 230 217 _Thread _threadToUpdate = _threadRepository.findByPostId(postId); 231 218 … … 235 222 _threadToUpdate.setTargetSubject(newTargetSubject); 236 223 237 _Thread newParentThread = null;238 if(newParentThreadId != -1) {239 newParentThread = _threadRepository.findByPostId(newParentThreadId); 240 if ( !newParentThread.getTargetSubject().equals(newTargetSubject))241 throw new IncompatiblePostId("Мислењето не припаѓа во специфицираната секција за дискусија.");242 if (_threadToUpdate.getChildren().contains(newParentThread))243 throw new DisallowedOperationException("Мислењето не може да се постави како дете на негово дете (бесконечна рекурзија)");244 }245 _threadToUpdate.setParent(newParentThread);224 if(newParentThreadId != null) { //samo ako e specificirano 225 _Thread newParentThread = _threadRepository.findByPostId(newParentThreadId); 226 227 if (_threadToUpdate.getParent() == null || _threadToUpdate.getParent().getPostId().equals(postId)) { 228 _threadToUpdate.setParent(newParentThread); 229 }//samo ako e naslovniot post ili directChild 230 } else if(_threadToUpdate.getParent() != null) { 231 _threadToUpdate.setParent(null); 232 } 246 233 247 234 if(_threadToUpdate.getParent() == null) { 248 235 _threadToUpdate.setTitle(newTitle); 249 236 } else { 250 251 }237 _threadToUpdate.setTitle(null); 238 } 252 239 253 240 for(Post p : _threadToUpdate.getChildren()) { … … 257 244 _threadToUpdate.setTimeLastEdited(LocalDateTime.now()); 258 245 _threadRepository.save(_threadToUpdate); 259 return null;260 246 } 261 247 … … 294 280 if (action.equals("resolve")) report.setResolved(true); 295 281 else if (action.equals("open")) report.setResolved(false); 296 postReportRepository.save(report);297 282 } 298 283 -
springapp/src/main/java/mk/profesori/springapp/Service/RegistrationService.java
r4abf55a re49d1b6 45 45 String tokenToResend = customUserDetailsService 46 46 .createToken(userRepository.findByEmail(request.getEmail()).get()); 47 String link = "http://192.168.0. 29:8080/registration/confirm?token=" + tokenToResend;47 String link = "http://192.168.0.19:8080/registration/confirm?token=" + tokenToResend; 48 48 emailSender.send(request.getEmail(), emailSender.buildEmail(request.getUsername(), link)); 49 49 return tokenToResend; … … 66 66 UserRole.REGULAR)); 67 67 68 String link = "http://192.168.0. 29:8080/registration/confirm?token=" + token;68 String link = "http://192.168.0.19:8080/registration/confirm?token=" + token; 69 69 70 70 emailSender.send(request.getEmail(), emailSender.buildEmail(request.getUsername(), link)); -
springapp/src/main/resources/application.properties
r4abf55a re49d1b6 1 spring.datasource.url=jdbc:postgresql://localhost:5432/profesorimk 1 spring.datasource.url=jdbc:postgresql://localhost:5432/profesori.mk 2 spring.datasource.connectionProperties=useUnicode=true;characterEncoding=utf-8; 2 3 spring.datasource.username=postgres 3 spring.datasource.password= baz@2284 spring.datasource.password=1win7337 4 5 spring.jpa.hibernate.ddl-auto=update 5 6 spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect 6 7 spring.jpa.show-sql=false 7 8 spring.jpa.properties.hibernate.format_sql=true 8 server.address=192.168.0. 299 server.address=192.168.0.19 9 10 spring.mail.host=localhost 10 11 spring.mail.username=mailuser
Note:
See TracChangeset
for help on using the changeset viewer.