Skip to content

Commit

Permalink
Merge pull request #699 from bounswe/develop
Browse files Browse the repository at this point in the history
[Deploy] Test deploy
  • Loading branch information
mmtftr authored Dec 16, 2024
2 parents 80dbd2d + 42aae89 commit dbb2333
Show file tree
Hide file tree
Showing 65 changed files with 1,935 additions and 711 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -123,9 +123,10 @@ public ResponseEntity<GenericApiResponse<Map<String, Object>>> searchQuestions(
@RequestParam(required = false) String tags,
@RequestParam(required = false) DifficultyLevel difficulty,
@RequestParam(defaultValue = "1") int page,
@RequestParam(defaultValue = "20") int pageSize) {
@RequestParam(defaultValue = "20") int pageSize,
@RequestParam(defaultValue = "recommended") String sortBy) {

Page<Question> questionPage = questionService.searchQuestions(query, tags, difficulty, page, pageSize);
Page<Question> questionPage = questionService.searchQuestions(query, tags, difficulty, page, pageSize, sortBy);

List<QuestionSummaryDto> questionSummaries = questionPage.getContent().stream()
.map(QuestionService::mapToQuestionSummary)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,16 +42,14 @@ public ResponseEntity<GenericApiResponse<SelfProfileResponseDto>> getUser() {
List<QuestionSummaryDto> questions = questionService.findByAuthorId(user.getId());
List<GetAnswerDtoForProfile> answers = answerService.findByAnsweredBy(user.getId());
selfProfileResponseDto.setFollowedTags(
tagService.getFollowedTags(user.getId())
);
tagService.getFollowedTags(user.getId()));
selfProfileResponseDto.setReputationPoints(userService.calculateReputation(user));
selfProfileResponseDto.setQuestionCount((long) questions.size());
selfProfileResponseDto.setQuestions(
questions);
questions);
selfProfileResponseDto.setAnswerCount((long) answers.size());
selfProfileResponseDto.setAnswers(
answers);

answers);

