Skip to content

Commit

Permalink
fix: bomb quiz
Browse files Browse the repository at this point in the history
  • Loading branch information
rabyeoljji committed Dec 21, 2024
1 parent c34e6da commit dd78ee3
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 6 deletions.
64 changes: 64 additions & 0 deletions src/features/document/config/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,67 @@ export const quizTypeFilters = [
{ key: 'MULTIPLE_CHOICE', label: '객관식' },
{ key: 'MIX_UP', label: 'O/X' },
] as const

import { z } from 'zod'

// 파일 관련 상수
export const FILE_CONSTRAINTS = {
MIN_CHARS: 1000,
MAX_CHARS: 50000,
MIN_SIZE: 6 * 1024, // 6KB
MAX_SIZE: 12 * 1024 * 1024, // 12MB
SUPPORTED_TYPES: {
PDF: {
mime: 'application/pdf',
extension: '.pdf',
},
DOCX: {
mime: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
extension: '.docx',
},
TXT: {
mime: 'text/plain',
extension: '.txt',
},
},
} as const

// 파일 정보 스키마
export const FileInfoSchema = z.object({
name: z.string().min(1, '파일 이름은 필수입니다'),
size: z
.number()
.min(
FILE_CONSTRAINTS.MIN_SIZE,
'파일 크기가 너무 작습니다. 6KB 이상의 파일만 업로드 가능합니다'
)
.max(FILE_CONSTRAINTS.MAX_SIZE, '12MB 미만의 파일만 업로드 가능합니다'),
charCount: z
.number()
.min(FILE_CONSTRAINTS.MIN_CHARS, '최소 1,000자 이상의 텍스트가 필요합니다')
.max(FILE_CONSTRAINTS.MAX_CHARS, '최대 50,000자까지 업로드 가능합니다'),
content: z.string().min(1, '파일 내용은 필수입니다'),
})

export type FileInfo = z.infer<typeof FileInfoSchema>

// 문서 생성 요청 스키마
export const CreateDocumentSchema = z.object({
directoryId: z.string().min(1, '폴더 선택은 필수입니다'),
documentName: z.string().min(1, '노트 이름은 필수입니다'),
file: z.string().min(1, '노트 내용은 필수입니다'),
quizType: z.enum(['MULTIPLE_CHOICE', 'MIX_UP']),
star: z.string().regex(/^[1-40]$/, '문제 수는 1-40 사이의 숫자여야 합니다'),
documentType: z.enum(['FILE', 'TEXT', 'NOTION']),
})

export type CreateDocumentRequest = z.infer<typeof CreateDocumentSchema>

// validation 유틸리티 함수
export const validateFileInfo = (fileInfo: unknown) => {
return FileInfoSchema.safeParse(fileInfo)
}

export const validateCreateDocument = (data: unknown) => {
return CreateDocumentSchema.safeParse(data)
}
22 changes: 16 additions & 6 deletions src/features/quiz/screen/quiz-view/hooks/use-bomb-quiz.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export const useBombQuiz = (key: Date) => {

const { mutate: updateWrongQuizResultMutate } = useUpdateWrongQuizResult()
// 무한 오답 터뜨리기 구현을 위한 쿼리 분리
// 남은 퀴즈 수가 1개일 때, 미리 서버에서 오답 리스트 불러와서 현재 리스트에 추가
// 남은 퀴즈 수가 3개일 때, 미리 서버에서 오답 리스트 불러와서 현재 리스트에 추가

// 초기 퀴즈 데이터 쿼리 - enabled 옵션으로 한 번만 실행되도록 제어
const { data: initialData, isLoading: isInitialLoading } = useQuery({
Expand All @@ -49,10 +49,10 @@ export const useBombQuiz = (key: Date) => {
}
}, [initialData, shouldFetchInitial])

// leftQuizCount가 1이 되면 추가 데이터를 가져오는 효과
// leftQuizCount가 3이 되면 추가 데이터를 가져오는 효과
useEffect(() => {
const fetchMoreQuizzes = () => {
if (leftQuizCount === 1 && !isLoadingMore) {
if (leftQuizCount === 3 && !isLoadingMore) {
// 추후 확장성을 위해 저장된 배열을 이용하는 코드를 남겨두었습니다
const results = prepareQuizResults(quizResults)

Expand All @@ -64,8 +64,18 @@ export const useBombQuiz = (key: Date) => {
const result = await refetchAdditionalData()

if (result.data?.quizzes) {
const currentQuizId = currentQuizInfo?.id
const addList = result.data.quizzes.filter((quiz) => quiz.id !== currentQuizId)
const lastThreeQuizIds = bombQuizList.map((quiz, index) => {
if (
index === currentIndex ||
index === currentIndex + 1 ||
index === currentIndex + 2
) {
return quiz.id
}
})
const addList = result.data.quizzes.filter(
(quiz) => !lastThreeQuizIds.includes(quiz.id)
)

if (
result.data?.quizzes.length === 1 &&
Expand Down Expand Up @@ -128,7 +138,7 @@ export const useBombQuiz = (key: Date) => {
if (hasNextQuiz) {
navigateToNext(currentIndex)
} else {
window.location.reload()
setBombQuizList([])
}
},
onError: () => {
Expand Down

0 comments on commit dd78ee3

Please sign in to comment.