Index: reactapp/src/App.js
===================================================================
--- reactapp/src/App.js	(revision 702ca779afcdb48bcc15202ffc07dfb4be2efebd)
+++ reactapp/src/App.js	(revision 6221ab65b38aad2d2b041055cb1aa8825b624f00)
@@ -8,9 +8,29 @@
 import AuthApi from "./api/AuthApi";
 import Cookies from "js-cookie";
+import axios from "./api/axios";
+import JSOG from "jsog";
 
 export default function App() {
   const [auth, setAuth] = useState(false);
+  const [user, setUser] = useState(null);
+  const [userLoaded, setUserLoaded] = useState(false);
   const variableAuth = useMemo(() => ({ auth, setAuth }), [auth]);
   const [authLoaded, setAuthLoaded] = useState(false);
+
+  const fetchUser = async () => {
+    try {
+      const response = await axios.get(
+        "http://192.168.0.19:8080/secure/currentUser",
+        { withCredentials: true }
+      );
+      var cyclicGraph = await response.data;
+      var jsogStructure = JSOG.encode(cyclicGraph);
+      cyclicGraph = JSOG.decode(jsogStructure);
+      setUser(cyclicGraph);
+      setUserLoaded(true);
+    } catch (error) {
+      console.log("Fetching error", error);
+    }
+  };
 
   const readCookie = async () => {
@@ -18,4 +38,5 @@
     if (session) {
       setAuth(true); // go stava true ako postoi takvo cookie (zasto auth=false na sekoe renderiranje)
+      fetchUser();
     } else {
       setAuth(false);
@@ -43,8 +64,14 @@
       <BrowserRouter>
         <Routes>
-          <Route path="/" element={<Home />}>
+          <Route
+            path="/"
+            element={<Home user={user} userLoaded={userLoaded} />}
+          >
             <Route path="login" element={<Login />}></Route>
             <Route path="professor">
-              <Route path=":professorId" element={<Professor />} />
+              <Route
+                path=":professorId"
+                element={<Professor user={user} userLoaded={userLoaded} />}
+              />
             </Route>
             <Route path="search" element={<SearchResults />}></Route>
@@ -53,5 +80,5 @@
               element={
                 <ProtectedRoute auth={auth}>
-                  <UserDashboard />
+                  {<UserDashboard user={user} userLoaded={userLoaded} />}
                 </ProtectedRoute>
               }
Index: reactapp/src/Components/OpinionTree.js
===================================================================
--- reactapp/src/Components/OpinionTree.js	(revision 702ca779afcdb48bcc15202ffc07dfb4be2efebd)
+++ reactapp/src/Components/OpinionTree.js	(revision 6221ab65b38aad2d2b041055cb1aa8825b624f00)
@@ -9,11 +9,79 @@
   StyledFontAwesomeIcon,
 } from "./Styled/OpinionCard.style";
-
 import { solid } from "@fortawesome/fontawesome-svg-core/import.macro";
 import { dateConverter } from "../Util/dateConverter";
-
-function OpinionTree({ professor }) {
+import AuthApi from "../api/AuthApi";
+import { useNavigate } from "react-router-dom";
+import { useContext, useState } from "react";
+import {
+  Modal,
+  ModalContent,
+  ModalClose,
+  ModalHeader,
+  ModalBody,
+  ModalTextarea,
+  ModalFooter,
+} from "../Components/Styled/Modal.style";
+import axios from "../api/axios";
+
+function OpinionTree({ professor, user, userLoaded }) {
   var renderedOpinionIds = [];
   var postCount; // za da ne go pokazuva ispod postot
+
+  let navigate = useNavigate();
+  const { auth, setAuth } = useContext(AuthApi);
+
+  let [replyModalDisplay, setReplyModalDisplay] = useState("none");
+  const [replyContent, setReplyContent] = useState("");
+
+  const handleLike = () => {
+    if (auth) {
+      return;
+    } else {
+      navigate("/login");
+    }
+  };
+
+  const handleDislike = () => {
+    if (auth) {
+      return;
+    } else {
+      navigate("/login");
+    }
+  };
+
+  const handleReply = () => {
+    if (auth) {
+      setReplyModalDisplay("block");
+    } else {
+      navigate("/login");
+    }
+  };
+
+  const handleModalCloseClick = () => {
+    setReplyModalDisplay("none");
+  };
+
+  const handleContentChange = (e) => {
+    setReplyContent(e.target.value);
+  };
+
+  const handleReplySubmit = async (e, postId) => {
+    e.preventDefault();
+
+    const response = await axios(
+      `http://192.168.0.19:8080/secure/professor/${professor.professorId}/replyToOpinion/${postId}`,
+      {
+        method: "post",
+        data: {
+          content: replyContent,
+        },
+        withCredentials: true,
+      }
+    );
+
+    window.location.reload(false);
+    //console.log(response);
+  };
 
   function displayChildPosts(child, parentPostAuthorUsername, replyIndent) {
@@ -34,19 +102,26 @@
               )}
             </OpinionReplyCardContentTime>
-            <StyledFontAwesomeIcon
-              icon={solid("thumbs-up")}
-              right={50 + "px"}
-              color="greenyellow"
-            />
-            <StyledFontAwesomeIcon
-              icon={solid("thumbs-down")}
-              right={10 + "px"}
-              color="indianred"
-            />
-            <StyledFontAwesomeIcon
-              icon={solid("reply")}
-              right={90 + "px"}
-              color="black"
-            />
+            {auth && userLoaded && user.user.id !== child.author.id && (
+              <>
+                <StyledFontAwesomeIcon
+                  icon={solid("thumbs-up")}
+                  right={50 + "px"}
+                  color="greenyellow"
+                  onClick={handleLike}
+                />
+                <StyledFontAwesomeIcon
+                  icon={solid("thumbs-down")}
+                  right={10 + "px"}
+                  color="indianred"
+                  onClick={handleDislike}
+                />
+                <StyledFontAwesomeIcon
+                  icon={solid("reply")}
+                  right={90 + "px"}
+                  color="black"
+                  onClick={handleReply} //todo
+                />
+              </>
+            )}
           </OpinionReplyCardContent>
           {child.children.map((childOfChild) =>
@@ -69,4 +144,31 @@
           return (
             <div key={opinion.postId}>
+              <Modal display={replyModalDisplay}>
+                <ModalContent>
+                  <ModalHeader>
+                    <ModalClose onClick={handleModalCloseClick}>
+                      &times;
+                    </ModalClose>
+                    <h3 style={{ marginTop: "5px" }}>
+                      Реплика на {opinion.author.username}
+                    </h3>
+                  </ModalHeader>
+                  <form onSubmit={(e) => handleReplySubmit(e, opinion.postId)}>
+                    <ModalBody>
+                      <label htmlFor="content">
+                        <b>Содржина</b>:
+                        <ModalTextarea
+                          id="content"
+                          rows="8"
+                          cols="100"
+                          value={replyContent}
+                          onChange={handleContentChange}
+                        />
+                      </label>
+                    </ModalBody>
+                    <ModalFooter type="submit">РЕПЛИЦИРАЈ</ModalFooter>
+                  </form>
+                </ModalContent>
+              </Modal>
               <OpinionCard>
                 <OpinionCardContent>
@@ -83,19 +185,26 @@
                     )}
                   </OpinionCardContentTime>
-                  <StyledFontAwesomeIcon
-                    icon={solid("thumbs-up")}
-                    right={50 + "px"}
-                    color="greenyellow"
-                  />
-                  <StyledFontAwesomeIcon
-                    icon={solid("thumbs-down")}
-                    right={10 + "px"}
-                    color="indianred"
-                  />
-                  <StyledFontAwesomeIcon
-                    icon={solid("reply")}
-                    right={90 + "px"}
-                    color="black"
-                  />
+                  {auth && userLoaded && user.user.id !== opinion.author.id && (
+                    <>
+                      <StyledFontAwesomeIcon
+                        icon={solid("thumbs-up")}
+                        right={50 + "px"}
+                        color="greenyellow"
+                        onClick={handleLike}
+                      />
+                      <StyledFontAwesomeIcon
+                        icon={solid("thumbs-down")}
+                        right={10 + "px"}
+                        color="indianred"
+                        onClick={handleDislike}
+                      />
+                      <StyledFontAwesomeIcon
+                        icon={solid("reply")}
+                        right={90 + "px"}
+                        color="black"
+                        onClick={handleReply}
+                      />
+                    </>
+                  )}
                 </OpinionCardContent>
                 {opinion.children.map((child) =>
Index: reactapp/src/Components/Search.js
===================================================================
--- reactapp/src/Components/Search.js	(revision 702ca779afcdb48bcc15202ffc07dfb4be2efebd)
+++ reactapp/src/Components/Search.js	(revision 6221ab65b38aad2d2b041055cb1aa8825b624f00)
@@ -15,5 +15,5 @@
 
   useEffect(() => {
-    const url = `http://192.168.0.17:8080/public/professors/nameContains/${transliterate(
+    const url = `http://192.168.0.19:8080/public/professors/nameContains/${transliterate(
       query
     )}`;
Index: reactapp/src/Components/Styled/Modal.style.js
===================================================================
--- reactapp/src/Components/Styled/Modal.style.js	(revision 702ca779afcdb48bcc15202ffc07dfb4be2efebd)
+++ reactapp/src/Components/Styled/Modal.style.js	(revision 6221ab65b38aad2d2b041055cb1aa8825b624f00)
@@ -27,5 +27,5 @@
   top: 0;
   width: 100%;
-  height: 100%;
+  height: auto;
   overflow: auto;
   background-color: rgb(0, 0, 0);
@@ -47,5 +47,5 @@
   background-color: #fefefe;
   margin: 15% auto;
-  padding: 0;
+  padding: 20px;
   border: 1px solid #888;
   width: 80%;
@@ -72,8 +72,8 @@
   color: white;
   height: 40px;
-  margin-bottom: 10px;
+  margin-bottom: 30px;
 `;
 
-export const ModalFooter = styled.div`
+export const ModalFooter = styled.button`
   padding: 2px 16px;
   background-color: rgba(0, 102, 204, 1);
@@ -81,5 +81,5 @@
   color: white;
   height: 40px;
-  margin-top: 10px;
+  margin-top: 30px;
   transition: 0.4s;
   &:hover {
@@ -87,4 +87,9 @@
     cursor: pointer;
   }
+  font-family: "Roboto Mono", monospace;
+  width: 100%;
+  border: 0;
+  font-size: 18px;
+  font-weight: bold;
 `;
 
@@ -109,3 +114,4 @@
   padding: 12px 16px;
   border: 1px solid #ccc;
+  resize: none;
 `;
Index: reactapp/src/Components/Styled/OpinionCard.style.js
===================================================================
--- reactapp/src/Components/Styled/OpinionCard.style.js	(revision 702ca779afcdb48bcc15202ffc07dfb4be2efebd)
+++ reactapp/src/Components/Styled/OpinionCard.style.js	(revision 6221ab65b38aad2d2b041055cb1aa8825b624f00)
@@ -61,4 +61,5 @@
   &:hover {
     color: ${(props) => props.color};
+    cursor: pointer;
   }
 `;
Index: reactapp/src/Components/UserHeader.js
===================================================================
--- reactapp/src/Components/UserHeader.js	(revision 702ca779afcdb48bcc15202ffc07dfb4be2efebd)
+++ reactapp/src/Components/UserHeader.js	(revision 6221ab65b38aad2d2b041055cb1aa8825b624f00)
@@ -4,29 +4,6 @@
 import Logout from "./Logout";
 
-function UserHeader() {
-  const [user, setUser] = useState(null);
-  const [loaded, setLoaded] = useState(false);
-
-  useEffect(() => {
-    const fetchData = async () => {
-      try {
-        const response = await axios.get(
-          "http://192.168.0.17:8080/secure/currentUser",
-          { withCredentials: true }
-        );
-        var cyclicGraph = await response.data;
-        var jsogStructure = JSOG.encode(cyclicGraph);
-        cyclicGraph = JSOG.decode(jsogStructure);
-        setUser(cyclicGraph);
-        setLoaded(true);
-      } catch (error) {
-        console.log("Fetching error", error);
-      }
-    };
-
-    fetchData();
-  }, []);
-
-  return loaded ? (
+function UserHeader({ user, userLoaded }) {
+  return userLoaded ? (
     <div style={{ float: "left", marginTop: 20, marginLeft: 40 }}>
       Најавен/а: <a href="/user_dashboard">{user.username}</a> <Logout />{" "}
Index: reactapp/src/Pages/Home.js
===================================================================
--- reactapp/src/Pages/Home.js	(revision 702ca779afcdb48bcc15202ffc07dfb4be2efebd)
+++ reactapp/src/Pages/Home.js	(revision 6221ab65b38aad2d2b041055cb1aa8825b624f00)
@@ -6,5 +6,5 @@
 import AuthApi from "../api/AuthApi";
 
-function Home() {
+function Home({ user, userLoaded }) {
   const { auth, setAuth } = useContext(AuthApi);
 
@@ -24,5 +24,5 @@
       </a>{" "}
       <Search />
-      {auth && <UserHeader />}
+      {auth && <UserHeader user={user} userLoaded={userLoaded} />}
       <div style={{ marginTop: "140px" }}></div>
       <Outlet />
Index: reactapp/src/Pages/Professor.js
===================================================================
--- reactapp/src/Pages/Professor.js	(revision 702ca779afcdb48bcc15202ffc07dfb4be2efebd)
+++ reactapp/src/Pages/Professor.js	(revision 6221ab65b38aad2d2b041055cb1aa8825b624f00)
@@ -22,18 +22,19 @@
 import AuthApi from "../api/AuthApi";
 import { useNavigate } from "react-router-dom";
+import axios from "../api/axios";
 
-function Professor() {
+function Professor(user, userLoaded) {
   let params = useParams();
 
   let [professor, setProfessor] = useState(null);
   let [loaded, setLoaded] = useState(null);
-  let [modalDisplay, setModalDisplay] = useState("none");
+  let [postModalDisplay, setPostModalDisplay] = useState("none");
   let navigate = useNavigate();
   const { auth, setAuth } = useContext(AuthApi);
-  const [addPostTitle, setAddPostTitle] = useState("");
-  const [addPostContent, setAddPostContent] = useState("");
+  const [postTitle, setPostTitle] = useState("");
+  const [postContent, setPostContent] = useState("");
 
   useEffect(() => {
-    const url = `http://192.168.0.17:8080/public/professor/${params.professorId}`;
+    const url = `http://192.168.0.19:8080/public/professor/${params.professorId}`;
 
     const fetchData = async () => {
@@ -55,5 +56,5 @@
   const handleAddOpinionButtonClick = () => {
     if (auth) {
-      setModalDisplay("block");
+      setPostModalDisplay("block");
     } else {
       navigate("/login");
@@ -62,16 +63,31 @@
 
   const handleModalCloseClick = () => {
-    setModalDisplay("none");
-    console.log("here");
+    setPostModalDisplay("none");
   };
 
-  const handlePostSubmit = () => {};
+  const handlePostSubmit = async (e) => {
+    e.preventDefault();
+
+    const response = await axios(
+      `http://192.168.0.19:8080/secure/professor/${professor.professorId}/addOpinion`,
+      {
+        method: "post",
+        data: {
+          title: postTitle,
+          content: postContent,
+        },
+        withCredentials: true,
+      }
+    );
+
+    window.location.reload(false);
+  };
 
   const handleTitleChange = (e) => {
-    setAddPostTitle(e.target.value);
+    setPostTitle(e.target.value);
   };
 
   const handleContentChange = (e) => {
-    setAddPostContent(e.target.value);
+    setPostContent(e.target.value);
   };
 
@@ -100,10 +116,12 @@
             {professor.relatedOpinions.length !== 1 ? "мислења" : "мислење"}
           </h3>
-          <AddOpinionButton onClick={handleAddOpinionButtonClick}>
-            Објави мислење
-          </AddOpinionButton>
+          {auth && (
+            <AddOpinionButton onClick={handleAddOpinionButtonClick}>
+              Објави мислење
+            </AddOpinionButton>
+          )}
         </div>
 
-        <Modal display={modalDisplay}>
+        <Modal display={postModalDisplay}>
           <ModalContent>
             <ModalHeader>
@@ -113,16 +131,16 @@
               </h3>
             </ModalHeader>
-            <ModalBody>
-              <form onSubmit={handlePostSubmit}>
-                <label for="title">
+            <form onSubmit={handlePostSubmit}>
+              <ModalBody>
+                <label htmlFor="title">
                   <b>Наслов</b>:
                   <ModalInput
                     id="title"
                     type="text"
-                    value={addPostTitle}
+                    value={postTitle}
                     onChange={handleTitleChange}
                   />
                 </label>
-                <label for="content">
+                <label htmlFor="content">
                   <b>Содржина</b>:
                   <ModalTextarea
@@ -130,18 +148,20 @@
                     rows="8"
                     cols="100"
-                    value={addPostContent}
+                    value={postContent}
                     onChange={handleContentChange}
                   />
                 </label>
-              </form>
-            </ModalBody>
-            <ModalFooter>
-              <h2 style={{ textAlign: "center" }}>ОБЈАВИ</h2>
-            </ModalFooter>
+              </ModalBody>
+              <ModalFooter type="submit">ОБЈАВИ</ModalFooter>
+            </form>
           </ModalContent>
         </Modal>
 
         <div className="opinionTree">
-          <OpinionTree professor={professor} />
+          <OpinionTree
+            professor={professor}
+            user={user}
+            userLoaded={userLoaded}
+          />
         </div>
         <Outlet />
Index: reactapp/src/Pages/UserDashboard.js
===================================================================
--- reactapp/src/Pages/UserDashboard.js	(revision 702ca779afcdb48bcc15202ffc07dfb4be2efebd)
+++ reactapp/src/Pages/UserDashboard.js	(revision 6221ab65b38aad2d2b041055cb1aa8825b624f00)
@@ -1,5 +1,3 @@
-import React, { useState, useEffect } from "react";
-import JSOG from "jsog";
-import axios from "../api/axios";
+import React, { useEffect } from "react";
 import {
   OpinionCard,
@@ -14,29 +12,13 @@
 import { dateConverter } from "../Util/dateConverter";
 
-function UserDashboard() {
-  const [user, setUser] = useState(null);
-  const [loaded, setLoaded] = useState(false);
-
+function UserDashboard({ user, userLoaded }) {
   useEffect(() => {
-    const fetchData = async () => {
-      try {
-        const response = await axios.get(
-          "http://192.168.0.17:8080/secure/currentUser",
-          { withCredentials: true }
-        );
-        var cyclicGraph = await response.data;
-        var jsogStructure = JSOG.encode(cyclicGraph);
-        cyclicGraph = JSOG.decode(jsogStructure);
-        setUser(cyclicGraph);
-        setLoaded(true);
-      } catch (error) {
-        console.log("Fetching error", error);
-      }
-    };
-
-    fetchData();
+    const timer = setTimeout(() => {
+      if (user === null) window.location.reload(false);
+    }, 3000);
+    return () => clearTimeout(timer);
   }, []);
 
-  return loaded ? (
+  return userLoaded ? (
     <>
       <h3>Кориснички податоци:</h3>
Index: reactapp/src/api/axios.js
===================================================================
--- reactapp/src/api/axios.js	(revision 702ca779afcdb48bcc15202ffc07dfb4be2efebd)
+++ reactapp/src/api/axios.js	(revision 6221ab65b38aad2d2b041055cb1aa8825b624f00)
@@ -2,4 +2,4 @@
 
 export default axios.create({
-  baseURL: "http://192.168.0.17:8080",
+  baseURL: "http://192.168.0.19:8080",
 });
Index: springapp/src/main/java/mk/profesori/springapp/Controller/PublicController.java
===================================================================
--- springapp/src/main/java/mk/profesori/springapp/Controller/PublicController.java	(revision 702ca779afcdb48bcc15202ffc07dfb4be2efebd)
+++ springapp/src/main/java/mk/profesori/springapp/Controller/PublicController.java	(revision 6221ab65b38aad2d2b041055cb1aa8825b624f00)
@@ -23,5 +23,5 @@
 @RestController
 @RequestMapping("/public")
-@CrossOrigin(origins = { "http://192.168.0.17:3000", "http://192.168.0.24:3000" })
+@CrossOrigin(origins = { "http://192.168.0.19:3000", "http://192.168.0.24:3000" })
 public class PublicController {
 
Index: springapp/src/main/java/mk/profesori/springapp/Controller/SecureController.java
===================================================================
--- springapp/src/main/java/mk/profesori/springapp/Controller/SecureController.java	(revision 702ca779afcdb48bcc15202ffc07dfb4be2efebd)
+++ springapp/src/main/java/mk/profesori/springapp/Controller/SecureController.java	(revision 6221ab65b38aad2d2b041055cb1aa8825b624f00)
@@ -25,5 +25,5 @@
 @RestController
 @RequestMapping("/secure")
-@CrossOrigin(origins = { "http://192.168.0.17:3000", "http://192.168.0.24:3000" })
+@CrossOrigin(origins = { "http://192.168.0.19:3000", "http://192.168.0.24:3000" })
 public class SecureController {
 
Index: springapp/src/main/java/mk/profesori/springapp/Security/SecurityConfiguration.java
===================================================================
--- springapp/src/main/java/mk/profesori/springapp/Security/SecurityConfiguration.java	(revision 702ca779afcdb48bcc15202ffc07dfb4be2efebd)
+++ springapp/src/main/java/mk/profesori/springapp/Security/SecurityConfiguration.java	(revision 6221ab65b38aad2d2b041055cb1aa8825b624f00)
@@ -37,5 +37,5 @@
             @Override
             public void addCorsMappings(CorsRegistry registry) {
-                registry.addMapping("/**").allowedOrigins("http://192.168.0.17:3000", "http://192.168.0.24:3000")
+                registry.addMapping("/**").allowedOrigins("http://192.168.0.19:3000", "http://192.168.0.24:3000")
                         .allowCredentials(true);
             }
Index: springapp/src/main/java/mk/profesori/springapp/Service/RegistrationService.java
===================================================================
--- springapp/src/main/java/mk/profesori/springapp/Service/RegistrationService.java	(revision 702ca779afcdb48bcc15202ffc07dfb4be2efebd)
+++ springapp/src/main/java/mk/profesori/springapp/Service/RegistrationService.java	(revision 6221ab65b38aad2d2b041055cb1aa8825b624f00)
@@ -45,5 +45,5 @@
                 String tokenToResend = customUserDetailsService
                         .createToken(userRepository.findByEmail(request.getEmail()).get());
-                String link = "http://192.168.0.17:8080/registration/confirm?token=" + tokenToResend;
+                String link = "http://192.168.0.19:8080/registration/confirm?token=" + tokenToResend;
                 emailSender.send(request.getEmail(), emailSender.buildEmail(request.getUsername(), link));
                 return tokenToResend;
@@ -66,5 +66,5 @@
                         UserRole.REGULAR));
 
-        String link = "http://192.168.0.17:8080/registration/confirm?token=" + token;
+        String link = "http://192.168.0.19:8080/registration/confirm?token=" + token;
 
         emailSender.send(request.getEmail(), emailSender.buildEmail(request.getUsername(), link));
Index: springapp/src/main/resources/application.properties
===================================================================
--- springapp/src/main/resources/application.properties	(revision 702ca779afcdb48bcc15202ffc07dfb4be2efebd)
+++ springapp/src/main/resources/application.properties	(revision 6221ab65b38aad2d2b041055cb1aa8825b624f00)
@@ -7,5 +7,5 @@
 spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
 spring.jpa.properties.hibernate.format_sql=true
-server.address=192.168.0.17
+server.address=192.168.0.19
 spring.mail.host=192.168.0.24
 spring.mail.username=mailuser
