From e3fd38cead51628ccc761843dd7de73348432a1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A5=98=EC=A0=95=EC=9A=B0?= <88191233+jw-r@users.noreply.github.com> Date: Tue, 26 Nov 2024 18:33:13 +0900 Subject: [PATCH] featL select document for create collection (#277) * feat: directory select * feat: select document for collections --- .../collections/create/@header/default.tsx | 2 +- .../(routes)/collections/create/layout.tsx | 2 +- .../select-quiz-from-collection.tsx | 31 +++++++++++----- .../components/selectable-quiz-card/index.tsx | 3 +- .../directory/components/directory-select.tsx | 35 ++++++++++++++----- src/requests/quiz/hooks.ts | 10 +++++- src/requests/quiz/index.tsx | 20 +++++++++-- src/shared/components/ui/select.tsx | 19 ++-------- src/shared/configs/endpoint.ts | 2 ++ src/types/quiz.d.ts | 9 +++++ 10 files changed, 94 insertions(+), 39 deletions(-) diff --git a/src/app/(routes)/collections/create/@header/default.tsx b/src/app/(routes)/collections/create/@header/default.tsx index a7ca9c32..107a98e1 100644 --- a/src/app/(routes)/collections/create/@header/default.tsx +++ b/src/app/(routes)/collections/create/@header/default.tsx @@ -3,7 +3,7 @@ import Text from '@/shared/components/ui/text' const Header = () => { return ( -
+
diff --git a/src/app/(routes)/collections/create/layout.tsx b/src/app/(routes)/collections/create/layout.tsx index 669c45bf..476d6229 100644 --- a/src/app/(routes)/collections/create/layout.tsx +++ b/src/app/(routes)/collections/create/layout.tsx @@ -11,7 +11,7 @@ const Layout: FunctionComponent = ({ header, children }) => { return (
{header} - {children} +
{children}
) } diff --git a/src/features/collection/components/select-quiz-from-collection.tsx b/src/features/collection/components/select-quiz-from-collection.tsx index 7741c090..75c574cc 100644 --- a/src/features/collection/components/select-quiz-from-collection.tsx +++ b/src/features/collection/components/select-quiz-from-collection.tsx @@ -5,21 +5,27 @@ import DirectorySelect from '../../directory/components/directory-select' import FixedBottom from '@/shared/components/custom/fixed-bottom' import { Button } from '@/shared/components/ui/button' import Text from '@/shared/components/ui/text' -import { quizzes } from '@/features/quiz/config' import SelectableQuizCard from './selectable-quiz-card' import { Checkbox } from '@/shared/components/ui/checkbox' import Label from '@/shared/components/ui/label' +import { useDirectories } from '@/requests/directory/hooks' +import { useDirectoryQuizzes } from '@/requests/quiz/hooks' const SelectQuizFromCollection = () => { - // TODO: 전체 or 디렉토리 배열의 첫 번째 요소 | null이면 전체 - const [selectedDirectoryId, setSelectedDirectoryId] = useState(null) + const { data: directoriesData } = useDirectories() + + const [selectedDirectoryId, setSelectedDirectoryId] = useState(null) const [selectedQuizIds, setSelectedQuizIds] = useState([]) const [allChecked, setAllChecked] = useState(false) + const { data: directoryQuizzesData } = useDirectoryQuizzes(selectedDirectoryId) + const handleSelectAllClick = (check: boolean) => { + if (!directoryQuizzesData) return + setAllChecked(check) if (check) { - const quizIds = quizzes.map((quiz) => quiz.id) + const quizIds = directoryQuizzesData.quizzes.map((quiz) => quiz.id) const unSelectedQuizIds = quizIds.filter((quizId) => !selectedQuizIds.includes(quizId)) setSelectedQuizIds([...selectedQuizIds, ...unSelectedQuizIds]) return @@ -36,8 +42,16 @@ const SelectQuizFromCollection = () => { } useEffect(() => { - selectedQuizIds.length === quizzes.length ? setAllChecked(true) : setAllChecked(false) - }, [selectedQuizIds]) + if (!directoriesData) return + setSelectedDirectoryId(directoriesData.directories[0].id) + }, [directoriesData]) + + useEffect(() => { + if (!directoryQuizzesData) return + selectedQuizIds.length === directoryQuizzesData.quizzes.length + ? setAllChecked(true) + : setAllChecked(false) + }, [selectedQuizIds.length, directoryQuizzesData]) const selectedQuizCount = selectedQuizIds.length @@ -45,8 +59,9 @@ const SelectQuizFromCollection = () => {
setSelectedDirectoryId(directoryId ?? null)} + selectDirectoryId={(directoryId: number) => setSelectedDirectoryId(directoryId)} /> {selectedQuizCount}개 선택됨 @@ -61,7 +76,7 @@ const SelectQuizFromCollection = () => {
    - {quizzes.map((quiz) => ( + {directoryQuizzesData?.quizzes.map((quiz) => ( { typography="text1-medium" className={cn('text-text-secondary', selected && 'text-text-accent')} > - {quiz.answer} + {quiz.quizType === 'MIX_UP' && (quiz.answer === 'correct' ? 'O' : 'X')} + {quiz.quizType === 'MULTIPLE_CHOICE' && quiz.answer}
diff --git a/src/features/directory/components/directory-select.tsx b/src/features/directory/components/directory-select.tsx index 3b05197c..fb16c427 100644 --- a/src/features/directory/components/directory-select.tsx +++ b/src/features/directory/components/directory-select.tsx @@ -1,17 +1,34 @@ -import Icon from '@/shared/components/custom/icon' +import { Select, SelectContent, SelectItem, SelectTrigger } from '@/shared/components/ui/select' interface Props { - selectedDirectoryId: string | null - selectDirectoryId: (categoryId?: string) => void + directories: Directory.Item[] + selectedDirectoryId: number | null + selectDirectoryId: (directoryId: number) => void } -const DirectorySelect = ({}: Props) => { +const DirectorySelect = ({ directories, selectedDirectoryId, selectDirectoryId }: Props) => { + const curDirectory = directories.find((directory) => directory.id === selectedDirectoryId) + return ( - + ) } diff --git a/src/requests/quiz/hooks.ts b/src/requests/quiz/hooks.ts index 943ed504..3fa45810 100644 --- a/src/requests/quiz/hooks.ts +++ b/src/requests/quiz/hooks.ts @@ -1,7 +1,7 @@ 'use client' import { useQuery } from '@tanstack/react-query' -import { fetchTodayQuizSetId } from '.' +import { fetchDirectoryQuizzes, fetchTodayQuizSetId } from '.' export const useTodayQuizSetId = () => { return useQuery({ @@ -9,3 +9,11 @@ export const useTodayQuizSetId = () => { queryFn: async () => fetchTodayQuizSetId(), }) } + +export const useDirectoryQuizzes = (directoryId: number | null) => { + return useQuery({ + queryKey: ['directoryQuizzes', directoryId], + queryFn: async () => fetchDirectoryQuizzes({ directoryId: directoryId! }), + enabled: !!directoryId, + }) +} diff --git a/src/requests/quiz/index.tsx b/src/requests/quiz/index.tsx index 96964093..98eab376 100644 --- a/src/requests/quiz/index.tsx +++ b/src/requests/quiz/index.tsx @@ -18,7 +18,6 @@ export const fetchTodayQuizSetId = async () => { ) return data } catch (error: unknown) { - console.error(error) throw error } } @@ -37,7 +36,24 @@ export const fetchQuizSet = async ({ quizSetId }: { quizSetId: string }) => { ) return data } catch (error: unknown) { - console.error(error) + throw error + } +} + +export const fetchDirectoryQuizzes = async ({ directoryId }: { directoryId: number }) => { + const session = await auth() + + try { + const { data } = await http.get( + API_ENDPOINTS.QUIZ.GET.BY_DIRECTORY(directoryId), + { + headers: { + Authorization: `Bearer ${session?.user.accessToken}`, + }, + } + ) + return data + } catch (error: unknown) { throw error } } diff --git a/src/shared/components/ui/select.tsx b/src/shared/components/ui/select.tsx index f8a0d507..fc940d51 100644 --- a/src/shared/components/ui/select.tsx +++ b/src/shared/components/ui/select.tsx @@ -5,6 +5,7 @@ import * as SelectPrimitive from '@radix-ui/react-select' import { Check, ChevronUp } from 'lucide-react' import { cn } from '@/shared/lib/utils' +import Icon from '../custom/icon' const Select = SelectPrimitive.Root @@ -27,7 +28,7 @@ const SelectTrigger = React.forwardRef< {children}
- +
@@ -57,7 +58,7 @@ const SelectScrollDownButton = React.forwardRef< className={cn('flex cursor-default items-center justify-center py-1', className)} {...props} > - + )) SelectScrollDownButton.displayName = SelectPrimitive.ScrollDownButton.displayName @@ -153,17 +154,3 @@ export { SelectScrollUpButton, SelectScrollDownButton, } - -function ChevronDown() { - return ( - - - - ) -} diff --git a/src/shared/configs/endpoint.ts b/src/shared/configs/endpoint.ts index 34ed1157..da8e46fe 100644 --- a/src/shared/configs/endpoint.ts +++ b/src/shared/configs/endpoint.ts @@ -157,6 +157,8 @@ export const API_ENDPOINTS = { REVIEW_PICK: (documentId: number) => `/documents/${documentId}/review-pick`, /** GET /documents/{document_id}/quizzes - document_id에 해당하는 모든 퀴즈 가져오기 */ BY_DOCUMENT: (documentId: number) => `/documents/${documentId}/quizzes`, + /** GET /directories/{directory_id}/quizzes - 디렉토리에 생성된 모든 퀴즈 랜덤하게 가져오기 */ + BY_DIRECTORY: (directoryId: number) => `/directories/${directoryId}/quizzes`, /** GET /documents/{document_id}/download-quiz - 퀴즈 다운로드 */ DOWNLOAD: (documentId: number) => `/documents/${documentId}/download-quiz`, }, diff --git a/src/types/quiz.d.ts b/src/types/quiz.d.ts index 542b8db1..c02dca4b 100644 --- a/src/types/quiz.d.ts +++ b/src/types/quiz.d.ts @@ -146,6 +146,10 @@ interface CreateQuizzesPayload { quizCount: number } +interface GetDirectoryQuizzesResponse { + quizzes: QuizWithMetadata[] +} + declare namespace Quiz { type Item = CombineQuiz type List = CombineQuiz[] @@ -212,6 +216,11 @@ declare namespace Quiz { */ type GetDocumentQuizzes = DocumentQuizzesResponse + /** GET /api/v2/directories/{directory_id}/quizzes + * 디렉토리에 생성된 모든 퀴즈 랜덤하게 가져오기 + */ + type GetDirectoryQuizzes = GetDirectoryQuizzesResponse + /** GET /api/v2/documents/{document_id}/download-quiz * 퀴즈 다운로드 */