diff --git a/src/features/Quiz/styles.ts b/src/features/Quiz/styles.ts new file mode 100644 index 0000000..9abc8bd --- /dev/null +++ b/src/features/Quiz/styles.ts @@ -0,0 +1,95 @@ +import styled from 'styled-components'; + +//문제(Quiz)의 제목(title)과 문항(question)이 들어갈 공간 +export const QuestionSection = styled.section` + display: flex; + flex-direction: column; + height: 343px; + margin-top: 22px; + border-radius: 2px; + border: 1px solid #afb1b6; + background: #efeff0; + grid-column: 3; + font-size: 1rem; +`; +//답을 적거나 클릭하는 영역을 잡는 스타일 +interface ResponseBoxProps { + $gapColumn?: string; + $gridColumn?: string; + $justifyContent?: string; +} + +export const ResponseBoxSection = styled.section` + display: flex; + justify-content: ${({ $justifyContent }) => $justifyContent || 'center'}; + align-items: center; + flex-wrap: wrap; + background: #efeff0; + grid-column: ${({ $gridColumn }) => $gridColumn || 3}; + margin-top: 20px; + border-radius: 2px; + border: 1px solid #afb1b6; + column-gap: ${({ $gapColumn }) => $gapColumn || '0px'}; +`; +//캐릭터가 들어갈 박스 +interface CharacterBoxProps { + $margin: string; +} + +export const CharacterBox = styled.div` + width: 176px; + height: 115.757px; + border: 2px solid #afb1b6; + background: #efeff0; + margin: ${({ $margin }) => $margin || '0'}; + border-radius: 8px; +`; +//ox유형에서 ox버튼 +export const OXButton = styled.button` + width: 110px; + height: 108px; + border-radius: 10px; +`; +//객관식에서 각 문항 버튼 +export const MultipleChoiceQuestionButton = styled.button` + width: 372px; + height: 26px; + border-radius: 8px; + background: #19191b; + color: #ffffff; + margin-top: 13px; +`; +//단답형 문항에서 단답형을 쓰는 인풋박스 +export const ShortAnswerInput = styled.input` + width: 372px; + height: 23px; +`; +//블럭유형에서 리스트박스를 잡는 리스트 박스 +export const CombinationUl = styled.ul` + display: flex; + grid-column: 3; + flex-wrap: wrap; + gap: 10px; + justify-content: center; + margin: 49px 0 0 0; + padding: 0; + :nth-last-child(1) { + margin-right: auto; + } +`; + +//블럭유형에서 각 텍스트에 해당하는 리스트 스타일 +export const TextBlockLi = styled.li` + border-radius: 8px; + background: #19191b; + color: #ffffff; + list-style-type: none; + padding: 0 20px; + height: 26px; +`; +//화면 하단의 +export const ResponseButton = styled.button` + width: 94px; + height: 26px; + border-radius: 24px; +`; diff --git a/src/features/Quiz/ui/Button.tsx b/src/features/Quiz/ui/Button.tsx new file mode 100644 index 0000000..3837128 --- /dev/null +++ b/src/features/Quiz/ui/Button.tsx @@ -0,0 +1,13 @@ +interface ButtonProps { + buttonName: string; + handleClick: () => void; +} +import { ResponseButton } from '../styles'; +export default function Button({ buttonName, handleClick }: ButtonProps) { + //답을 제출하고 + return ( + <> + {buttonName} + + ); +} diff --git a/src/features/Quiz/ui/Combination.tsx b/src/features/Quiz/ui/Combination.tsx new file mode 100644 index 0000000..635d0bc --- /dev/null +++ b/src/features/Quiz/ui/Combination.tsx @@ -0,0 +1,14 @@ +import Quiz from '../../../types/Quiz'; +import { CombinationUl, TextBlockLi } from '../styles'; + +export default function Combination({ + answerChoice, +}: Pick) { + return ( + + {answerChoice.map(value => ( + {value} + ))} + + ); +} diff --git a/src/features/Quiz/ui/MultipleChoice.tsx b/src/features/Quiz/ui/MultipleChoice.tsx new file mode 100644 index 0000000..3633e2c --- /dev/null +++ b/src/features/Quiz/ui/MultipleChoice.tsx @@ -0,0 +1,15 @@ +import Quiz from '../../../types/Quiz'; +import { MultipleChoiceQuestionButton, ResponseBoxSection } from '../styles'; +export default function MultipleChoice({ + answerChoice, +}: Pick) { + return ( + + {answerChoice.map((value, index) => ( + + {index + 1} : {value} + + ))} + + ); +} diff --git a/src/features/Quiz/ui/OXSelector.tsx b/src/features/Quiz/ui/OXSelector.tsx new file mode 100644 index 0000000..5027420 --- /dev/null +++ b/src/features/Quiz/ui/OXSelector.tsx @@ -0,0 +1,13 @@ +import { OXButton, CharacterBox, ResponseBoxSection } from '../styles'; +export default function OXSelector() { + //OX버튼을 눌러 답을 제출함 + return ( + <> + + + 캐릭터 들어갈예정 + + + + ); +} diff --git a/src/features/Quiz/ui/Question.tsx b/src/features/Quiz/ui/Question.tsx new file mode 100644 index 0000000..4a11372 --- /dev/null +++ b/src/features/Quiz/ui/Question.tsx @@ -0,0 +1,15 @@ +import { QuestionSection } from './../styles'; +interface questiontype { + title: string; + question: string; +} +export default function Question({ title, question }: questiontype) { + return ( + <> + +
title: {title}
+
question: {question}
+
+ + ); +} diff --git a/src/features/Quiz/ui/ShortAnswer.tsx b/src/features/Quiz/ui/ShortAnswer.tsx new file mode 100644 index 0000000..fa9605f --- /dev/null +++ b/src/features/Quiz/ui/ShortAnswer.tsx @@ -0,0 +1,10 @@ +import { ResponseBoxSection, ShortAnswerInput } from '../styles'; +import { CharacterBox } from '../styles'; +export default function ShortAnswer() { + return ( + + + + + ); +} diff --git a/src/pages/Quiz/Quiz.tsx b/src/pages/Quiz/Quiz.tsx new file mode 100644 index 0000000..2537431 --- /dev/null +++ b/src/pages/Quiz/Quiz.tsx @@ -0,0 +1,100 @@ +import Question from '../../features/Quiz/ui/Question'; + +import { AlignCenter } from '../../style/LayOut'; +import { + GridContainer, + HeaderSection, + ProgressSection, + FooterSection, +} from './styles'; +import type Quiz from '../../types/Quiz'; +import { useClientQuizStore } from '../../store/useQuizStore'; +import Button from '../../features/Quiz/ui/Button'; +import Combination from '../../features/Quiz/ui/Combination'; +import MultipleChoice from '../../features/Quiz/ui/MultipleChoice'; +import OXSelector from '../../features/Quiz/ui/OXSelector'; +import ShortAnswer from '../../features/Quiz/ui/ShortAnswer'; +import componentMapping from '../../utils/componentMap'; + +//퀴즈페이지 +export default function Quiz() { + // const { section, part } = useParams(); + const { currentPage, handleNextPage } = useClientQuizStore(); + //대충 가져온 문제들 + const quiz: Quiz[] = [ + //예시 1섹션 1파트에 문제 4개 + //단답형 + { + id: 1, + partId: 1, + sectionId: 1, + title: '실행결과를 쓰시오', + question: 'console.log(1 + 2)', + answer: ['3'], + category: 'ShortAnswer', + answerChoice: [''], + }, + //객관식 + { + id: 2, + partId: 1, + sectionId: 1, + title: '실행결과를 쓰시오', + question: 'console.log(1 + 2)', + answer: ['3'], + category: 'MultipleChoice', + answerChoice: ['1', '4', '3', '7'], + }, + //ox유형 + { + id: 3, + partId: 1, + sectionId: 1, + title: 'OX문제', + question: '1 은 number타입이다?', + answer: ['O'], + category: 'OXSelector', + answerChoice: [''], + }, + //조합형 + { + id: 4, + partId: 1, + sectionId: 1, + title: '빈칸을 채우시오', + question: '[ ].log([ ])', + answer: ['3'], + category: 'Combination', + answerChoice: ['console', '1+2', 'function', '어쩌구저쩌구', '두두두두'], + }, + ]; + const { title, question, category, answer, answerChoice } = quiz[currentPage]; + + const { choice } = componentMapping>({ + //조합식 + Combination, + //객관식 + MultipleChoice, + //ox + OXSelector, + //단답형 + ShortAnswer, + }); + return ( + + + +
로고
+
돈-??-프사
+
+ 진행도 + + {choice(category, { answerChoice })} + +