From f172a6a51639d214a2226ccc307b12d40ded35d1 Mon Sep 17 00:00:00 2001 From: GeunaNa <155413929+rabyeoljji@users.noreply.github.com> Date: Wed, 4 Dec 2024 17:55:50 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20=ED=80=B4=EC=A6=88=20=EA=B2=B0=EA=B3=BC?= =?UTF-8?q?=20=EC=97=85=EB=8D=B0=EC=9D=B4=ED=8A=B8=20api=20=EC=97=B0?= =?UTF-8?q?=EB=8F=99=20(#293)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit + fix: quiz fetch api 변동 --- src/app/(routes)/quiz/[id]/page.tsx | 20 +++----- src/features/quiz/screen/quiz-view/index.tsx | 16 ++++++ src/features/quiz/utils/index.ts | 18 +++++++ src/requests/quiz/hooks.ts | 7 +++ src/requests/quiz/index.tsx | 54 +++++++++++--------- src/shared/configs/endpoint.ts | 6 +-- src/types/quiz.d.ts | 11 ++++ 7 files changed, 91 insertions(+), 41 deletions(-) diff --git a/src/app/(routes)/quiz/[id]/page.tsx b/src/app/(routes)/quiz/[id]/page.tsx index efb35a39..4249ecbf 100644 --- a/src/app/(routes)/quiz/[id]/page.tsx +++ b/src/app/(routes)/quiz/[id]/page.tsx @@ -1,5 +1,6 @@ import IntroAndQuizView from '@/features/quiz/screen/intro-and-quiz-view' -import { fetchCollectionQuizSet, fetchDocumentQuizSet } from '@/requests/quiz' +import { getQuizSetTypeEnum } from '@/features/quiz/utils' +import { fetchQuizSetById } from '@/requests/quiz' import { notFound } from 'next/navigation' interface Props { @@ -33,18 +34,11 @@ const QuizDetailPage = async ({ params, searchParams }: Props) => { collectionEmoji, } = searchParams - const todayQuizSet = { quizzes: [] } // today quiz list 가져오기 - const documentQuizSet = - quizType === 'document' ? await fetchDocumentQuizSet({ quizSetId: params.id }) : undefined - const collectionQuizSet = - quizType === 'collection' - ? await fetchCollectionQuizSet({ - collectionId: Number(collectionId), - quizSetId: params.id, - }) - : undefined - - const quizSet = documentQuizSet || collectionQuizSet || todayQuizSet + const quizSet = await fetchQuizSetById({ + quizSetId: params.id, + collectionId: quizType === 'collection' ? Number(collectionId) : undefined, + quizSetType: getQuizSetTypeEnum(quizType), + }) const hasDocumentInfo = documentName !== undefined && directoryEmoji !== undefined const hasCollectionInfo = diff --git a/src/features/quiz/screen/quiz-view/index.tsx b/src/features/quiz/screen/quiz-view/index.tsx index ebe68153..cb014a96 100644 --- a/src/features/quiz/screen/quiz-view/index.tsx +++ b/src/features/quiz/screen/quiz-view/index.tsx @@ -12,6 +12,8 @@ import { isQuizSolved } from '../../utils' import ResultIcon from '../../components/result-icon' import ExitDialog from './components/exit-dialog' import { useState } from 'react' +import { useParams, useRouter } from 'next/navigation' +import { useUpdateQuizResult } from '@/requests/quiz/hooks' interface Props { quizzes: Quiz.ItemWithMetadata[] @@ -19,6 +21,9 @@ interface Props { } const QuizView = ({ quizzes, isFirst }: Props) => { + const router = useRouter() + const { id } = useParams() + const { mutate: updateQuizResultMutate } = useUpdateQuizResult() const { currentIndex, navigateToNext } = useQuizNavigation() const { quizResults, showExplanation, totalElapsedTime, setQuizResults, handleNext, isRunning } = useQuizState({ @@ -37,6 +42,17 @@ const QuizView = ({ quizzes, isFirst }: Props) => { navigateToNext(currentIndex) } else { // TODO: 퀴즈 종료 처리 로직 추가 + const quizResultPayload = { + quizSetId: id, + quizzes: quizResults, + } as Quiz.Request.UpdateQuizResult + + updateQuizResultMutate(quizResultPayload, { + onSuccess: () => { + // 퀴즈 결과 페이지로 이동 + router.replace('/') // 임시 + }, + }) } } diff --git a/src/features/quiz/utils/index.ts b/src/features/quiz/utils/index.ts index 6cc9fc59..4838128a 100644 --- a/src/features/quiz/utils/index.ts +++ b/src/features/quiz/utils/index.ts @@ -32,3 +32,21 @@ export const getAnswerText = (answer: string) => { return answer } + +export const getQuizSetTypeEnum = (quizSetType: 'today' | 'document' | 'collection') => { + let enumQuizType: QuizSetType + + switch (quizSetType) { + case 'today': + enumQuizType = 'TODAY_QUIZ_SET' + break + case 'document': + enumQuizType = 'DOCUMENT_QUIZ_SET' + break + case 'collection': + enumQuizType = 'COLLECTION_QUIZ_SET' + break + } + + return enumQuizType +} diff --git a/src/requests/quiz/hooks.ts b/src/requests/quiz/hooks.ts index acd26cea..5b74c5ea 100644 --- a/src/requests/quiz/hooks.ts +++ b/src/requests/quiz/hooks.ts @@ -6,6 +6,7 @@ import { createReplayDocumentQuizSet, fetchDirectoryQuizzes, fetchTodayQuizSetId, + updateQuizResult, } from '.' export const useTodayQuizSetId = () => { @@ -37,3 +38,9 @@ export const useReplayDocumentQuiz = () => { }) => createReplayDocumentQuizSet(payload), }) } + +export const useUpdateQuizResult = () => { + return useMutation({ + mutationFn: async (requestBody: Quiz.Request.UpdateQuizResult) => updateQuizResult(requestBody), + }) +} diff --git a/src/requests/quiz/index.tsx b/src/requests/quiz/index.tsx index ed850385..048af873 100644 --- a/src/requests/quiz/index.tsx +++ b/src/requests/quiz/index.tsx @@ -22,37 +22,26 @@ export const fetchTodayQuizSetId = async () => { } } -export const fetchDocumentQuizSet = async ({ quizSetId }: { quizSetId: string }) => { - const session = await auth() - - try { - const { data } = await http.get( - API_ENDPOINTS.QUIZ.GET.DOCUMENT(quizSetId), - { - headers: { - Authorization: `Bearer ${session?.user.accessToken}`, - }, - } - ) - return data - } catch (error: unknown) { - throw error - } -} - -export const fetchCollectionQuizSet = async ({ - collectionId, +export const fetchQuizSetById = async ({ quizSetId, + collectionId, + quizSetType, }: { - collectionId: number quizSetId: string + collectionId?: number + quizSetType: QuizSetType }) => { const session = await auth() + const params = collectionId + ? { 'collection-id': collectionId, 'quiz-set-type': quizSetType } + : { 'quiz-set-type': quizSetType } + try { - const { data } = await http.get( - API_ENDPOINTS.QUIZ.GET.COLLECTION(collectionId, quizSetId), + const { data } = await http.get( + API_ENDPOINTS.QUIZ.GET.BY_SET_ID(quizSetId), { + params, headers: { Authorization: `Bearer ${session?.user.accessToken}`, }, @@ -176,3 +165,22 @@ export const createReplayDocumentQuizSet = async ({ throw error } } + +export const updateQuizResult = async (requestBody: Quiz.Request.UpdateQuizResult) => { + const session = await auth() + + try { + const { data } = await http.patch( + API_ENDPOINTS.QUIZ.PATCH.UPDATE_RESULT, + requestBody, + { + headers: { + Authorization: `Bearer ${session?.user.accessToken}`, + }, + } + ) + return data + } catch (error: unknown) { + throw error + } +} diff --git a/src/shared/configs/endpoint.ts b/src/shared/configs/endpoint.ts index d95bfc3f..2c8c4606 100644 --- a/src/shared/configs/endpoint.ts +++ b/src/shared/configs/endpoint.ts @@ -156,11 +156,7 @@ export const API_ENDPOINTS = { `/quizzes/${quizSetId}/${quizSetType}/quiz-record`, /** GET /quizzes/quiz-records - 전체 퀴즈 기록 */ ALL_RECORDS: '/quizzes/quiz-records', - /** GET /documents/quiz-sets/{quiz_set_id} - 문서 퀴즈 세트 */ - DOCUMENT: (quizSetId: string) => `/documents/quiz-sets/${quizSetId}`, - /** GET /collections/{collection_id}/quiz-sets/{quiz_set_id} - 컬렉션 퀴즈 세트 */ - COLLECTION: (collectionId: number, quizSetId: string) => - `/collections/${collectionId}/quiz-sets/${quizSetId}`, + BY_SET_ID: (quizSetId: string) => `/quiz-sets/${quizSetId}`, /** GET /quiz-sets/today - 오늘의 퀴즈 세트 정보 가져오기 */ TODAY_SET: '/quiz-sets/today', /** GET /quiz-analysis - 퀴즈 분석 */ diff --git a/src/types/quiz.d.ts b/src/types/quiz.d.ts index cd7f13ea..8aa64223 100644 --- a/src/types/quiz.d.ts +++ b/src/types/quiz.d.ts @@ -83,6 +83,12 @@ interface QuizRecordsResponse extends ConsecutiveDays { quizRecords: QuizSetRecord[] } +/** GET /api/v2/quiz-sets/{quiz_set_id} */ +interface BaseQuizSetResponse { + quizzes: QuizWithMetadata[] + collectionName?: string +} + /** GET /api/v2/documents/quiz-sets/{quiz_set_id} */ interface DocumentQuizSetResponse { quizzes: QuizWithMetadata[] @@ -201,6 +207,11 @@ declare namespace Quiz { */ type GetQuizRecords = QuizRecordsResponse + /** GET /api/v2/quiz-sets/{quiz_set_id} + * quizSet-type과 quizSet_id로 퀴즈 세트 가져오기 + */ + type GetBaseQuizSet = BaseQuizSetResponse + /** GET /api/v2/documents/quiz-sets/{quiz_set_id} * quizSet_id로 문서 퀴즈 세트 가져오기 */