Add new lives mode and more test options!

Users can now choose from two modes - lives and questions. Lives mode will end when the user makes the chosen number of mistakes. Questions mode will end when the user answers all questions correctly from a list of questions the length of which the user chooses.
This commit is contained in:
2021-09-12 20:26:45 +01:00
parent 069407fa57
commit 42cfa1d619
8 changed files with 585 additions and 54 deletions

78
src/ClassicTestStart.js Normal file
View File

@@ -0,0 +1,78 @@
import React from "react";
import { CloseRounded as CloseRoundedIcon, ArrowForwardRounded as ArrowForwardRoundedIcon } from "@material-ui/icons";
import Button from "./Button";
import Checkbox from '@material-ui/core/Checkbox';
import Slider from "rc-slider";
import "rc-slider/assets/index.css";
export default function ClassicTestStart(props) {
return (
<>
<div className="overlay" onClick={props.hide}></div>
<div className="overlay-content slider-overlay-content">
<h1>Number of Questions</h1>
<div className="slider-container">
<Slider
min={1}
max={props.max}
value={props.sliderValue}
onChange={props.onSliderChange}
railStyle={{
backgroundColor: getComputedStyle(
document.querySelector("#root > div")
).getPropertyValue("--text-color")
.trim(),
border: 0,
}}
handleStyle={{
backgroundColor: getComputedStyle(
document.querySelector("#root > div")
).getPropertyValue("--primary-color")
.trim(),
border: 0,
}}
trackStyle={{
backgroundColor: getComputedStyle(
document.querySelector("#root > div")
).getPropertyValue("--primary-color-tinted")
.trim(),
}}
/>
<input
type="number"
onKeyDown={(event) => !isNaN(Number(event.key))}
onChange={(event) => props.onSliderChange(Number(event.target.value))}
value={props.sliderValue}
min={1}
max={props.max}
size="1"
/>
</div>
<label>
<Checkbox
checked={props.switchLanguage}
onChange={props.handleSwitchLanguageChange}
inputProps={{ 'aria-label': 'checkbox' }}
/>
<span>Swap terms &amp; definitions</span>
</label>
<Button
onClick={() => props.startTest("questions")}
icon={<ArrowForwardRoundedIcon />}
className="button--round continue-button"
loading={props.loading}
></Button>
<Button
onClick={props.hide}
icon={<CloseRoundedIcon />}
className="button--no-background popup-close-button"
></Button>
</div>
</>
)
}

16
src/CountdownTestStart.js Normal file
View File

@@ -0,0 +1,16 @@
import React from "react";
export default function CountdownTestStart(props) {
return (
<>
<div className="overlay" onClick={props.hideTestStart}></div>
<div className="overlay-content options-list-overlay-content">
Awaiting content
<div onClick={props.hideTestStart}>
Cancel
</div>
</div>
</>
)
}

78
src/LivesTestStart.js Normal file
View File

@@ -0,0 +1,78 @@
import React from "react";
import { CloseRounded as CloseRoundedIcon, ArrowForwardRounded as ArrowForwardRoundedIcon } from "@material-ui/icons";
import Button from "./Button";
import Checkbox from '@material-ui/core/Checkbox';
import Slider from "rc-slider";
import "rc-slider/assets/index.css";
export default function LivesTestStart(props) {
return (
<>
<div className="overlay" onClick={props.hide}></div>
<div className="overlay-content slider-overlay-content">
<h1>Number of Lives</h1>
<div className="slider-container">
<Slider
min={1}
max={props.max}
value={props.sliderValue}
onChange={props.onSliderChange}
railStyle={{
backgroundColor: getComputedStyle(
document.querySelector("#root > div")
).getPropertyValue("--text-color")
.trim(),
border: 0,
}}
handleStyle={{
backgroundColor: getComputedStyle(
document.querySelector("#root > div")
).getPropertyValue("--primary-color")
.trim(),
border: 0,
}}
trackStyle={{
backgroundColor: getComputedStyle(
document.querySelector("#root > div")
).getPropertyValue("--primary-color-tinted")
.trim(),
}}
/>
<input
type="number"
onKeyDown={(event) => !isNaN(Number(event.key))}
onChange={(event) => props.onSliderChange(Number(event.target.value))}
value={props.sliderValue}
min={1}
max={props.max}
size="1"
/>
</div>
<label>
<Checkbox
checked={props.switchLanguage}
onChange={props.handleSwitchLanguageChange}
inputProps={{ 'aria-label': 'checkbox' }}
/>
<span>Swap terms &amp; definitions</span>
</label>
<Button
onClick={() => props.startTest("lives")}
icon={<ArrowForwardRoundedIcon />}
className="button--round continue-button"
loading={props.loading}
></Button>
<Button
onClick={props.hide}
icon={<CloseRoundedIcon />}
className="button--no-background popup-close-button"
></Button>
</div>
</>
)
}

