Changeset 3b6962d


Ignore:
Timestamp:
11/23/22 12:15:28 (2 years ago)
Author:
unknown <mlviktor23@…>
Branches:
main
Children:
af801e3, e49d1b6
Parents:
c68150f
Message:

moderation/reporting api in spring boot

Files:
7 added
28 edited

Legend:

Unmodified
Added
Removed
  • reactapp/src/Components/OpinionTree.js

    rc68150f r3b6962d  
    4242
    4343  useEffect(() => {
    44     const url = `http://192.168.0.17:8080/secure/currentUser`;
     44    const url = `http://192.168.0.19:8080/secure/currentUser`;
    4545
    4646    const fetchUser = async () => {
     
    6868      ) {
    6969        const response = await axios(
    70           `http://192.168.0.17:8080/secure/upvoteOpinion/${post.postId}`,
     70          `http://192.168.0.19:8080/secure/upvoteOpinion/${post.postId}`,
    7171          {
    7272            method: "get",
     
    9191      ) {
    9292        const response = await axios(
    93           `http://192.168.0.17:8080/secure/downvoteOpinion/${post.postId}`,
     93          `http://192.168.0.19:8080/secure/downvoteOpinion/${post.postId}`,
    9494          {
    9595            method: "get",
     
    111111      setReplyModalDisplay("block");
    112112      setPostForModal(opinion);
     113      document.body.style.overflowY = "hidden";
    113114    } else {
    114115      navigate("/login");
     
    118119  const handleModalCloseClick = () => {
    119120    setReplyModalDisplay("none");
     121    document.body.style.overflowY = "auto";
    120122  };
    121123
     
    129131    if (!replyContent.length < 1) {
    130132      const response = await axios(
    131         `http://192.168.0.17:8080/secure/professor/${professor.professorId}/replyToOpinion/${postId}`,
     133        `http://192.168.0.19:8080/secure/professor/${professor.professorId}/replyToOpinion/${postId}`,
    132134        {
    133135          method: "post",
     
    159161              {child.content}
    160162            </p>
    161             <OpinionReplyCardContentTime>
    162               {dateConverter(
    163                 new Date(child.timePosted).toString().slice(4, -43)
    164               )}
    165             </OpinionReplyCardContentTime>
     163            {child.timePosted === child.timeLastEdited ? (
     164              <OpinionCardContentTime>
     165                {dateConverter(
     166                  new Date(child.timePosted).toString().slice(4, -43)
     167                )}
     168              </OpinionCardContentTime>
     169            ) : (
     170              <OpinionCardContentTime>
     171                {dateConverter(
     172                  new Date(child.timeLastEdited).toString().slice(4, -43)
     173                )}{" "}
     174                (едитирано од модератор)
     175              </OpinionCardContentTime>
     176            )}
    166177
    167178            <div
     
    181192                        (e) => e.vote === "UPVOTE" && e.user.id === user.id
    182193                      )
    183                       ? "greenyellow"
     194                      ? "green"
    184195                      : "darkgrey"
    185196                    : "darkgrey"
     
    249260                    {opinion.content}
    250261                  </p>
    251                   <OpinionCardContentTime>
    252                     {dateConverter(
    253                       new Date(opinion.timePosted).toString().slice(4, -43)
    254                     )}
    255                   </OpinionCardContentTime>
     262                  {opinion.timePosted === opinion.timeLastEdited ? (
     263                    <OpinionCardContentTime>
     264                      {dateConverter(
     265                        new Date(opinion.timePosted).toString().slice(4, -43)
     266                      )}
     267                    </OpinionCardContentTime>
     268                  ) : (
     269                    <OpinionCardContentTime>
     270                      {dateConverter(
     271                        new Date(opinion.timeLastEdited)
     272                          .toString()
     273                          .slice(4, -43)
     274                      )}{" "}
     275                      (едитирано од модератор)
     276                    </OpinionCardContentTime>
     277                  )}
    256278
    257279                  <div
     
    273295                                e.vote === "UPVOTE" && e.user.id === user.id
    274296                            )
    275                             ? "greenyellow"
     297                            ? "green"
    276298                            : "darkgrey"
    277299                          : "darkgrey"
     
    343365                    value={replyContent}
    344366                    onChange={handleContentChange}
     367                    spellCheck={false}
    345368                  />
    346369                </label>
  • reactapp/src/Components/Search.js

    rc68150f r3b6962d  
    1515
    1616  useEffect(() => {
    17     const url = `http://192.168.0.17:8080/public/professors/nameContains/${transliterate(
     17    const url = `http://192.168.0.19:8080/public/professors/nameContains/${transliterate(
    1818      query
    1919    )}`;
  • reactapp/src/Components/Styled/Modal.style.js

    rc68150f r3b6962d  
    2828  top: 0;
    2929  width: 100%;
    30   height: auto;
     30  height: 100%;
    3131  overflow: auto;
    3232  background-color: rgb(0, 0, 0);
     
    4747export const ModalContent = styled.div`
    4848  background-color: #fefefe;
    49   margin: 15% auto;
     49  margin: 2% auto;
    5050  padding: 20px;
    5151  border: 1px solid #888;
     
    107107  padding: 12px 16px;
    108108  border: 1px solid #ccc;
     109  font-family: inherit;
    109110`;
    110111
     
    116117  border: 1px solid #ccc;
    117118  resize: none;
     119  font-family: inherit;
    118120`;
  • reactapp/src/Components/UserHeader.js

    rc68150f r3b6962d  
    1010
    1111  useEffect(() => {
    12     const url = `http://192.168.0.17:8080/secure/currentUser`;
     12    const url = `http://192.168.0.19:8080/secure/currentUser`;
    1313
    1414    const fetchUser = async () => {
  • reactapp/src/Pages/Faculty.js

    rc68150f r3b6962d  
    2727
    2828  useEffect(() => {
    29     const urlProfessors = `http://192.168.0.17:8080/public/professors?facultyId=${params.facultyId}`;
    30     const urlStudyProgrammes = `http://192.168.0.17: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}`;
    3131
    3232    const fetchDataProfessors = async () => {
  • reactapp/src/Pages/Professor.js

    rc68150f r3b6962d  
    3939
    4040  useEffect(() => {
    41     const url = `http://192.168.0.17:8080/public/professor/${params.professorId}`;
     41    const url = `http://192.168.0.19:8080/public/professor/${params.professorId}`;
    4242
    4343    const fetchProfessor = async () => {
     
    6060    if (auth) {
    6161      setPostModalDisplay("block");
     62      document.body.style.overflowY = "hidden";
    6263    } else {
    6364      navigate("/login");
     
    6768  const handleModalCloseClick = () => {
    6869    setPostModalDisplay("none");
     70    document.body.style.overflowY = "auto";
    6971  };
    7072
     
    7476    if (!postContent.length < 1) {
    7577      const response = await axios(
    76         `http://192.168.0.17:8080/secure/professor/${params.professorId}/addOpinion`,
     78        `http://192.168.0.19:8080/secure/professor/${params.professorId}/addOpinion`,
    7779        {
    7880          method: "post",
     
    152154                    rows="8"
    153155                    cols="100"
     156                    spellCheck={false}
    154157                    value={postContent}
    155158                    onChange={handleContentChange}
  • reactapp/src/Pages/Subject.js

    rc68150f r3b6962d  
    4646
    4747  useEffect(() => {
    48     const url = `http://192.168.0.17:8080/public/subject/${params.subjectId}`;
     48    const url = `http://192.168.0.19:8080/public/subject/${params.subjectId}`;
    4949
    5050    const fetchData = async () => {
     
    6767    if (auth) {
    6868      setTopicModalDisplay("block");
     69      document.body.style.overflowY = "hidden";
    6970    } else {
    7071      navigate("/login");
     
    7475  const handleModalCloseClick = () => {
    7576    setTopicModalDisplay("none");
     77    document.body.style.overflowY = "auto";
    7678  };
    7779
     
    8183    if (!topicTitle.length < 1 && !topicContent.length < 1) {
    8284      const response = await axios(
    83         `http://192.168.0.17:8080/secure/subject/${params.subjectId}/addThread`,
     85        `http://192.168.0.19:8080/secure/subject/${params.subjectId}/addThread`,
    8486        {
    8587          method: "post",
     
    178180                  value={topicTitle}
    179181                  onChange={handleTitleChange}
     182                  spellCheck={false}
    180183                />
    181184              </label>
     
    188191                  value={topicContent}
    189192                  onChange={handleContentChange}
     193                  spellCheck={false}
    190194                />
    191195              </label>
  • reactapp/src/Pages/Topic.js

    rc68150f r3b6962d  
    4848
    4949  useEffect(() => {
    50     const url1 = `http://192.168.0.17:8080/public/thread/${params.topicId}`;
    51     const url2 = `http://192.168.0.17: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`;
    5252
    5353    const fetchTopic = async () => {
     
    8484      setReplyModalDisplay("block");
    8585      setPostForModal(post);
     86      document.body.style.overflowY = "hidden";
    8687    } else {
    8788      navigate("/login");
     
    9899    if (!replyContent.length < 1) {
    99100      const response = await axios(
    100         `http://192.168.0.17:8080/secure/subject/${thread.targetSubject.subjectId}/replyToThread/${postId}`,
     101        `http://192.168.0.19:8080/secure/subject/${thread.targetSubject.subjectId}/replyToThread/${postId}`,
    101102        {
    102103          method: "post",
     
    117118    if (auth) {
    118119      setPostModalDisplay("block");
     120      document.body.style.overflowY = "hidden";
    119121    } else {
    120122      navigate("/login");
     
    126128    if (!postContent.length < 1) {
    127129      const response = await axios(
    128         `http://192.168.0.17:8080/secure/subject/${thread.targetSubject.subjectId}/replyToThread/${params.topicId}`,
     130        `http://192.168.0.19:8080/secure/subject/${thread.targetSubject.subjectId}/replyToThread/${params.topicId}`,
    129131        {
    130132          method: "post",
     
    144146    setPostModalDisplay("none");
    145147    setReplyModalDisplay("none");
     148    document.body.style.overflowY = "auto";
    146149  };
    147150  const handleContentChange = (e) => {
     
    157160      ) {
    158161        const response = await axios(
    159           `http://192.168.0.17:8080/secure/upvoteThread/${post.postId}`,
     162          `http://192.168.0.19:8080/secure/upvoteThread/${post.postId}`,
    160163          {
    161164            method: "get",
     
    180183      ) {
    181184        const response = await axios(
    182           `http://192.168.0.17:8080/secure/downvoteThread/${post.postId}`,
     185          `http://192.168.0.19:8080/secure/downvoteThread/${post.postId}`,
    183186          {
    184187            method: "get",
     
    210213              {child.content}
    211214            </p>
    212             <OpinionReplyCardContentTime>
    213               {dateConverter(
    214                 new Date(child.timePosted).toString().slice(4, -43)
    215               )}
    216             </OpinionReplyCardContentTime>
     215            {thread.timePosted === thread.timeLastEdited ? (
     216              <OpinionCardContentTime>
     217                {dateConverter(
     218                  new Date(thread.timePosted).toString().slice(4, -43)
     219                )}
     220              </OpinionCardContentTime>
     221            ) : (
     222              <OpinionCardContentTime>
     223                {dateConverter(
     224                  new Date(thread.timeLastEdited).toString().slice(4, -43)
     225                )}{" "}
     226                (едитирано од модератор)
     227              </OpinionCardContentTime>
     228            )}
    217229
    218230            <div
     
    232244                        (e) => e.vote === "UPVOTE" && e.user.id === user.id
    233245                      )
    234                       ? "greenyellow"
     246                      ? "green"
    235247                      : "darkgrey"
    236248                    : "darkgrey"
     
    337349                  value={postContent}
    338350                  onChange={handleContentChange}
     351                  spellCheck={false}
    339352                />
    340353              </label>
     
    356369            {thread.content}
    357370          </p>
    358           <OpinionCardContentTime>
    359             {dateConverter(
    360               new Date(thread.timePosted).toString().slice(4, -43)
    361             )}
    362           </OpinionCardContentTime>
     371          {thread.timePosted === thread.timeLastEdited ? (
     372            <OpinionCardContentTime>
     373              {dateConverter(
     374                new Date(thread.timePosted).toString().slice(4, -43)
     375              )}
     376            </OpinionCardContentTime>
     377          ) : (
     378            <OpinionCardContentTime>
     379              {dateConverter(
     380                new Date(thread.timeLastEdited).toString().slice(4, -43)
     381              )}{" "}
     382              (едитирано од модератор)
     383            </OpinionCardContentTime>
     384          )}
    363385          <div
    364386            style={{
     
    377399                      (e) => e.vote === "UPVOTE" && e.user.id === user.id
    378400                    )
    379                     ? "greenyellow"
     401                    ? "green"
    380402                    : "darkgrey"
    381403                  : "darkgrey"
     
    422444                {directChild.content}
    423445              </p>
    424               <OpinionCardContentTime>
    425                 {dateConverter(
    426                   new Date(directChild.timePosted).toString().slice(4, -43)
    427                 )}
    428               </OpinionCardContentTime>
     446              {directChild.timePosted === directChild.timeLastEdited ? (
     447                <OpinionCardContentTime>
     448                  {dateConverter(
     449                    new Date(directChild.timePosted).toString().slice(4, -43)
     450                  )}
     451                </OpinionCardContentTime>
     452              ) : (
     453                <OpinionCardContentTime>
     454                  {dateConverter(
     455                    new Date(directChild.timeLastEdited)
     456                      .toString()
     457                      .slice(4, -43)
     458                  )}{" "}
     459                  (едитирано од модератор)
     460                </OpinionCardContentTime>
     461              )}
    429462              <div
    430463                style={{
     
    444477                          (e) => e.vote === "UPVOTE" && e.user.id === user.id
    445478                        )
    446                         ? "greenyellow"
     479                        ? "green"
    447480                        : "darkgrey"
    448481                      : "darkgrey"
  • reactapp/src/Pages/University.js

    rc68150f r3b6962d  
    2222
    2323  useEffect(() => {
    24     const url = `http://192.168.0.17:8080/public/faculties?universityId=${params.universityId}`;
     24    const url = `http://192.168.0.19:8080/public/faculties?universityId=${params.universityId}`;
    2525
    2626    const fetchData = async () => {
  • reactapp/src/Pages/UserDashboard.js

    rc68150f r3b6962d  
    1313import JSOG from "jsog";
    1414import AuthApi from "../api/AuthApi";
     15import {EntityLi, EntityTypeSelector, EntityUl} from "../Components/Styled/EntityList.style";
     16import {
     17  AddOpinionButton,
     18  Modal,
     19  ModalBody,
     20  ModalClose,
     21  ModalContent, ModalFooter,
     22  ModalHeader, ModalTextarea,
     23    ModalInput
     24} from "../Components/Styled/Modal.style";
    1525
    1626function UserDashboard() {
     
    2131  const [fetchError, setFetchError] = useState(false);
    2232
     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
    2357  useEffect(() => {
    24     const url = `http://192.168.0.17:8080/secure/currentUser`;
     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`;
    2571
    2672    const fetchUser = async () => {
    2773      try {
    28         const response = await axios.get(url, { withCredentials: true });
    29         var cyclicGraph = await response.data;
    30         var jsogStructure = JSOG.encode(cyclicGraph);
    31         cyclicGraph = JSOG.decode(jsogStructure);
    32         setUser(cyclicGraph);
    33         setLoadedUser(true);
     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();
    3483      } catch (error) {
    3584        setFetchError(true);
     
    3786    };
    3887
     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
    39101    if (auth) fetchUser();
    40   }, []);
     102
     103  }, [user]);
    41104
    42105  // useEffect(() => {
     
    50113    if (post.parent === null) return post;
    51114    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);
    52155  }
    53156
     
    68171        </UserDetailsCardContent>
    69172        <UserDetailsCardContent>
    70           <b>Карма:</b> {user.karma}
     173          <b>Карма:</b>{" "}
     174          <span style={{ color: user.karma < 0 ? "indianred" : "green" }}>
     175            {user.karma}
     176          </span>
    71177        </UserDetailsCardContent>
    72178      </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>
    73195      {user.authoredPosts.length > 0 ? (
    74         <h3 style={{ marginBottom: "10px" }}>Ваши мислења:</h3>
     196        <h3 style={{ marginBottom: "10px", marginTop:"30px" }}>Ваши мислења:</h3>
    75197      ) : (
    76         <h3>Немате објавени мислења</h3>
     198        <h3 style={{ marginBottom: "10px" }}>Немате објавени мислења</h3>
    77199      )}
    78200      {user.authoredPosts.map((post) => {
     
    110232        );
    111233      })}
     234      {reportForModal && (
     235          <Modal display={reportModalDisplay}>
     236            <ModalContent>
     237              <ModalHeader>
     238                <ModalClose onClick={handleModalCloseClick}>&times;</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      )}
    112412    </>
    113413  ) : (
  • reactapp/src/api/axios.js

    rc68150f r3b6962d  
    22
    33export default axios.create({
    4   baseURL: "http://192.168.0.17:8080",
     4  baseURL: "http://192.168.0.19:8080",
    55});
  • springapp/src/main/java/mk/profesori/springapp/Controller/PublicController.java

    rc68150f r3b6962d  
    2525@RestController
    2626@RequestMapping("/public")
    27 @CrossOrigin(origins = { "http://192.168.0.17:3000", "http://192.168.0.39:3000" })
     27@CrossOrigin(origins = { "http://192.168.0.19:3000", "http://192.168.0.39:3000" })
    2828public class PublicController {
    2929
  • springapp/src/main/java/mk/profesori/springapp/Controller/SecureController.java

    rc68150f r3b6962d  
    33import com.fasterxml.jackson.databind.node.ObjectNode;
    44import mk.profesori.springapp.Model.CustomUserDetails;
     5import mk.profesori.springapp.Model.PostReport;
     6import mk.profesori.springapp.Model.UserRole;
    57import mk.profesori.springapp.Service.CustomUserDetailsService;
    68import mk.profesori.springapp.Service.MainService;
     9import org.apache.tomcat.websocket.AuthenticationException;
    710import org.springframework.security.core.Authentication;
    811import org.springframework.security.core.annotation.CurrentSecurityContext;
     
    1114import org.springframework.web.bind.annotation.*;
    1215
     16import java.util.List;
     17
    1318@RestController
    1419@RequestMapping("/secure")
    15 @CrossOrigin(origins = { "http://192.168.0.17:3000", "http://192.168.0.39:3000" })
     20@CrossOrigin(origins = { "http://192.168.0.19:3000", "http://192.168.0.39:3000" })
    1621public class SecureController {
    1722
    1823    private final MainService mainService;
    19     final
    20     CustomUserDetailsService customUserDetailsService;
     24    final CustomUserDetailsService customUserDetailsService;
    2125
    2226    public SecureController(MainService mainService, CustomUserDetailsService customUserDetailsService) {
     
    2832    public void addOpinion(@RequestBody ObjectNode objectNode, @PathVariable Long professorId,
    2933            @CurrentSecurityContext SecurityContext context) {
    30 
    31         Authentication authentication = context.getAuthentication();
    32 
     34        Authentication authentication = context.getAuthentication();
    3335        if (authentication != null && authentication.getPrincipal() instanceof CustomUserDetails currentUser) {
    3436            String content = objectNode.get("content").asText();
     
    4042    public void replyToOpinion(@RequestBody ObjectNode objectNode, @PathVariable Long professorId,
    4143            @PathVariable Long postId, @CurrentSecurityContext SecurityContext context) {
    42 
    43         Authentication authentication = context.getAuthentication();
    44 
     44        Authentication authentication = context.getAuthentication();
    4545        if (authentication != null && authentication.getPrincipal() instanceof CustomUserDetails currentUser) {
    4646            String content = objectNode.get("content").asText();
     
    5252    public void addThread(@RequestBody ObjectNode objectNode, @PathVariable Long subjectId,
    5353            @CurrentSecurityContext SecurityContext context) {
    54 
    55         Authentication authentication = context.getAuthentication();
    56 
     54        Authentication authentication = context.getAuthentication();
    5755        if (authentication != null && authentication.getPrincipal() instanceof CustomUserDetails currentUser) {
    5856            String title = objectNode.get("title").asText();
     
    6563    public void replyToThread(@RequestBody ObjectNode objectNode, @PathVariable Long subjectId,
    6664            @PathVariable Long postId, @CurrentSecurityContext SecurityContext context) {
    67 
    68         Authentication authentication = context.getAuthentication();
    69 
     65        Authentication authentication = context.getAuthentication();
    7066        if (authentication != null && authentication.getPrincipal() instanceof CustomUserDetails currentUser) {
    7167            String content = objectNode.get("content").asText();
     
    7672    @RequestMapping(value = "/currentUser", method = RequestMethod.GET)
    7773    public UserDetails getUserDetails(@CurrentSecurityContext SecurityContext context) {
    78 
    7974        Authentication authentication = context.getAuthentication();
    8075        if (authentication != null && authentication.getPrincipal() instanceof CustomUserDetails currentUser) {
    8176            return customUserDetailsService.loadUserByUsername(currentUser.getEmail());
    8277        }
    83 
    8478        return null;
    8579    }
     
    8781    @RequestMapping(value = "/upvoteOpinion/{postId}", method = RequestMethod.GET)
    8882    public void upvoteOpinion(@PathVariable Long postId, @CurrentSecurityContext SecurityContext context) {
    89 
    90         Authentication authentication = context.getAuthentication();
    91 
     83        Authentication authentication = context.getAuthentication();
    9284        if (authentication != null && authentication.getPrincipal() instanceof CustomUserDetails currentUser) {
    9385            mainService.upvoteOpinion(postId, currentUser);
     
    9789    @RequestMapping(value = "/downvoteOpinion/{postId}", method = RequestMethod.GET)
    9890    public void downvoteOpinion(@PathVariable Long postId, @CurrentSecurityContext SecurityContext context) {
    99 
    100         Authentication authentication = context.getAuthentication();
    101 
     91        Authentication authentication = context.getAuthentication();
    10292        if (authentication != null && authentication.getPrincipal() instanceof CustomUserDetails currentUser) {
    10393            mainService.downvoteOpinion(postId, currentUser);
     
    10797    @RequestMapping(value = "/upvoteThread/{postId}", method = RequestMethod.GET)
    10898    public void upvoteThread(@PathVariable Long postId, @CurrentSecurityContext SecurityContext context) {
    109 
    110         Authentication authentication = context.getAuthentication();
    111 
     99        Authentication authentication = context.getAuthentication();
    112100        if (authentication != null && authentication.getPrincipal() instanceof CustomUserDetails currentUser) {
    113101            mainService.upvote_Thread(postId, currentUser);
     
    119107
    120108        Authentication authentication = context.getAuthentication();
    121 
    122109        if (authentication != null && authentication.getPrincipal() instanceof CustomUserDetails currentUser) {
    123110            mainService.downvote_Thread(postId, currentUser);
     
    125112    }
    126113
     114    @RequestMapping(value = "/deleteOpinion/{postId}", method = RequestMethod.DELETE)
     115    public void deleteOpinion(@PathVariable Long postId, @CurrentSecurityContext SecurityContext context)
     116            throws Exception {
     117        Authentication authentication = context.getAuthentication();
     118        if (authentication != null && authentication.getPrincipal() instanceof CustomUserDetails currentUser
     119                && currentUser.getUserRole().equals(UserRole.MODERATOR)) {
     120            mainService.deleteOpinion(postId);
     121        } else
     122            throw new AuthenticationException("Auth exception");
     123    }
     124
     125    @RequestMapping(value = "/deleteThread/{postId}", method = RequestMethod.DELETE)
     126    public void deleteThread(@PathVariable Long postId, @CurrentSecurityContext SecurityContext context) {
     127        Authentication authentication = context.getAuthentication();
     128        if (authentication != null && authentication.getPrincipal() instanceof CustomUserDetails currentUser
     129                && currentUser.getUserRole().equals(UserRole.MODERATOR)) {
     130            mainService.delete_Thread(postId);
     131        }
     132    }
     133
     134    @RequestMapping(value = "/updateOpinion/{postId}", method = RequestMethod.PUT)
     135    public void updateOpinion(@RequestBody ObjectNode objectNode, @PathVariable Long postId,
     136            @CurrentSecurityContext SecurityContext context) {
     137        Authentication authentication = context.getAuthentication();
     138        if (authentication != null && authentication.getPrincipal() instanceof CustomUserDetails currentUser
     139                && currentUser.getUserRole().equals(UserRole.MODERATOR)) {
     140            String newContent = objectNode.get("newContent").asText();
     141            Long newTargetProfessorId = objectNode.get("newTargetProfessorId").asLong();
     142            mainService.updateOpinion(newContent, newTargetProfessorId, postId);
     143        }
     144    }
     145
     146    @RequestMapping(value = "/updateThread/{postId}", method = RequestMethod.PUT)
     147    public void updateThread(@RequestBody ObjectNode objectNode, @PathVariable Long postId,
     148            @CurrentSecurityContext SecurityContext context) {
     149        Authentication authentication = context.getAuthentication();
     150        if (authentication != null && authentication.getPrincipal() instanceof CustomUserDetails currentUser
     151                && currentUser.getUserRole().equals(UserRole.MODERATOR)) {
     152            String newTitle = objectNode.get("newTitle").asText();
     153            String newContent = objectNode.get("newContent").asText();
     154            Long newTargetSubjectId = objectNode.get("newTargetSubjectId").asLong();
     155
     156            if (objectNode.has("newParentThreadId")) {
     157                Long newParentThreadId = objectNode.get("newParentThreadId").asLong();
     158                mainService.update_Thread(newTitle, newContent, newTargetSubjectId, newParentThreadId, postId);
     159            } else {
     160                mainService.update_Thread(newTitle, newContent, newTargetSubjectId, null, postId);
     161            }
     162        }
     163    }
     164
     165    @RequestMapping(value = "/lockUser/{userId}", method = RequestMethod.GET)
     166    public void lockUser(@PathVariable Long userId, @CurrentSecurityContext SecurityContext context) {
     167        Authentication authentication = context.getAuthentication();
     168        if (authentication != null && authentication.getPrincipal() instanceof CustomUserDetails currentUser
     169                && currentUser.getUserRole().equals(UserRole.MODERATOR)) {
     170            mainService.lockUser(userId);
     171        }
     172    }
     173
     174    @RequestMapping(value = "/deleteUser/{userId}", method = RequestMethod.DELETE)
     175    public void deleteUser(@PathVariable Long userId, @CurrentSecurityContext SecurityContext context) {
     176        Authentication authentication = context.getAuthentication();
     177        if (authentication != null && authentication.getPrincipal() instanceof CustomUserDetails currentUser
     178                && currentUser.getUserRole().equals(UserRole.MODERATOR)) {
     179            mainService.deleteUser(userId);
     180        }
     181    }
     182
     183    @RequestMapping(value = "/updateUserFullName/{userId}", method = RequestMethod.PUT)
     184    public void updateUserFullName(@RequestBody ObjectNode objectNode, @PathVariable Long userId,
     185            @CurrentSecurityContext SecurityContext context) {
     186        Authentication authentication = context.getAuthentication();
     187        if (authentication != null && authentication.getPrincipal() instanceof CustomUserDetails currentUser
     188                && (currentUser.getUserRole().equals(UserRole.MODERATOR) || currentUser.getId().equals(userId))) {
     189            String newFullName = objectNode.get("newFullName").asText();
     190            mainService.updateUserFullName(newFullName, userId);
     191        }
     192    }
     193
     194    @RequestMapping(value = "/updateUserUsername/{userId}", method = RequestMethod.PUT)
     195    public void updateUserUsername(@RequestBody ObjectNode objectNode, @PathVariable Long userId,
     196            @CurrentSecurityContext SecurityContext context) {
     197        Authentication authentication = context.getAuthentication();
     198        if (authentication != null && authentication.getPrincipal() instanceof CustomUserDetails currentUser
     199                && (currentUser.getUserRole().equals(UserRole.MODERATOR) || currentUser.getId().equals(userId))) {
     200            String newUsername = objectNode.get("newUsername").asText();
     201            mainService.updateUserUsername(newUsername, userId);
     202        }
     203    }
     204
     205    @RequestMapping(value = "/reportOpinion/{postId}", method = RequestMethod.POST)
     206    public void reportOpinion(@RequestBody ObjectNode objectNode, @PathVariable Long postId,
     207                              @CurrentSecurityContext SecurityContext context) {
     208        Authentication authentication = context.getAuthentication();
     209        if (authentication != null && authentication.getPrincipal() instanceof CustomUserDetails currentUser) {
     210            String description = objectNode.get("description").asText();
     211            mainService.reportOpinion(postId, currentUser, description);
     212        }
     213    }
     214
     215    @RequestMapping(value = "/reportThread/{postId}", method = RequestMethod.POST)
     216    public void reportThread(@RequestBody ObjectNode objectNode, @PathVariable Long postId,
     217                              @CurrentSecurityContext SecurityContext context) {
     218        Authentication authentication = context.getAuthentication();
     219        if (authentication != null && authentication.getPrincipal() instanceof CustomUserDetails currentUser) {
     220            String description = objectNode.get("description").asText();
     221            mainService.reportThread(postId, currentUser, description);
     222        }
     223    }
     224
     225    @RequestMapping(value = "/markReportResolved/{postReportId}/", method = RequestMethod.GET)
     226    public void markReportResolved(@PathVariable Long postReportId, @PathVariable String action, @CurrentSecurityContext SecurityContext context) {
     227        Authentication authentication = context.getAuthentication();
     228        if (authentication != null && authentication.getPrincipal() instanceof CustomUserDetails currentUser) {
     229            mainService.markReport(postReportId, action);
     230        }
     231    }
     232
     233    @RequestMapping(value = "/getAllPostReports", method = RequestMethod.GET)
     234    public List<PostReport> getAllPostReports(@CurrentSecurityContext SecurityContext context) throws AuthenticationException{
     235        Authentication authentication = context.getAuthentication();
     236        if (authentication != null && authentication.getPrincipal() instanceof CustomUserDetails currentUser
     237                && currentUser.getUserRole().equals(UserRole.MODERATOR)) {
     238            return mainService.getAllPostReports();
     239        } else throw new AuthenticationException("Invalid role");
     240     }
     241
     242
    127243}
  • springapp/src/main/java/mk/profesori/springapp/Model/CustomUserDetails.java

    rc68150f r3b6962d  
    2929    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "user_sequence")
    3030    private Long id;
    31     private String fullName; // opcionalno, smee da e prazno
     31    private String fullName;
    3232    private String username;
    3333    private String email;
    34     private String password; // TODO dont expose password in api
     34    private String password; // TODO
    3535    @Enumerated(EnumType.STRING)
    3636    private UserRole userRole;
    3737    private Boolean locked = false;
    3838    private Boolean enabled = false;
    39     @OneToMany(mappedBy = "customUserDetails", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
     39    @OneToMany(mappedBy = "customUserDetails", fetch = FetchType.EAGER, orphanRemoval = true)
    4040    private Set<ConfirmationToken> confirmationTokens = new HashSet<>();
    41     @OneToMany(mappedBy = "author", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
     41    @OneToMany(mappedBy = "author", fetch = FetchType.EAGER, orphanRemoval = true)
    4242    private Set<Post> authoredPosts = new HashSet<>();
    4343    private Integer karma = 0;
    4444
    45     public Set<PostVote> getVotes() {
    46         return votes;
     45    @OneToMany(mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true)
     46    private Set<PostVote> votes = new HashSet<>();
     47
     48    @OneToMany(mappedBy = "user", cascade = {CascadeType.PERSIST})
     49    private Set<PostReport> reportsSubmitted = new HashSet<>();
     50    @PreRemove
     51    public void preRemove() {
     52        reportsSubmitted.forEach(report -> {
     53            report.setUser(null);
     54        });
    4755    }
    48 
    49     public void setVotes(Set<PostVote> votes) {
    50         this.votes = votes;
    51     }
    52 
    53     @OneToMany(mappedBy = "user")
    54     private Set<PostVote> votes = new HashSet<>();
    5556
    5657    public CustomUserDetails(String fullName, String username, String email, String password, UserRole userRole) {
     
    115116    }
    116117
     118    public void setLocked(Boolean locked) {
     119        this.locked = locked;
     120    }
     121
     122    public Set<PostVote> getVotes() {
     123        return votes;
     124    }
     125
     126    public void setVotes(Set<PostVote> votes) {
     127        this.votes = votes;
     128    }
    117129}
  • springapp/src/main/java/mk/profesori/springapp/Model/Opinion.java

    rc68150f r3b6962d  
    4040        return targetProfessor;
    4141    }
    42 
    4342    public void setTargetProfessor(Professor targetProfessor) {
    4443        this.targetProfessor = targetProfessor;
    4544    }
     45
    4646}
  • springapp/src/main/java/mk/profesori/springapp/Model/Post.java

    rc68150f r3b6962d  
    11package mk.profesori.springapp.Model;
    22
     3import com.fasterxml.jackson.annotation.JsonIdentityInfo;
     4import com.voodoodyne.jackson.jsog.JSOGGenerator;
     5import lombok.NoArgsConstructor;
     6
     7import javax.persistence.*;
    38import java.time.LocalDateTime;
    49import java.util.ArrayList;
     
    611import java.util.List;
    712import java.util.Set;
    8 
    9 import javax.persistence.CascadeType;
    10 import javax.persistence.Column;
    11 import javax.persistence.DiscriminatorColumn;
    12 import javax.persistence.Entity;
    13 import javax.persistence.GeneratedValue;
    14 import javax.persistence.GenerationType;
    15 import javax.persistence.Id;
    16 import javax.persistence.Inheritance;
    17 import javax.persistence.DiscriminatorType;
    18 import javax.persistence.InheritanceType;
    19 import javax.persistence.JoinColumn;
    20 import javax.persistence.ManyToMany;
    21 import javax.persistence.ManyToOne;
    22 import javax.persistence.OneToMany;
    23 
    24 import com.fasterxml.jackson.annotation.JsonIdentityInfo;
    25 import com.voodoodyne.jackson.jsog.JSOGGenerator;
    26 
    27 import lombok.NoArgsConstructor;
    2813
    2914@Entity(name = "post")
     
    5944    private Post parent;
    6045
    61     @OneToMany(mappedBy = "post")
     46    @OneToMany(mappedBy = "post", cascade = CascadeType.ALL, orphanRemoval = true)
    6247    private Set<PostVote> votes = new HashSet<>();
    6348
     49    @OneToMany(mappedBy = "post", cascade={CascadeType.PERSIST})
     50    private Set<PostReport> reports = new HashSet<>();
     51    @PreRemove
     52    public void preRemove() {
     53        reports.forEach(report -> {
     54            report.setPost(null);
     55            report.setResolved(true);
     56        });
     57    }
     58
     59
     60    @OneToMany(mappedBy = "parent", cascade = CascadeType.ALL, orphanRemoval = true)
     61    private List<Post> children = new ArrayList<>();
     62
     63    // getters and setters
    6464    public Set<PostVote> getVotes() {
    6565        return votes;
     
    6969        this.votes = votes;
    7070    }
    71 
    72     @OneToMany(mappedBy = "parent", cascade = CascadeType.ALL)
    73     private List<Post> children = new ArrayList<>();
    74 
    75     // getters and setters
    7671    public Long getPostId() {
    7772        return postId;
     
    169164    }
    170165
     166
    171167}
  • springapp/src/main/java/mk/profesori/springapp/Model/_Thread.java

    rc68150f r3b6962d  
    4141    }
    4242
     43    public void setTargetSubject(Subject targetSubject) {
     44        this.targetSubject = targetSubject;
     45    }
    4346}
  • springapp/src/main/java/mk/profesori/springapp/Repository/CityRepository.java

    rc68150f r3b6962d  
    1111public interface CityRepository extends CrudRepository<City, Long>{
    1212
    13     public List<City> findAll();
    14     public City findByCityId(Long id);
     13    List<City> findAll();
     14    City findByCityId(Long id);
    1515}
  • springapp/src/main/java/mk/profesori/springapp/Repository/FacultyRepository.java

    rc68150f r3b6962d  
    1212public interface FacultyRepository extends CrudRepository<Faculty, Long>{
    1313
    14     public List<Faculty> findAll();
    15     public Faculty findByFacultyId(Long id);
    16     public List<Faculty> findByUniversity(University university);
     14    List<Faculty> findAll();
     15    Faculty findByFacultyId(Long id);
     16    List<Faculty> findByUniversity(University university);
    1717}
  • springapp/src/main/java/mk/profesori/springapp/Repository/ProfessorRepository.java

    rc68150f r3b6962d  
    1313public interface ProfessorRepository extends CrudRepository<Professor, Long>, JpaSpecificationExecutor<Professor> {
    1414
    15     public List<Professor> findAll();
     15    List<Professor> findAll();
    1616
    17     public Professor findByProfessorId(Long id);
     17    Professor findByProfessorId(Long id);
    1818
    19     public List<Professor> findByFaculty(Faculty faculty);
     19    List<Professor> findByFaculty(Faculty faculty);
    2020
    21     public List<Professor> findByProfessorNameContainingIgnoreCase(String name);
     21    List<Professor> findByProfessorNameContainingIgnoreCase(String name);
    2222}
  • springapp/src/main/java/mk/profesori/springapp/Repository/StudyProgrammeRepository.java

    rc68150f r3b6962d  
    1313public interface StudyProgrammeRepository extends CrudRepository<StudyProgramme, Long>{
    1414   
    15     public List<StudyProgramme> findAll();
    16     public StudyProgramme findByStudyProgrammeId(Long id);
    17     public List<StudyProgramme> findByFaculty(Faculty faculty);
     15    List<StudyProgramme> findAll();
     16    StudyProgramme findByStudyProgrammeId(Long id);
     17    List<StudyProgramme> findByFaculty(Faculty faculty);
    1818}
  • springapp/src/main/java/mk/profesori/springapp/Repository/SubjectRepository.java

    rc68150f r3b6962d  
    88@Repository
    99public interface SubjectRepository extends CrudRepository<Subject, Long> {
    10     public Subject findBySubjectId(Long id);
     10    Subject findBySubjectId(Long id);
    1111}
  • springapp/src/main/java/mk/profesori/springapp/Repository/UniversityRepository.java

    rc68150f r3b6962d  
    1212public interface UniversityRepository extends CrudRepository<University, Long> {
    1313
    14     public List<University> findAll();
     14    List<University> findAll();
    1515
    16     public University findByUniversityId(Long id);
     16    University findByUniversityId(Long id);
    1717
    18     public List<University> findByCity(City city);
     18    List<University> findByCity(City city);
    1919}
  • springapp/src/main/java/mk/profesori/springapp/Security/SecurityConfiguration.java

    rc68150f r3b6962d  
    3737            @Override
    3838            public void addCorsMappings(CorsRegistry registry) {
    39                 registry.addMapping("/**").allowedOrigins("http://192.168.0.17:3000", "http://192.168.0.39:3000")
     39                registry.addMapping("/**").allowedOrigins("http://192.168.0.19:3000", "http://192.168.0.39:3000")
    4040                        .allowCredentials(true);
    4141            }
  • springapp/src/main/java/mk/profesori/springapp/Service/CustomUserDetailsService.java

    rc68150f r3b6962d  
    4343        userRepository.save(customUserDetails);
    4444
    45         String token = createToken(customUserDetails);
    46 
    47         return token;
     45        return createToken(customUserDetails);
    4846    }
    4947
     
    6058    }
    6159
    62     public int enableUser(String email) {
    63         return userRepository.enableUser(email);
     60    public void enableUser(String email) {
     61        userRepository.enableUser(email);
    6462    }
    6563}
  • springapp/src/main/java/mk/profesori/springapp/Service/MainService.java

    rc68150f r3b6962d  
    33import mk.profesori.springapp.Model.*;
    44import mk.profesori.springapp.Repository.*;
     5import org.springframework.security.core.userdetails.UsernameNotFoundException;
    56import org.springframework.stereotype.Service;
    67
     8import java.time.LocalDateTime;
    79import java.util.ArrayList;
    810import java.util.List;
     
    2123    private final PostVoteRepository postVoteRepository;
    2224    private final UserRepository userRepository;
    23 
    24     public MainService(ProfessorRepository professorRepository, StudyProgrammeRepository studyProgrammeRepository, FacultyRepository facultyRepository, UniversityRepository universityRepository, CityRepository cityRepository, OpinionRepository opinionRepository, _ThreadRepository _threadRepository, SubjectRepository subjectRepository, PostVoteRepository postVoteRepository, UserRepository userRepository) {
     25    private final PostReportRepository postReportRepository;
     26
     27    public MainService(ProfessorRepository professorRepository, StudyProgrammeRepository studyProgrammeRepository, FacultyRepository facultyRepository, UniversityRepository universityRepository, CityRepository cityRepository, OpinionRepository opinionRepository, _ThreadRepository _threadRepository, SubjectRepository subjectRepository, PostVoteRepository postVoteRepository, UserRepository userRepository, PostReportRepository postReportRepository) {
    2528        this.professorRepository = professorRepository;
    2629        this.studyProgrammeRepository = studyProgrammeRepository;
     
    3336        this.postVoteRepository = postVoteRepository;
    3437        this.userRepository = userRepository;
     38        this.postReportRepository = postReportRepository;
    3539    }
    3640
     
    183187        targetPost.getAuthor().setKarma(targetPost.getAuthor().getKarma()+1);
    184188        userRepository.save(targetPost.getAuthor());
    185 
    186189    }
    187190    public void downvote_Thread(Long postId, CustomUserDetails currentUser) {
     
    192195        userRepository.save(targetPost.getAuthor());
    193196    }
     197
     198    public void deleteOpinion(Long postId) {opinionRepository.deleteById(postId);}
     199    public void delete_Thread(Long postId) {_threadRepository.deleteById(postId);}
     200
     201    public void updateOpinion(String newContent, Long newTargetProfessorId, Long postId) {
     202        Opinion opinionToUpdate = opinionRepository.findByPostId(postId);
     203
     204        opinionToUpdate.setContent(newContent);
     205
     206        Professor newTargetProfessor = professorRepository.findByProfessorId(newTargetProfessorId);
     207        opinionToUpdate.setTargetProfessor(newTargetProfessor); //opcijava da ja dava samo kaj postovi so parentPost==null
     208        for(Post p : opinionToUpdate.getChildren()) {
     209            Opinion o = (Opinion) p;
     210            o.setTargetProfessor(newTargetProfessor);
     211        }
     212        opinionToUpdate.setTimeLastEdited(LocalDateTime.now());
     213        opinionRepository.save(opinionToUpdate);
     214    }
     215
     216    public void update_Thread(String newTitle, String newContent, Long newTargetSubjectId, Long newParentThreadId, Long postId) {
     217        _Thread _threadToUpdate = _threadRepository.findByPostId(postId);
     218
     219        _threadToUpdate.setContent(newContent);
     220
     221        Subject newTargetSubject = subjectRepository.findBySubjectId(newTargetSubjectId);
     222        _threadToUpdate.setTargetSubject(newTargetSubject);
     223
     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            }
     233
     234            if(_threadToUpdate.getParent() == null) {
     235             _threadToUpdate.setTitle(newTitle);
     236            } else {
     237             _threadToUpdate.setTitle(null);
     238             }
     239
     240         for(Post p : _threadToUpdate.getChildren()) {
     241                _Thread t = (_Thread) p;
     242                t.setTargetSubject(newTargetSubject);
     243            }
     244         _threadToUpdate.setTimeLastEdited(LocalDateTime.now());
     245          _threadRepository.save(_threadToUpdate);
     246    }
     247
     248    public void lockUser(Long userId) {
     249        CustomUserDetails user = userRepository.findById(userId).orElseThrow(() -> new UsernameNotFoundException("Invalid userId"));
     250        user.setLocked(true);
     251        userRepository.save(user);
     252    }
     253
     254    public void deleteUser(Long userId) {
     255        userRepository.deleteById(userId);
     256    }
     257
     258
     259    public void updateUserFullName(String newFullName, Long userId) {
     260        CustomUserDetails user = userRepository.findById(userId).orElseThrow(() -> new UsernameNotFoundException("Invalid userId"));
     261        user.setFullName(newFullName);
     262        userRepository.save(user);
     263    }
     264
     265    public void updateUserUsername(String newUsername, Long userId) {
     266        CustomUserDetails user = userRepository.findById(userId).orElseThrow(() -> new UsernameNotFoundException("Invalid userId"));
     267        user.setUsername(newUsername);
     268        userRepository.save(user);
     269    }
     270
     271
     272    public void reportOpinion(Long postId, CustomUserDetails currentUser, String description) {
     273            Post targetPost = opinionRepository.findByPostId(postId);
     274            PostReport reportToAdd = new PostReport(currentUser, targetPost, description);
     275            postReportRepository.save(reportToAdd);
     276    }
     277
     278    public void markReport(Long postReportId, String action) {
     279        PostReport report = postReportRepository.findByPostReportId(postReportId);
     280        if (action.equals("resolve")) report.setResolved(true);
     281        else if (action.equals("open")) report.setResolved(false);
     282     }
     283
     284    public List<PostReport> getAllPostReports() {
     285        return postReportRepository.findAll();
     286    }
     287
     288    public void reportThread(Long postId, CustomUserDetails currentUser, String description) {
     289        Post targetPost = _threadRepository.findByPostId(postId);
     290        PostReport reportToAdd = new PostReport(currentUser, targetPost, description);
     291        postReportRepository.save(reportToAdd);
     292    }
    194293}
  • springapp/src/main/java/mk/profesori/springapp/Service/RegistrationService.java

    rc68150f r3b6962d  
    4545                String tokenToResend = customUserDetailsService
    4646                        .createToken(userRepository.findByEmail(request.getEmail()).get());
    47                 String link = "http://192.168.0.17:8080/registration/confirm?token=" + tokenToResend;
     47                String link = "http://192.168.0.19:8080/registration/confirm?token=" + tokenToResend;
    4848                emailSender.send(request.getEmail(), emailSender.buildEmail(request.getUsername(), link));
    4949                return tokenToResend;
     
    6666                        UserRole.REGULAR));
    6767
    68         String link = "http://192.168.0.17:8080/registration/confirm?token=" + token;
     68        String link = "http://192.168.0.19:8080/registration/confirm?token=" + token;
    6969
    7070        emailSender.send(request.getEmail(), emailSender.buildEmail(request.getUsername(), link));
  • springapp/src/main/resources/application.properties

    rc68150f r3b6962d  
    77spring.jpa.show-sql=false
    88spring.jpa.properties.hibernate.format_sql=true
    9 server.address=192.168.0.17
    10 spring.mail.host=192.168.0.39
     9server.address=192.168.0.19
     10spring.mail.host=localhost
    1111spring.mail.username=mailuser
    1212spring.mail.password=mailpass
Note: See TracChangeset for help on using the changeset viewer.