kj1352 4 лет назад
Родитель
Сommit
c0381f509d
6 измененных файлов: 191 добавлений и 60 удалений
  1. +1
    -1
      src/components/revise/Revise.module.scss
  2. +78
    -11
      src/components/revise/Revise.tsx
  3. +1
    -1
      src/components/revise/options/Options.module.scss
  4. +27
    -37
      src/components/revise/options/Options.tsx
  5. +49
    -1
      src/components/revise/question/Question.module.scss
  6. +35
    -9
      src/components/revise/question/Question.tsx

+ 1
- 1
src/components/revise/Revise.module.scss Просмотреть файл

@@ -12,7 +12,7 @@
font-size: 1.2rem;
font-weight: 700;
color: white;
background-color: var(--teal);
background-color: var(--red);
margin: 0 auto;
display: block;
border: none;


+ 78
- 11
src/components/revise/Revise.tsx Просмотреть файл

@@ -3,33 +3,100 @@ import styles from './Revise.module.scss';

import { Question } from "./question/Question";
import { Summary } from "./summary/Summary";
import { recollectionQuestions } from "../../services/recollectionquestions";
import { MongoShelfWord } from "../../shared/models/shelf";


interface WordWithShelfId extends MongoShelfWord {
shelfId: string
}
import { recollectionQuestions, updateRecollectionQuestion } from "../../services/recollectionquestions";
import { MobileShelf } from "../../shared/models/shelf";
import { MobileUser } from "../../shared/models/user";

