import { Fragment, useRef, useState } from 'react'; import { useUpdateEffect } from 'react-use'; import clsx from 'clsx'; import { usePrompt } from 'libs/hooks'; import { Answer, createClient, Qualification, Query, Question as QuestionT, } from 'libs/graphql'; import { QUERY_GENERATE_TEST_SIMILAR_QUALIFICATIONS } from '../../queries'; import { QueryGenerateTestSimilarQualificationsArgs } from '../../types'; import { makeStyles } from '@material-ui/core/styles'; import { AppBar, Box, Container, Paper, Tab, Tabs, Typography, } from '@material-ui/core'; import Section from 'common/Section/Section'; import TabPanel from './TabPanel'; import Question from './Question'; import Navigation from './Navigation'; import Summary from './Summary'; import FixedSpinner from './FixedSpinner'; import KeyboardNavigationNote from './KeyboardNavigationNote'; export interface TestProps { initialQuestions: QuestionT[]; qualification: Qualification; } const MIN_QUESTIONS_REQUIRED_TO_SHOW_CONFIRMATION = 2; const Test = ({ initialQuestions, qualification }: TestProps) => { const headingRef = useRef(null); const [isFetching, setIsFetching] = useState(false); const [questions, setQuestions] = useState(initialQuestions); const [selectedAnswers, setSelectedAnswers] = useState( new Array(initialQuestions.length).fill('') ); const [currentTab, setCurrentTab] = useState(0); const [reviewMode, setReviewMode] = useState(false); const [startedAt, setStartedAt] = useState(new Date()); const [endedAt, setEndedAt] = useState(new Date()); const classes = useStyles(); const maxTabIndex = questions.length + (reviewMode ? 1 : 0) - 1; usePrompt(!reviewMode); useUpdateEffect(() => { if (headingRef.current?.scrollIntoView) { headingRef.current?.scrollIntoView({ behavior: 'smooth', block: 'start', }); } }, [currentTab]); useUpdateEffect(() => { resetValues(initialQuestions); }, [qualification, initialQuestions]); const resetValues = ( questions?: Pick['generateTest'] ) => { if (Array.isArray(questions)) { setQuestions(questions); } setStartedAt(new Date()); setEndedAt(new Date()); setSelectedAnswers( new Array((questions ?? initialQuestions).length).fill('') ); setCurrentTab(0); setReviewMode(false); }; const handleSelectAnswer = (index: number, newAnswer: Answer) => { if (selectedAnswers[index] === newAnswer) { return; } setSelectedAnswers(answers => answers.map((oldAnswer, index2) => index2 === index ? newAnswer : oldAnswer ) ); }; const handleReset = async () => { if (isFetching) { return; } try { setIsFetching(true); const { generateTest: newQuestions } = await createClient().request< Pick, QueryGenerateTestSimilarQualificationsArgs >(QUERY_GENERATE_TEST_SIMILAR_QUALIFICATIONS, { limitTest: questions.length, limitSuggestions: 0, skipSuggestions: true, qualificationID: qualification.id, }); resetValues(newQuestions); } catch (e) {} setIsFetching(false); }; const handleFinish = () => { if ( initialQuestions.length >= MIN_QUESTIONS_REQUIRED_TO_SHOW_CONFIRMATION && !window.confirm('Czy na pewno chcesz zakończyć test?') ) { return; } setEndedAt(new Date()); setCurrentTab(currentTab => currentTab + 1); setReviewMode(true); }; const handleGoToNextTab = () => { if (currentTab === maxTabIndex) { return; } setCurrentTab(current => current + 1); }; const handleGoToPrevTab = () => { if (currentTab === 0) { return; } setCurrentTab(current => current - 1); }; return (
{isFetching && }
Kwalifikacja {qualification.code}
{questions.length === 0 ? ( Do tej kwalifikacji nie zostały dodane żadne pytania. ) : ( setCurrentTab(newTab)} > {questions.map((question, index) => { return ( ); })} {questions.map((question, index) => ( handleSelectAnswer(index, answer) } reviewMode={reviewMode} current={currentTab === index} /> ))} )}
); }; const useStyles = makeStyles(theme => { return { incorrect: { color: `${theme.palette.error.main} !important`, }, correct: { color: `${theme.palette.success.main} !important`, }, }; }); export default Test;