From a580c303b55fad4f6c4bac64bd5946360ed6d1d6 Mon Sep 17 00:00:00 2001 From: omerfaruk Date: Tue, 10 Dec 2024 21:45:03 +0300 Subject: [PATCH 01/30] Add DataInitializer and UserResponse classes; enhance GetPostResponse and PostController for user and subforum integration --- .../Tradeverse/config/DataInitializer.java | 5 + .../Tradeverse/controller/PostController.java | 32 ++++-- .../Tradeverse/dto/post/GetPostResponse.java | 50 ++++++++- .../Tradeverse/dto/user/UserResponse.java | 31 ++++++ .../Tradeverse/service/PostService.java | 100 ++++++++++++------ 5 files changed, 174 insertions(+), 44 deletions(-) create mode 100644 backend/src/main/java/com/bounswe2024group10/Tradeverse/config/DataInitializer.java create mode 100644 backend/src/main/java/com/bounswe2024group10/Tradeverse/dto/user/UserResponse.java diff --git a/backend/src/main/java/com/bounswe2024group10/Tradeverse/config/DataInitializer.java b/backend/src/main/java/com/bounswe2024group10/Tradeverse/config/DataInitializer.java new file mode 100644 index 00000000..bf8cc0c1 --- /dev/null +++ b/backend/src/main/java/com/bounswe2024group10/Tradeverse/config/DataInitializer.java @@ -0,0 +1,5 @@ +package com.bounswe2024group10.Tradeverse.config; + +public class DataInitializer { + +} diff --git a/backend/src/main/java/com/bounswe2024group10/Tradeverse/controller/PostController.java b/backend/src/main/java/com/bounswe2024group10/Tradeverse/controller/PostController.java index 2858c2ca..fbf75dfc 100644 --- a/backend/src/main/java/com/bounswe2024group10/Tradeverse/controller/PostController.java +++ b/backend/src/main/java/com/bounswe2024group10/Tradeverse/controller/PostController.java @@ -1,14 +1,13 @@ package com.bounswe2024group10.Tradeverse.controller; -import com.bounswe2024group10.Tradeverse.dto.post.*; -import com.bounswe2024group10.Tradeverse.service.PostService; -import com.bounswe2024group10.Tradeverse.util.JwtUtil; +import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.CrossOrigin; import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestHeader; @@ -16,7 +15,13 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; -import java.util.List; +import com.bounswe2024group10.Tradeverse.dto.post.CreatePostRequest; +import com.bounswe2024group10.Tradeverse.dto.post.CreatePostResponse; +import com.bounswe2024group10.Tradeverse.dto.post.DeletePostRequest; +import com.bounswe2024group10.Tradeverse.dto.post.DeletePostResponse; +import com.bounswe2024group10.Tradeverse.dto.post.GetPostResponse; +import com.bounswe2024group10.Tradeverse.service.PostService; +import com.bounswe2024group10.Tradeverse.util.JwtUtil; @RestController @RequestMapping(value = "/api/post") @@ -61,8 +66,8 @@ public ResponseEntity deletePost(@RequestBody DeletePostRequ @CrossOrigin(origins = "*", allowedHeaders = "*") @GetMapping("/get-posts-by-subforum") public ResponseEntity> getPostsBySubforum( - @RequestParam Long subforumId, - @RequestHeader("Authorization") String token + @RequestParam Long subforumId, + @RequestHeader("Authorization") String token ) { String username = null; if (token != null && token.startsWith("Bearer ")) { @@ -132,4 +137,19 @@ public ResponseEntity> getFollowedPeoplePosts(@RequestHead List posts = postService.getFollowedPeoplePosts(username); return ResponseEntity.ok(posts); } + + @CrossOrigin(origins = "*", allowedHeaders = "*") + @GetMapping("/{id}") + public ResponseEntity getPostById(@PathVariable Long id, @RequestHeader("Authorization") String token) { + String username = null; + if (token != null && token.startsWith("Bearer ")) { + token = token.substring(7); + username = jwtUtil.extractUsername(token); + } + GetPostResponse response = postService.getPost(id, username); + if (response == null) { + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build(); + } + return ResponseEntity.ok(response); + } } diff --git a/backend/src/main/java/com/bounswe2024group10/Tradeverse/dto/post/GetPostResponse.java b/backend/src/main/java/com/bounswe2024group10/Tradeverse/dto/post/GetPostResponse.java index dfb521b8..af645b92 100644 --- a/backend/src/main/java/com/bounswe2024group10/Tradeverse/dto/post/GetPostResponse.java +++ b/backend/src/main/java/com/bounswe2024group10/Tradeverse/dto/post/GetPostResponse.java @@ -1,10 +1,14 @@ package com.bounswe2024group10.Tradeverse.dto.post; -import com.bounswe2024group10.Tradeverse.model.Content; import java.time.LocalDateTime; import java.util.List; +import com.bounswe2024group10.Tradeverse.dto.user.UserResponse; +import com.bounswe2024group10.Tradeverse.model.Content; +import com.bounswe2024group10.Tradeverse.model.Subforum; + public class GetPostResponse { + private Long id; private String title; private List content; @@ -15,10 +19,27 @@ public class GetPostResponse { private int commentCount; private boolean isLikedByUser; private boolean isDislikedByUser; + private UserResponse author; + private Subforum subforum; + + public GetPostResponse(Long id, String title, List content, String createdBy, + LocalDateTime creationDate, int likeCount, int dislikeCount, + int commentCount, boolean isLikedByUser, boolean isDislikedByUser) { + this.id = id; + this.title = title; + this.content = content; + this.createdBy = createdBy; + this.creationDate = creationDate; + this.likeCount = likeCount; + this.dislikeCount = dislikeCount; + this.commentCount = commentCount; + this.isLikedByUser = isLikedByUser; + this.isDislikedByUser = isDislikedByUser; + } - public GetPostResponse(Long id, String title, List content, String createdBy, - LocalDateTime creationDate, int likeCount, int dislikeCount, - int commentCount, boolean isLikedByUser, boolean isDislikedByUser) { + public GetPostResponse(Long id, String title, List content, String createdBy, + LocalDateTime creationDate, int likeCount, int dislikeCount, + int commentCount, boolean isLikedByUser, boolean isDislikedByUser, String userPhoto, String authorUserName, Subforum subforum) { this.id = id; this.title = title; this.content = content; @@ -29,6 +50,9 @@ public GetPostResponse(Long id, String title, List content, String crea this.commentCount = commentCount; this.isLikedByUser = isLikedByUser; this.isDislikedByUser = isDislikedByUser; + this.author.setUserPhoto(userPhoto); + this.author.setName(authorUserName); + this.subforum = subforum; } public Long getId() { @@ -110,4 +134,20 @@ public boolean getIsDislikedByUser() { public void setIsDislikedByUser(boolean isDislikedByUser) { this.isDislikedByUser = isDislikedByUser; } -} \ No newline at end of file + + public UserResponse getAuthor() { + return author; + } + + public void setAuthor(UserResponse author) { + this.author = author; + } + + public Subforum getSubforum() { + return subforum; + } + + public void setSubforum(Subforum subforum) { + this.subforum = subforum; + } +} diff --git a/backend/src/main/java/com/bounswe2024group10/Tradeverse/dto/user/UserResponse.java b/backend/src/main/java/com/bounswe2024group10/Tradeverse/dto/user/UserResponse.java new file mode 100644 index 00000000..e8831bf7 --- /dev/null +++ b/backend/src/main/java/com/bounswe2024group10/Tradeverse/dto/user/UserResponse.java @@ -0,0 +1,31 @@ +package com.bounswe2024group10.Tradeverse.dto.user; + +public class UserResponse { + + private String userPhoto; + private String name; + + public UserResponse() { + } + + public UserResponse(String userPhoto, String name) { + this.userPhoto = userPhoto; + this.name = name; + } + + public String getUserPhoto() { + return userPhoto; + } + + public void setUserPhoto(String userPhoto) { + this.userPhoto = userPhoto; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/backend/src/main/java/com/bounswe2024group10/Tradeverse/service/PostService.java b/backend/src/main/java/com/bounswe2024group10/Tradeverse/service/PostService.java index a91f0edf..bb1961c1 100644 --- a/backend/src/main/java/com/bounswe2024group10/Tradeverse/service/PostService.java +++ b/backend/src/main/java/com/bounswe2024group10/Tradeverse/service/PostService.java @@ -1,26 +1,45 @@ package com.bounswe2024group10.Tradeverse.service; -import com.bounswe2024group10.Tradeverse.dto.post.*; -import com.bounswe2024group10.Tradeverse.model.*; -import com.bounswe2024group10.Tradeverse.repository.*; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; - +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; import java.time.LocalDateTime; import java.util.ArrayList; -import java.util.List; -import java.util.Map; import java.util.Base64; import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; import java.util.UUID; import java.util.stream.Collectors; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.util.Optional; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import com.bounswe2024group10.Tradeverse.dto.post.CreatePostRequest; +import com.bounswe2024group10.Tradeverse.dto.post.CreatePostResponse; +import com.bounswe2024group10.Tradeverse.dto.post.DeletePostRequest; +import com.bounswe2024group10.Tradeverse.dto.post.DeletePostResponse; +import com.bounswe2024group10.Tradeverse.dto.post.GetPostResponse; +import com.bounswe2024group10.Tradeverse.model.Comment; +import com.bounswe2024group10.Tradeverse.model.Content; +import com.bounswe2024group10.Tradeverse.model.Follow; +import com.bounswe2024group10.Tradeverse.model.FollowSubforum; +import com.bounswe2024group10.Tradeverse.model.Post; +import com.bounswe2024group10.Tradeverse.model.Subforum; +import com.bounswe2024group10.Tradeverse.model.User; +import com.bounswe2024group10.Tradeverse.repository.CommentRepository; +import com.bounswe2024group10.Tradeverse.repository.DislikeRepository; +import com.bounswe2024group10.Tradeverse.repository.FollowRepository; +import com.bounswe2024group10.Tradeverse.repository.FollowSubforumRepository; +import com.bounswe2024group10.Tradeverse.repository.LikeRepository; +import com.bounswe2024group10.Tradeverse.repository.PostRepository; +import com.bounswe2024group10.Tradeverse.repository.SubforumRepository; +import com.bounswe2024group10.Tradeverse.repository.UserRepository; @Service public class PostService { + @Autowired private UserRepository userRepository; @@ -88,13 +107,13 @@ public CreatePostResponse createPost(CreatePostRequest request, String username) } Post post = new Post( - request.getTitle(), - content, - username, - request.getSubforumID(), - 0, - LocalDateTime.now(), - null + request.getTitle(), + content, + username, + request.getSubforumID(), + 0, + LocalDateTime.now(), + null ); postRepository.save(post); return new CreatePostResponse(true, "Post created successfully", post.getId()); @@ -130,17 +149,24 @@ private GetPostResponse convertToGetPostResponse(Post post, String username) { int commentCount = commentRepository.countByPostID(post.getId()); boolean isLikedByUser = username != null && likeRepository.existsByUsernameAndPostID(username, post.getId()); boolean isDislikedByUser = username != null && dislikeRepository.existsByUsernameAndPostID(username, post.getId()); + User creatorUser = userRepository.findByUsername(post.getCreatedBy()); + String userPhoto = creatorUser.getProfilePhoto(); + String creatorUserName = creatorUser.getName(); + Subforum subforum = subforumRepository.findById(post.getSubforumID()).orElse(null); return new GetPostResponse( - post.getId(), - post.getTitle(), - post.getContent(), - post.getCreatedBy(), - post.getCreationDate(), - likeCount, - dislikeCount, - commentCount, - isLikedByUser, - isDislikedByUser + post.getId(), + post.getTitle(), + post.getContent(), + post.getCreatedBy(), + post.getCreationDate(), + likeCount, + dislikeCount, + commentCount, + isLikedByUser, + isDislikedByUser, + userPhoto, + creatorUserName, + subforum ); } @@ -184,8 +210,8 @@ public List getForYouPosts(String username) { postScoreMap.put(post.getId(), score); } List sortedPosts = posts.stream() - .sorted((p1, p2) -> postScoreMap.get(p2.getId()) - postScoreMap.get(p1.getId())) - .collect(Collectors.toList()); + .sorted((p1, p2) -> postScoreMap.get(p2.getId()) - postScoreMap.get(p1.getId())) + .collect(Collectors.toList()); for (Post post : sortedPosts) { response.add(convertToGetPostResponse(post, username)); @@ -205,8 +231,8 @@ public List getRecentPosts(String username) { postScoreMap.put(post.getId(), score); } List sortedPosts = posts.stream() - .sorted((p1, p2) -> postScoreMap.get(p2.getId()) - postScoreMap.get(p1.getId())) - .collect(Collectors.toList()); + .sorted((p1, p2) -> postScoreMap.get(p2.getId()) - postScoreMap.get(p1.getId())) + .collect(Collectors.toList()); for (Post post : sortedPosts) { response.add(convertToGetPostResponse(post, username)); } @@ -246,4 +272,12 @@ public List getFollowedPeoplePosts(String username) { } return response; } + + public GetPostResponse getPost(Long postId, String username) { + Post post = postRepository.findById(postId).orElse(null); + if (post == null) { + return null; + } + return convertToGetPostResponse(post, username); + } } From 82498ed7662db0e259e1ad6fbe16e583b75a4bfa Mon Sep 17 00:00:00 2001 From: omerfaruk Date: Tue, 10 Dec 2024 22:23:25 +0300 Subject: [PATCH 02/30] Add DataInitializer for admin user setup; update GetPostResponse to include author information --- .../Tradeverse/config/DataInitializer.java | 32 +++++++++++++++++++ .../Tradeverse/dto/post/GetPostResponse.java | 1 + 2 files changed, 33 insertions(+) diff --git a/backend/src/main/java/com/bounswe2024group10/Tradeverse/config/DataInitializer.java b/backend/src/main/java/com/bounswe2024group10/Tradeverse/config/DataInitializer.java index bf8cc0c1..8aec804d 100644 --- a/backend/src/main/java/com/bounswe2024group10/Tradeverse/config/DataInitializer.java +++ b/backend/src/main/java/com/bounswe2024group10/Tradeverse/config/DataInitializer.java @@ -1,5 +1,37 @@ package com.bounswe2024group10.Tradeverse.config; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.CommandLineRunner; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.crypto.password.PasswordEncoder; + +import com.bounswe2024group10.Tradeverse.model.User; +import com.bounswe2024group10.Tradeverse.repository.UserRepository; + +@Configuration public class DataInitializer { + @Autowired + private UserRepository userRepository; + + @Autowired + private PasswordEncoder passwordEncoder; + + @Bean + public CommandLineRunner initData() { + return args -> { + if (userRepository.findByUsername("admin") == null) { + User user = new User(); + user.setEmail("admin@tradeverse.com"); + user.setUsername("admin"); + user.setPassword(passwordEncoder.encode("admin")); + user.setName("admin"); + user.setTag(0); + user.setBio("admin"); + user.setIsAdmin(true); + userRepository.save(user); + } + }; + } } diff --git a/backend/src/main/java/com/bounswe2024group10/Tradeverse/dto/post/GetPostResponse.java b/backend/src/main/java/com/bounswe2024group10/Tradeverse/dto/post/GetPostResponse.java index af645b92..5bec8026 100644 --- a/backend/src/main/java/com/bounswe2024group10/Tradeverse/dto/post/GetPostResponse.java +++ b/backend/src/main/java/com/bounswe2024group10/Tradeverse/dto/post/GetPostResponse.java @@ -50,6 +50,7 @@ public GetPostResponse(Long id, String title, List content, String crea this.commentCount = commentCount; this.isLikedByUser = isLikedByUser; this.isDislikedByUser = isDislikedByUser; + this.author = new UserResponse(); this.author.setUserPhoto(userPhoto); this.author.setName(authorUserName); this.subforum = subforum; From 4e7ce157135cde10ce66f3175c1c512e0a57c179 Mon Sep 17 00:00:00 2001 From: omerfaruk Date: Tue, 10 Dec 2024 23:31:10 +0300 Subject: [PATCH 03/30] Enhance subforum functionality: add GetSubforumResponse DTO, update PostService and SubforumService for post retrieval, and improve FollowSubforumRepository methods --- .../controller/SubforumController.java | 40 ++++++-- .../dto/subforum/GetSubforumResponse.java | 96 +++++++++++++++++++ .../dto/user/GetProfileResponse.java | 31 +++++- .../repository/FollowSubforumRepository.java | 14 ++- .../Tradeverse/repository/PostRepository.java | 10 +- .../Tradeverse/service/PostService.java | 2 +- .../Tradeverse/service/SubforumService.java | 26 ++++- .../Tradeverse/service/UserService.java | 54 ++++++----- 8 files changed, 231 insertions(+), 42 deletions(-) create mode 100644 backend/src/main/java/com/bounswe2024group10/Tradeverse/dto/subforum/GetSubforumResponse.java diff --git a/backend/src/main/java/com/bounswe2024group10/Tradeverse/controller/SubforumController.java b/backend/src/main/java/com/bounswe2024group10/Tradeverse/controller/SubforumController.java index 8d436de3..7028a77e 100644 --- a/backend/src/main/java/com/bounswe2024group10/Tradeverse/controller/SubforumController.java +++ b/backend/src/main/java/com/bounswe2024group10/Tradeverse/controller/SubforumController.java @@ -1,19 +1,34 @@ package com.bounswe2024group10.Tradeverse.controller; -import com.bounswe2024group10.Tradeverse.dto.subforum.*; -import com.bounswe2024group10.Tradeverse.model.Subforum; -import com.bounswe2024group10.Tradeverse.service.SubforumService; -import com.bounswe2024group10.Tradeverse.util.JwtUtil; +import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.CrossOrigin; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestHeader; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; -import java.util.List; +import com.bounswe2024group10.Tradeverse.dto.subforum.CreateSubforumRequest; +import com.bounswe2024group10.Tradeverse.dto.subforum.CreateSubforumResponse; +import com.bounswe2024group10.Tradeverse.dto.subforum.DeleteSubforumRequest; +import com.bounswe2024group10.Tradeverse.dto.subforum.DeleteSubforumResponse; +import com.bounswe2024group10.Tradeverse.dto.subforum.FollowSubforumRequest; +import com.bounswe2024group10.Tradeverse.dto.subforum.FollowSubforumResponse; +import com.bounswe2024group10.Tradeverse.dto.subforum.GetFollowedSubforumsResponse; +import com.bounswe2024group10.Tradeverse.dto.subforum.GetSubforumResponse; +import com.bounswe2024group10.Tradeverse.model.Subforum; +import com.bounswe2024group10.Tradeverse.service.SubforumService; +import com.bounswe2024group10.Tradeverse.util.JwtUtil; @RestController @RequestMapping("/api/subforum") public class SubforumController { + @Autowired private JwtUtil jwtUtil; @Autowired @@ -79,4 +94,15 @@ public ResponseEntity> getFollowedSubforums(@ } return ResponseEntity.ok(subforumService.getFollowedSubforums(username)); } -} + + @CrossOrigin(origins = "*", allowedHeaders = "*") + @GetMapping("/{id}") + public ResponseEntity getSubforum(@RequestHeader("Authorization") String token, @PathVariable Long id) { + String username = null; + if (token != null && token.startsWith("Bearer ")) { + token = token.substring(7); + username = jwtUtil.extractUsername(token); + } + return ResponseEntity.ok(subforumService.getSubforum(username, id)); + } +} diff --git a/backend/src/main/java/com/bounswe2024group10/Tradeverse/dto/subforum/GetSubforumResponse.java b/backend/src/main/java/com/bounswe2024group10/Tradeverse/dto/subforum/GetSubforumResponse.java new file mode 100644 index 00000000..629af00d --- /dev/null +++ b/backend/src/main/java/com/bounswe2024group10/Tradeverse/dto/subforum/GetSubforumResponse.java @@ -0,0 +1,96 @@ +package com.bounswe2024group10.Tradeverse.dto.subforum; + +import java.util.List; + +import com.bounswe2024group10.Tradeverse.dto.post.GetPostResponse; + +public class GetSubforumResponse { + + private Long id; + private String name; + private String description; + private String tagColor; + private boolean isFollowed; + private int followerCount; + private int postCount; + private List posts; + + public GetSubforumResponse(Long id, String name, String description, String tagColor, boolean isFollowed, int followerCount, int postCount, List posts) { + this.id = id; + this.name = name; + this.description = description; + this.tagColor = tagColor; + this.isFollowed = isFollowed; + this.followerCount = followerCount; + this.postCount = postCount; + this.posts = posts; + } + + public GetSubforumResponse() { + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getTagColor() { + return tagColor; + } + + public void setTagColor(String tagColor) { + this.tagColor = tagColor; + } + + public boolean isFollowed() { + return isFollowed; + } + + public void setFollowed(boolean isFollowed) { + this.isFollowed = isFollowed; + } + + public int getFollowerCount() { + return followerCount; + } + + public void setFollowerCount(int followerCount) { + this.followerCount = followerCount; + } + + public int getPostCount() { + return postCount; + } + + public void setPostCount(int postCount) { + this.postCount = postCount; + } + + public List getPosts() { + return posts; + } + + public void setPosts(List posts) { + this.posts = posts; + } + +} diff --git a/backend/src/main/java/com/bounswe2024group10/Tradeverse/dto/user/GetProfileResponse.java b/backend/src/main/java/com/bounswe2024group10/Tradeverse/dto/user/GetProfileResponse.java index b30e829c..e7b8846a 100644 --- a/backend/src/main/java/com/bounswe2024group10/Tradeverse/dto/user/GetProfileResponse.java +++ b/backend/src/main/java/com/bounswe2024group10/Tradeverse/dto/user/GetProfileResponse.java @@ -1,12 +1,15 @@ package com.bounswe2024group10.Tradeverse.dto.user; import java.util.List; + import com.bounswe2024group10.Tradeverse.dto.post.GetPostResponse; public class GetProfileResponse { + private boolean success; private String message; private String username; + private String name; private String profilePhoto; private int postCount; private int followerCount; @@ -19,11 +22,25 @@ public GetProfileResponse(boolean success, String message) { this.message = message; } - public GetProfileResponse(String username, String profilePhoto, int postCount, - int followerCount, boolean isFollowing, - List popularPosts, List recentPosts) { + public GetProfileResponse(String username, String profilePhoto, int postCount, + int followerCount, boolean isFollowing, + List popularPosts, List recentPosts) { + this.success = true; + this.username = username; + this.profilePhoto = profilePhoto; + this.postCount = postCount; + this.followerCount = followerCount; + this.isFollowing = isFollowing; + this.popularPosts = popularPosts; + this.recentPosts = recentPosts; + } + + public GetProfileResponse(String username, String name, String profilePhoto, int postCount, + int followerCount, boolean isFollowing, + List popularPosts, List recentPosts) { this.success = true; this.username = username; + this.name = name; this.profilePhoto = profilePhoto; this.postCount = postCount; this.followerCount = followerCount; @@ -56,6 +73,14 @@ public void setUsername(String username) { this.username = username; } + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + public String getProfilePhoto() { return profilePhoto; } diff --git a/backend/src/main/java/com/bounswe2024group10/Tradeverse/repository/FollowSubforumRepository.java b/backend/src/main/java/com/bounswe2024group10/Tradeverse/repository/FollowSubforumRepository.java index 28b4a254..a142ac35 100644 --- a/backend/src/main/java/com/bounswe2024group10/Tradeverse/repository/FollowSubforumRepository.java +++ b/backend/src/main/java/com/bounswe2024group10/Tradeverse/repository/FollowSubforumRepository.java @@ -1,18 +1,24 @@ package com.bounswe2024group10.Tradeverse.repository; -import com.bounswe2024group10.Tradeverse.model.FollowSubforum; -import com.bounswe2024group10.Tradeverse.model.Subforum; -import com.bounswe2024group10.Tradeverse.model.User; +import java.util.List; + import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; -import java.util.List; +import com.bounswe2024group10.Tradeverse.model.FollowSubforum; @Repository public interface FollowSubforumRepository extends JpaRepository { + FollowSubforum findByFollowerUsernameAndSubforumID(String followerUsername, Long subforumID); + + boolean existsByFollowerUsernameAndSubforumID(String followerUsername, Long subforumID); + List findByFollowerUsername(String followerUsername); + List findBySubforumID(Long subforumID); + int countBySubforumID(Long subforumID); + int countByFollowerUsername(String followerUsername); } diff --git a/backend/src/main/java/com/bounswe2024group10/Tradeverse/repository/PostRepository.java b/backend/src/main/java/com/bounswe2024group10/Tradeverse/repository/PostRepository.java index a239fe1d..d3777a7e 100644 --- a/backend/src/main/java/com/bounswe2024group10/Tradeverse/repository/PostRepository.java +++ b/backend/src/main/java/com/bounswe2024group10/Tradeverse/repository/PostRepository.java @@ -1,16 +1,24 @@ package com.bounswe2024group10.Tradeverse.repository; -import com.bounswe2024group10.Tradeverse.model.Post; import java.util.List; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; +import com.bounswe2024group10.Tradeverse.model.Post; + @Repository public interface PostRepository extends JpaRepository { + List findByCreatedBy(String createdBy); + + List findBySubforumID(Long subforumID); + List findAllBySubforumIDOrderByCreationDateDesc(Long subforumID); + List findTop100ByOrderByCreationDateDesc(); + int countByCreatedBy(String createdBy); + int countBySubforumID(Long subforumID); } diff --git a/backend/src/main/java/com/bounswe2024group10/Tradeverse/service/PostService.java b/backend/src/main/java/com/bounswe2024group10/Tradeverse/service/PostService.java index bb1961c1..01712400 100644 --- a/backend/src/main/java/com/bounswe2024group10/Tradeverse/service/PostService.java +++ b/backend/src/main/java/com/bounswe2024group10/Tradeverse/service/PostService.java @@ -142,7 +142,7 @@ public DeletePostResponse deletePost(DeletePostRequest request, String username) return new DeletePostResponse(true, "Post deleted successfully"); } - private GetPostResponse convertToGetPostResponse(Post post, String username) { + protected GetPostResponse convertToGetPostResponse(Post post, String username) { post.setViewCount(post.getViewCount() + 1); int likeCount = likeRepository.countByPostID(post.getId()); int dislikeCount = dislikeRepository.countByPostID(post.getId()); diff --git a/backend/src/main/java/com/bounswe2024group10/Tradeverse/service/SubforumService.java b/backend/src/main/java/com/bounswe2024group10/Tradeverse/service/SubforumService.java index 804f85c3..c0f535db 100644 --- a/backend/src/main/java/com/bounswe2024group10/Tradeverse/service/SubforumService.java +++ b/backend/src/main/java/com/bounswe2024group10/Tradeverse/service/SubforumService.java @@ -1,5 +1,6 @@ package com.bounswe2024group10.Tradeverse.service; +import com.bounswe2024group10.Tradeverse.dto.post.GetPostResponse; import com.bounswe2024group10.Tradeverse.dto.subforum.*; import com.bounswe2024group10.Tradeverse.model.Subforum; import com.bounswe2024group10.Tradeverse.model.FollowSubforum; @@ -16,8 +17,11 @@ import java.util.List; import java.util.Optional; +import com.bounswe2024group10.Tradeverse.model.Post; + @Service public class SubforumService { + @Autowired private SubforumRepository subforumRepository; @@ -29,6 +33,9 @@ public class SubforumService { @Autowired private FollowSubforumRepository followSubforumRepository; + @Autowired + private PostService postService; + public List getAllSubforums() { return subforumRepository.findAll(); } @@ -126,4 +133,21 @@ public List getFollowedSubforums(String username) } return response; } -} \ No newline at end of file + + public GetSubforumResponse getSubforum(String username, Long id) { + Subforum subforum = subforumRepository.findById(id).orElse(null); + if (subforum == null) { + return new GetSubforumResponse(); + } + boolean isFollowed = username != null && followSubforumRepository.existsByFollowerUsernameAndSubforumID(username, id); + int followerCount = followSubforumRepository.countBySubforumID(id); + int postCount = postRepository.countBySubforumID(id); + List posts = postRepository.findBySubforumID(id); + List postResponses = new ArrayList<>(); + for (Post post : posts) { + postResponses.add(postService.convertToGetPostResponse(post, username)); + } + GetSubforumResponse response = new GetSubforumResponse(subforum.getId(), subforum.getName(), subforum.getDescription(), subforum.getTagColor(), isFollowed, followerCount, postCount, postResponses); + return response; + } +} diff --git a/backend/src/main/java/com/bounswe2024group10/Tradeverse/service/UserService.java b/backend/src/main/java/com/bounswe2024group10/Tradeverse/service/UserService.java index 84320d77..33326635 100644 --- a/backend/src/main/java/com/bounswe2024group10/Tradeverse/service/UserService.java +++ b/backend/src/main/java/com/bounswe2024group10/Tradeverse/service/UserService.java @@ -1,16 +1,5 @@ package com.bounswe2024group10.Tradeverse.service; -import com.bounswe2024group10.Tradeverse.dto.post.GetPostResponse; -import com.bounswe2024group10.Tradeverse.dto.user.*; -import com.bounswe2024group10.Tradeverse.model.Post; -import com.bounswe2024group10.Tradeverse.model.User; -import com.bounswe2024group10.Tradeverse.repository.UserRepository; -import com.bounswe2024group10.Tradeverse.repository.PostRepository; -import com.bounswe2024group10.Tradeverse.repository.FollowRepository; -import com.bounswe2024group10.Tradeverse.repository.LikeRepository; -import com.bounswe2024group10.Tradeverse.repository.DislikeRepository; -import com.bounswe2024group10.Tradeverse.repository.CommentRepository; - import java.io.File; import java.io.FileOutputStream; import java.io.IOException; @@ -25,14 +14,29 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import com.bounswe2024group10.Tradeverse.dto.post.GetPostResponse; +import com.bounswe2024group10.Tradeverse.dto.user.GetProfileResponse; +import com.bounswe2024group10.Tradeverse.dto.user.GetUserDetailsResponse; +import com.bounswe2024group10.Tradeverse.dto.user.SetUserDetailsRequest; +import com.bounswe2024group10.Tradeverse.dto.user.SetUserDetailsResponse; +import com.bounswe2024group10.Tradeverse.model.Post; +import com.bounswe2024group10.Tradeverse.model.User; +import com.bounswe2024group10.Tradeverse.repository.CommentRepository; +import com.bounswe2024group10.Tradeverse.repository.DislikeRepository; +import com.bounswe2024group10.Tradeverse.repository.FollowRepository; +import com.bounswe2024group10.Tradeverse.repository.LikeRepository; +import com.bounswe2024group10.Tradeverse.repository.PostRepository; +import com.bounswe2024group10.Tradeverse.repository.UserRepository; + @Service public class UserService { + @Autowired private UserRepository userRepository; @Autowired private PostRepository postRepository; - + @Autowired private FollowRepository followRepository; @@ -91,16 +95,16 @@ private GetPostResponse convertToGetPostResponse(Post post, String username) { boolean isLikedByUser = username != null && likeRepository.existsByUsernameAndPostID(username, post.getId()); boolean isDislikedByUser = username != null && dislikeRepository.existsByUsernameAndPostID(username, post.getId()); return new GetPostResponse( - post.getId(), - post.getTitle(), - post.getContent(), - post.getCreatedBy(), - post.getCreationDate(), - likeCount, - dislikeCount, - commentCount, - isLikedByUser, - isDislikedByUser + post.getId(), + post.getTitle(), + post.getContent(), + post.getCreatedBy(), + post.getCreationDate(), + likeCount, + dislikeCount, + commentCount, + isLikedByUser, + isDislikedByUser ); } @@ -126,12 +130,12 @@ public GetProfileResponse getProfile(String username, String requesterUsername) postScoreMap.put(post.getId(), score); } List sortedPosts = recentPosts.stream() - .sorted((p1, p2) -> postScoreMap.get(p2.getId()) - postScoreMap.get(p1.getId())) - .collect(Collectors.toList()); + .sorted((p1, p2) -> postScoreMap.get(p2.getId()) - postScoreMap.get(p1.getId())) + .collect(Collectors.toList()); List popularPostResponses = new ArrayList<>(); for (Post post : sortedPosts) { popularPostResponses.add(convertToGetPostResponse(post, requesterUsername)); } - return new GetProfileResponse(user.getUsername(), user.getProfilePhoto(), postCount, followerCount, isFollowing, popularPostResponses, recentPostResponses); + return new GetProfileResponse(user.getUsername(), user.getName(), user.getProfilePhoto(), postCount, followerCount, isFollowing, popularPostResponses, recentPostResponses); } } From f1375f2b4e55194e135ddb2256ef278b4ad068a8 Mon Sep 17 00:00:00 2001 From: omerfaruk Date: Tue, 10 Dec 2024 23:45:34 +0300 Subject: [PATCH 04/30] Add AllSubforumResponse DTO and update SubforumService and SubforumController for enhanced subforum data retrieval --- .../controller/PortfolioController.java | 15 +++- .../controller/SubforumController.java | 4 +- .../portfolio/AddAssetToPortfolioRequest.java | 4 +- .../dto/subforum/AllSubforumResponse.java | 71 +++++++++++++++++++ .../Tradeverse/service/SubforumService.java | 15 +++- 5 files changed, 101 insertions(+), 8 deletions(-) create mode 100644 backend/src/main/java/com/bounswe2024group10/Tradeverse/dto/subforum/AllSubforumResponse.java diff --git a/backend/src/main/java/com/bounswe2024group10/Tradeverse/controller/PortfolioController.java b/backend/src/main/java/com/bounswe2024group10/Tradeverse/controller/PortfolioController.java index 6118d573..e3795c34 100644 --- a/backend/src/main/java/com/bounswe2024group10/Tradeverse/controller/PortfolioController.java +++ b/backend/src/main/java/com/bounswe2024group10/Tradeverse/controller/PortfolioController.java @@ -1,10 +1,19 @@ package com.bounswe2024group10.Tradeverse.controller; -import com.bounswe2024group10.Tradeverse.dto.portfolio.*; -import com.bounswe2024group10.Tradeverse.service.PortfolioService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.CrossOrigin; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import com.bounswe2024group10.Tradeverse.dto.portfolio.AddAssetToPortfolioRequest; +import com.bounswe2024group10.Tradeverse.dto.portfolio.AddAssetToPortfolioResponse; +import com.bounswe2024group10.Tradeverse.dto.portfolio.GetPortfolioResponse; +import com.bounswe2024group10.Tradeverse.service.PortfolioService; @RestController @RequestMapping("/api/portfolio") diff --git a/backend/src/main/java/com/bounswe2024group10/Tradeverse/controller/SubforumController.java b/backend/src/main/java/com/bounswe2024group10/Tradeverse/controller/SubforumController.java index 7028a77e..bc1556c4 100644 --- a/backend/src/main/java/com/bounswe2024group10/Tradeverse/controller/SubforumController.java +++ b/backend/src/main/java/com/bounswe2024group10/Tradeverse/controller/SubforumController.java @@ -13,6 +13,7 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; +import com.bounswe2024group10.Tradeverse.dto.subforum.AllSubforumResponse; import com.bounswe2024group10.Tradeverse.dto.subforum.CreateSubforumRequest; import com.bounswe2024group10.Tradeverse.dto.subforum.CreateSubforumResponse; import com.bounswe2024group10.Tradeverse.dto.subforum.DeleteSubforumRequest; @@ -21,7 +22,6 @@ import com.bounswe2024group10.Tradeverse.dto.subforum.FollowSubforumResponse; import com.bounswe2024group10.Tradeverse.dto.subforum.GetFollowedSubforumsResponse; import com.bounswe2024group10.Tradeverse.dto.subforum.GetSubforumResponse; -import com.bounswe2024group10.Tradeverse.model.Subforum; import com.bounswe2024group10.Tradeverse.service.SubforumService; import com.bounswe2024group10.Tradeverse.util.JwtUtil; @@ -36,7 +36,7 @@ public class SubforumController { @CrossOrigin(origins = "*", allowedHeaders = "*") @GetMapping("/all") - public ResponseEntity> getAllSubforums() { + public ResponseEntity> getAllSubforums() { return ResponseEntity.ok(subforumService.getAllSubforums()); } diff --git a/backend/src/main/java/com/bounswe2024group10/Tradeverse/dto/portfolio/AddAssetToPortfolioRequest.java b/backend/src/main/java/com/bounswe2024group10/Tradeverse/dto/portfolio/AddAssetToPortfolioRequest.java index 98c5cfd5..0a934ad8 100644 --- a/backend/src/main/java/com/bounswe2024group10/Tradeverse/dto/portfolio/AddAssetToPortfolioRequest.java +++ b/backend/src/main/java/com/bounswe2024group10/Tradeverse/dto/portfolio/AddAssetToPortfolioRequest.java @@ -1,6 +1,7 @@ package com.bounswe2024group10.Tradeverse.dto.portfolio; public class AddAssetToPortfolioRequest { + private String username; private Long assetId; private double amount; @@ -12,6 +13,7 @@ public String getUsername() { public void setUsername(String username) { this.username = username; } + public Long getAssetId() { return assetId; } @@ -27,4 +29,4 @@ public double getAmount() { public void setAmount(double amount) { this.amount = amount; } -} \ No newline at end of file +} diff --git a/backend/src/main/java/com/bounswe2024group10/Tradeverse/dto/subforum/AllSubforumResponse.java b/backend/src/main/java/com/bounswe2024group10/Tradeverse/dto/subforum/AllSubforumResponse.java new file mode 100644 index 00000000..924d630d --- /dev/null +++ b/backend/src/main/java/com/bounswe2024group10/Tradeverse/dto/subforum/AllSubforumResponse.java @@ -0,0 +1,71 @@ +package com.bounswe2024group10.Tradeverse.dto.subforum; + +public class AllSubforumResponse { + + private Long id; + private String name; + private String description; + private String tagColor; + private int followerCount; + private int postCount; + + public AllSubforumResponse(Long id, String name, String description, String tagColor, int followerCount, int postCount) { + this.id = id; + this.name = name; + this.description = description; + this.tagColor = tagColor; + this.followerCount = followerCount; + this.postCount = postCount; + } + + public AllSubforumResponse() { + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getTagColor() { + return tagColor; + } + + public void setTagColor(String tagColor) { + this.tagColor = tagColor; + } + + public int getFollowerCount() { + return followerCount; + } + + public void setFollowerCount(int followerCount) { + this.followerCount = followerCount; + } + + public int getPostCount() { + return postCount; + } + + public void setPostCount(int postCount) { + this.postCount = postCount; + } +} diff --git a/backend/src/main/java/com/bounswe2024group10/Tradeverse/service/SubforumService.java b/backend/src/main/java/com/bounswe2024group10/Tradeverse/service/SubforumService.java index c0f535db..a2b54943 100644 --- a/backend/src/main/java/com/bounswe2024group10/Tradeverse/service/SubforumService.java +++ b/backend/src/main/java/com/bounswe2024group10/Tradeverse/service/SubforumService.java @@ -36,8 +36,19 @@ public class SubforumService { @Autowired private PostService postService; - public List getAllSubforums() { - return subforumRepository.findAll(); + public List getAllSubforums() { + List response = new ArrayList<>(); + List subforums = subforumRepository.findAll(); + for (Subforum subforum : subforums) { + response.add(convertToAllSubforumResponse(subforum)); + } + return response; + } + + private AllSubforumResponse convertToAllSubforumResponse(Subforum subforum) { + int followerCount = followSubforumRepository.countBySubforumID(subforum.getId()); + int postCount = postRepository.countBySubforumID(subforum.getId()); + return new AllSubforumResponse(subforum.getId(), subforum.getName(), subforum.getDescription(), subforum.getTagColor(), followerCount, postCount); } public CreateSubforumResponse createSubforum(CreateSubforumRequest request, String username) { From 6f76b983fbdcec0cfcbdc49c2183b73251e8e5a9 Mon Sep 17 00:00:00 2001 From: omerfaruk Date: Wed, 11 Dec 2024 00:34:40 +0300 Subject: [PATCH 05/30] Added auth token logic instead of username --- .../controller/DislikeController.java | 45 ++++++++++--- .../controller/FollowController.java | 65 ++++++++++++++++--- .../Tradeverse/controller/LikeController.java | 54 ++++++++++++--- .../controller/PortfolioController.java | 19 +++++- .../portfolio/AddAssetToPortfolioRequest.java | 9 --- .../AddAssetToPortfolioServiceRequest.java | 32 +++++++++ .../Tradeverse/service/PortfolioService.java | 35 +++++----- .../service/PortfolioServiceUnitTest.java | 21 +++--- 8 files changed, 218 insertions(+), 62 deletions(-) create mode 100644 backend/src/main/java/com/bounswe2024group10/Tradeverse/dto/portfolio/AddAssetToPortfolioServiceRequest.java diff --git a/backend/src/main/java/com/bounswe2024group10/Tradeverse/controller/DislikeController.java b/backend/src/main/java/com/bounswe2024group10/Tradeverse/controller/DislikeController.java index 64a70ec6..daff5903 100644 --- a/backend/src/main/java/com/bounswe2024group10/Tradeverse/controller/DislikeController.java +++ b/backend/src/main/java/com/bounswe2024group10/Tradeverse/controller/DislikeController.java @@ -1,29 +1,58 @@ package com.bounswe2024group10.Tradeverse.controller; -import com.bounswe2024group10.Tradeverse.dto.dislike.*; -import com.bounswe2024group10.Tradeverse.service.DislikeService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.CrossOrigin; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestHeader; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import com.bounswe2024group10.Tradeverse.dto.dislike.DislikePostRequest; +import com.bounswe2024group10.Tradeverse.dto.dislike.DislikePostResponse; +import com.bounswe2024group10.Tradeverse.dto.dislike.UndislikePostRequest; +import com.bounswe2024group10.Tradeverse.dto.dislike.UndislikePostResponse; +import com.bounswe2024group10.Tradeverse.service.DislikeService; +import com.bounswe2024group10.Tradeverse.util.JwtUtil; @RestController @RequestMapping("/api/dislike") public class DislikeController { + @Autowired private DislikeService dislikeService; + @Autowired + private JwtUtil jwtUtil; @CrossOrigin(origins = "*", allowedHeaders = "*") - @PostMapping("/dislike-post") - public ResponseEntity dislikePost(@RequestBody DislikePostRequest request) { + @GetMapping("/dislike-post") + public ResponseEntity dislikePost(@RequestParam Long postId, @RequestHeader("Authorization") String token) { + String username = null; + if (token != null && token.startsWith("Bearer ")) { + token = token.substring(7); + username = jwtUtil.extractUsername(token); + } + DislikePostRequest request = new DislikePostRequest(); + request.setPostId(postId); + request.setUsername(username); DislikePostResponse response = dislikeService.dislikePost(request); return ResponseEntity.ok(response); } @CrossOrigin(origins = "*", allowedHeaders = "*") - @PostMapping("/undislike-post") - public ResponseEntity undislikePost(@RequestBody UndislikePostRequest request) { + @GetMapping("/undislike-post") + public ResponseEntity undislikePost(@RequestParam Long postId, @RequestHeader("Authorization") String token) { + String username = null; + if (token != null && token.startsWith("Bearer ")) { + token = token.substring(7); + username = jwtUtil.extractUsername(token); + } + UndislikePostRequest request = new UndislikePostRequest(); + request.setPostId(postId); + request.setUsername(username); UndislikePostResponse response = dislikeService.undislikePost(request); return ResponseEntity.ok(response); } -} \ No newline at end of file +} diff --git a/backend/src/main/java/com/bounswe2024group10/Tradeverse/controller/FollowController.java b/backend/src/main/java/com/bounswe2024group10/Tradeverse/controller/FollowController.java index 7dc7b6f8..ebd3140d 100644 --- a/backend/src/main/java/com/bounswe2024group10/Tradeverse/controller/FollowController.java +++ b/backend/src/main/java/com/bounswe2024group10/Tradeverse/controller/FollowController.java @@ -1,41 +1,88 @@ package com.bounswe2024group10.Tradeverse.controller; -import com.bounswe2024group10.Tradeverse.dto.follow.*; -import com.bounswe2024group10.Tradeverse.service.FollowService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.CrossOrigin; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestHeader; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import com.bounswe2024group10.Tradeverse.dto.follow.FollowUserRequest; +import com.bounswe2024group10.Tradeverse.dto.follow.FollowUserResponse; +import com.bounswe2024group10.Tradeverse.dto.follow.GetFollowersRequest; +import com.bounswe2024group10.Tradeverse.dto.follow.GetFollowersResponse; +import com.bounswe2024group10.Tradeverse.dto.follow.GetFollowingsRequest; +import com.bounswe2024group10.Tradeverse.dto.follow.GetFollowingsResponse; +import com.bounswe2024group10.Tradeverse.dto.follow.UnfollowUserRequest; +import com.bounswe2024group10.Tradeverse.dto.follow.UnfollowUserResponse; +import com.bounswe2024group10.Tradeverse.service.FollowService; +import com.bounswe2024group10.Tradeverse.util.JwtUtil; @RestController @RequestMapping("/api/follow") public class FollowController { + @Autowired private FollowService followService; + @Autowired + private JwtUtil jwtUtil; @CrossOrigin(origins = "*", allowedHeaders = "*") - @PostMapping("/follow-user") - public ResponseEntity followUser(@RequestBody FollowUserRequest request) { + @GetMapping("/follow-user") + public ResponseEntity followUser(@RequestParam String followedUsername, @RequestHeader("Authorization") String token) { + String username = null; + if (token != null && token.startsWith("Bearer ")) { + token = token.substring(7); + username = jwtUtil.extractUsername(token); + } + FollowUserRequest request = new FollowUserRequest(); + request.setFollowedUsername(followedUsername); + request.setFollowerUsername(username); FollowUserResponse response = followService.followUser(request); return ResponseEntity.ok(response); } @CrossOrigin(origins = "*", allowedHeaders = "*") - @PostMapping("/unfollow-user") - public ResponseEntity unfollowUser(@RequestBody UnfollowUserRequest request) { + @GetMapping("/unfollow-user") + public ResponseEntity unfollowUser(@RequestParam String unfollowedUsername, @RequestHeader("Authorization") String token) { + String username = null; + if (token != null && token.startsWith("Bearer ")) { + token = token.substring(7); + username = jwtUtil.extractUsername(token); + } + UnfollowUserRequest request = new UnfollowUserRequest(); + request.setFollowedUsername(unfollowedUsername); + request.setFollowerUsername(username); UnfollowUserResponse response = followService.unfollowUser(request); return ResponseEntity.ok(response); } @CrossOrigin(origins = "*", allowedHeaders = "*") @GetMapping("/get-followings") - public ResponseEntity getFollowings(@RequestBody GetFollowingsRequest request) { + public ResponseEntity getFollowings(@RequestHeader("Authorization") String token) { + String username = null; + if (token != null && token.startsWith("Bearer ")) { + token = token.substring(7); + username = jwtUtil.extractUsername(token); + } + GetFollowingsRequest request = new GetFollowingsRequest(); + request.setUsername(username); GetFollowingsResponse response = followService.getFollowings(request); return ResponseEntity.ok(response); } @CrossOrigin(origins = "*", allowedHeaders = "*") @GetMapping("/get-followers") - public ResponseEntity getFollowers(@RequestBody GetFollowersRequest request) { + public ResponseEntity getFollowers(@RequestHeader("Authorization") String token) { + String username = null; + if (token != null && token.startsWith("Bearer ")) { + token = token.substring(7); + username = jwtUtil.extractUsername(token); + } + GetFollowersRequest request = new GetFollowersRequest(); + request.setUsername(username); GetFollowersResponse response = followService.getFollowers(request); return ResponseEntity.ok(response); } diff --git a/backend/src/main/java/com/bounswe2024group10/Tradeverse/controller/LikeController.java b/backend/src/main/java/com/bounswe2024group10/Tradeverse/controller/LikeController.java index 9f92b71d..4d75cbe3 100644 --- a/backend/src/main/java/com/bounswe2024group10/Tradeverse/controller/LikeController.java +++ b/backend/src/main/java/com/bounswe2024group10/Tradeverse/controller/LikeController.java @@ -1,34 +1,72 @@ package com.bounswe2024group10.Tradeverse.controller; -import com.bounswe2024group10.Tradeverse.dto.like.*; -import com.bounswe2024group10.Tradeverse.service.LikeService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.CrossOrigin; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestHeader; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import com.bounswe2024group10.Tradeverse.dto.like.GetLikedPostsRequest; +import com.bounswe2024group10.Tradeverse.dto.like.GetLikedPostsResponse; +import com.bounswe2024group10.Tradeverse.dto.like.LikePostRequest; +import com.bounswe2024group10.Tradeverse.dto.like.LikePostResponse; +import com.bounswe2024group10.Tradeverse.dto.like.UnlikePostRequest; +import com.bounswe2024group10.Tradeverse.dto.like.UnlikePostResponse; +import com.bounswe2024group10.Tradeverse.service.LikeService; +import com.bounswe2024group10.Tradeverse.util.JwtUtil; @RestController @RequestMapping("/api/like") public class LikeController { + @Autowired private LikeService likeService; + @Autowired + private JwtUtil jwtUtil; @CrossOrigin(origins = "*", allowedHeaders = "*") - @PostMapping("/like-post") - public ResponseEntity likePost(@RequestBody LikePostRequest request) { + @GetMapping("/like-post") + public ResponseEntity likePost(@RequestParam Long postId, @RequestHeader("Authorization") String token) { + String username = null; + if (token != null && token.startsWith("Bearer ")) { + token = token.substring(7); + username = jwtUtil.extractUsername(token); + } + LikePostRequest request = new LikePostRequest(); + request.setPostId(postId); + request.setUsername(username); LikePostResponse response = likeService.likePost(request); return ResponseEntity.ok(response); } @CrossOrigin(origins = "*", allowedHeaders = "*") - @PostMapping("/unlike-post") - public ResponseEntity unlikePost(@RequestBody UnlikePostRequest request) { + @GetMapping("/unlike-post") + public ResponseEntity unlikePost(@RequestParam Long postId, @RequestHeader("Authorization") String token) { + String username = null; + if (token != null && token.startsWith("Bearer ")) { + token = token.substring(7); + username = jwtUtil.extractUsername(token); + } + UnlikePostRequest request = new UnlikePostRequest(); + request.setPostId(postId); + request.setUsername(username); UnlikePostResponse response = likeService.unlikePost(request); return ResponseEntity.ok(response); } @CrossOrigin(origins = "*", allowedHeaders = "*") @GetMapping("/get-liked-posts") - public ResponseEntity getLikedPosts(@RequestBody GetLikedPostsRequest request) { + public ResponseEntity getLikedPosts(@RequestHeader("Authorization") String token) { + String username = null; + if (token != null && token.startsWith("Bearer ")) { + token = token.substring(7); + username = jwtUtil.extractUsername(token); + } + GetLikedPostsRequest request = new GetLikedPostsRequest(); + request.setUsername(username); GetLikedPostsResponse response = likeService.getLikedPosts(request); return ResponseEntity.ok(response); } diff --git a/backend/src/main/java/com/bounswe2024group10/Tradeverse/controller/PortfolioController.java b/backend/src/main/java/com/bounswe2024group10/Tradeverse/controller/PortfolioController.java index e3795c34..73d95e2e 100644 --- a/backend/src/main/java/com/bounswe2024group10/Tradeverse/controller/PortfolioController.java +++ b/backend/src/main/java/com/bounswe2024group10/Tradeverse/controller/PortfolioController.java @@ -6,14 +6,17 @@ import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import com.bounswe2024group10.Tradeverse.dto.portfolio.AddAssetToPortfolioRequest; import com.bounswe2024group10.Tradeverse.dto.portfolio.AddAssetToPortfolioResponse; +import com.bounswe2024group10.Tradeverse.dto.portfolio.AddAssetToPortfolioServiceRequest; import com.bounswe2024group10.Tradeverse.dto.portfolio.GetPortfolioResponse; import com.bounswe2024group10.Tradeverse.service.PortfolioService; +import com.bounswe2024group10.Tradeverse.util.JwtUtil; @RestController @RequestMapping("/api/portfolio") @@ -22,6 +25,9 @@ public class PortfolioController { @Autowired private PortfolioService portfolioService; + @Autowired + private JwtUtil jwtUtil; + @CrossOrigin(origins = "*", allowedHeaders = "*") @GetMapping("/get-portfolio") public GetPortfolioResponse getPortfolio(@RequestParam String username) { @@ -30,8 +36,17 @@ public GetPortfolioResponse getPortfolio(@RequestParam String username) { @CrossOrigin(origins = "*", allowedHeaders = "*") @PostMapping("/add-asset") - public ResponseEntity addAssetToPortfolio(@RequestBody AddAssetToPortfolioRequest request) { - AddAssetToPortfolioResponse response = portfolioService.addAssetToPortfolio(request); + public ResponseEntity addAssetToPortfolio(@RequestBody AddAssetToPortfolioRequest request, @RequestHeader("Authorization") String token) { + String username = null; + if (token != null && token.startsWith("Bearer ")) { + token = token.substring(7); + username = jwtUtil.extractUsername(token); + } + AddAssetToPortfolioServiceRequest serviceRequest = new AddAssetToPortfolioServiceRequest(); + serviceRequest.setAssetId(request.getAssetId()); + serviceRequest.setAmount(request.getAmount()); + serviceRequest.setUsername(username); + AddAssetToPortfolioResponse response = portfolioService.addAssetToPortfolio(serviceRequest); return ResponseEntity.ok(response); } diff --git a/backend/src/main/java/com/bounswe2024group10/Tradeverse/dto/portfolio/AddAssetToPortfolioRequest.java b/backend/src/main/java/com/bounswe2024group10/Tradeverse/dto/portfolio/AddAssetToPortfolioRequest.java index 0a934ad8..3a68d6c9 100644 --- a/backend/src/main/java/com/bounswe2024group10/Tradeverse/dto/portfolio/AddAssetToPortfolioRequest.java +++ b/backend/src/main/java/com/bounswe2024group10/Tradeverse/dto/portfolio/AddAssetToPortfolioRequest.java @@ -2,18 +2,9 @@ public class AddAssetToPortfolioRequest { - private String username; private Long assetId; private double amount; - public String getUsername() { - return username; - } - - public void setUsername(String username) { - this.username = username; - } - public Long getAssetId() { return assetId; } diff --git a/backend/src/main/java/com/bounswe2024group10/Tradeverse/dto/portfolio/AddAssetToPortfolioServiceRequest.java b/backend/src/main/java/com/bounswe2024group10/Tradeverse/dto/portfolio/AddAssetToPortfolioServiceRequest.java new file mode 100644 index 00000000..0f42bfab --- /dev/null +++ b/backend/src/main/java/com/bounswe2024group10/Tradeverse/dto/portfolio/AddAssetToPortfolioServiceRequest.java @@ -0,0 +1,32 @@ +package com.bounswe2024group10.Tradeverse.dto.portfolio; + +public class AddAssetToPortfolioServiceRequest { + + private String username; + private Long assetId; + private double amount; + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public Long getAssetId() { + return assetId; + } + + public void setAssetId(Long assetId) { + this.assetId = assetId; + } + + public double getAmount() { + return amount; + } + + public void setAmount(double amount) { + this.amount = amount; + } +} diff --git a/backend/src/main/java/com/bounswe2024group10/Tradeverse/service/PortfolioService.java b/backend/src/main/java/com/bounswe2024group10/Tradeverse/service/PortfolioService.java index ebc0cf83..0388b937 100644 --- a/backend/src/main/java/com/bounswe2024group10/Tradeverse/service/PortfolioService.java +++ b/backend/src/main/java/com/bounswe2024group10/Tradeverse/service/PortfolioService.java @@ -1,19 +1,23 @@ package com.bounswe2024group10.Tradeverse.service; -import com.bounswe2024group10.Tradeverse.dto.asset.*; -import com.bounswe2024group10.Tradeverse.dto.portfolio.*; -import com.bounswe2024group10.Tradeverse.model.Portfolio; -import com.bounswe2024group10.Tradeverse.model.Asset; -import com.bounswe2024group10.Tradeverse.repository.PortfolioRepository; -import com.bounswe2024group10.Tradeverse.repository.AssetRepository; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Service; import org.springframework.web.client.RestTemplate; -import java.util.List; -import java.util.ArrayList; -import java.util.stream.Collectors; +import com.bounswe2024group10.Tradeverse.dto.asset.YahooFinanceChartResponse; +import com.bounswe2024group10.Tradeverse.dto.portfolio.AddAssetToPortfolioResponse; +import com.bounswe2024group10.Tradeverse.dto.portfolio.AddAssetToPortfolioServiceRequest; +import com.bounswe2024group10.Tradeverse.dto.portfolio.GetPortfolioResponse; +import com.bounswe2024group10.Tradeverse.dto.portfolio.PortfolioDto; +import com.bounswe2024group10.Tradeverse.model.Asset; +import com.bounswe2024group10.Tradeverse.model.Portfolio; +import com.bounswe2024group10.Tradeverse.repository.AssetRepository; +import com.bounswe2024group10.Tradeverse.repository.PortfolioRepository; @Service public class PortfolioService { @@ -24,7 +28,6 @@ public class PortfolioService { @Autowired private AssetRepository assetRepository; - public GetPortfolioResponse getPortfolio(String username) { try { List portfolios = portfolioRepository.findByUsername(username); @@ -63,7 +66,7 @@ public GetPortfolioResponse getPortfolio(String username) { } } - public AddAssetToPortfolioResponse addAssetToPortfolio(AddAssetToPortfolioRequest request) { + public AddAssetToPortfolioResponse addAssetToPortfolio(AddAssetToPortfolioServiceRequest request) { try { // Check if asset exists if (!assetRepository.existsById(request.getAssetId())) { @@ -117,10 +120,10 @@ public GetPortfolioResponse getPortfoliosByAsset(Long assetId) { List portfolioDtos = portfolios.stream() .map(portfolio -> new PortfolioDto( - portfolio.getId(), - asset, - portfolio.getAmount() - )) + portfolio.getId(), + asset, + portfolio.getAmount() + )) .collect(Collectors.toList()); return new GetPortfolioResponse(true, "Portfolios retrieved successfully", null, portfolioDtos, 0.0); diff --git a/backend/src/test/java/service/PortfolioServiceUnitTest.java b/backend/src/test/java/service/PortfolioServiceUnitTest.java index c53f3bcc..086630cd 100644 --- a/backend/src/test/java/service/PortfolioServiceUnitTest.java +++ b/backend/src/test/java/service/PortfolioServiceUnitTest.java @@ -1,20 +1,21 @@ package service; -import com.bounswe2024group10.Tradeverse.dto.portfolio.AddAssetToPortfolioRequest; -import com.bounswe2024group10.Tradeverse.dto.portfolio.AddAssetToPortfolioResponse; -import com.bounswe2024group10.Tradeverse.repository.AssetRepository; -import com.bounswe2024group10.Tradeverse.repository.PortfolioRepository; -import com.bounswe2024group10.Tradeverse.service.PortfolioService; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.mockito.InjectMocks; import org.mockito.Mock; +import static org.mockito.Mockito.when; import org.mockito.MockitoAnnotations; import org.springframework.web.client.RestTemplate; - -import static org.junit.jupiter.api.Assertions.*; -import static org.mockito.Mockito.*; +import com.bounswe2024group10.Tradeverse.dto.portfolio.AddAssetToPortfolioResponse; +import com.bounswe2024group10.Tradeverse.dto.portfolio.AddAssetToPortfolioServiceRequest; +import com.bounswe2024group10.Tradeverse.repository.AssetRepository; +import com.bounswe2024group10.Tradeverse.repository.PortfolioRepository; +import com.bounswe2024group10.Tradeverse.service.PortfolioService; public class PortfolioServiceUnitTest { @@ -37,7 +38,7 @@ public void setUp() { @Test public void testAddAssetToPortfolio_AssetNotFound() { - AddAssetToPortfolioRequest request = new AddAssetToPortfolioRequest(); + AddAssetToPortfolioServiceRequest request = new AddAssetToPortfolioServiceRequest(); when(assetRepository.existsById(2L)).thenReturn(false); AddAssetToPortfolioResponse result = portfolioService.addAssetToPortfolio(request); @@ -48,7 +49,7 @@ public void testAddAssetToPortfolio_AssetNotFound() { @Test public void testAddAssetToPortfolio_AssetFound() { - AddAssetToPortfolioRequest request = new AddAssetToPortfolioRequest(); + AddAssetToPortfolioServiceRequest request = new AddAssetToPortfolioServiceRequest(); when(assetRepository.existsById(1L)).thenReturn(true); AddAssetToPortfolioResponse result = portfolioService.addAssetToPortfolio(request); From 5b68cd0f6db8bde9ccd4afd2ef4403c65734a4b9 Mon Sep 17 00:00:00 2001 From: omerfaruk Date: Wed, 11 Dec 2024 00:59:23 +0300 Subject: [PATCH 06/30] Refactor follower and following responses to use GetUserResponse DTO for enhanced user data representation --- .../dto/follow/GetFollowersResponse.java | 11 +++-- .../dto/follow/GetFollowingsResponse.java | 11 +++-- .../Tradeverse/dto/user/GetUserResponse.java | 42 +++++++++++++++++++ .../Tradeverse/service/FollowService.java | 40 ++++++++++++------ 4 files changed, 84 insertions(+), 20 deletions(-) create mode 100644 backend/src/main/java/com/bounswe2024group10/Tradeverse/dto/user/GetUserResponse.java diff --git a/backend/src/main/java/com/bounswe2024group10/Tradeverse/dto/follow/GetFollowersResponse.java b/backend/src/main/java/com/bounswe2024group10/Tradeverse/dto/follow/GetFollowersResponse.java index 8cdfe3ed..97753e20 100644 --- a/backend/src/main/java/com/bounswe2024group10/Tradeverse/dto/follow/GetFollowersResponse.java +++ b/backend/src/main/java/com/bounswe2024group10/Tradeverse/dto/follow/GetFollowersResponse.java @@ -2,12 +2,15 @@ import java.util.List; +import com.bounswe2024group10.Tradeverse.dto.user.GetUserResponse; + public class GetFollowersResponse { + private boolean isSuccessful; private String message; - private List followers; + private List followers; - public GetFollowersResponse(boolean isSuccessful, String message, List followers) { + public GetFollowersResponse(boolean isSuccessful, String message, List followers) { this.isSuccessful = isSuccessful; this.message = message; this.followers = followers; @@ -29,11 +32,11 @@ public void setMessage(String message) { this.message = message; } - public List getFollowers() { + public List getFollowers() { return followers; } - public void setFollowers(List followers) { + public void setFollowers(List followers) { this.followers = followers; } } diff --git a/backend/src/main/java/com/bounswe2024group10/Tradeverse/dto/follow/GetFollowingsResponse.java b/backend/src/main/java/com/bounswe2024group10/Tradeverse/dto/follow/GetFollowingsResponse.java index f1c269b8..0b827823 100644 --- a/backend/src/main/java/com/bounswe2024group10/Tradeverse/dto/follow/GetFollowingsResponse.java +++ b/backend/src/main/java/com/bounswe2024group10/Tradeverse/dto/follow/GetFollowingsResponse.java @@ -2,12 +2,15 @@ import java.util.List; +import com.bounswe2024group10.Tradeverse.dto.user.GetUserResponse; + public class GetFollowingsResponse { + private boolean isSuccessful; private String message; - private List followings; + private List followings; - public GetFollowingsResponse(boolean isSuccessful, String message, List followings) { + public GetFollowingsResponse(boolean isSuccessful, String message, List followings) { this.isSuccessful = isSuccessful; this.message = message; this.followings = followings; @@ -29,11 +32,11 @@ public void setMessage(String message) { this.message = message; } - public List getFollowings() { + public List getFollowings() { return followings; } - public void setFollowings(List followings) { + public void setFollowings(List followings) { this.followings = followings; } } diff --git a/backend/src/main/java/com/bounswe2024group10/Tradeverse/dto/user/GetUserResponse.java b/backend/src/main/java/com/bounswe2024group10/Tradeverse/dto/user/GetUserResponse.java new file mode 100644 index 00000000..57416f48 --- /dev/null +++ b/backend/src/main/java/com/bounswe2024group10/Tradeverse/dto/user/GetUserResponse.java @@ -0,0 +1,42 @@ +package com.bounswe2024group10.Tradeverse.dto.user; + +public class GetUserResponse { + + private String username; + private String name; + private String userPhoto; + + public GetUserResponse(String username, String name, String userPhoto) { + this.username = username; + this.name = name; + this.userPhoto = userPhoto; + } + + public GetUserResponse() { + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getUserPhoto() { + return userPhoto; + } + + public void setUserPhoto(String userPhoto) { + this.userPhoto = userPhoto; + } + +} diff --git a/backend/src/main/java/com/bounswe2024group10/Tradeverse/service/FollowService.java b/backend/src/main/java/com/bounswe2024group10/Tradeverse/service/FollowService.java index 6b2f6e21..57397568 100644 --- a/backend/src/main/java/com/bounswe2024group10/Tradeverse/service/FollowService.java +++ b/backend/src/main/java/com/bounswe2024group10/Tradeverse/service/FollowService.java @@ -1,18 +1,28 @@ package com.bounswe2024group10.Tradeverse.service; -import com.bounswe2024group10.Tradeverse.dto.follow.*; +import java.util.List; +import java.util.stream.Collectors; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import com.bounswe2024group10.Tradeverse.dto.follow.FollowUserRequest; +import com.bounswe2024group10.Tradeverse.dto.follow.FollowUserResponse; +import com.bounswe2024group10.Tradeverse.dto.follow.GetFollowersRequest; +import com.bounswe2024group10.Tradeverse.dto.follow.GetFollowersResponse; +import com.bounswe2024group10.Tradeverse.dto.follow.GetFollowingsRequest; +import com.bounswe2024group10.Tradeverse.dto.follow.GetFollowingsResponse; +import com.bounswe2024group10.Tradeverse.dto.follow.UnfollowUserRequest; +import com.bounswe2024group10.Tradeverse.dto.follow.UnfollowUserResponse; +import com.bounswe2024group10.Tradeverse.dto.user.GetUserResponse; import com.bounswe2024group10.Tradeverse.model.Follow; import com.bounswe2024group10.Tradeverse.model.User; import com.bounswe2024group10.Tradeverse.repository.FollowRepository; import com.bounswe2024group10.Tradeverse.repository.UserRepository; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; - -import java.util.List; -import java.util.stream.Collectors; @Service public class FollowService { + @Autowired private FollowRepository followRepository; @@ -56,11 +66,14 @@ public GetFollowingsResponse getFollowings(GetFollowingsRequest request) { } List followings = followRepository.findByFollowerUsername(user.getUsername()); - List followedUsernames = followings.stream() - .map(Follow::getFollowedUsername) + List followedUsers = followings.stream() + .map(follow -> userRepository.findByUsername(follow.getFollowedUsername())) + .collect(Collectors.toList()); + List followedUserResponses = followedUsers.stream() + .map(user1 -> new GetUserResponse(user1.getUsername(), user1.getName(), user1.getProfilePhoto())) .collect(Collectors.toList()); - return new GetFollowingsResponse(true, "Followings retrieved successfully", followedUsernames); + return new GetFollowingsResponse(true, "Followings retrieved successfully", followedUserResponses); } public GetFollowersResponse getFollowers(GetFollowersRequest request) { @@ -70,10 +83,13 @@ public GetFollowersResponse getFollowers(GetFollowersRequest request) { } List followers = followRepository.findByFollowedUsername(user.getUsername()); - List followerUsernames = followers.stream() - .map(Follow::getFollowerUsername) + List followerUsers = followers.stream() + .map(follow -> userRepository.findByUsername(follow.getFollowerUsername())) + .collect(Collectors.toList()); + List followerUserResponces = followerUsers.stream() + .map(user1 -> new GetUserResponse(user1.getUsername(), user1.getName(), user1.getProfilePhoto())) .collect(Collectors.toList()); - return new GetFollowersResponse(true, "Followers retrieved successfully", followerUsernames); + return new GetFollowersResponse(true, "Followers retrieved successfully", followerUserResponces); } } From 365b3a2e82d0aad8abe78dee3d5a96c6639e2e6a Mon Sep 17 00:00:00 2001 From: omerfaruk Date: Wed, 11 Dec 2024 03:46:39 +0300 Subject: [PATCH 07/30] Update DataInitializer for admin name, enhance SubforumService visibility, and add search functionality in repositories --- .../Tradeverse/config/DataInitializer.java | 2 +- .../controller/DislikeController.java | 6 +- .../controller/FollowController.java | 5 +- .../Tradeverse/controller/LikeController.java | 5 +- .../controller/SearchController.java | 60 ++++++++ .../Tradeverse/dto/post/PostResponse.java | 137 ++++++++++++++++++ .../repository/AssetRepository.java | 18 ++- .../Tradeverse/repository/PostRepository.java | 11 ++ .../repository/SubforumRepository.java | 11 +- .../Tradeverse/repository/UserRepository.java | 9 +- .../Tradeverse/service/SearchService.java | 118 +++++++++++++++ .../Tradeverse/service/SubforumService.java | 2 +- 12 files changed, 371 insertions(+), 13 deletions(-) create mode 100644 backend/src/main/java/com/bounswe2024group10/Tradeverse/controller/SearchController.java create mode 100644 backend/src/main/java/com/bounswe2024group10/Tradeverse/dto/post/PostResponse.java create mode 100644 backend/src/main/java/com/bounswe2024group10/Tradeverse/service/SearchService.java diff --git a/backend/src/main/java/com/bounswe2024group10/Tradeverse/config/DataInitializer.java b/backend/src/main/java/com/bounswe2024group10/Tradeverse/config/DataInitializer.java index 8aec804d..6e1358c1 100644 --- a/backend/src/main/java/com/bounswe2024group10/Tradeverse/config/DataInitializer.java +++ b/backend/src/main/java/com/bounswe2024group10/Tradeverse/config/DataInitializer.java @@ -26,7 +26,7 @@ public CommandLineRunner initData() { user.setEmail("admin@tradeverse.com"); user.setUsername("admin"); user.setPassword(passwordEncoder.encode("admin")); - user.setName("admin"); + user.setName("admin_name"); user.setTag(0); user.setBio("admin"); user.setIsAdmin(true); diff --git a/backend/src/main/java/com/bounswe2024group10/Tradeverse/controller/DislikeController.java b/backend/src/main/java/com/bounswe2024group10/Tradeverse/controller/DislikeController.java index daff5903..861a43c0 100644 --- a/backend/src/main/java/com/bounswe2024group10/Tradeverse/controller/DislikeController.java +++ b/backend/src/main/java/com/bounswe2024group10/Tradeverse/controller/DislikeController.java @@ -3,7 +3,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.CrossOrigin; -import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; @@ -26,7 +26,7 @@ public class DislikeController { private JwtUtil jwtUtil; @CrossOrigin(origins = "*", allowedHeaders = "*") - @GetMapping("/dislike-post") + @PostMapping("/dislike-post") public ResponseEntity dislikePost(@RequestParam Long postId, @RequestHeader("Authorization") String token) { String username = null; if (token != null && token.startsWith("Bearer ")) { @@ -41,7 +41,7 @@ public ResponseEntity dislikePost(@RequestParam Long postId } @CrossOrigin(origins = "*", allowedHeaders = "*") - @GetMapping("/undislike-post") + @PostMapping("/undislike-post") public ResponseEntity undislikePost(@RequestParam Long postId, @RequestHeader("Authorization") String token) { String username = null; if (token != null && token.startsWith("Bearer ")) { diff --git a/backend/src/main/java/com/bounswe2024group10/Tradeverse/controller/FollowController.java b/backend/src/main/java/com/bounswe2024group10/Tradeverse/controller/FollowController.java index ebd3140d..9ce587e0 100644 --- a/backend/src/main/java/com/bounswe2024group10/Tradeverse/controller/FollowController.java +++ b/backend/src/main/java/com/bounswe2024group10/Tradeverse/controller/FollowController.java @@ -4,6 +4,7 @@ import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.CrossOrigin; import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; @@ -30,7 +31,7 @@ public class FollowController { private JwtUtil jwtUtil; @CrossOrigin(origins = "*", allowedHeaders = "*") - @GetMapping("/follow-user") + @PostMapping("/follow-user") public ResponseEntity followUser(@RequestParam String followedUsername, @RequestHeader("Authorization") String token) { String username = null; if (token != null && token.startsWith("Bearer ")) { @@ -45,7 +46,7 @@ public ResponseEntity followUser(@RequestParam String follow } @CrossOrigin(origins = "*", allowedHeaders = "*") - @GetMapping("/unfollow-user") + @PostMapping("/unfollow-user") public ResponseEntity unfollowUser(@RequestParam String unfollowedUsername, @RequestHeader("Authorization") String token) { String username = null; if (token != null && token.startsWith("Bearer ")) { diff --git a/backend/src/main/java/com/bounswe2024group10/Tradeverse/controller/LikeController.java b/backend/src/main/java/com/bounswe2024group10/Tradeverse/controller/LikeController.java index 4d75cbe3..caff0ba4 100644 --- a/backend/src/main/java/com/bounswe2024group10/Tradeverse/controller/LikeController.java +++ b/backend/src/main/java/com/bounswe2024group10/Tradeverse/controller/LikeController.java @@ -4,6 +4,7 @@ import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.CrossOrigin; import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; @@ -28,7 +29,7 @@ public class LikeController { private JwtUtil jwtUtil; @CrossOrigin(origins = "*", allowedHeaders = "*") - @GetMapping("/like-post") + @PostMapping("/like-post") public ResponseEntity likePost(@RequestParam Long postId, @RequestHeader("Authorization") String token) { String username = null; if (token != null && token.startsWith("Bearer ")) { @@ -43,7 +44,7 @@ public ResponseEntity likePost(@RequestParam Long postId, @Req } @CrossOrigin(origins = "*", allowedHeaders = "*") - @GetMapping("/unlike-post") + @PostMapping("/unlike-post") public ResponseEntity unlikePost(@RequestParam Long postId, @RequestHeader("Authorization") String token) { String username = null; if (token != null && token.startsWith("Bearer ")) { diff --git a/backend/src/main/java/com/bounswe2024group10/Tradeverse/controller/SearchController.java b/backend/src/main/java/com/bounswe2024group10/Tradeverse/controller/SearchController.java new file mode 100644 index 00000000..3a153568 --- /dev/null +++ b/backend/src/main/java/com/bounswe2024group10/Tradeverse/controller/SearchController.java @@ -0,0 +1,60 @@ +package com.bounswe2024group10.Tradeverse.controller; + +import java.util.List; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.CrossOrigin; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import com.bounswe2024group10.Tradeverse.dto.post.PostResponse; +import com.bounswe2024group10.Tradeverse.dto.subforum.AllSubforumResponse; +import com.bounswe2024group10.Tradeverse.dto.user.GetUserResponse; +import com.bounswe2024group10.Tradeverse.model.Asset; +import com.bounswe2024group10.Tradeverse.service.SearchService; +import com.bounswe2024group10.Tradeverse.util.JwtUtil; + +@RestController +@RequestMapping("/api/search") +public class SearchController { + + @Autowired + private SearchService searchService; + + @Autowired + private JwtUtil jwtUtil; + + @CrossOrigin(origins = "*", allowedHeaders = "*") + @GetMapping("/subforum") + public ResponseEntity> searchSubforums(@RequestParam String keyword) { + return ResponseEntity.ok(searchService.searchSubforums(keyword)); + } + + @CrossOrigin(origins = "*", allowedHeaders = "*") + @GetMapping("/tag") + public ResponseEntity> searchTags(@RequestParam String keyword) { + return ResponseEntity.ok(searchService.searchTags(keyword)); + } + + @CrossOrigin(origins = "*", allowedHeaders = "*") + @GetMapping("/user") + public ResponseEntity> searchUsers(@RequestParam String keyword) { + return ResponseEntity.ok(searchService.searchUsers(keyword)); + } + + @CrossOrigin(origins = "*", allowedHeaders = "*") + @GetMapping("/post") + public ResponseEntity> searchPosts(@RequestParam String keyword) { + return ResponseEntity.ok(searchService.searchPosts(keyword)); + } + + @CrossOrigin(origins = "*", allowedHeaders = "*") + @GetMapping("/asset") + public ResponseEntity> searchAssets(@RequestParam String keyword) { + return ResponseEntity.ok(searchService.searchAssets(keyword)); + } + +} diff --git a/backend/src/main/java/com/bounswe2024group10/Tradeverse/dto/post/PostResponse.java b/backend/src/main/java/com/bounswe2024group10/Tradeverse/dto/post/PostResponse.java new file mode 100644 index 00000000..60bccefa --- /dev/null +++ b/backend/src/main/java/com/bounswe2024group10/Tradeverse/dto/post/PostResponse.java @@ -0,0 +1,137 @@ +package com.bounswe2024group10.Tradeverse.dto.post; + +import java.time.LocalDateTime; +import java.util.List; + +import com.bounswe2024group10.Tradeverse.dto.user.UserResponse; +import com.bounswe2024group10.Tradeverse.model.Content; +import com.bounswe2024group10.Tradeverse.model.Subforum; + +public class PostResponse { + + private Long id; + private String title; + private List content; + private String createdBy; + private LocalDateTime creationDate; + private int likeCount; + private int dislikeCount; + private int commentCount; + private UserResponse author; + private Subforum subforum; + + public PostResponse(Long id, String title, List content, String createdBy, + LocalDateTime creationDate, int likeCount, int dislikeCount, + int commentCount, UserResponse author, Subforum subforum) { + this.id = id; + this.title = title; + this.content = content; + this.createdBy = createdBy; + this.creationDate = creationDate; + this.likeCount = likeCount; + this.dislikeCount = dislikeCount; + this.commentCount = commentCount; + this.author = author; + this.subforum = subforum; + } + + public PostResponse(Long id, String title, List content, String createdBy, + LocalDateTime creationDate, int likeCount, int dislikeCount, + int commentCount, String userPhoto, String authorUserName, Subforum subforum) { + this.id = id; + this.title = title; + this.content = content; + this.createdBy = createdBy; + this.creationDate = creationDate; + this.likeCount = likeCount; + this.dislikeCount = dislikeCount; + this.commentCount = commentCount; + this.author = new UserResponse(); + this.author.setUserPhoto(userPhoto); + this.author.setName(authorUserName); + this.subforum = subforum; + } + + public PostResponse() { + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public List getContent() { + return content; + } + + public void setContent(List content) { + this.content = content; + } + + public String getCreatedBy() { + return createdBy; + } + + public void setCreatedBy(String createdBy) { + this.createdBy = createdBy; + } + + public LocalDateTime getCreationDate() { + return creationDate; + } + + public void setCreationDate(LocalDateTime creationDate) { + this.creationDate = creationDate; + } + + public int getLikeCount() { + return likeCount; + } + + public void setLikeCount(int likeCount) { + this.likeCount = likeCount; + } + + public int getDislikeCount() { + return dislikeCount; + } + + public void setDislikeCount(int dislikeCount) { + this.dislikeCount = dislikeCount; + } + + public int getCommentCount() { + return commentCount; + } + + public void setCommentCount(int commentCount) { + this.commentCount = commentCount; + } + + public UserResponse getAuthor() { + return author; + } + + public void setAuthor(UserResponse author) { + this.author = author; + } + + public Subforum getSubforum() { + return subforum; + } + + public void setSubforum(Subforum subforum) { + this.subforum = subforum; + } +} diff --git a/backend/src/main/java/com/bounswe2024group10/Tradeverse/repository/AssetRepository.java b/backend/src/main/java/com/bounswe2024group10/Tradeverse/repository/AssetRepository.java index 6bf2f52d..a03dcf2f 100644 --- a/backend/src/main/java/com/bounswe2024group10/Tradeverse/repository/AssetRepository.java +++ b/backend/src/main/java/com/bounswe2024group10/Tradeverse/repository/AssetRepository.java @@ -1,14 +1,28 @@ package com.bounswe2024group10.Tradeverse.repository; -import com.bounswe2024group10.Tradeverse.model.Asset; +import java.util.List; + import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; + +import com.bounswe2024group10.Tradeverse.model.Asset; public interface AssetRepository extends JpaRepository { + Asset findByName(String name); + Asset findByYahooFinanceSymbol(String yahooFinanceSymbol); + Asset findByTradingViewSymbol(String tradingViewSymbol); + boolean existsById(Long id); + boolean existsByName(String name); + boolean existsByYahooFinanceSymbol(String yahooFinanceSymbol); + boolean existsByTradingViewSymbol(String tradingViewSymbol); -} \ No newline at end of file + + @Query("SELECT a FROM Asset a WHERE a.name LIKE %:keyword% OR a.yahooFinanceSymbol LIKE %:keyword% OR a.tradingViewSymbol LIKE %:keyword%") + List findByKeyword(String keyword); +} diff --git a/backend/src/main/java/com/bounswe2024group10/Tradeverse/repository/PostRepository.java b/backend/src/main/java/com/bounswe2024group10/Tradeverse/repository/PostRepository.java index d3777a7e..5dfa9604 100644 --- a/backend/src/main/java/com/bounswe2024group10/Tradeverse/repository/PostRepository.java +++ b/backend/src/main/java/com/bounswe2024group10/Tradeverse/repository/PostRepository.java @@ -3,8 +3,11 @@ import java.util.List; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Repository; +import com.bounswe2024group10.Tradeverse.model.Content; import com.bounswe2024group10.Tradeverse.model.Post; @Repository @@ -21,4 +24,12 @@ public interface PostRepository extends JpaRepository { int countByCreatedBy(String createdBy); int countBySubforumID(Long subforumID); + + List findByTitleContaining(String keyword); + + @Query("SELECT DISTINCT c FROM Post p JOIN p.content c WHERE c.type = 'tag' AND c.value LIKE %:keyword%") + List findTagsByValueContaining(@Param("keyword") String keyword); + + @Query("SELECT DISTINCT p FROM Post p JOIN p.content c WHERE (c.type = 'text' OR c.type = 'tag') AND c.value LIKE %:keyword% OR p.title LIKE %:keyword%") + List findByTextContaining(@Param("keyword") String keyword); } diff --git a/backend/src/main/java/com/bounswe2024group10/Tradeverse/repository/SubforumRepository.java b/backend/src/main/java/com/bounswe2024group10/Tradeverse/repository/SubforumRepository.java index aefac4c2..212fea87 100644 --- a/backend/src/main/java/com/bounswe2024group10/Tradeverse/repository/SubforumRepository.java +++ b/backend/src/main/java/com/bounswe2024group10/Tradeverse/repository/SubforumRepository.java @@ -1,9 +1,18 @@ package com.bounswe2024group10.Tradeverse.repository; -import com.bounswe2024group10.Tradeverse.model.Subforum; +import java.util.List; + import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; +import com.bounswe2024group10.Tradeverse.model.Subforum; + @Repository public interface SubforumRepository extends JpaRepository { + + List findByNameContaining(String keyword); + + List findByDescriptionContaining(String keyword); + + List findByNameContainingOrDescriptionContaining(String keyword1, String keyword2); } diff --git a/backend/src/main/java/com/bounswe2024group10/Tradeverse/repository/UserRepository.java b/backend/src/main/java/com/bounswe2024group10/Tradeverse/repository/UserRepository.java index a5c941cd..ef36eb8c 100644 --- a/backend/src/main/java/com/bounswe2024group10/Tradeverse/repository/UserRepository.java +++ b/backend/src/main/java/com/bounswe2024group10/Tradeverse/repository/UserRepository.java @@ -1,11 +1,18 @@ package com.bounswe2024group10.Tradeverse.repository; -import com.bounswe2024group10.Tradeverse.model.User; +import java.util.List; + import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; +import com.bounswe2024group10.Tradeverse.model.User; + @Repository public interface UserRepository extends JpaRepository { + User findByUsername(String username); + User findByEmail(String email); + + List findByUsernameContainingOrNameContainingOrBioContaining(String keyword1, String keyword2, String keyword3); } diff --git a/backend/src/main/java/com/bounswe2024group10/Tradeverse/service/SearchService.java b/backend/src/main/java/com/bounswe2024group10/Tradeverse/service/SearchService.java new file mode 100644 index 00000000..747f975d --- /dev/null +++ b/backend/src/main/java/com/bounswe2024group10/Tradeverse/service/SearchService.java @@ -0,0 +1,118 @@ +package com.bounswe2024group10.Tradeverse.service; + +import java.util.ArrayList; +import java.util.List; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import com.bounswe2024group10.Tradeverse.dto.post.PostResponse; +import com.bounswe2024group10.Tradeverse.dto.subforum.AllSubforumResponse; +import com.bounswe2024group10.Tradeverse.dto.user.GetUserResponse; +import com.bounswe2024group10.Tradeverse.model.Asset; +import com.bounswe2024group10.Tradeverse.model.Content; +import com.bounswe2024group10.Tradeverse.model.Post; +import com.bounswe2024group10.Tradeverse.model.Subforum; +import com.bounswe2024group10.Tradeverse.model.User; +import com.bounswe2024group10.Tradeverse.repository.AssetRepository; +import com.bounswe2024group10.Tradeverse.repository.CommentRepository; +import com.bounswe2024group10.Tradeverse.repository.DislikeRepository; +import com.bounswe2024group10.Tradeverse.repository.LikeRepository; +import com.bounswe2024group10.Tradeverse.repository.PostRepository; +import com.bounswe2024group10.Tradeverse.repository.SubforumRepository; +import com.bounswe2024group10.Tradeverse.repository.UserRepository; + +@Service +public class SearchService { + + @Autowired + private SubforumRepository subforumRepository; + + @Autowired + private PostRepository postRepository; + + @Autowired + private UserRepository userRepository; + + @Autowired + private AssetRepository assetRepository; + + @Autowired + private SubforumService subforumService; + + @Autowired + private PostService postService; + + @Autowired + private LikeRepository likeRepository; + + @Autowired + private DislikeRepository dislikeRepository; + + @Autowired + private CommentRepository commentRepository; + + public List searchSubforums(String keyword) { + List subforums = subforumRepository.findByNameContainingOrDescriptionContaining(keyword, keyword); + List response = new ArrayList<>(); + for (Subforum subforum : subforums) { + response.add(subforumService.convertToAllSubforumResponse(subforum)); + } + return response; + } + + public List searchTags(String keyword) { + List tags = new ArrayList<>(); + List contents = postRepository.findTagsByValueContaining(keyword); + for (Content content : contents) { + tags.add(content.getValue()); + } + return tags; + } + + public List searchUsers(String keyword) { + List users = userRepository.findByUsernameContainingOrNameContainingOrBioContaining(keyword, keyword, keyword); + List response = new ArrayList<>(); + for (User user : users) { + response.add(new GetUserResponse(user.getUsername(), user.getName(), user.getProfilePhoto())); + } + return response; + } + + public List searchAssets(String keyword) { + return assetRepository.findByKeyword(keyword); + } + + public List searchPosts(String keyword) { + List posts = postRepository.findByTextContaining(keyword); + List response = new ArrayList<>(); + for (Post post : posts) { + response.add(convertToPostResponse(post)); + } + return response; + } + + private PostResponse convertToPostResponse(Post post) { + post.setViewCount(post.getViewCount() + 1); + int likeCount = likeRepository.countByPostID(post.getId()); + int dislikeCount = dislikeRepository.countByPostID(post.getId()); + int commentCount = commentRepository.countByPostID(post.getId()); + User creatorUser = userRepository.findByUsername(post.getCreatedBy()); + String userPhoto = creatorUser.getProfilePhoto(); + String creatorUserName = creatorUser.getName(); + Subforum subforum = subforumRepository.findById(post.getSubforumID()).orElse(null); + return new PostResponse( + post.getId(), + post.getTitle(), + post.getContent(), + post.getCreatedBy(), + post.getCreationDate(), + likeCount, + dislikeCount, + commentCount, + userPhoto, + creatorUserName, + subforum + ); + } +} diff --git a/backend/src/main/java/com/bounswe2024group10/Tradeverse/service/SubforumService.java b/backend/src/main/java/com/bounswe2024group10/Tradeverse/service/SubforumService.java index a2b54943..604789f1 100644 --- a/backend/src/main/java/com/bounswe2024group10/Tradeverse/service/SubforumService.java +++ b/backend/src/main/java/com/bounswe2024group10/Tradeverse/service/SubforumService.java @@ -45,7 +45,7 @@ public List getAllSubforums() { return response; } - private AllSubforumResponse convertToAllSubforumResponse(Subforum subforum) { + protected AllSubforumResponse convertToAllSubforumResponse(Subforum subforum) { int followerCount = followSubforumRepository.countBySubforumID(subforum.getId()); int postCount = postRepository.countBySubforumID(subforum.getId()); return new AllSubforumResponse(subforum.getId(), subforum.getName(), subforum.getDescription(), subforum.getTagColor(), followerCount, postCount); From 8b6f9c6b2cfe48b66e7555a6c8ee67f88beb0a4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Yasin=20Atl=C4=B1?= Date: Wed, 11 Dec 2024 23:15:57 +0300 Subject: [PATCH 08/30] new-dislike-enpoint-connected --- web/tradeverse/src/services/dislike.js | 31 +++++++++++++++++--------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/web/tradeverse/src/services/dislike.js b/web/tradeverse/src/services/dislike.js index 843da58f..eefbf314 100644 --- a/web/tradeverse/src/services/dislike.js +++ b/web/tradeverse/src/services/dislike.js @@ -1,21 +1,30 @@ import api from "./api"; -export async function dislikePost(postPayload) { +export async function dislikePost(token, postId) { try { - const response = await api.post('/dislike/dislike-post', postPayload); - return response.data; - } - catch (error) { + const response = await api.post(`/dislike/dislike-post?postId=${postId}`, null, { + headers: { + Authorization: `Bearer ${token}`, // Add Authorization header + }, + }); + return response.data; // Return the response data + } catch (error) { console.error("Error liking post:", error); + throw error; // Rethrow the error for the caller to handle } } -export async function undislikePost(postPayload) { + +export async function undislikePost(token, postId) { try { - const response = await api.post('/sidlike/undislike-post', postPayload); - return response.data; - } - catch (error) { - console.error("Error unliking post:", error); + const response = await api.post(`/dislike/undislike-post?postId=${postId}`, null, { + headers: { + Authorization: `Bearer ${token}`, // Add Authorization header + }, + }); + return response.data; // Return the response data + } catch (error) { + console.error("Error liking post:", error); + throw error; // Rethrow the error for the caller to handle } } \ No newline at end of file From b4aeef5dd139d4e008e33ce1ced858b4421fee9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Yasin=20Atl=C4=B1?= Date: Wed, 11 Dec 2024 23:16:10 +0300 Subject: [PATCH 09/30] new-like-enpoint-connected --- web/tradeverse/src/services/like.js | 30 ++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/web/tradeverse/src/services/like.js b/web/tradeverse/src/services/like.js index 41587e85..e8186b7f 100644 --- a/web/tradeverse/src/services/like.js +++ b/web/tradeverse/src/services/like.js @@ -1,21 +1,29 @@ import api from "./api"; -export async function likePost(postPayload) { +export async function likePost(token, postId) { try { - const response = await api.post('/like/like-post', postPayload); - return response.data; - } - catch (error) { + const response = await api.post(`/like/like-post?postId=${postId}`, null, { + headers: { + Authorization: `Bearer ${token}`, // Add Authorization header + }, + }); + return response.data; // Return the response data + } catch (error) { console.error("Error liking post:", error); + throw error; // Rethrow the error for the caller to handle } } -export async function unlikePost(postPayload) { +export async function unlikePost(token, postId) { try { - const response = await api.post('/like/unlike-post', postPayload); - return response.data; - } - catch (error) { + const response = await api.post(`/like/unlike-post?postId=${postId}`, null, { + headers: { + Authorization: `Bearer ${token}`, // Add Authorization header + }, + }); + return response.data; // Return the response data + } catch (error) { console.error("Error unliking post:", error); + throw error; // Rethrow the error for the caller to handle } -} \ No newline at end of file +} From e2ef4bb0b98c34e37025ea7b1b771383208268fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Yasin=20Atl=C4=B1?= Date: Wed, 11 Dec 2024 23:16:19 +0300 Subject: [PATCH 10/30] new-post-enpoint-connected --- web/tradeverse/src/services/post.js | 65 +++++++++++++++++++++++++---- 1 file changed, 58 insertions(+), 7 deletions(-) diff --git a/web/tradeverse/src/services/post.js b/web/tradeverse/src/services/post.js index b95ab501..c482acc3 100644 --- a/web/tradeverse/src/services/post.js +++ b/web/tradeverse/src/services/post.js @@ -41,9 +41,13 @@ export async function feed(username) { } } -export async function getPost(postId) { +export async function getPost(postId,token,userAuthenticated) { try { - const response = await api.get(`/post/get-post?postId=${postId}`); + const response = await api.get(`/post/${postId}` ,{ + headers: { + Authorization: userAuthenticated ? `Bearer ${token}` : "", + }, + }); console.log(response.data); return response.data; } @@ -51,13 +55,60 @@ export async function getPost(postId) { console.error("Error fetching post:", error); } } +export async function getComments(postId) { + try { + const response = await api.get(`/comment/get-comments?postId=${postId}`); + if (response.status >= 200 && response.status < 300) { + return response.data; + } else { + console.error("Unexpected response status:", response.status); + throw new Error(`Failed to fetch comments. Status: ${response.status}`); + } + } catch (error) { + console.error("Error fetching comments:", error); + throw error; + } +} + -export async function createComment(commentPayload) { + +export async function createComment(commentPayload, token) { try { - const response = await api.post('/post/create-comment', commentPayload); - return response.data; + const response = await api.post("/comment/create", commentPayload, { + headers: { + Authorization: `Bearer ${token}`, + "Content-Type": "application/json", + }, + }); + + if (response.status >= 200 && response.status < 300) { + return response.data; // Return the API response directly + } else { + console.error("Unexpected response status:", response.status); + return { isSuccessful: false, message: "Unexpected response status" }; + } + } catch (error) { + console.error("Error creating comment:", error); + return { isSuccessful: false, message: error.message }; } - catch (error) { +} +export async function deleteComment(commentPayload, token) { + try { + const response = await api.post("/comment/delete", commentPayload, { + headers: { + Authorization: `Bearer ${token}`, + "Content-Type": "application/json", + }, + }); + + if (response.status >= 200 && response.status < 300) { + return response.data; // Return the API response directly + } else { + console.error("Unexpected response status:", response.status); + return { isSuccessful: false, message: "Unexpected response status" }; + } + } catch (error) { console.error("Error creating comment:", error); + return { isSuccessful: false, message: error.message }; } -} \ No newline at end of file +} From 9268f9f6d9729ecec67f441f7f510d5d19c50b54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Yasin=20Atl=C4=B1?= Date: Wed, 11 Dec 2024 23:16:33 +0300 Subject: [PATCH 11/30] Home-post-fetching --- web/tradeverse/src/pages/Home.js | 64 +++++++++++++++++++------------- 1 file changed, 39 insertions(+), 25 deletions(-) diff --git a/web/tradeverse/src/pages/Home.js b/web/tradeverse/src/pages/Home.js index a79fda93..780a3989 100644 --- a/web/tradeverse/src/pages/Home.js +++ b/web/tradeverse/src/pages/Home.js @@ -15,35 +15,49 @@ const Home = () => { useEffect(() => { const fetchExplorePosts = async () => { - const data = await explore(); - - if (data.isSuccessful) { - setForYouPosts(data.popularPosts); - if (filterType === "For You") { - setPosts(data.popularPosts); + try { + const headers = { + "Content-Type": "application/json", + }; + + // Conditionally add Authorization header if the user is authenticated + if (user.isAuthenticated) { + const token = localStorage.getItem("authToken"); + console.log("Retrieved Token:", token); + headers.Authorization = `Bearer ${token}`; + } + else{ + headers.Authorization = `Bearer `; + } + + const response = await fetch("http://35.246.188.121:8080/api/post/recent", { + method: "GET", + headers, + }); + + if (!response.ok) { + throw new Error("Failed to fetch posts"); } + + const data = await response.json(); + + if (data && Array.isArray(data)) { + setForYouPosts(data); // Set fetched posts as "For You" posts + if (filterType === "For You") { + setPosts(data); + } + } else { + console.error("Unexpected response format", data); + } + } catch (error) { + console.error("Error fetching explore posts:", error); } - } - // const fetchFeedPosts = async () => { - // const data = await feed(user.name); - // console.log(data); - // if (data.successful) { - // if (data.followedSubforumPosts?.["Post 1"]) { - // setFollowedSubforumsPosts( - // data.followedSubforumPosts["Post 1"].filter((post) => post.postType === "POST") - // ); - // } - // if (data.followedUserPosts?.[user.name]) { - // setFollowedUserPosts( - // data.followedUserPosts[user.name].filter((post) => post.postType === "POST") - // ); - // } - // } - // } - // fetchFeedPosts(); + }; + fetchExplorePosts(); + }, [filterType, user.isAuthenticated]); // Add user.isAuthenticated to dependencies + - }, [filterType]); From 71ce4e34d3cea3555eb8176ed77140379f8a0026 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Yasin=20Atl=C4=B1?= Date: Wed, 11 Dec 2024 23:16:45 +0300 Subject: [PATCH 12/30] new-link-to-post --- web/tradeverse/src/components/structure/subforumNavbar.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/tradeverse/src/components/structure/subforumNavbar.js b/web/tradeverse/src/components/structure/subforumNavbar.js index 268a0f3d..786ee8a3 100644 --- a/web/tradeverse/src/components/structure/subforumNavbar.js +++ b/web/tradeverse/src/components/structure/subforumNavbar.js @@ -19,7 +19,7 @@ const SubforumNavbar = ({ subforums }) => { key={i} className={isSelected ? `${styles.selected}` : ""} > - {subforum.name} + {subforum.name} ); })} From 9d03bb6deb52390144f51942a1c7ea6bbd0e3b16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Yasin=20Atl=C4=B1?= Date: Wed, 11 Dec 2024 23:17:16 +0300 Subject: [PATCH 13/30] PostPage-endpoint-fixes --- web/tradeverse/src/pages/PostPage.js | 126 ++++++++++++++++++++------- 1 file changed, 94 insertions(+), 32 deletions(-) diff --git a/web/tradeverse/src/pages/PostPage.js b/web/tradeverse/src/pages/PostPage.js index d2a73123..759cc64d 100644 --- a/web/tradeverse/src/pages/PostPage.js +++ b/web/tradeverse/src/pages/PostPage.js @@ -1,7 +1,7 @@ import React, { useState, useEffect } from "react"; import Post from "../components/structure/Post"; import Comment from "../components/structure/comment"; -import { getPost, createComment } from "../services/post"; +import { getPost, createComment ,getComments} from "../services/post"; import styles from "./styles/PostPage.module.css"; import { useParams } from "react-router-dom"; import { AuthData } from "../auth/AuthWrapper"; @@ -11,18 +11,47 @@ const PostPage = () => { const { user } = AuthData(); const { parentId, postId } = useParams(); const [post, setPost] = useState(null); + const [comments, setComments] = useState([]); // State to store comments const [newComment, setNewComment] = useState(""); + const [loadingPost, setLoadingPost] = useState(true); // Loading state for post + const [loadingComments, setLoadingComments] = useState(true); // Loading state for comments useEffect(() => { const fetchPost = async () => { - const data = await getPost(postId); - if (data.isSuccessful) { - setPost(data.post); + try { + const token = localStorage.getItem("authToken"); + const data = await getPost(postId, token,user.isAuthenticated); + if (data && data.id && data.title && data.content) { + setPost(data); + } else { + console.error("Invalid post data received:", data); + } + } catch (error) { + console.error("Error fetching post:", error); + } finally { + setLoadingPost(false); + } + }; + + const fetchComments = async () => { + try { + + const data = await getComments(postId); // Fetch comments + if (Array.isArray(data)) { + setComments(data); // Set comments if the response is an array + } else { + console.error("Invalid comments data received:", data); + } + } catch (error) { + console.error("Error fetching comments:", error); + } finally { + setLoadingComments(false); } }; - fetchPost(); - }, [postId]); + fetchPost(); + fetchComments(); + }, [postId,user.isAuthenticated]); const handleNewCommentChange = (e) => { setNewComment(e.target.value); @@ -46,19 +75,29 @@ const PostPage = () => { }; - const handleNewCommentSubmit = async () => { + const handleNewCommentSubmit = async () => { if (!newComment.trim()) return; const commentPayload = { - username: user.name, - parentID: postId, - content: [...parseContent(newComment)] + content: parseContent(newComment), + postID: postId, + parentCommentID: null, // Top-level comment }; - try { - const response = await createComment(commentPayload); // Add comment via API - if (response.successful) { + const token = localStorage.getItem("authToken"); + const response = await createComment(commentPayload, token); // Add comment via API + if (response && response.isSuccessful) { + const newAddedComment = { + id: response.id, + content: commentPayload.content, + createdBy: user.name, + creationDate: new Date().toISOString(), + replies: [], + postID: postId, + parentCommentID: null, + }; + setComments((prevComments) => [...prevComments, newAddedComment]); // Add new comment to the list setNewComment(""); // Clear the input field } else { alert("Failed to add comment."); @@ -68,33 +107,56 @@ const PostPage = () => { alert("Error adding comment."); } }; + const refreshComments = async () => { + try { + const data = await getComments(postId); // Fetch updated comments from API + if (Array.isArray(data)) { + setComments(data); // Update comments state + } else { + console.error("Invalid comments data received:", data); + } + } catch (error) { + console.error("Error refreshing comments:", error); + } + }; // Add a condition to handle when the post is still being fetched or not found + if (loadingPost) { + return

Loading post...

; + } + if (!post) { - return

Loading post or post not found...

; + return

Post not found.

; } return (
{/* Render the Post component with the specific post */} -
-