GenericApiResponse<SelfProfileResponseDto> response = ApiResponseBuilder.buildSuccessResponse(
selfProfileResponseDto.getClass(),
Expand Down Expand Up @@ -84,10 +82,13 @@ public ResponseEntity<GenericApiResponse<UserProfileResponseDto>> getUserById(
UserProfileResponseDto.class);
userProfileResponseDto.setReputationPoints(userService.calculateReputation(user.get()));
userProfileResponseDto.setSelfFollowing(userService.selfFollowing(user.get()));
userProfileResponseDto.setFollowedTags(
tagService.getFollowedTags(user.get().getId())
);

List<QuestionSummaryDto> questions = questionService.findByAuthorId(id);
userProfileResponseDto.setQuestions(questions);
userProfileResponseDto.setQuestionCount((long) questions.size());
List<GetAnswerDtoForProfile> answers = answerService.findByAnsweredBy(id);
userProfileResponseDto.setAnswers(answers);
userProfileResponseDto.setAnswerCount((long) answers.size());
userProfileResponseDto.setFollowedTags(tagService.getFollowedTags(id));

GenericApiResponse<UserProfileResponseDto> response = ApiResponseBuilder.buildSuccessResponse(
userProfileResponseDto.getClass(),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
package com.group1.programminglanguagesforum.DTOs.Responses;

import com.group1.programminglanguagesforum.Entities.ExperienceLevel;
import lombok.*;

Expand All @@ -25,5 +26,7 @@ public class UserProfileResponseDto {
private ExperienceLevel experienceLevel;
@Builder.Default
private List<SelfProfileResponseDto.FollowedTags> followedTags = new ArrayList<>();

private Long questionCount;
private List<QuestionSummaryDto> questions;
private List<GetAnswerDtoForProfile> answers;
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,22 @@ Page<Question> searchQuestions(
@Param("difficulty") DifficultyLevel difficulty,
Pageable pageable);

@Query("SELECT DISTINCT q FROM Question q " +
"LEFT JOIN q.tags t " +
"WHERE (:query IS NULL OR " +
" LOWER(q.title) LIKE LOWER(CONCAT('%', :query, '%')) OR " +
" LOWER(q.questionBody) LIKE LOWER(CONCAT('%', :query, '%'))) " +
"AND (:tagIds IS NULL OR t.id IN :tagIds) " +
"AND (:difficulty IS NULL OR q.difficulty = :difficulty) " +
"ORDER BY " +
" CASE WHEN :authorIds IS NOT NULL AND q.askedBy.id IN :authorIds THEN 1 ELSE 0 END DESC")
Page<Question> searchQuestionsByRecommended(
@Param("query") String query,
@Param("authorIds") List<Long> authorIds,
@Param("tagIds") List<Long> tagIds,
@Param("difficulty") DifficultyLevel difficulty,
Pageable pageable);

@Query("SELECT q FROM Question q WHERE q.askedBy.id = :author")
List<Question> findByAuthorId(@Param("author") Long authorId);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.Objects;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
Expand Down Expand Up @@ -218,17 +219,32 @@ public Page<Question> searchQuestions(
String tagIdsStr,
DifficultyLevel difficulty,
int page,
int pageSize) {
int pageSize,
String sortBy) {

List<Long> tagIds = null;
if (tagIdsStr != null && !tagIdsStr.isEmpty()) {
tagIds = Arrays.stream(tagIdsStr.split(","))
.map(Long::parseLong)
.collect(Collectors.toList());
}
User currentUser;
try {
currentUser = userContextService.getCurrentUser();
} catch (UnauthorizedAccessException e) {
currentUser = null;
}

PageRequest pageable = PageRequest.of(page - 1, pageSize);
return questionRepository.searchQuestions(query, tagIds, difficulty, pageable);
if (Objects.equals(sortBy, "default") || Objects.equals(sortBy, null) || Objects.equals(currentUser, null)) {
return questionRepository.searchQuestions(query, tagIds, difficulty, pageable);
} else {
List<Long> authorIds = currentUser.getFollowing().stream()
.map(User::getId) // Map each User to its ID
.collect(Collectors.toList()); // Collect the IDs into a List
return questionRepository.searchQuestionsByRecommended(query, authorIds, tagIds, difficulty, pageable);
}

}

public static QuestionSummaryDto mapToQuestionSummary(Question question) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,13 +101,16 @@ public GetTagDetailsResponseDto getTagDetails(Long tagId) {
following = false;
}

Long followerCount = (long) tagEntity.getFollowers().size();

if (tagType == TagType.PROGRAMMING_LANGUAGE) {
ProgrammingLanguagesTag languageTag = (ProgrammingLanguagesTag) tagEntity;
GetProgrammingLanguageTagResponseDto responseDto = modelMapper.map(languageTag,
GetProgrammingLanguageTagResponseDto.class);
responseDto.setTagType(tagType.toString());
responseDto.setRelatedQuestions(relatedQuestions);
responseDto.setQuestionCount(questionCount);
responseDto.setFollowerCount(followerCount);
responseDto.setFollowing(following);
return responseDto;
} else if (tagType == TagType.PROGRAMMING_PARADIGM) {
Expand All @@ -117,6 +120,7 @@ public GetTagDetailsResponseDto getTagDetails(Long tagId) {
responseDto.setTagType(tagType.toString());
responseDto.setRelatedQuestions(relatedQuestions);
responseDto.setQuestionCount(questionCount);
responseDto.setFollowerCount(followerCount);
responseDto.setFollowing(following);
return responseDto;
}
Expand All @@ -128,6 +132,7 @@ public GetTagDetailsResponseDto getTagDetails(Long tagId) {
.tagType(getTagType(tagEntity).toString())
.relatedQuestions(relatedQuestions)
.questionCount(questionCount)
.followerCount(followerCount)
.following(following)
.build();

Expand All @@ -149,6 +154,7 @@ public Page<GetTagDetailsResponseDto> searchTags(String q, Pageable pageable) {
return tags.map(tag -> GetTagDetailsResponseDto.builder()
.tagId(tag.getId())
.questionCount((long) questionRepository.findQuestionsByTagId(tag.getId()).size())
.followerCount((long) tag.getFollowers().size())
.name(tag.getTagName())
.description(tag.getTagDescription())
.tagType(getTagType(tag).toString())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,4 +107,5 @@ public Page<User> searchUsers(String query, int page, int pageSize) {
public List<User> getFollowing(User user) {
return user.getFollowing().stream().toList();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

import java.util.Arrays;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.Optional;
Expand Down Expand Up @@ -111,7 +112,7 @@ void testGetTagDetails_Success() {
.reputationPoints(0L)
.build();

Tag mockTag = new Tag(1L, null, "Tag1", "Description1", null);
Tag mockTag = new Tag(1L, null, "Tag1", "Description1", new HashSet<>());

Question q1 = Question.builder()
.id(1L)
Expand Down
3 changes: 3 additions & 0 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
"@radix-ui/react-accordion": "^1.1.2",
"@radix-ui/react-aspect-ratio": "^1.0.3",
"@radix-ui/react-avatar": "^1.0.4",
"@radix-ui/react-collapsible": "^1.1.2",
"@radix-ui/react-dialog": "^1.1.2",
"@radix-ui/react-dropdown-menu": "^2.0.6",
"@radix-ui/react-label": "^2.0.2",
Expand All @@ -33,6 +34,8 @@
"@radix-ui/react-slot": "^1.1.0",
"@radix-ui/react-tabs": "^1.0.4",
"@radix-ui/react-toast": "^1.1.5",
"@radix-ui/react-toggle": "^1.1.1",
"@radix-ui/react-toggle-group": "^1.1.1",
"@radix-ui/react-tooltip": "^1.1.3",
"@tailwindcss/typography": "^0.5.15",
"@tanstack/react-query": "^5.35.1",
Expand Down
Binary file added frontend/src/assets/placeholder_profile.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 3 additions & 1 deletion frontend/src/components/AnswerCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Card } from "@/components/ui/card";
import { ArrowRight, CornerDownRight, Star } from "lucide-react";
import React from "react";
import { Link } from "react-router-dom";
import placeholderProfile from "@/assets/placeholder_profile.png";

interface AnswerCardProps {
id: number;
Expand Down Expand Up @@ -48,7 +49,8 @@ export const AnswerCard: React.FC<AnswerCardProps> = ({
<div className="flex items-center justify-between">
<Link to={`/users/${author.id}`} className="h-10 w-10">
<img
src={author.profilePicture}
src={author?.profilePicture ||
placeholderProfile}
alt={"Profile picture"}
className="rounded-full object-cover"
/>
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/components/AnswerItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { ThumbsDown, ThumbsUp } from "lucide-react";
import React from "react";
import { Link } from "react-router-dom";
import { ContentWithSnippets } from "./ContentWithSnippets";
import placeholderProfile from "@/assets/placeholder_profile.png";

interface AnswerItemProps {
answer: AnswerDetails;
Expand Down Expand Up @@ -61,8 +62,7 @@ export const AnswerItem: React.FC<AnswerItemProps> = ({
>
<img
src={
answer.author?.profilePicture ||
"https://placehold.co/100x100"
answer.author?.profilePicture || placeholderProfile
}
alt={"Profile picture"}
className="h-8 w-8 rounded-full object-cover"
Expand Down
7 changes: 7 additions & 0 deletions frontend/src/components/Answers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,13 @@ export function Answers({ questionId }: AnswersProps) {
onDownvote={() => handleVote(answer.id, -1)}
/>
))}
{answers.length === 0 && (
<span>
{" "}
This question doesn't have an answer yet. Contribute to the discussion
by answering this question.
</span>
)}
</div>
);
}
Loading

0 comments on commit dbb2333

Please sign in to comment.