View File

@@ -12,9 +12,16 @@ import "firebase/functions";
import Button from './Button';
import LinkButton from './LinkButton';
import Footer from "./Footer";
import TestStart from './TestStart';
import ClassicTestStart from './ClassicTestStart';
import LivesTestStart from './LivesTestStart';
import CountdownTestStart from './CountdownTestStart';
import "./css/Form.css";
import "./css/History.css";
import "./css/LoggedInHome.css";
import "./css/PopUp.css";
import "./css/OptionsListOverlay.css";
import "./css/SliderOverlay.css";
import { withRouter } from "react-router-dom";
@@ -54,6 +61,12 @@ export default withRouter(class LoggedInHome extends React.Component {
}
],
progressHistoryIncomplete: [],
showTestStart: false,
showClassicTestStart: false,
showLivesTestStart: false,
sliderValue: 1,
switchLanguage: false,
totalTestQuestions: 1,
};
let isMounted = true;
@@ -177,15 +190,15 @@ export default withRouter(class LoggedInHome extends React.Component {
});
}
startTest = () => {
startTest = (mode) => {
if (this.state.canStartTest) {
const selections = Object.keys(this.state.selections)
.filter(x => this.state.selections[x]);
this.state.functions.createProgress({
sets: selections,
switch_language: false,
mode: "questions",
limit: 1000,
switch_language: this.state.switchLanguage,
mode: mode,
limit: this.state.sliderValue,
}).then((result) => {
const progressId = result.data;
this.stopLoading();
@@ -231,6 +244,94 @@ export default withRouter(class LoggedInHome extends React.Component {
});
}
showTestStart = () => {
if (this.state.canStartTest) {
this.setState({
showTestStart: true,
totalTestQuestions: 1,
});
}
}
hideTestStart = () => {
this.setState({
showTestStart: false,
});
}
showIndividualTestPrompt = async (mode) => {
if (!this.state.loading) {
if (mode === "classic") {
this.setState({
loading: true,
})
const setIds = Object.keys(this.state.selections)
.filter(x => this.state.selections[x]);
const totalTestQuestions = (await Promise.all(setIds.map((setId) =>
this.state.db.collection("sets")
.doc(setId)
.collection("vocab")
.get()
.then(querySnapshot => querySnapshot.docs.length)
))).reduce((a, b) => a + b);
this.setState({
showTestStart: false,
showClassicTestStart: true,
sliderValue: totalTestQuestions,
switchLanguage: false,
totalTestQuestions: totalTestQuestions,
loading: false,
});
} else if (mode === "lives") {
this.setState({
showTestStart: false,
showLivesTestStart: true,
switchLanguage: false,
sliderValue: 5,
});
} else {
// countdown
// this.setState({
// showTestStart: false,
// showCountdownTestStart: true,
// switchLanguage: false,
// });
}
}
}
hideClassicTestStart = () => {
this.setState({
showClassicTestStart: false,
});
}
hideLivesTestStart = () => {
this.setState({
showLivesTestStart: false,
});
}
hideCountdownTestStart = () => {
this.setState({
showCountdownTestStart: false,
});
}
changeSliderValue = (value) => {
if (value >= 1 && value <= 999) this.setState({
sliderValue: value,
});
}
handleSwitchLanguageChange = (event) => {
this.setState({
switchLanguage: event.target.checked,
});
}
render() {
return (
<div>
@@ -241,8 +342,7 @@ export default withRouter(class LoggedInHome extends React.Component {
<h1>Study</h1>
<div className="button-container buttons--desktop">
<Button
onClick={this.startTest}
loading={this.state.loading}
onClick={this.showTestStart}
disabled={!this.state.canStartTest}
>
Test ({Object.values(this.state.selections).filter(x => x === true).length})
@@ -264,17 +364,39 @@ export default withRouter(class LoggedInHome extends React.Component {
</div>
<LinkButton id="create-set-button-mobile" to="/create-set" icon={<AddRoundedIcon />} className="button--round buttons--mobile"></LinkButton>
</div>
<div className="page-header page-header--left buttons--mobile">
<Button
onClick={this.showTestStart}
disabled={!this.state.canStartTest}
>
Test ({Object.values(this.state.selections).filter(x => x === true).length})
</Button>
<LinkButton
to="/groups"
>
Groups
</LinkButton>
{
this.state.userSets && this.state.userSets.length > 0 &&
<LinkButton
to="/my-sets"
>
My Sets
</LinkButton>
}
</div>
{
this.state.progressHistoryIncomplete.length > 0 &&
<>
<h2>Incomplete Tests</h2>
<div className="progress-history-container">
<div className="progress-history-container progress-history-container--incomplete">
<div>
<h3>Set</h3>
<h3>Progress</h3>
<h3>Mark</h3>
<h3>Grade</h3>
<h3>Mode</h3>
<span></span>
</div>
{
this.state.progressHistoryIncomplete.map((progressItem) =>
@@ -313,28 +435,6 @@ export default withRouter(class LoggedInHome extends React.Component {
</div>
</>
}
<div className="page-header page-header--left buttons--mobile">
<Button
onClick={this.startTest}
loading={this.state.loading}
disabled={!this.state.canStartTest}
>
Test ({Object.values(this.state.selections).filter(x => x === true).length})
</Button>
<LinkButton
to="/groups"
>
Groups
</LinkButton>
{
this.state.userSets && this.state.userSets.length > 0 &&
<LinkButton
to="/my-sets"
>
My Sets
</LinkButton>
}
</div>
<p id="page-intro" className="page-intro">
{
this.state.userSets && this.state.userSets.length > 0
@@ -440,6 +540,48 @@ export default withRouter(class LoggedInHome extends React.Component {
</div>
</main>
<Footer />
{
this.state.showTestStart &&
<TestStart
hideTestStart={this.hideTestStart}
showIndividualTestPrompt={this.showIndividualTestPrompt}
loading={this.state.loading}
/>
}
{
this.state.showClassicTestStart &&
<ClassicTestStart
hide={this.hideClassicTestStart}
startTest={this.startTest}
max={this.state.totalTestQuestions}
sliderValue={this.state.sliderValue}
onSliderChange={this.changeSliderValue}
switchLanguage={this.state.switchLanguage}
handleSwitchLanguageChange={this.handleSwitchLanguageChange}
loading={this.state.loading}
/>
}
{
this.state.showLivesTestStart &&
<LivesTestStart
hide={this.hideLivesTestStart}
startTest={this.startTest}
max={20}
sliderValue={this.state.sliderValue}
onSliderChange={this.changeSliderValue}
switchLanguage={this.state.switchLanguage}
handleSwitchLanguageChange={this.handleSwitchLanguageChange}
loading={this.state.loading}
/>
}
{
this.state.showCountdownTestStart &&
<CountdownTestStart
hide={this.hideCountdownTestStart}
startTest={this.startTest}
/>
}
</div>
)
}

View File

@@ -1,6 +1,6 @@
import React from 'react';
import { withRouter } from "react-router-dom";
import { HomeRounded as HomeRoundedIcon, ArrowForwardRounded as ArrowForwardRoundedIcon, SettingsRounded as SettingsRoundedIcon, CloseRounded as CloseRoundedIcon } from "@material-ui/icons";
import { HomeRounded as HomeRoundedIcon, ArrowForwardRounded as ArrowForwardRoundedIcon, SettingsRounded as SettingsRoundedIcon, CloseRounded as CloseRoundedIcon, PeopleRounded as PeopleRoundedIcon, QuestionAnswerRounded as QuestionAnswerRoundedIcon } from "@material-ui/icons";
import NavBar from "./NavBar";
import Button from "./Button";
import LinkButton from "./LinkButton";
@@ -66,6 +66,9 @@ export default withRouter(class Progress extends React.Component {
attemptHistory: {},
questions: [],
originalTotalQuestions: 1,
lives: 1,
startLives: null,
setComplete: false,
};
let isMounted = true;
@@ -102,10 +105,12 @@ export default withRouter(class Progress extends React.Component {
nextPrompt: null,
setIds: data.setIds,
originalTotalQuestions: [...new Set(data.questions)].length,
setComplete: data.duration !== null,
};
if (data.lives) {
newState.lives = data.lives;
newState.startLives = data.start_lives;
}
return [ newState, data.duration !== null, data.incorrect, data.duration ];
@@ -152,7 +157,7 @@ export default withRouter(class Progress extends React.Component {
.get()
.then((querySnapshot) => {
newState.attemptNumber = querySnapshot.docs.map((doc) => doc.id).indexOf(this.props.match.params.progressId) + 1;
if (newState.attemptNumber > 1)
if (querySnapshot.docs.length > 1)
newState.attemptHistory = querySnapshot.docs.filter((doc) => doc.data().duration !== null)
.map((doc) => ({
x: new Date(doc.data().start_time),
@@ -309,7 +314,9 @@ export default withRouter(class Progress extends React.Component {
});
}
if (data.correct && !data.moreAnswers && this.state.incorrectAnswers[data.currentVocabId]) {
if (this.state.mode === "lives") newState.lives = data.lives;
if ((data.correct || data.lives === 0) && !data.moreAnswers && this.state.incorrectAnswers[data.currentVocabId]) {
// all answers to question given correctly
// answer was previously wrong
// store correct answer
@@ -318,10 +325,11 @@ export default withRouter(class Progress extends React.Component {
} else if (!data.correct) {
// incorrect answer given
// store prompt and count=0
// store answer if in lives mode and no lives left
newState.incorrectAnswers = this.state.incorrectAnswers;
newState.incorrectAnswers[data.currentVocabId] = {
prompt: this.state.currentPrompt,
answer: "",
answer: data.lives === 0 ? data.correctAnswers : "",
count: 0,
};
}
@@ -343,7 +351,7 @@ export default withRouter(class Progress extends React.Component {
.get()
.then((querySnapshot) => {
newState.attemptNumber = querySnapshot.docs.map((doc) => doc.id).indexOf(this.props.match.params.progressId) + 1;
if (newState.attemptNumber > 1)
if (querySnapshot.docs.length > 1)
newState.attemptHistory = querySnapshot.docs.filter((doc) => doc.data().duration !== null)
.map((doc) => ({
x: new Date(doc.data().start_time),
@@ -360,7 +368,7 @@ export default withRouter(class Progress extends React.Component {
}
data.incorrectAnswers.map((vocabId) => {
if (newState.incorrectAnswers[vocabId]) {
if (newState.incorrectAnswers[vocabId] && newState.incorrectAnswers[vocabId].answer !== "") {
// already been logged including prompt and correct answer
newState.incorrectAnswers[vocabId].count++;
} else {
@@ -431,13 +439,14 @@ export default withRouter(class Progress extends React.Component {
};
if (!this.state.moreAnswers) {
if (this.state.nextPrompt === null) newState.setComplete = true;
newState.currentCorrect = [];
newState.currentPrompt = this.state.nextPrompt;
newState.currentSound = this.state.nextSound;
newState.currentSetOwner = this.state.nextSetOwner;
}
this.setState(newState, () => (this.isMounted) && this.answerInput.focus());
this.setState(newState, () => (this.isMounted && !this.state.setComplete) && this.answerInput.focus());
}
}
@@ -464,7 +473,7 @@ export default withRouter(class Progress extends React.Component {
<>
<NavBar items={this.state.navbarItems} />
{
this.state.currentAnswerStatus === null
this.state.currentAnswerStatus === null && !this.state.setComplete
?
<main className="progress-container">
<div>
@@ -512,11 +521,24 @@ export default withRouter(class Progress extends React.Component {
</div>
</main>
:
this.state.nextPrompt === null && !this.state.moreAnswers
this.state.nextPrompt === null && !this.state.moreAnswers && this.state.setComplete
?
<main>
{/* DONE */}
<h1>{this.state.setTitle}</h1>
<div className="page-header">
<h1>
{this.state.setTitle}
<span className="title-icon">
{
this.state.mode === "questions"
?
<QuestionAnswerRoundedIcon />
:
<PeopleRoundedIcon />
}
</span>
</h1>
</div>
<div className="progress-stat-row-container">
<div className="stat-row stat-row--inline">
<p>You got</p>
@@ -534,6 +556,14 @@ export default withRouter(class Progress extends React.Component {
<p>Attempt #</p>
<h1>{this.state.attemptNumber}</h1>
</div>
{
this.state.startLives &&
<div className="stat-row stat-row--inline">
<p>with</p>
<h1>{this.state.startLives}</h1>
<p>lives</p>
</div>
}
</div>
{
this.state.incorrectAnswers && Object.keys(this.state.incorrectAnswers).length > 0 &&
@@ -560,7 +590,7 @@ export default withRouter(class Progress extends React.Component {
</>
}
{this.state.attemptNumber > 1 &&
{Object.keys(this.state.attemptHistory).length > 1 &&
<>
<h2 className="chart-title">History</h2>
<LineChart data={this.state.attemptHistory} />
@@ -625,14 +655,15 @@ export default withRouter(class Progress extends React.Component {
</main>
}
{
(this.state.currentAnswerStatus === null ||
!(this.state.nextPrompt === null && !this.state.moreAnswers)) &&
!this.state.setComplete &&
<ProgressStats
correct={this.state.correct}
incorrect={this.state.incorrect}
totalVocabItems={this.state.originalTotalQuestions}
progressNumerator={this.state.mode === "lives" ? this.state.lives : this.state.correct}
progressDenominator={this.state.mode === "lives" ? this.state.startLives : this.state.originalTotalQuestions}
progress={this.state.progress}
grade={this.state.totalQuestions > 0 ? this.state.correct / this.state.totalQuestions * 100 : 0}
grade={(this.state.correct + this.state.incorrect) > 0 ? this.state.correct / (this.state.correct + this.state.incorrect) * 100 : 0}
maxQuestions={this.state.mode === "lives" ? this.state.originalTotalQuestions : null}
/>
}
<Footer />

View File

@@ -10,7 +10,17 @@ export default function ProgressStats(props) {
</div>
<div className="stat-row stat-row--inline">
<h1>{props.correct}</h1>
{
props.maxQuestions
?
<>
<p>correct of</p>
<h1>{props.maxQuestions}</h1>
<p>possible questions</p>
</>
:
<p>correct</p>
}
</div>
<div className="stat-row stat-row--inline">
<h1>{props.incorrect}</h1>
@@ -22,8 +32,8 @@ export default function ProgressStats(props) {
</div>
</div>
<div className="progress-bar">
<div style={{ width: props.correct > 0 && props.totalVocabItems > 0 ? `${(props.correct / props.totalVocabItems * 100)}%` : "0" }}>
<p>{props.correct}/{props.totalVocabItems}</p>
<div style={{ width: props.progressNumerator > 0 && props.progressDenominator > 0 ? `${(props.progressNumerator / props.progressDenominator * 100)}%` : "0" }}>
<p>{props.progressNumerator}/{props.progressDenominator}</p>
</div>
</div>
</div>

View File

@@ -6,6 +6,10 @@ import Button from "./Button";
import LinkButton from "./LinkButton";
import Error404 from "./Error404";
import Footer from "./Footer";
import TestStart from './TestStart';
import ClassicTestStart from './ClassicTestStart';
import LivesTestStart from './LivesTestStart';
import CountdownTestStart from './CountdownTestStart';
import "./css/PopUp.css";
import "./css/SetPage.css";
@@ -43,6 +47,12 @@ export default withRouter(class SetPage extends React.Component {
groups: {},
currentSetGroups: [],
showDeleteConfirmation: false,
showTestStart: false,
showClassicTestStart: false,
showLivesTestStart: false,
sliderValue: 1,
switchLanguage: false,
totalTestQuestions: 1,
};
let isMounted = true;
@@ -113,13 +123,13 @@ export default withRouter(class SetPage extends React.Component {
});
}
startTest = () => {
startTest = (mode) => {
if (this.state.canStartTest) {
this.state.functions.createProgress({
sets: [this.props.match.params.setId],
switch_language: false,
mode: "questions",
limit: 1000,
switch_language: this.state.switchLanguage,
mode: mode,
limit: this.state.sliderValue,
}).then((result) => {
const progressId = result.data;
this.stopLoading();
@@ -233,6 +243,94 @@ export default withRouter(class SetPage extends React.Component {
});
}
showTestStart = () => {
if (this.state.canStartTest) {
this.setState({
showTestStart: true,
totalTestQuestions: 1,
});
}
}
hideTestStart = () => {
this.setState({
showTestStart: false,
});
}
showIndividualTestPrompt = async (mode) => {
if (!this.state.loading) {
if (mode === "classic") {
this.setState({
loading: true,
})
const setIds = Object.keys(this.state.selections)
.filter(x => this.state.selections[x]);
const totalTestQuestions = (await Promise.all(setIds.map((setId) =>
this.state.db.collection("sets")
.doc(setId)
.collection("vocab")
.get()
.then(querySnapshot => querySnapshot.docs.length)
))).reduce((a, b) => a + b);
this.setState({
showTestStart: false,
showClassicTestStart: true,
sliderValue: totalTestQuestions,
switchLanguage: false,
totalTestQuestions: totalTestQuestions,
loading: false,
});
} else if (mode === "lives") {
this.setState({
showTestStart: false,
showLivesTestStart: true,
switchLanguage: false,
sliderValue: 5,
});
} else {
// countdown
// this.setState({
// showTestStart: false,
// showCountdownTestStart: true,
// switchLanguage: false,
// });
}
}
}
hideClassicTestStart = () => {
this.setState({
showClassicTestStart: false,
});
}
hideLivesTestStart = () => {
this.setState({
showLivesTestStart: false,
});
}
hideCountdownTestStart = () => {
this.setState({
showCountdownTestStart: false,
});
}
changeSliderValue = (value) => {
if (value >= 1 && value <= 999) this.setState({
sliderValue: value,
});
}
handleSwitchLanguageChange = (event) => {
this.setState({
switchLanguage: event.target.checked,
});
}
render() {
return (
<div>
@@ -251,7 +349,7 @@ export default withRouter(class SetPage extends React.Component {
{
this.state.set.public
?
<span className="set-cloud-icon"><CloudQueueRoundedIcon /></span>
<span className="title-icon"><CloudQueueRoundedIcon /></span>
:
""
}
@@ -259,7 +357,7 @@ export default withRouter(class SetPage extends React.Component {
<div className="button-container">
<Button
loading={this.state.loading}
onClick={() => this.startTest()}
onClick={this.showTestStart}
icon={<PlayArrowRoundedIcon />}
disabled={!this.state.canStartTest}
className="button--round"
@@ -371,6 +469,48 @@ export default withRouter(class SetPage extends React.Component {
</div>
</>
}
{
this.state.showTestStart &&
<TestStart
hideTestStart={this.hideTestStart}
showIndividualTestPrompt={this.showIndividualTestPrompt}
loading={this.state.loading}
/>
}
{
this.state.showClassicTestStart &&
<ClassicTestStart
hide={this.hideClassicTestStart}
startTest={this.startTest}
max={this.state.totalTestQuestions}
sliderValue={this.state.sliderValue}
onSliderChange={this.changeSliderValue}
switchLanguage={this.state.switchLanguage}
handleSwitchLanguageChange={this.handleSwitchLanguageChange}
loading={this.state.loading}
/>
}
{
this.state.showLivesTestStart &&
<LivesTestStart
hide={this.hideLivesTestStart}
startTest={this.startTest}
max={20}
sliderValue={this.state.sliderValue}
onSliderChange={this.changeSliderValue}
switchLanguage={this.state.switchLanguage}
handleSwitchLanguageChange={this.handleSwitchLanguageChange}
loading={this.state.loading}
/>
}
{
this.state.showCountdownTestStart &&
<CountdownTestStart
hide={this.hideCountdownTestStart}
startTest={this.startTest}
/>
}
</>
}
</div>

36
src/TestStart.js Normal file
View File

@@ -0,0 +1,36 @@
import React from "react";
import Loader from "./puff-loader.svg";
export default function TestStart(props) {
return (
<>
<div className="overlay" onClick={props.hideTestStart}></div>
<div className="overlay-content options-list-overlay-content">
{
props.loading
?
<img className="button-loader" src={Loader} alt="Loading..." />
:
<>
{
// ["Classic", "Lives", "Countdown"].map((mode) =>
["Classic", "Lives"].map((mode) =>
<h3
key={mode}
onClick={() => props.showIndividualTestPrompt(mode.toLowerCase())}
>
{mode}
</h3>
)
}
<div onClick={props.hideTestStart}>
Cancel
</div>
</>
}
</div>
</>
)
}