export const Revise: React.FC = () => {
const [progressState, setProgressState] = useState<'INTRO' | 'QUESTION' | 'END'>('QUESTION');
const [questions, setQuestions] = useState<Array<WordWithShelfId>>([]);
const [questions, setQuestions] = useState<Array<any>>([]);
const [answeredQuestions, setAnsweredQuestion] = useState<Array<{
wordId: string,
hasRecalled: boolean
}>>([]);

const [currentQuestion, setCurrentQuestion] = useState<number>(0);

useEffect(() => {
recollectionQuestions().then((response: any) => {
setQuestions(response.data);
let questions: Array<any> = response.data;
const curatedQuestions: Array<any> = [];
let allShelves: Array<MobileShelf> = [];
const userProfile: MobileUser = JSON.parse(localStorage.getItem('userProfile') || "");
userProfile.categories.forEach(category => {
category.shelves?.forEach((shelf) => {
allShelves.push(shelf);
});
});

questions.forEach((question) => {
let index = allShelves.findIndex(shelf => shelf._id === question.shelfId);

if (index !== undefined) {
const word = allShelves[index].words?.find(word => word.word._id === question.word)?.word;

if (word !== undefined) {
curatedQuestions.push({
...question,
word: word
})
}

}

});

setQuestions(curatedQuestions);

if (curatedQuestions.length === 0) {
setProgressState('END');
}

}, (e) => {
window.alert("Failed to get questions");
console.log(e);
});
}, []);



return <section className={styles.revisePage}>
{ progressState === 'QUESTION' && <div>
<Question />
{ questions.map((question, index) => {
return currentQuestion === index && <Question key={index} totalQuestions={questions.length} questionNumber={currentQuestion}
word={question.word}
selectOption={(flag) => {
let temp = answeredQuestions;

temp.push({
wordId: question.word._id,
hasRecalled: flag,
});

setAnsweredQuestion(temp);

console.log(question)

setTimeout(() => {

if (currentQuestion < questions.length - 1) {
setCurrentQuestion(currentQuestion + 1);
} else {
setProgressState('END');
}

updateRecollectionQuestion(question.shelfId, question.word._id, flag);

}, 200);

}} />
}) }

<button className={styles.finishButton} onClick={() => setProgressState('END')}>
Finish
Done
</button>
</div> }



+ 1
- 1
src/components/revise/options/Options.module.scss Просмотреть файл

@@ -33,7 +33,7 @@
p {
font-size: 1.2rem;
font-weight: 500;
color: var(--black);
color: var(--grey);
}

.checkmark {


+ 27
- 37
src/components/revise/options/Options.tsx Просмотреть файл

@@ -1,43 +1,33 @@
import React from "react";
import React, { useState } from "react";
import styles from './Options.module.scss';
import { ReactComponent as CheckCircleIcon } from '../../../assets/icons/check.svg';

export const Options: React.FC = () => {
return <ul className={styles.optionsHolder}>
<li className={styles.active}>
<p>
Argentina &amp; Leo Messi
</p>
<div className={styles.checkmark}>
<CheckCircleIcon />
</div>
</li>

<li>
<p>
Brazil &amp; Neymar
</p>
<div className={styles.checkmark}>
</div>
</li>
type OwnProps = {
options: Array<{
text: string,
function:() => void,
}>
}

<li>
<p>
Chile &amp; Sanchez
</p>
<div className={styles.checkmark}>
</div>
</li>
export const Options: React.FC<OwnProps> = (props) => {
const [selectedOption, setSelectedOption] = useState<{
text: string,
function:() => void,
} | undefined>();

<li>
<p>
Mexico &amp; Chicharito
</p>
<div className={styles.checkmark}>
</div>
</li>
</ul>;
return <ul className={styles.optionsHolder}>
{ props.options.map((option, index) => {
return <li key={index} className={selectedOption === option ? styles.active : ''} onClick={() => {
option.function();
setSelectedOption(option);
}}>
<p>
{ option.text }
</p>
{ selectedOption === option && <div className={styles.checkmark} >
<CheckCircleIcon />
</div> }
</li>
}) }
</ul>;
}

+ 49
- 1
src/components/revise/question/Question.module.scss Просмотреть файл

@@ -1,7 +1,7 @@
$common-width: calc(100% - 4rem);

.questionHolder {
height: calc(100vh - 8rem);
height: calc(100vh - 6rem);
padding-top: 2rem;
overflow: auto;
}
@@ -76,4 +76,52 @@ $common-width: calc(100% - 4rem);
.answerTypes {
width: #{$common-width};
margin: 0 auto 2rem;
}

.meaning {
width: $common-width;
margin: 0 auto 2rem;
list-style: none;
position: relative;

&::before {
content: '';
left: 0;
top: 0;
width: 100%;
height: 100%;
background-color: var(--lighter-grey);
position: absolute;
border-radius: 5px;
opacity: 0.95;
transition: opacity 0.5s;
}

&.unblock {
&::before {
opacity: 0;
}
}

li {
margin-bottom: 1rem;

}

p {
font-size: 14px;
color: var(--light-grey);

span {
vertical-align: middle;
}
}
}

.caption {
font-size: 14px;
color: var(--light-grey);
font-style: italic;
width: $common-width;
margin: 0 auto 2rem;
}

+ 35
- 9
src/components/revise/question/Question.tsx Просмотреть файл

@@ -1,22 +1,48 @@
import React from "react";
import React, { useState } from "react";
import styles from './Question.module.scss';
import { ReactComponent as TimeIcon } from '../../../assets/icons/timer.svg';
import { Options } from "../options/Options";
import { Word } from "../../../shared/models/word";

type OwnProps = {
questionNumber: number,
totalQuestions: number,
word: Word,
selectOption: (hasRecalled: boolean) => void,
}

export const Question: React.FC<OwnProps> = (props) => {
const [isMeaningShown, setShowMeaning] = useState<boolean>(false);

export const Question: React.FC = () => {
return <section className={styles.questionHolder}>
<div className={styles.progressBarHolder}>
<span className={styles.progressBar} style={{width: '60%'}}></span>
<span className={styles.text}> 30 </span>
<TimeIcon />
<span className={styles.progressBar} style={{width: (props.questionNumber / props.totalQuestions * 100) + '%'}}></span>
{/* <span className={styles.text}> 30 </span>
<TimeIcon /> */}
</div>

<h3 className={styles.questionCount}> Question 10/<span>10</span> </h3>
<h3 className={styles.questionCount}> Question {props.questionNumber + 1} / <span> { props.totalQuestions } </span> </h3>

<h3 className={styles.question}> Do you recall this word? <br /> <strong> { props.word.name } </strong> </h3>
<ol className={styles.meaning + ' ' + (isMeaningShown ? styles.unblock : '')}
onClick={() => setShowMeaning(true)}>
{ props.word.grammaticalDetails.map((detail, index) => {
return <li key={index}>
<p> <span> - </span> { detail.description } </p>
</li>
}) }
</ol>

<h3 className={styles.question}> Who won Copa America 2021 and who was the Captian? </h3>
{ !isMeaningShown && <p className={styles.caption}> Tap on the blocked section to see the meaning </p> }

<section className={styles.answerTypes}>
<Options />
<Options options={[{
text: 'Yes',
function: () => props.selectOption(true)
}, {
text: 'No',
function: () => props.selectOption(false)
}]} />
</section>
</section>
}

Загрузка…
Отмена
Сохранить