diff --git a/backend/src/main/java/online/wesal/wesal/controller/PostController.java b/backend/src/main/java/online/wesal/wesal/controller/PostController.java index c649145..fddf4e5 100644 --- a/backend/src/main/java/online/wesal/wesal/controller/PostController.java +++ b/backend/src/main/java/online/wesal/wesal/controller/PostController.java @@ -7,6 +7,7 @@ import online.wesal.wesal.dto.ApiResponse; import online.wesal.wesal.dto.PostCreateRequestDTO; import online.wesal.wesal.dto.PostLikeRequestDTO; import online.wesal.wesal.dto.PostResponseDTO; +import online.wesal.wesal.dto.PostWithLikesResponseDTO; import online.wesal.wesal.entity.Post; import online.wesal.wesal.service.PostService; import online.wesal.wesal.service.UserService; @@ -184,4 +185,32 @@ public class PostController { return ResponseEntity.status(500).body(ApiResponse.error("Something went wrong.. We're sorry but try again later")); } } + + @GetMapping("/get") + @Operation(summary = "Get post by ID", description = "Get a specific post by ID with all liked users (limit 100)") + public ResponseEntity> getPostById( + @RequestParam Long id, + Authentication authentication) { + + try { + if (id == null || id <= 0) { + return ResponseEntity.badRequest().body(ApiResponse.error("Valid post ID is required")); + } + + PostWithLikesResponseDTO response = postService.getPostById(id); + return ResponseEntity.ok(ApiResponse.success(response)); + } catch (RuntimeException e) { + String message; + if (e.getMessage().contains("Post not found")) { + message = "Post not found"; + } else if (e.getMessage().contains("User not found") || e.getMessage().contains("Creator not found")) { + message = "Authentication error. Please log in again."; + } else { + message = "Something went wrong.. We're sorry but try again later"; + } + return ResponseEntity.badRequest().body(ApiResponse.error(message)); + } catch (Exception e) { + return ResponseEntity.status(500).body(ApiResponse.error("Something went wrong.. We're sorry but try again later")); + } + } } \ No newline at end of file diff --git a/backend/src/main/java/online/wesal/wesal/dto/LikedUserDTO.java b/backend/src/main/java/online/wesal/wesal/dto/LikedUserDTO.java new file mode 100644 index 0000000..fe11315 --- /dev/null +++ b/backend/src/main/java/online/wesal/wesal/dto/LikedUserDTO.java @@ -0,0 +1,43 @@ +package online.wesal.wesal.dto; + +import online.wesal.wesal.entity.User; +import java.time.LocalDateTime; + +public class LikedUserDTO { + + private String id; + private String displayName; + private LocalDateTime likeTime; + + public LikedUserDTO() {} + + public LikedUserDTO(User user, LocalDateTime likeTime) { + this.id = String.valueOf(user.getId()); + this.displayName = user.getDisplayName(); + this.likeTime = likeTime; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getDisplayName() { + return displayName; + } + + public void setDisplayName(String displayName) { + this.displayName = displayName; + } + + public LocalDateTime getLikeTime() { + return likeTime; + } + + public void setLikeTime(LocalDateTime likeTime) { + this.likeTime = likeTime; + } +} \ No newline at end of file diff --git a/backend/src/main/java/online/wesal/wesal/dto/PostWithLikesResponseDTO.java b/backend/src/main/java/online/wesal/wesal/dto/PostWithLikesResponseDTO.java new file mode 100644 index 0000000..bf36b86 --- /dev/null +++ b/backend/src/main/java/online/wesal/wesal/dto/PostWithLikesResponseDTO.java @@ -0,0 +1,95 @@ +package online.wesal.wesal.dto; + +import online.wesal.wesal.entity.Post; +import online.wesal.wesal.entity.User; +import java.time.LocalDateTime; +import java.util.List; + +public class PostWithLikesResponseDTO { + + private String id; + private CreatorDTO creator; + private String body; + private String likes; + private String comments; + private boolean liked; + private LocalDateTime creationDate; + private List likedUsers; + + public PostWithLikesResponseDTO() {} + + public PostWithLikesResponseDTO(Post post, User creator, boolean liked, List likedUsers) { + this.id = String.valueOf(post.getId()); + this.creator = new CreatorDTO(creator); + this.body = post.getBody(); + this.likes = String.valueOf(post.getLikes()); + this.comments = String.valueOf(post.getComments()); + this.liked = liked; + this.creationDate = post.getCreationDate(); + this.likedUsers = likedUsers; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public CreatorDTO getCreator() { + return creator; + } + + public void setCreator(CreatorDTO creator) { + this.creator = creator; + } + + public String getBody() { + return body; + } + + public void setBody(String body) { + this.body = body; + } + + public String getLikes() { + return likes; + } + + public void setLikes(String likes) { + this.likes = likes; + } + + public String getComments() { + return comments; + } + + public void setComments(String comments) { + this.comments = comments; + } + + public boolean isLiked() { + return liked; + } + + public void setLiked(boolean liked) { + this.liked = liked; + } + + public LocalDateTime getCreationDate() { + return creationDate; + } + + public void setCreationDate(LocalDateTime creationDate) { + this.creationDate = creationDate; + } + + public List getLikedUsers() { + return likedUsers; + } + + public void setLikedUsers(List likedUsers) { + this.likedUsers = likedUsers; + } +} \ No newline at end of file diff --git a/backend/src/main/java/online/wesal/wesal/repository/PostLikeRepository.java b/backend/src/main/java/online/wesal/wesal/repository/PostLikeRepository.java index ca40e23..f9bfbfd 100644 --- a/backend/src/main/java/online/wesal/wesal/repository/PostLikeRepository.java +++ b/backend/src/main/java/online/wesal/wesal/repository/PostLikeRepository.java @@ -22,4 +22,7 @@ public interface PostLikeRepository extends JpaRepository { @Query("SELECT pl.postId FROM PostLike pl WHERE pl.userId = :userId") Set findAllLikedPostIdsByUserId(@Param("userId") Long userId); + + @Query("SELECT pl FROM PostLike pl WHERE pl.postId = :postId ORDER BY pl.createdAt DESC") + List findByPostIdOrderByCreatedAtDesc(@Param("postId") Long postId); } \ No newline at end of file diff --git a/backend/src/main/java/online/wesal/wesal/service/PostService.java b/backend/src/main/java/online/wesal/wesal/service/PostService.java index 3cbb492..2916e53 100644 --- a/backend/src/main/java/online/wesal/wesal/service/PostService.java +++ b/backend/src/main/java/online/wesal/wesal/service/PostService.java @@ -1,6 +1,8 @@ package online.wesal.wesal.service; +import online.wesal.wesal.dto.LikedUserDTO; import online.wesal.wesal.dto.PostResponseDTO; +import online.wesal.wesal.dto.PostWithLikesResponseDTO; import online.wesal.wesal.entity.Post; import online.wesal.wesal.entity.PostLike; import online.wesal.wesal.entity.User; @@ -155,4 +157,41 @@ public class PostService { return new PostResponseDTO(post, creator, isLiked); } + + public PostWithLikesResponseDTO getPostById(Long postId) { + // Get the post + Post post = postRepository.findById(postId) + .orElseThrow(() -> new RuntimeException("Post not found")); + + // Get the creator + User creator = userRepository.findById(post.getCreatorId()) + .orElseThrow(() -> new RuntimeException("Creator not found")); + + // Get current user to check if they liked the post + User currentUser = userService.getCurrentUser(); + Long currentUserId = currentUser.getId(); + boolean isLiked = postLikeRepository.existsByPostIdAndUserId(postId, currentUserId); + + // Get liked users (limit 100) with their like timestamps + List postLikes = postLikeRepository.findByPostIdOrderByCreatedAtDesc(postId); + List limitedPostLikes = postLikes.stream() + .limit(100) + .collect(Collectors.toList()); + + // Get user IDs for batch fetch + List likedUserIds = limitedPostLikes.stream() + .map(PostLike::getUserId) + .collect(Collectors.toList()); + + // Batch fetch users + Map usersMap = userRepository.findAllById(likedUserIds).stream() + .collect(Collectors.toMap(User::getId, user -> user)); + + // Create LikedUserDTO list + List likedUsers = limitedPostLikes.stream() + .map(postLike -> new LikedUserDTO(usersMap.get(postLike.getUserId()), postLike.getCreatedAt())) + .collect(Collectors.toList()); + + return new PostWithLikesResponseDTO(post, creator, isLiked, likedUsers); + } } \ No newline at end of file