Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
67f0583
fix: 질문지 생성 기능에서 유저 payload 가져오기
twalla26 Nov 21, 2024
541656f
fix: 테이블 명을 questionListCategory에서 스네이크 케이스로 변경
twalla26 Nov 21, 2024
42ff9d8
feat: 질문지의 질문 내용 조회 기능
twalla26 Nov 21, 2024
cf21ee6
fix: 질문지 내용을 전달해줄 때 userId 대신 username 전달
twalla26 Nov 21, 2024
9f2618c
feat: 내가 만든 질문지 조회 기능
twalla26 Nov 21, 2024
444fbaa
feat: 질문지 조회 기능에 usage, questionCount 추가
twalla26 Nov 21, 2024
d1cc140
fix: 질문지 리스트 페이지 interface 수정
ShipFriend0516 Nov 21, 2024
cc0b8ab
Merge pull request #192 from twalla26/feature/question-list
ShipFriend0516 Nov 21, 2024
2674566
Merge remote-tracking branch 'upstream/dev' into feature/questions-li…
ShipFriend0516 Nov 21, 2024
e91e14d
feat: vite 환경변수 타입 설정 및 vite.config.ts에서도 환경변수 사용할 수 있도록 구현
ShipFriend0516 Nov 21, 2024
4a877dd
feat: 로딩이 끝났는데 데이터가 하나도 없다면 생성해달라는 문구를 출력하도록 구현
ShipFriend0516 Nov 21, 2024
4ed4e14
feat: 세션 생성 모달창에서 질문지 리스트 불러오는 API 연동
ShipFriend0516 Nov 21, 2024
a1abc23
chore: mock 데이터 제거
ShipFriend0516 Nov 21, 2024
98d3ff9
feat: 각 리스트에 대한 로딩인디케이터 추가
ShipFriend0516 Nov 21, 2024
0221b07
feat: create_room 이벤트에 질문지 아이디 전달
ShipFriend0516 Nov 21, 2024
892ab59
Merge branch 'dev-fe' into feature/questions-list-api
ShipFriend0516 Nov 21, 2024
073b3b4
Merge branch 'dev-fe' into feature/questions-list-api
ShipFriend0516 Nov 21, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions backend/src/question-list/dto/get-all-question-list.dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,6 @@ export interface GetAllQuestionListDto {
id: number;
title: string;
categoryNames: string[];
usage: number;
questionCount: number;
}
10 changes: 10 additions & 0 deletions backend/src/question-list/dto/my-question-list.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { Question } from "../question.entity";

export interface MyQuestionListDto {
id: number;
title: string;
contents: Question[];
categoryNames: string[];
isPublic: boolean;
usage: number;
}
10 changes: 10 additions & 0 deletions backend/src/question-list/dto/question-list-contents.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { Question } from "../question.entity";

export interface QuestionListContentsDto {
id: number;
title: string;
categoryNames: string[];
contents: Question[];
usage: number;
username: string;
}
72 changes: 66 additions & 6 deletions backend/src/question-list/question-list.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,21 @@ import { QuestionListService } from "./question-list.service";
import { CreateQuestionListDto } from "./dto/create-question-list.dto";
import { CreateQuestionDto } from "./dto/create-question.dto";
import { GetAllQuestionListDto } from "./dto/get-all-question-list.dto";
import { QuestionListContentsDto } from "./dto/question-list-contents.dto";
import { AuthGuard } from "@nestjs/passport";
import { JwtPayload } from "../auth/jwt/jwt.decorator";
import { IJwtPayload } from "../auth/jwt/jwt.model";
import { MyQuestionListDto } from "./dto/my-question-list.dto";

