Changeset 62b653f


Ignore:
Timestamp:
08/30/22 15:33:18 (22 months ago)
Author:
unknown <mlviktor23@…>
Branches:
main
Children:
cae16b5
Parents:
2fcbde4
Message:

implemented upvote/downvote func. in react

Files:
17 edited

Legend:

Unmodified
Added
Removed
  • reactapp/src/App.js

    r2fcbde4 r62b653f  
    2121    try {
    2222      const response = await axios.get(
    23         "http://192.168.0.19:8080/secure/currentUser",
     23        "http://192.168.0.17:8080/secure/currentUser",
    2424        { withCredentials: true }
    2525      );
  • reactapp/src/Components/OpinionTree.js

    r2fcbde4 r62b653f  
    88  OpinionReplyCardContentTime,
    99  StyledFontAwesomeIcon,
     10  VoteCount,
    1011} from "./Styled/OpinionCard.style";
    1112import { solid } from "@fortawesome/fontawesome-svg-core/import.macro";
     
    3738  const [postForModal, setPostForModal] = useState(null);
    3839
    39   const handleLike = () => {
    40     if (auth) {
     40  const handleLike = async (post) => {
     41    if (
     42      auth &&
     43      userLoaded &&
     44      !post.likes.some((e) => e.id === user.user.id) &&
     45      !post.dislikes.some((e) => e.id === user.user.id)
     46    ) {
     47      const response = await axios(
     48        `http://192.168.0.17:8080/secure/professor/${professor.professorId}/upvoteOpinion/${post.postId}`,
     49        {
     50          method: "get",
     51          withCredentials: true,
     52        }
     53      );
     54
     55      window.location.reload(false);
     56    } else {
    4157      return;
     58    }
     59  };
     60
     61  const handleDislike = async (post) => {
     62    if (
     63      auth &&
     64      auth &&
     65      userLoaded &&
     66      !post.likes.some((e) => e.id === user.user.id) &&
     67      !post.dislikes.some((e) => e.id === user.user.id)
     68    ) {
     69      const response = await axios(
     70        `http://192.168.0.17:8080/secure/professor/${professor.professorId}/downvoteOpinion/${post.postId}`,
     71        {
     72          method: "get",
     73          withCredentials: true,
     74        }
     75      );
     76
     77      window.location.reload(false);
    4278    } else {
    43       navigate("/login");
    44     }
    45   };
    46 
    47   const handleDislike = () => {
    48     if (auth) {
    4979      return;
    50     } else {
    51       navigate("/login");
    5280    }
    5381  };
     
    74102
    75103    const response = await axios(
    76       `http://192.168.0.19:8080/secure/professor/${professor.professorId}/replyToOpinion/${postId}`,
     104      `http://192.168.0.17:8080/secure/professor/${professor.professorId}/replyToOpinion/${postId}`,
    77105      {
    78106        method: "post",
     
    110138                  icon={solid("thumbs-up")}
    111139                  right={50 + "px"}
    112                   color="greenyellow"
    113                   onClick={handleLike}
     140                  color={
     141                    child.likes.some((e) => e.id === user.user.id)
     142                      ? "greenyellow"
     143                      : "darkgrey"
     144                  }
     145                  onClick={() => handleLike(child)}
    114146                />
     147                <VoteCount right={50 + "px"}>{child.likes.length}</VoteCount>
    115148                <StyledFontAwesomeIcon
    116149                  icon={solid("thumbs-down")}
    117150                  right={10 + "px"}
    118                   color="indianred"
    119                   onClick={handleDislike}
     151                  color={
     152                    child.dislikes.some((e) => e.id === user.user.id)
     153                      ? "indianred"
     154                      : "darkgrey"
     155                  }
     156                  onClick={() => handleDislike(child)}
    120157                />
     158                <VoteCount right={10 + "px"}>{child.dislikes.length}</VoteCount>
    121159                <StyledFontAwesomeIcon
    122160                  icon={solid("reply")}
    123161                  right={90 + "px"}
    124                   color="black"
     162                  color="darkgrey"
    125163                  onClick={() => handleReply(child)}
    126164                />
     
    166204                        icon={solid("thumbs-up")}
    167205                        right={50 + "px"}
    168                         color="greenyellow"
    169                         onClick={handleLike}
     206                        color={
     207                          opinion.likes.some((e) => e.id === user.user.id)
     208                            ? "greenyellow"
     209                            : "darkgrey"
     210                        }
     211                        onClick={() => handleLike(opinion)}
    170212                      />
     213                      <VoteCount right={50 + "px"}>
     214                        {opinion.likes.length}
     215                      </VoteCount>
    171216                      <StyledFontAwesomeIcon
    172217                        icon={solid("thumbs-down")}
    173218                        right={10 + "px"}
    174                         color="indianred"
    175                         onClick={handleDislike}
     219                        color={
     220                          opinion.dislikes.some((e) => e.id === user.user.id)
     221                            ? "indianred"
     222                            : "darkgrey"
     223                        }
     224                        onClick={() => handleDislike(opinion)}
    176225                      />
     226                      <VoteCount right={10 + "px"}>
     227                        {opinion.dislikes.length}
     228                      </VoteCount>
    177229                      <StyledFontAwesomeIcon
    178230                        icon={solid("reply")}
    179231                        right={90 + "px"}
    180                         color="black"
     232                        color="darkgrey"
    181233                        onClick={() => handleReply(opinion)}
    182234                      />
  • reactapp/src/Components/Search.js

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

    r2fcbde4 r62b653f  
    5252
    5353export const StyledFontAwesomeIcon = styled(FontAwesomeIcon)`
    54   color: darkgrey;
     54  color: ${(props) => props.color};
    5555  display: block;
    5656  position: absolute;
     
    6464  }
    6565`;
     66
     67export const VoteCount = styled.p`
     68  color: darkgrey;
     69  display: block;
     70  position: absolute;
     71  top: 80%;
     72  transform: translateY(-50%);
     73  right: ${(props) => props.right};
     74  transition: 0.5s;
     75`;
  • reactapp/src/Pages/Professor.js

    r2fcbde4 r62b653f  
    3636
    3737  useEffect(() => {
    38     const url = `http://192.168.0.19:8080/public/professor/${params.professorId}`;
     38    const url = `http://192.168.0.17:8080/public/professor/${params.professorId}`;
    3939
    4040    const fetchData = async () => {
     
    7070
    7171    const response = await axios(
    72       `http://192.168.0.19:8080/secure/professor/${professor.professorId}/addOpinion`,
     72      `http://192.168.0.17:8080/secure/professor/${professor.professorId}/addOpinion`,
    7373      {
    7474        method: "post",
  • reactapp/src/api/axios.js

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

    r2fcbde4 r62b653f  
    2323@RestController
    2424@RequestMapping("/public")
    25 @CrossOrigin(origins = { "http://192.168.0.19: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

    r2fcbde4 r62b653f  
    2525@RestController
    2626@RequestMapping("/secure")
    27 @CrossOrigin(origins = { "http://192.168.0.19: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
     
    7272    }
    7373
     74    @RequestMapping(value = "/professor/{professorId}/upvoteOpinion/{postId}", method = RequestMethod.GET)
     75    public void upvoteOpinion(@PathVariable Long professorId,
     76            @PathVariable Long postId, @CurrentSecurityContext SecurityContext context) {
     77
     78        Authentication authentication = context.getAuthentication();
     79
     80        if (authentication != null && authentication.getPrincipal() instanceof CustomUserDetails) {
     81            CustomUserDetails currentUser = (CustomUserDetails) authentication.getPrincipal();
     82            mainService.upvoteOpinion(postId, currentUser);
     83        }
     84    }
     85
     86    @RequestMapping(value = "/professor/{professorId}/downvoteOpinion/{postId}", method = RequestMethod.GET)
     87    public void downvoteOpinion(@PathVariable Long professorId,
     88            @PathVariable Long postId, @CurrentSecurityContext SecurityContext context) {
     89
     90        Authentication authentication = context.getAuthentication();
     91
     92        if (authentication != null && authentication.getPrincipal() instanceof CustomUserDetails) {
     93            CustomUserDetails currentUser = (CustomUserDetails) authentication.getPrincipal();
     94            mainService.downvoteOpinion(postId, currentUser);
     95        }
     96    }
     97
    7498}
  • springapp/src/main/java/mk/profesori/springapp/Model/CustomUserDetails.java

    r2fcbde4 r62b653f  
    1212import javax.persistence.EnumType;
    1313import javax.persistence.Enumerated;
     14import javax.persistence.FetchType;
    1415import javax.persistence.GeneratedValue;
    1516import javax.persistence.GenerationType;
    1617import javax.persistence.Id;
     18import javax.persistence.JoinTable;
     19import javax.persistence.JoinColumn;
     20import javax.persistence.ManyToMany;
    1721import javax.persistence.OneToMany;
    1822import javax.persistence.SequenceGenerator;
     
    5054    private Boolean locked = false;
    5155    private Boolean enabled = false;
    52     @OneToMany(mappedBy = "customUserDetails", cascade = CascadeType.ALL)
     56    @OneToMany(mappedBy = "customUserDetails", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
    5357    private Set<ConfirmationToken> confirmationTokens = new HashSet<>();
    54     @OneToMany(mappedBy = "author", cascade = CascadeType.ALL)
     58    @OneToMany(mappedBy = "author", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
    5559    private Set<Post> authoredPosts = new HashSet<>();
    56     private Integer karma;
     60    private Integer karma = 0;
     61    @ManyToMany(fetch = FetchType.EAGER)
     62    @JoinTable(name = "post_like", joinColumns = @JoinColumn(name = "custom_user_details_id"), inverseJoinColumns = @JoinColumn(name = "post_id"))
     63    Set<Post> likedPosts;
     64    @ManyToMany(fetch = FetchType.EAGER)
     65    @JoinTable(name = "post_dislike", joinColumns = @JoinColumn(name = "custom_user_details_id"), inverseJoinColumns = @JoinColumn(name = "post_id"))
     66    Set<Post> dislikedPosts;
    5767
    5868    public CustomUserDetails(String fullName, String username, String email, String password, UserRole userRole) {
     
    105115
    106116    public Integer getKarma() {
    107         Integer karma = 0;
    108         for (Post post : this.authoredPosts) {
    109             karma += post.getUpvoteCount() - post.getDownvoteCount();
    110         }
    111         return karma;
     117        return this.karma;
    112118    }
    113119
     120    public void setKarma(Integer karma) {
     121        this.karma = karma;
     122    }
     123
     124    public Set<Post> getLikedPosts() {
     125        return this.likedPosts;
     126    }
     127
     128    public void setLikedPosts(Set<Post> likedPosts) {
     129        this.likedPosts = likedPosts;
     130    }
     131
     132    public Set<Post> getDislikedPosts() {
     133        return this.dislikedPosts;
     134    }
     135
     136    public void setDislikedPosts(Set<Post> dislikedPosts) {
     137        this.likedPosts = dislikedPosts;
     138    }
    114139}
  • springapp/src/main/java/mk/profesori/springapp/Model/Opinion.java

    r2fcbde4 r62b653f  
    2323    public Opinion(String title, String content, CustomUserDetails author, LocalDateTime timePosted,
    2424            LocalDateTime timeLastEdited,
    25             Integer upvoteCount, Integer downvoteCount, Post parent, List<Post> children, Professor targetProfessor) {
    26         super(title, content, author, timePosted, timeLastEdited, upvoteCount, downvoteCount, parent, children);
     25            Post parent, List<Post> children, Professor targetProfessor) {
     26        super(title, content, author, timePosted, timeLastEdited, parent, children);
    2727        this.targetProfessor = targetProfessor;
    2828    }
     
    3131    public Opinion(String title, String content, CustomUserDetails author, LocalDateTime timePosted,
    3232            LocalDateTime timeLastEdited,
    33             Integer upvoteCount, Integer downvoteCount, List<Post> children, Professor targetProfessor) {
    34         super(title, content, author, timePosted, timeLastEdited, upvoteCount, downvoteCount, children);
     33            List<Post> children, Professor targetProfessor) {
     34        super(title, content, author, timePosted, timeLastEdited, children);
    3535        this.targetProfessor = targetProfessor;
    3636    }
  • springapp/src/main/java/mk/profesori/springapp/Model/Post.java

    r2fcbde4 r62b653f  
    44import java.util.ArrayList;
    55import java.util.List;
     6import java.util.Set;
    67
    78import javax.persistence.CascadeType;
     
    1617import javax.persistence.InheritanceType;
    1718import javax.persistence.JoinColumn;
     19import javax.persistence.ManyToMany;
    1820import javax.persistence.ManyToOne;
    1921import javax.persistence.OneToMany;
     
    5254    private LocalDateTime timeLastEdited;
    5355
    54     @Column(name = "upvote_count")
    55     private Integer upvoteCount;
    56 
    57     @Column(name = "downvote_count")
    58     private Integer downvoteCount;
    59 
    6056    @ManyToOne
    6157    @JoinColumn(name = "parent_post_id", nullable = true)
     
    6460    @OneToMany(mappedBy = "parent", cascade = CascadeType.ALL)
    6561    private List<Post> children = new ArrayList<>();
     62
     63    @ManyToMany(mappedBy = "likedPosts")
     64    Set<CustomUserDetails> likes;
     65
     66    @ManyToMany(mappedBy = "dislikedPosts")
     67    Set<CustomUserDetails> dislikes;
    6668
    6769    // getters and setters
     
    114116    }
    115117
    116     public Integer getUpvoteCount() {
    117         return upvoteCount;
    118     }
    119 
    120     public void setUpvoteCount(Integer upvoteCount) {
    121         this.upvoteCount = upvoteCount;
    122     }
    123 
    124     public Integer getDownvoteCount() {
    125         return downvoteCount;
    126     }
    127 
    128     public void setDownvoteCount(Integer downvoteCount) {
    129         this.downvoteCount = downvoteCount;
    130     }
    131 
    132118    public Post getParent() {
    133119        return parent;
     
    146132    }
    147133
     134    public Set<CustomUserDetails> getLikes() {
     135        return likes;
     136    }
     137
     138    public void setLikes(Set<CustomUserDetails> likes) {
     139        this.likes = likes;
     140    }
     141
     142    public Set<CustomUserDetails> getDislikes() {
     143        return dislikes;
     144    }
     145
     146    public void setDislikes(Set<CustomUserDetails> dislikes) {
     147        this.dislikes = dislikes;
     148    }
     149
    148150    // konstruktor so parent (koga e reply)
    149151    public Post(String title, String content, CustomUserDetails author, LocalDateTime timePosted,
    150152            LocalDateTime timeLastEdited,
    151             Integer upvoteCount, Integer downvoteCount, Post parent, List<Post> children) {
     153            Post parent, List<Post> children) {
    152154        this.title = title;
    153155        this.content = content;
     
    155157        this.timePosted = LocalDateTime.now();
    156158        this.timeLastEdited = LocalDateTime.now();
    157         this.upvoteCount = 0;
    158         this.downvoteCount = 0;
    159159        this.parent = parent;
    160160        this.children = new ArrayList<>();
     
    164164    public Post(String title, String content, CustomUserDetails author, LocalDateTime timePosted,
    165165            LocalDateTime timeLastEdited,
    166             Integer upvoteCount, Integer downvoteCount, List<Post> children) {
     166            List<Post> children) {
    167167        this.title = title;
    168168        this.content = content;
     
    170170        this.timePosted = LocalDateTime.now();
    171171        this.timeLastEdited = LocalDateTime.now();
    172         this.upvoteCount = 0;
    173         this.downvoteCount = 0;
    174172        this.parent = null;
    175173        this.children = new ArrayList<>();
  • springapp/src/main/java/mk/profesori/springapp/Security/SecurityConfiguration.java

    r2fcbde4 r62b653f  
    3737            @Override
    3838            public void addCorsMappings(CorsRegistry registry) {
    39                 registry.addMapping("/**").allowedOrigins("http://192.168.0.19: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/ConfirmationTokenService.java

    r2fcbde4 r62b653f  
    1313@AllArgsConstructor
    1414public class ConfirmationTokenService {
    15    
     15
    1616    private final ConfirmationTokenRepository confirmationTokenRepository;
    1717
  • springapp/src/main/java/mk/profesori/springapp/Service/CustomUserDetailsService.java

    r2fcbde4 r62b653f  
    2222
    2323    private final UserRepository userRepository;
     24
    2425    @Autowired
    25     public PasswordEncoder passwordEncoder()
    26     {
     26    public PasswordEncoder passwordEncoder() {
    2727        return new BCryptPasswordEncoder();
    2828    }
     29
    2930    private final static String USER_NOT_FOUND_MSG = "User with email %s not found";
    3031    private final ConfirmationTokenService confirmationTokenService;
     
    3334    public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException {
    3435        return userRepository.findByEmail(email).orElseThrow(
    35             () -> new UsernameNotFoundException(String.format(USER_NOT_FOUND_MSG,email))
    36             );
     36                () -> new UsernameNotFoundException(String.format(USER_NOT_FOUND_MSG, email)));
    3737    }
    3838
     
    5151        String token = UUID.randomUUID().toString();
    5252        ConfirmationToken confirmationToken = new ConfirmationToken(
    53             token,
    54             LocalDateTime.now(),
    55             LocalDateTime.now().plusMinutes(10),
    56             customUserDetails
    57         );
    58        
     53                token,
     54                LocalDateTime.now(),
     55                LocalDateTime.now().plusMinutes(10),
     56                customUserDetails);
     57
    5958        confirmationTokenService.saveConfirmationToken(confirmationToken);
    6059        return token;
  • springapp/src/main/java/mk/profesori/springapp/Service/MainService.java

    r2fcbde4 r62b653f  
    1313import mk.profesori.springapp.Repository.StudyProgrammeRepository;
    1414import mk.profesori.springapp.Repository.UniversityRepository;
     15import mk.profesori.springapp.Repository.UserRepository;
    1516import mk.profesori.springapp.Model.City;
    1617import mk.profesori.springapp.Model.CustomUserDetails;
     
    3637    @Autowired
    3738    private OpinionRepository opinionRepository;
     39    @Autowired
     40    private UserRepository userRepository;
    3841
    3942    public List<Professor> getAllProfessors() {
     
    138141
    139142        Opinion opinionToAdd = new Opinion(title, content, currentUser, null, null,
    140                 null, null, null, targetProfessor);
     143                null, targetProfessor);
    141144
    142145        opinionRepository.save(opinionToAdd);
     
    149152
    150153        Opinion opinionToAdd = new Opinion(null, content, currentUser, null, null,
    151                 null, null, targetOpinion, null, targetProfessor);
     154                targetOpinion, null, targetProfessor);
    152155        opinionRepository.save(opinionToAdd);
    153156
     
    155158        opinionRepository.save(targetOpinion);
    156159    }
     160
     161    public void upvoteOpinion(Long postId, CustomUserDetails currentUser) {
     162        Opinion targetOpinion = opinionRepository.findByPostId(postId);
     163
     164        if (!targetOpinion.getLikes().contains(currentUser)) {
     165
     166            targetOpinion.getLikes().add(currentUser);
     167            // opinionRepository.save(targetOpinion);
     168
     169            targetOpinion.getAuthor().setKarma(targetOpinion.getAuthor().getKarma() + 1);
     170            userRepository.save(targetOpinion.getAuthor());
     171
     172            currentUser.getLikedPosts().add(targetOpinion);
     173            userRepository.save(currentUser);
     174        }
     175    }
     176
     177    public void downvoteOpinion(Long postId, CustomUserDetails currentUser) {
     178        Opinion targetOpinion = opinionRepository.findByPostId(postId);
     179
     180        if (!targetOpinion.getDislikes().contains(currentUser)) {
     181
     182            targetOpinion.getDislikes().add(currentUser);
     183            // opinionRepository.save(targetOpinion);
     184
     185            targetOpinion.getAuthor().setKarma(targetOpinion.getAuthor().getKarma() - 1);
     186            userRepository.save(targetOpinion.getAuthor());
     187
     188            currentUser.getDislikedPosts().add(targetOpinion);
     189            userRepository.save(currentUser);
     190        }
     191    }
    157192}
  • springapp/src/main/java/mk/profesori/springapp/Service/RegistrationService.java

    r2fcbde4 r62b653f  
    4545                String tokenToResend = customUserDetailsService
    4646                        .createToken(userRepository.findByEmail(request.getEmail()).get());
    47                 String link = "http://192.168.0.19: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.19: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

    r2fcbde4 r62b653f  
    77spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
    88spring.jpa.properties.hibernate.format_sql=true
    9 server.address=192.168.0.19
     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.