Changeset 702ca77


Ignore:
Timestamp:
08/19/22 19:10:24 (2 years ago)
Author:
unknown <mlviktor23@…>
Branches:
main
Children:
6221ab6
Parents:
6eba109
Message:

added current user/logout in header, display karma on user dashboard, started add post functionality in react

Files:
4 added
1 deleted
15 edited

Legend:

Unmodified
Added
Removed
  • reactapp/src/App.js

    r6eba109 r702ca77  
    44import { BrowserRouter, Routes, Route, Navigate } from "react-router-dom";
    55import Home from "./Pages/Home";
    6 import User from "./Pages/User";
     6import UserDashboard from "./Pages/UserDashboard";
    77import { useEffect, useState, useMemo } from "react";
    88import AuthApi from "./api/AuthApi";
     
    1212  const [auth, setAuth] = useState(false);
    1313  const variableAuth = useMemo(() => ({ auth, setAuth }), [auth]);
     14  const [authLoaded, setAuthLoaded] = useState(false);
    1415
    15   const readCookie = () => {
     16  const readCookie = async () => {
    1617    const session = Cookies.get("JSESSIONID");
    1718    if (session) {
    1819      setAuth(true); // go stava true ako postoi takvo cookie (zasto auth=false na sekoe renderiranje)
     20    } else {
     21      setAuth(false);
    1922    }
     23    setAuthLoaded(true);
    2024  };
    2125
     
    2529
    2630  const ProtectedRoute = ({ auth, children }) => {
    27     if (!auth) {
    28       return <Navigate to="/login" replace />;
     31    if (authLoaded) {
     32      if (!auth) {
     33        return <Navigate to="/login" replace />;
     34      }
     35      return children;
     36    } else {
     37      return <div>се вчитува cookie...</div>;
    2938    }
    30     return children;
    3139  };
    3240
     
    4250            <Route path="search" element={<SearchResults />}></Route>
    4351            <Route
    44               path="user"
     52              path="user_dashboard"
    4553              element={
    4654                <ProtectedRoute auth={auth}>
    47                   <User />
     55                  <UserDashboard />
    4856                </ProtectedRoute>
    4957              }
  • reactapp/src/Components/Logout.js

    r6eba109 r702ca77  
    22import AuthApi from "../api/AuthApi";
    33import Cookies from "js-cookie";
     4import { LogoutButton } from "./Styled/UserDetails.style";
     5import { Navigate } from "react-router-dom";
    46
    57function Logout() {
     
    1113  };
    1214
    13   return <button onClick={handleLogout}>Одјави се</button>;
     15  return <LogoutButton onClick={handleLogout}>Одјави се</LogoutButton>;
    1416}
    1517
  • reactapp/src/Components/Search.js

    r6eba109 r702ca77  
    1515
    1616  useEffect(() => {
    17     const url = `http://192.168.0.18:8080/public/professors/nameContains/${transliterate(
     17    const url = `http://192.168.0.17:8080/public/professors/nameContains/${transliterate(
    1818      query
    1919    )}`;
     
    2323        const response = await fetch(url);
    2424        var cyclicGraph = await response.json();
    25         var jsogStructure = JSOG.encode(cyclicGraph); // has { '@ref': 'ID' } links instead of cycles
     25        var jsogStructure = JSOG.encode(cyclicGraph);
    2626        cyclicGraph = JSOG.decode(jsogStructure);
    2727        setProfessors(cyclicGraph);
    28         //setLoaded(true);
    2928      } catch (error) {
    30         console.log("Fetching error occured", error);
     29        console.log("Fetching error", error);
    3130      }
    3231    };
  • reactapp/src/Components/Styled/Main.style.js

    r6eba109 r702ca77  
    66  margin: auto;
    77  margin-top: 20px;
     8  margin-bottom: 20px;
    89  padding-left: 50px;
    910  padding-right: 50px;
  • reactapp/src/Components/Styled/Search.style.js

    r6eba109 r702ca77  
    3030  &:hover {
    3131    background-color: papayawhip;
    32     border: 1px solid blue;
    33     text-decoration: underline 1px blue;
     32    border: 1px solid #0066cc;
     33    text-decoration: underline 1px #0066cc;
    3434  }
    3535  padding: 10px;
  • reactapp/src/Pages/Home.js

    r6eba109 r702ca77  
    1 import React from "react";
     1import React, { useContext } from "react";
    22import { MainWrapper, MainTitle } from "../Components/Styled/Main.style";
    33import { Outlet } from "react-router-dom";
    44import Search from "../Components/Search";
     5import UserHeader from "../Components/UserHeader";
     6import AuthApi from "../api/AuthApi";
    57
    68function Home() {
     9  const { auth, setAuth } = useContext(AuthApi);
     10
    711  return (
    812    <MainWrapper>
     
    2024      </a>{" "}
    2125      <Search />
     26      {auth && <UserHeader />}
    2227      <div style={{ marginTop: "140px" }}></div>
    2328      <Outlet />
  • reactapp/src/Pages/Login.js

    r6eba109 r702ca77  
    4545  };
    4646
    47   const handleLogout = () => {
    48     setAuth(false);
    49     Cookies.remove("JSESSIONID");
    50   };
    51 
    5247  return auth ? (
    53     /*
    54     <div style={{ marginTop: "140px" }}>
    55       <h1>Успешна најава!</h1>
    56       <br />
    57       <p>
    58         <a href="/user">Оди на protected</a>
    59       </p>
    60       <button onClick={handleLogout}>Одјави се</button>
    61     </div>
    62     */
    63     <Navigate to="/user" />
     48    <Navigate to="/user_dashboard" />
    6449  ) : (
    6550    <div style={{ marginTop: "140px" }}>
  • reactapp/src/Pages/Professor.js

    r6eba109 r702ca77  
    1 import React, { useEffect, useState } from "react";
     1import React, { useEffect, useState, useContext } from "react";
    22import { Outlet, useParams } from "react-router-dom";
    33import JSOG from "jsog";
    44import OpinionTree from "../Components/OpinionTree";
    5 
     5import {
     6  AddOpinionButton,
     7  Modal,
     8  ModalContent,
     9  ModalClose,
     10  ModalHeader,
     11  ModalBody,
     12  ModalInput,
     13  ModalTextarea,
     14  ModalFooter,
     15} from "../Components/Styled/Modal.style";
    616import {
    717  ProfessorCard,
     
    1020  ProfessorCardSeparator,
    1121} from "../Components/Styled/ProfessorCard.style";
     22import AuthApi from "../api/AuthApi";
     23import { useNavigate } from "react-router-dom";
    1224
    13 function Professor(props) {
     25function Professor() {
    1426  let params = useParams();
    1527
    1628  let [professor, setProfessor] = useState(null);
    1729  let [loaded, setLoaded] = useState(null);
     30  let [modalDisplay, setModalDisplay] = useState("none");
     31  let navigate = useNavigate();
     32  const { auth, setAuth } = useContext(AuthApi);
     33  const [addPostTitle, setAddPostTitle] = useState("");
     34  const [addPostContent, setAddPostContent] = useState("");
    1835
    1936  useEffect(() => {
    20     const url = `http://192.168.0.18:8080/public/professor/${params.professorId}`;
     37    const url = `http://192.168.0.17:8080/public/professor/${params.professorId}`;
    2138
    2239    const fetchData = async () => {
     
    2441        const response = await fetch(url);
    2542        var cyclicGraph = await response.json();
    26         var jsogStructure = JSOG.encode(cyclicGraph); // has { '@ref': 'ID' } links instead of cycles
     43        var jsogStructure = JSOG.encode(cyclicGraph);
    2744        cyclicGraph = JSOG.decode(jsogStructure);
    2845        setProfessor(cyclicGraph);
    2946        setLoaded(true);
    3047      } catch (error) {
    31         console.log("Error", error);
     48        console.log("Fetching error", error);
    3249      }
    3350    };
     
    3552    fetchData();
    3653  }, [params.professorId]);
     54
     55  const handleAddOpinionButtonClick = () => {
     56    if (auth) {
     57      setModalDisplay("block");
     58    } else {
     59      navigate("/login");
     60    }
     61  };
     62
     63  const handleModalCloseClick = () => {
     64    setModalDisplay("none");
     65    console.log("here");
     66  };
     67
     68  const handlePostSubmit = () => {};
     69
     70  const handleTitleChange = (e) => {
     71    setAddPostTitle(e.target.value);
     72  };
     73
     74  const handleContentChange = (e) => {
     75    setAddPostContent(e.target.value);
     76  };
    3777
    3878  if (loaded) {
     
    5191          </div>
    5292        </ProfessorCard>
    53         <h3 style={{ marginBottom: "10px" }}>
    54           {professor.relatedOpinions.length}{" "}
    55           {professor.relatedOpinions.length !== 1 ? "мислења" : "мислење"}
    56         </h3>
     93        <div style={{ height: "20px", marginBottom: "30px" }}>
     94          <h3
     95            style={{
     96              float: "left",
     97            }}
     98          >
     99            {professor.relatedOpinions.length}{" "}
     100            {professor.relatedOpinions.length !== 1 ? "мислења" : "мислење"}
     101          </h3>
     102          <AddOpinionButton onClick={handleAddOpinionButtonClick}>
     103            Објави мислење
     104          </AddOpinionButton>
     105        </div>
     106
     107        <Modal display={modalDisplay}>
     108          <ModalContent>
     109            <ModalHeader>
     110              <ModalClose onClick={handleModalCloseClick}>&times;</ModalClose>
     111              <h3 style={{ marginTop: "5px" }}>
     112                Мислење за {professor.professorName}
     113              </h3>
     114            </ModalHeader>
     115            <ModalBody>
     116              <form onSubmit={handlePostSubmit}>
     117                <label for="title">
     118                  <b>Наслов</b>:
     119                  <ModalInput
     120                    id="title"
     121                    type="text"
     122                    value={addPostTitle}
     123                    onChange={handleTitleChange}
     124                  />
     125                </label>
     126                <label for="content">
     127                  <b>Содржина</b>:
     128                  <ModalTextarea
     129                    id="content"
     130                    rows="8"
     131                    cols="100"
     132                    value={addPostContent}
     133                    onChange={handleContentChange}
     134                  />
     135                </label>
     136              </form>
     137            </ModalBody>
     138            <ModalFooter>
     139              <h2 style={{ textAlign: "center" }}>ОБЈАВИ</h2>
     140            </ModalFooter>
     141          </ModalContent>
     142        </Modal>
     143
    57144        <div className="opinionTree">
    58145          <OpinionTree professor={professor} />
  • reactapp/src/api/axios.js

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

    r6eba109 r702ca77  
    2323@RestController
    2424@RequestMapping("/public")
    25 @CrossOrigin(origins = { "http://192.168.0.18:3000", "http://192.168.0.24:3000" })
     25@CrossOrigin(origins = { "http://192.168.0.17:3000", "http://192.168.0.24:3000" })
    2626public class PublicController {
    2727
  • springapp/src/main/java/mk/profesori/springapp/Controller/SecureController.java

    r6eba109 r702ca77  
    2525@RestController
    2626@RequestMapping("/secure")
    27 @CrossOrigin(origins = { "http://192.168.0.18:3000", "http://192.168.0.24:3000" })
     27@CrossOrigin(origins = { "http://192.168.0.17:3000", "http://192.168.0.24:3000" })
    2828public class SecureController {
    2929
     
    6060    }
    6161
    62     @RequestMapping(value = "/user", method = RequestMethod.GET)
     62    @RequestMapping(value = "/currentUser", method = RequestMethod.GET)
    6363    public UserDetails getUserDetails(@CurrentSecurityContext SecurityContext context) {
    6464
  • springapp/src/main/java/mk/profesori/springapp/Model/CustomUserDetails.java

    r6eba109 r702ca77  
    5454    @OneToMany(mappedBy = "author", cascade = CascadeType.ALL)
    5555    private Set<Post> authoredPosts = new HashSet<>();
     56    private Integer karma;
    5657
    5758    public CustomUserDetails(String fullName, String username, String email, String password, UserRole userRole) {
     
    103104    }
    104105
     106    public Integer getKarma() {
     107        Integer karma = 0;
     108        for (Post post : this.authoredPosts) {
     109            karma += post.getUpvoteCount() - post.getDownvoteCount();
     110        }
     111        return karma;
     112    }
     113
    105114}
  • springapp/src/main/java/mk/profesori/springapp/Security/SecurityConfiguration.java

    r6eba109 r702ca77  
    3737            @Override
    3838            public void addCorsMappings(CorsRegistry registry) {
    39                 registry.addMapping("/**").allowedOrigins("http://192.168.0.18:3000", "http://192.168.0.24:3000")
     39                registry.addMapping("/**").allowedOrigins("http://192.168.0.17:3000", "http://192.168.0.24:3000")
    4040                        .allowCredentials(true);
    4141            }
  • springapp/src/main/java/mk/profesori/springapp/Service/RegistrationService.java

    r6eba109 r702ca77  
    4545                String tokenToResend = customUserDetailsService
    4646                        .createToken(userRepository.findByEmail(request.getEmail()).get());
    47                 String link = "http://192.168.0.18:8080/registration/confirm?token=" + tokenToResend;
     47                String link = "http://192.168.0.17: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.18:8080/registration/confirm?token=" + token;
     68        String link = "http://192.168.0.17:8080/registration/confirm?token=" + token;
    6969
    7070        emailSender.send(request.getEmail(), emailSender.buildEmail(request.getUsername(), link));
  • springapp/src/main/resources/application.properties

    r6eba109 r702ca77  
    77spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
    88spring.jpa.properties.hibernate.format_sql=true
    9 server.address=192.168.0.18
     9server.address=192.168.0.17
    1010spring.mail.host=192.168.0.24
    1111spring.mail.username=mailuser
Note: See TracChangeset for help on using the changeset viewer.