@Controller("question-list")
export class QuestionListController {
constructor(private readonly questionService: QuestionListService) {}
constructor(private readonly questionListService: QuestionListService) {}

@Get()
async getAllQuestionLists(@Res() res) {
try {
const allQuestionLists: GetAllQuestionListDto[] =
await this.questionService.getAllQuestionLists();
await this.questionListService.getAllQuestionLists();
return res.send({
success: true,
message: "All question lists received successfully.",
Expand All @@ -41,6 +45,7 @@ export class QuestionListController {
@Post()
@UseGuards(AuthGuard("jwt"))
async createQuestionList(
@JwtPayload() token: IJwtPayload,
@Req() req,
@Res() res,
@Body()
Expand All @@ -59,12 +64,12 @@ export class QuestionListController {
title,
categoryNames,
isPublic,
userId: req.user.userId,
userId: token.userId,
};

// 질문지 생성
const createdQuestionList =
await this.questionService.createQuestionList(
await this.questionListService.createQuestionList(
createQuestionListDto
);

Expand All @@ -76,7 +81,9 @@ export class QuestionListController {

// 질문 생성
const createdQuestions =
await this.questionService.createQuestions(createQuestionDto);
await this.questionListService.createQuestions(
createQuestionDto
);

return res.send({
success: true,
Expand Down Expand Up @@ -106,7 +113,7 @@ export class QuestionListController {
try {
const { categoryName } = body;
const allQuestionLists: GetAllQuestionListDto[] =
await this.questionService.getAllQuestionListsByCategoryName(
await this.questionListService.getAllQuestionListsByCategoryName(
categoryName
);
return res.send({
Expand All @@ -124,4 +131,57 @@ export class QuestionListController {
});
}
}

@Post("contents")
async getQuestionListContents(
@Res() res,
@Body()
body: {
questionListId: number;
}
) {
try {
const { questionListId } = body;
const questionListContents: QuestionListContentsDto =
await this.questionListService.getQuestionListContents(
questionListId
);
return res.send({
success: true,
message: "Question list contents received successfully.",
data: {
questionListContents,
},
});
} catch (error) {
return res.send({
success: false,
message: "Failed to get question list contents.",
error: error.message,
});
}
}

@Get("my")
@UseGuards(AuthGuard("jwt"))
async getMyQuestionLists(@Res() res, @JwtPayload() token: IJwtPayload) {
try {
const userId = token.userId;
const myQuestionLists: MyQuestionListDto[] =
await this.questionListService.getMyQuestionLists(userId);
return res.send({
success: true,
message: "My question lists received successfully.",
data: {
myQuestionLists,
},
});
} catch (error) {
return res.send({
success: false,
message: "Failed to get my question lists.",
error: error.message,
});
}
}
}
2 changes: 1 addition & 1 deletion backend/src/question-list/question-list.entity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ export class QuestionList {
cascade: true,
})
@JoinTable({
name: "questionListCategory",
name: "question_list_category",
joinColumn: {
name: "questionListId",
referencedColumnName: "id",
Expand Down
37 changes: 37 additions & 0 deletions backend/src/question-list/question-list.repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { Question } from "./question.entity";
import { QuestionDto } from "./dto/question.dto";
import { Category } from "./category.entity";
import { QuestionListDto } from "./dto/question-list.dto";
import { User } from "../user/user.entity";

@Injectable()
export class QuestionListRepository {
Expand Down Expand Up @@ -65,4 +66,40 @@ export class QuestionListRepository {
},
});
}

getQuestionListById(questionListId: number) {
return this.dataSource.getRepository(QuestionList).findOne({
where: { id: questionListId },
});
}

getContentsByQuestionListId(questionListId: number) {
return this.dataSource.getRepository(Question).find({
where: { questionListId: questionListId },
});
}

async getUsernameById(userId: number) {
const user = await this.dataSource.getRepository(User).findOne({
where: { id: userId },
});

return user?.username || null;
}

getQuestionListsByUserId(userId: number) {
return this.dataSource.getRepository(QuestionList).find({
where: { userId },
});
}

getQuestionCountByQuestionListId(questionListId: number) {
return this.dataSource
.getRepository(Question)
.createQueryBuilder("question")
.where("question.questionListId = :questionListId", {
questionListId,
})
.getCount();
}
}
82 changes: 80 additions & 2 deletions backend/src/question-list/question-list.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import { CreateQuestionDto } from "./dto/create-question.dto";
import { QuestionDto } from "./dto/question.dto";
import { QuestionListDto } from "./dto/question-list.dto";
import { GetAllQuestionListDto } from "./dto/get-all-question-list.dto";
import { QuestionListContentsDto } from "./dto/question-list-contents.dto";
import { MyQuestionListDto } from "./dto/my-question-list.dto";

@Injectable()
export class QuestionListService {
Expand All @@ -19,16 +21,23 @@ export class QuestionListService {
await this.questionListRepository.findPublicQuestionLists();

for (const publicQuestionList of publicQuestionLists) {
const { id, title } = publicQuestionList;
const { id, title, usage } = publicQuestionList;
const categoryNames: string[] =
await this.questionListRepository.findCategoryNamesByQuestionListId(
id
);

const questionCount =
await this.questionListRepository.getQuestionCountByQuestionListId(
id
);

const questionList: GetAllQuestionListDto = {
id,
title,
categoryNames,
usage,
questionCount,
};
allQuestionLists.push(questionList);
}
Expand All @@ -51,16 +60,23 @@ export class QuestionListService {
);

for (const publicQuestionList of publicQuestionLists) {
const { id, title } = publicQuestionList;
const { id, title, usage } = publicQuestionList;
const categoryNames: string[] =
await this.questionListRepository.findCategoryNamesByQuestionListId(
id
);

const questionCount =
await this.questionListRepository.getQuestionCountByQuestionListId(
id
);

const questionList: GetAllQuestionListDto = {
id,
title,
categoryNames,
usage,
questionCount,
};
allQuestionLists.push(questionList);
}
Expand Down Expand Up @@ -104,4 +120,66 @@ export class QuestionListService {

return await this.questionListRepository.createQuestions(questionDtos);
}

async getQuestionListContents(questionListId: number) {
const questionList =
await this.questionListRepository.getQuestionListById(
questionListId
);
const { id, title, usage, userId } = questionList;

const contents =
await this.questionListRepository.getContentsByQuestionListId(
questionListId
);

const categoryNames =
await this.questionListRepository.findCategoryNamesByQuestionListId(
questionListId
);

const username =
await this.questionListRepository.getUsernameById(userId);

const questionListContents: QuestionListContentsDto = {
id,
title,
contents,
categoryNames,
usage,
username,
};

return questionListContents;
}

async getMyQuestionLists(userId: number) {
const questionLists =
await this.questionListRepository.getQuestionListsByUserId(userId);

const myQuestionLists: MyQuestionListDto[] = [];
for (const myQuestionList of questionLists) {
const { id, title, isPublic, usage } = myQuestionList;
const categoryNames: string[] =
await this.questionListRepository.findCategoryNamesByQuestionListId(
id
);

const contents =
await this.questionListRepository.getContentsByQuestionListId(
id
);

const questionList: MyQuestionListDto = {
id,
title,
contents,
categoryNames,
isPublic,
usage,
};
myQuestionLists.push(questionList);
}
return myQuestionLists;
}
}
4 changes: 2 additions & 2 deletions frontend/src/components/questions/QuestionsPreviewCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ interface QuestionCardProps {
title: string;
questionCount: number;
usage: number;
isStarred: boolean;
isStarred?: boolean;
category: string;
onClick: () => void;
}
Expand All @@ -14,7 +14,7 @@ const QuestionCard = ({
title,
questionCount,
usage,
isStarred,
isStarred = false,
category,
onClick,
}: QuestionCardProps) => {
Expand Down
Loading