소스 검색

created multiSelect and text input for quiz

develop
Ajay_S 3 년 전
부모
커밋
1a66dd07e8
6개의 변경된 파일176개의 추가작업 그리고 34개의 파일을 삭제
  1. +23
    -5
      src/mockData/QuizDetails.ts
  2. +1
    -0
      src/models/QuizDetails.ts
  3. +64
    -1
      src/pages/quiz/Options.module.scss
  4. +65
    -7
      src/pages/quiz/Options.tsx
  5. +19
    -20
      src/pages/quiz/Question.tsx
  6. +4
    -1
      src/pages/quiz/Quiz.tsx

+ 23
- 5
src/mockData/QuizDetails.ts 파일 보기

@@ -11,7 +11,8 @@ const Quiz_Details: QuizDetails[] = [
],
answer: ["System.out.println('Hello, how are you?');"],
result: false,
timeLimit: 10
timeLimit: 10,
type: "singleSelect"
},
{
question: "How do you write 'Hello World' in an alert box?",
@@ -23,7 +24,9 @@ const Quiz_Details: QuizDetails[] = [
],
answer: ["alert('Hello World');"],
result: false,
timeLimit: 10
timeLimit: 10,
type: "singleSelect"

},
{
question: "is javascript",
@@ -35,15 +38,30 @@ const Quiz_Details: QuizDetails[] = [
],
answer: ["B", "C"],
result: false,
timeLimit: 35
timeLimit: 35,
type: "multiSelect"
},
{
question: "Is javascript single threaded or multi threaded? enter the answer in the below box ",
options: [],
answer: ["single threaded"],
result: false,
timeLimit: 40
}
timeLimit: 40,
type: "textInpit"
},
{
question: "is javascript",
options: [
"A",
"B",
"C",
"D"
],
answer: ["B", "C"],
result: false,
timeLimit: 35,
type: "multiSelect"
},
];



+ 1
- 0
src/models/QuizDetails.ts 파일 보기

@@ -4,4 +4,5 @@ export interface QuizDetails {
answer: string[];
result: boolean;
timeLimit: number;
type: string;
}

+ 64
- 1
src/pages/quiz/Options.module.scss 파일 보기

@@ -1,12 +1,75 @@
.optionHolder {
ion-list {
ion-radio-group {

ion-item {
width: 99%;
margin: 0 auto;
--background: white;
border: 1px solid #DBDBDB;
border-radius: 25px;

ion-label {
--color: #626262;
font-size: 1.2rem !important;
font-weight: 200;
}
ion-radio {
--color-checked: var(--primary-button-color);
margin-left: 1.5rem;
}
}

.highlighted {
box-shadow: 0px 0px 10px #00000029;

ion-radio {
--color: var(--primary-button-color);
}
}

// styles for multiselect checkbox
.checkBoxHolder {
border: 0.2rem solid #707070;
border-radius: 2.5rem;
width: 2rem;
height: 2rem;
margin-left: 2rem;

.checkBox {
--background-checked: var(--primary-button-color);
--checkmark-color: var(--primary-button-color);
--border-width: 0;
margin: 0;
margin-top: 0.26rem;
margin-left: 0.27rem;
width: 1.2rem;
height: 1.2rem;
}
}

.multiSelectLabel {
margin-left: 2rem;
}

.options {
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-around;
height: 40vh;


.textInput {
width: 95%;
margin: 0 auto;
width: 30rem;
height: 4rem;
font-size: 1.4rem;
border-radius: 2.5rem;
padding-left: 2rem;
}

ion-item {
width: 99%;
margin: 0 auto;


+ 65
- 7
src/pages/quiz/Options.tsx 파일 보기

@@ -1,17 +1,46 @@
import { IonButton, IonItem, IonLabel, IonList, IonRadio, IonRadioGroup } from '@ionic/react';
import { useState } from 'react';
import { IonButton, IonCheckbox, IonItem, IonLabel, IonList, IonRadio, IonRadioGroup } from '@ionic/react';
import { useEffect, useRef, useState } from 'react';
import Input from '../../components/formInput/Input';
import styles from './Options.module.scss';

interface OwnProps {
options: string[] | undefined;
type: string;
updateQuestionNumber: () => void;
}

const Options: React.FC<OwnProps> = (props) => {

const [selected, setSelected] = useState<string | undefined>(undefined);
const [selectedOptions, setSelectedOptions] = useState<string[]>([]);
const [textInput, setTextInput] = useState<String>("");
const [answers, setAnswers] = useState<string[]>([]);
const inputRef = useRef<HTMLInputElement>(null);

// console.log(selected);

useEffect(() => {
console.log("render");
setSelected(undefined);
setSelectedOptions([]);
}, [props.options]);

const selectChecked = (option: string) => {
let newOption: string[] = [];
if (selectedOptions.includes(option)) {
newOption = selectedOptions.filter(oldOption => oldOption !== option);
} else {
newOption = selectedOptions.concat([option]);
}
setSelectedOptions(newOption);
}

console.log(selectedOptions);
console.log(selected);

const handleInput = () => {
setTextInput(inputRef.current?.value!)
console.log(textInput);
}

const options = props.options!.map((option, key) => {
return (
@@ -22,19 +51,48 @@ const Options: React.FC<OwnProps> = (props) => {
);
});

const MultiSelectOptions = props.options!.map((option, key) => {
return (
<IonItem lines='none' key={key} className={(selectedOptions.includes(option)) ? styles.highlighted : ""}>
<div className={styles.checkBoxHolder}>
<IonCheckbox slot="start" mode='ios' className={styles.checkBox} onIonChange={e => selectChecked(option)} />
</div>
<IonLabel className={styles.multiSelectLabel}>{option}</IonLabel>
</IonItem>
);
});

return (
<div className={styles.optionHolder}>
<IonList>
<IonRadioGroup onIonChange={e => setSelected(e.detail.value)}>
{options}
</IonRadioGroup>
{props.type === "singleSelect" &&
<IonRadioGroup onIonChange={e => setSelected(e.detail.value)} allowEmptySelection={true} className={styles.options}>
{options}
</IonRadioGroup>
}
{props.type === "multiSelect" &&
<div className={styles.options}>
{MultiSelectOptions}
</div>
}
{props.type === "textInpit" &&
<div className={styles.options}>
<input
type="text"
className={styles.textInput}
placeholder="enter your answer"
ref={inputRef}
onChange={handleInput} />
</div>
}

</IonList>

<div className={styles.button + " " + (selected ? styles.active : "")}
onClick={() => props.updateQuestionNumber()}>
<IonButton shape="round" expand='block'>Next</IonButton>
</div>
</div>
</div >
);
}


+ 19
- 20
src/pages/quiz/Question.tsx 파일 보기

@@ -10,29 +10,28 @@ interface OwnProp {
updateQuestionNumber: () => void;
}


let timeout: NodeJS.Timeout;

const Question: React.FC<OwnProp> = (props) => {

const [seconds, setSeconds] = useState<number>(props.timeLimit);
const [duration, setDuration] = useState<number>(props.timeLimit);
const displaySeconds = seconds % 60;

useEffect(() => {
setSeconds(props.timeLimit);
setDuration(props.timeLimit);
}, [props.questionNumber]);
// useEffect(() => {
// setSeconds(props.timeLimit);
// setDuration(props.timeLimit);
// }, [props.questionNumber]);

// useEffect(() => {
// console.log(seconds);
// setTimeout(() => {
// if (seconds > 0) {
// setSeconds(seconds - 1);
// } else {
// props.updateQuestionNumber();
// }
// }, 1000);

useEffect(() => {
setTimeout(() => {
if (seconds > 0) {
setSeconds(seconds - 1);
} else {
props.updateQuestionNumber();
}
}, 1000);
}, [seconds]);
// }, [seconds]);

const renderTime = () => {
return (
@@ -59,12 +58,12 @@ const Question: React.FC<OwnProp> = (props) => {

<CountdownCircleTimer
isPlaying
duration={duration}
duration={0}
colors={'#6BD534'}
size={60}
onComplete={() => {
return { shouldRepeat: true, delay: 1.5 }
}}
// onComplete={() => {
// return { shouldRepeat: true, delay: 1.5 }
// }}
strokeWidth={5} >

{renderTime}


+ 4
- 1
src/pages/quiz/Quiz.tsx 파일 보기

@@ -38,7 +38,10 @@ const Quiz: React.FC = () => {

<div className={styles.quizOptions}>
<div className={styles.options}>
<Options options={Quiz_Details[questionNumber - 1].options} updateQuestionNumber={updateQuestionNumber} />
<Options
options={Quiz_Details[questionNumber - 1].options}
updateQuestionNumber={updateQuestionNumber}
type={Quiz_Details[questionNumber - 1].type} />
</div>

{/* <Link to="/" className={styles.button + " " + (selected ? styles.active : "")}>


불러오는 중...
취소
저장