From 17a107f01eb25cb07ed612de2bfdd9a29bf13ec1 Mon Sep 17 00:00:00 2001 From: wenhwang97 Date: Thu, 5 Sep 2024 13:19:33 -0400 Subject: [PATCH 01/10] add auth guard and switch to hash router --- src/App.tsx | 10 +++++-- src/contexts/auth.context.tsx | 18 ++++++++++++ src/main.tsx | 13 +++++---- src/pages/AuthPage.tsx | 54 +++++++++++++++++++++++++++++++++++ src/pages/TestPage.tsx | 21 ++++++++++++++ 5 files changed, 109 insertions(+), 7 deletions(-) create mode 100644 src/contexts/auth.context.tsx create mode 100644 src/pages/AuthPage.tsx diff --git a/src/App.tsx b/src/App.tsx index 4409910..d1cfeed 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,9 +1,15 @@ import "./App.css"; -import { createBrowserRouter, RouterProvider } from "react-router-dom"; +import { createHashRouter, RouterProvider } from "react-router-dom"; import { TestPage } from "./pages/TestPage"; +import { AuthPage } from "./pages/AuthPage"; function App() { - const router = createBrowserRouter([{ path: "assessments", element: }]); + const router = createHashRouter([ + { path: "assessments/:participantId", element: }, + { path: "assessments", element: }, + { path: "auth/:participantId", element: }, + { path: "auth/", element: }, + ]); return ; } diff --git a/src/contexts/auth.context.tsx b/src/contexts/auth.context.tsx new file mode 100644 index 0000000..0273a3c --- /dev/null +++ b/src/contexts/auth.context.tsx @@ -0,0 +1,18 @@ +import { createContext, FC, ReactNode, useState } from "react"; + +interface AuthContextType { + participantId: string | undefined; + setParticipantId: (id: string | undefined) => void; +} + +export const AuthContext = createContext(undefined); + +export interface AuthProviderProps { + children: ReactNode; +} + +export const AuthProvider: FC = ({ children }) => { + const [participantId, setParticipantId] = useState(""); + + return {children}; +}; diff --git a/src/main.tsx b/src/main.tsx index 3a53a20..59b8351 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -4,13 +4,16 @@ import App from "./App.tsx"; import "./index.css"; import { GeneralProvider } from "./contexts/general.context.tsx"; import { TestProvider } from "./contexts/test.context.tsx"; +import { AuthProvider } from "./contexts/auth.context.tsx"; ReactDOM.createRoot(document.getElementById("root")!).render( - - - - - + + + + + + + ); diff --git a/src/pages/AuthPage.tsx b/src/pages/AuthPage.tsx new file mode 100644 index 0000000..f3bc90d --- /dev/null +++ b/src/pages/AuthPage.tsx @@ -0,0 +1,54 @@ +import { Button, Container, TextField, Typography } from "@mui/material"; +import { ChangeEvent, FC, useContext, useEffect, useState } from "react"; +import { useNavigate, useParams } from "react-router-dom"; +import { AuthContext } from "../contexts/auth.context"; + +export const AuthPage: FC = () => { + const authCxt = useContext(AuthContext); + + const { participantId } = useParams<{ participantId: string }>(); + const [input, setInput] = useState(""); + const navigate = useNavigate(); + + useEffect(() => { + if (validateParticipantId(participantId)) { + authCxt!.setParticipantId(participantId); + console.log(`Participant ${participantId} is validated`); + navigate(`/assessments/${participantId}`); + } + }, []); + + const inputChangeHandler = (event: ChangeEvent) => { + setInput(event.target.value); + }; + + const submitHandler = () => { + if (!validateParticipantId(input)) { + return; + } + + authCxt!.setParticipantId(input); + navigate(`/assessments/${input}`); + }; + + const validateParticipantId = (id: string | undefined) => { + if (!id || id === "undefined") { + return false; + } + // TODO: validate participant ID + + return true; + }; + + return ( + + + Enter Participant ID + + + + + ); +}; diff --git a/src/pages/TestPage.tsx b/src/pages/TestPage.tsx index 12c3fa6..71a38a6 100644 --- a/src/pages/TestPage.tsx +++ b/src/pages/TestPage.tsx @@ -11,20 +11,41 @@ import { MemoryRecallMain } from "../components/MemoryRecallMain"; import { Transition } from "../components/Transition"; import { SoundCheck } from "../components/SoundCheck"; import { GeneralDirection } from "../components/GeneralDirection"; +import { useNavigate, useParams } from "react-router-dom"; +import { AuthContext } from "../contexts/auth.context"; export const TestPage: FC = () => { + const { participantId } = useParams<{ participantId: string }>(); + + const authCxt = useContext(AuthContext); + // Routing hooks const cxt = useContext(GeneralContext); // Test setup const testCxt = useContext(TestContext); + const navigate = useNavigate(); + const [digitSymbolMatchingIdx, setDigitSymbolMatchingIdx] = useState(0); const [choiceReactionTimeIdx, setChoiceReactionTimeIdx] = useState(0); const [spacialMemoryIdx, setSpacialMemoryIdx] = useState(0); const [visualPairsIdx, setVisualPairsIdx] = useState(0); useEffect(() => { + console.log(authCxt?.participantId); + if (!authCxt!.participantId) { + console.log("No participant ID"); + + if (!participantId) { + navigate("auth"); + return; + } else { + navigate(`auth/${participantId}`); + return; + } + } + if (!cxt!.testPhase) { cxt!.setTestPhase(TestPhase.MEMORY_RECALL_IMMEDIATE); cxt!.setStage(Stage.GENERAL_DIRECTION); From 47f1d633686531df9ebafd68c8a84404e61339c4 Mon Sep 17 00:00:00 2001 From: wenhwang97 Date: Thu, 5 Sep 2024 13:20:04 -0400 Subject: [PATCH 02/10] fix selection number --- src/components/MemoryRecallMain.tsx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/components/MemoryRecallMain.tsx b/src/components/MemoryRecallMain.tsx index 7b3f106..1f7c62f 100644 --- a/src/components/MemoryRecallMain.tsx +++ b/src/components/MemoryRecallMain.tsx @@ -30,6 +30,10 @@ export const MemoryRecallMain: FC = ({ selected, handleSu }, [clickedNum]); const clickHandler = (index: number) => { + if (clickedNum >= maxSelection) { + return; + } + setClickedNum((num) => num + 1); setValues((prev) => { const newValues = { ...prev }; From 4bfe756cfcabff9b4d4e4dfacf06a3df1ac21c37 Mon Sep 17 00:00:00 2001 From: wenhwang97 Date: Thu, 5 Sep 2024 18:21:55 -0400 Subject: [PATCH 03/10] reconfigure for vertical view --- src/components/ChoiceReactionTimeMain.tsx | 80 ++++++++++++---------- src/components/DigitSymbolMatchingMain.tsx | 29 +++++--- src/components/MemoryRecallMain.tsx | 6 +- src/components/SoundCheck.tsx | 12 ++-- src/components/SpacialMemoryMain.tsx | 20 ++++-- src/components/VisualPairsMemorize.tsx | 8 +-- src/components/VisualPairsRecall.tsx | 14 +++- src/config/uiConfig.ts | 13 ++-- src/pages/TestPage.tsx | 3 - 9 files changed, 112 insertions(+), 73 deletions(-) diff --git a/src/components/ChoiceReactionTimeMain.tsx b/src/components/ChoiceReactionTimeMain.tsx index 8d69ce7..33e3cbc 100644 --- a/src/components/ChoiceReactionTimeMain.tsx +++ b/src/components/ChoiceReactionTimeMain.tsx @@ -1,5 +1,5 @@ import { FC, useEffect, useState } from "react"; -import { Box, Button, Typography } from "@mui/material"; +import { Box, Button, Grid, Typography } from "@mui/material"; import { shuffleList } from "../utils/generalUtils"; import { choiceReactionTimeConfig as uiConfig } from "../config/uiConfig"; import { choiceReactionTimeConfig as testConfig } from "../config/testConfig"; @@ -37,24 +37,7 @@ export const ChoiceReactionTimeMain: FC = ({ }, [handleSubmit]); return ( - - + {hide ? ( @@ -82,23 +65,48 @@ export const ChoiceReactionTimeMain: FC = ({ )} - + + + + + + + + + + ); }; diff --git a/src/components/DigitSymbolMatchingMain.tsx b/src/components/DigitSymbolMatchingMain.tsx index 6af27b6..a26ff05 100644 --- a/src/components/DigitSymbolMatchingMain.tsx +++ b/src/components/DigitSymbolMatchingMain.tsx @@ -2,6 +2,16 @@ import { FC } from "react"; import { Box, Button, Divider, Grid, Typography } from "@mui/material"; import { digitSymbolConfig as testConfig } from "../config/testConfig"; import { digitSymbolConfig as uiConfig } from "../config/uiConfig"; +import styled from "@emotion/styled"; + +const Cell = styled(Box, { + shouldForwardProp: (prop) => prop !== "leftBox" && prop !== "rightBox" && prop !== "middleBox", +})<{ leftBox?: boolean; rightBox?: boolean; middleBox?: boolean }>(({ leftBox, rightBox }) => ({ + borderLeft: leftBox ? "2px solid black" : "1px solid black", + borderRight: rightBox ? "2px solid black" : "1px solid black", + borderBottom: "2px solid black", + borderTop: "2px solid black", +})); interface DigitSymbolMatchingMainProps { correctIndex: number; @@ -21,22 +31,23 @@ export const DigitSymbolMatchingMain: FC = ({ corr width={uiConfig.topSymbolHeight} style={{ marginBottom: 8 }} /> - + {testConfig.symbolPairs.map((symbol, index) => ( - - - + + {symbol.num} - + ))} @@ -64,7 +75,7 @@ export const DigitSymbolMatchingMain: FC = ({ corr height: uiConfig.buttonHeight, backgroundColor: uiConfig.buttonBg, color: uiConfig.textColor, - fontSize: uiConfig.fontSize, + fontSize: uiConfig.bubttonFontSize, "&:active": { backgroundColor: uiConfig.buttonClickedBg, }, @@ -85,7 +96,7 @@ export const DigitSymbolMatchingMain: FC = ({ corr height: uiConfig.buttonHeight, backgroundColor: uiConfig.buttonBg, color: uiConfig.textColor, - fontSize: uiConfig.fontSize, + fontSize: uiConfig.bubttonFontSize, "&:active": { backgroundColor: uiConfig.buttonClickedBg, }, @@ -106,7 +117,7 @@ export const DigitSymbolMatchingMain: FC = ({ corr height: uiConfig.buttonHeight, backgroundColor: uiConfig.buttonBg, color: uiConfig.textColor, - fontSize: uiConfig.fontSize, + fontSize: uiConfig.bubttonFontSize, "&:active": { backgroundColor: uiConfig.buttonClickedBg, }, diff --git a/src/components/MemoryRecallMain.tsx b/src/components/MemoryRecallMain.tsx index 1f7c62f..a25b0e5 100644 --- a/src/components/MemoryRecallMain.tsx +++ b/src/components/MemoryRecallMain.tsx @@ -45,10 +45,10 @@ export const MemoryRecallMain: FC = ({ selected, handleSu return ( - {Array.from({ length: 4 }).map((_, rowIndex) => ( + {Array.from({ length: 8 }).map((_, rowIndex) => ( - {Array.from({ length: 4 }).map((_, colIndex) => { - const index = rowIndex * 4 + colIndex; + {Array.from({ length: 2 }).map((_, colIndex) => { + const index = rowIndex * 2 + colIndex; return ( { const [animationClass, setAnimationClass] = useState(""); useEffect(() => { - setRandomNum(Math.floor(Math.random() * 10)); + setRandomNum(Math.floor(Math.random() * 9)); }, []); useEffect(() => { @@ -77,7 +77,7 @@ export const SoundCheck: FC = () => { }; return ( - <> + Sound Check @@ -88,10 +88,10 @@ export const SoundCheck: FC = () => { Otherwise, please increase your speaks volume. - {Array.from({ length: 2 }).map((_, rowIndex) => ( + {Array.from({ length: 3 }).map((_, rowIndex) => ( - {Array.from({ length: 5 }).map((_, colIndex) => { - const index = rowIndex * 5 + colIndex + 1; + {Array.from({ length: 3 }).map((_, colIndex) => { + const index = rowIndex * 3 + colIndex + 1; return ( { ))} - + ); }; diff --git a/src/components/SpacialMemoryMain.tsx b/src/components/SpacialMemoryMain.tsx index ab25e6a..b75969d 100644 --- a/src/components/SpacialMemoryMain.tsx +++ b/src/components/SpacialMemoryMain.tsx @@ -58,7 +58,7 @@ export const SpacialMemoryMain: FC = ({ numNodes, handle }; return ( - + <> {grid.map((row: any[], rowIndex: number) => ( @@ -76,11 +76,23 @@ export const SpacialMemoryMain: FC = ({ numNodes, handle ))} ))} - - - + + ); }; diff --git a/src/components/VisualPairsMemorize.tsx b/src/components/VisualPairsMemorize.tsx index d7d1989..e6eb413 100644 --- a/src/components/VisualPairsMemorize.tsx +++ b/src/components/VisualPairsMemorize.tsx @@ -1,6 +1,6 @@ import { FC, useEffect, useState } from "react"; import { visualPairsConfig as testConfig } from "../config/testConfig"; -import { Box, Grid } from "@mui/material"; +import { Grid } from "@mui/material"; interface ChoiceReactionTimeMemorizeProps { imageGroupList: string[]; @@ -33,9 +33,9 @@ export const VisualPairsMemorize: FC = ({ }, [pairIdx]); return ( - + <> {pairIdx >= 0 && pairIdx < imageGroupList.length && ( - + = ({ /> )} - + ); }; diff --git a/src/components/VisualPairsRecall.tsx b/src/components/VisualPairsRecall.tsx index d84ed15..036f407 100644 --- a/src/components/VisualPairsRecall.tsx +++ b/src/components/VisualPairsRecall.tsx @@ -32,7 +32,17 @@ export const VisualPairsRecall: FC = ({ imageTheme, refe border="3px solid red" /> - {options.slice(0, 2).map((option, idx) => ( + + submitHandler(options[0])} + /> + + + + {options.slice(1, 3).map((option, idx) => ( = ({ imageTheme, refe ))} - {options.slice(2).map((option, idx) => ( + {options.slice(3).map((option, idx) => ( { console.log("No participant ID"); if (!participantId) { - navigate("auth"); - return; - } else { navigate(`auth/${participantId}`); return; } From 4b1541e797dc71a10de0ec561dbfa534b6f91155 Mon Sep 17 00:00:00 2001 From: wenhwang97 Date: Thu, 5 Sep 2024 18:24:31 -0400 Subject: [PATCH 04/10] fix duplicated click --- src/components/MemoryRecallMain.tsx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/components/MemoryRecallMain.tsx b/src/components/MemoryRecallMain.tsx index a25b0e5..dd78d5a 100644 --- a/src/components/MemoryRecallMain.tsx +++ b/src/components/MemoryRecallMain.tsx @@ -34,6 +34,10 @@ export const MemoryRecallMain: FC = ({ selected, handleSu return; } + if (values[randomList[index]] !== "unselected") { + return; + } + setClickedNum((num) => num + 1); setValues((prev) => { const newValues = { ...prev }; From 52610cadc8d176f5514e9c3d7ec41972fd0fcd09 Mon Sep 17 00:00:00 2001 From: wenhwang97 Date: Fri, 6 Sep 2024 16:30:49 -0400 Subject: [PATCH 05/10] store auth in local --- src/contexts/auth.context.tsx | 18 ------------------ src/main.tsx | 13 +++++-------- src/pages/AuthPage.tsx | 9 +++------ src/pages/TestPage.tsx | 13 ++++--------- 4 files changed, 12 insertions(+), 41 deletions(-) delete mode 100644 src/contexts/auth.context.tsx diff --git a/src/contexts/auth.context.tsx b/src/contexts/auth.context.tsx deleted file mode 100644 index 0273a3c..0000000 --- a/src/contexts/auth.context.tsx +++ /dev/null @@ -1,18 +0,0 @@ -import { createContext, FC, ReactNode, useState } from "react"; - -interface AuthContextType { - participantId: string | undefined; - setParticipantId: (id: string | undefined) => void; -} - -export const AuthContext = createContext(undefined); - -export interface AuthProviderProps { - children: ReactNode; -} - -export const AuthProvider: FC = ({ children }) => { - const [participantId, setParticipantId] = useState(""); - - return {children}; -}; diff --git a/src/main.tsx b/src/main.tsx index 59b8351..3a53a20 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -4,16 +4,13 @@ import App from "./App.tsx"; import "./index.css"; import { GeneralProvider } from "./contexts/general.context.tsx"; import { TestProvider } from "./contexts/test.context.tsx"; -import { AuthProvider } from "./contexts/auth.context.tsx"; ReactDOM.createRoot(document.getElementById("root")!).render( - - - - - - - + + + + + ); diff --git a/src/pages/AuthPage.tsx b/src/pages/AuthPage.tsx index f3bc90d..669563d 100644 --- a/src/pages/AuthPage.tsx +++ b/src/pages/AuthPage.tsx @@ -1,18 +1,15 @@ import { Button, Container, TextField, Typography } from "@mui/material"; -import { ChangeEvent, FC, useContext, useEffect, useState } from "react"; +import { ChangeEvent, FC, useEffect, useState } from "react"; import { useNavigate, useParams } from "react-router-dom"; -import { AuthContext } from "../contexts/auth.context"; export const AuthPage: FC = () => { - const authCxt = useContext(AuthContext); - const { participantId } = useParams<{ participantId: string }>(); const [input, setInput] = useState(""); const navigate = useNavigate(); useEffect(() => { if (validateParticipantId(participantId)) { - authCxt!.setParticipantId(participantId); + sessionStorage.setItem("participantId", participantId!); console.log(`Participant ${participantId} is validated`); navigate(`/assessments/${participantId}`); } @@ -27,7 +24,7 @@ export const AuthPage: FC = () => { return; } - authCxt!.setParticipantId(input); + sessionStorage.setItem("participantId", input); navigate(`/assessments/${input}`); }; diff --git a/src/pages/TestPage.tsx b/src/pages/TestPage.tsx index 038c8da..47017d6 100644 --- a/src/pages/TestPage.tsx +++ b/src/pages/TestPage.tsx @@ -12,13 +12,10 @@ import { Transition } from "../components/Transition"; import { SoundCheck } from "../components/SoundCheck"; import { GeneralDirection } from "../components/GeneralDirection"; import { useNavigate, useParams } from "react-router-dom"; -import { AuthContext } from "../contexts/auth.context"; export const TestPage: FC = () => { const { participantId } = useParams<{ participantId: string }>(); - const authCxt = useContext(AuthContext); - // Routing hooks const cxt = useContext(GeneralContext); @@ -33,14 +30,12 @@ export const TestPage: FC = () => { const [visualPairsIdx, setVisualPairsIdx] = useState(0); useEffect(() => { - console.log(authCxt?.participantId); - if (!authCxt!.participantId) { + const localParticipantId = sessionStorage.getItem("participantId"); + if (!localParticipantId || !participantId) { console.log("No participant ID"); - if (!participantId) { - navigate(`auth/${participantId}`); - return; - } + navigate(`auth/${participantId}`); + return; } if (!cxt!.testPhase) { From df49f46f7252918926fdf7ff9749820bf8e711c1 Mon Sep 17 00:00:00 2001 From: wenhwang97 Date: Fri, 6 Sep 2024 18:33:24 -0400 Subject: [PATCH 06/10] store stage and phase in local --- src/contexts/general.context.tsx | 26 +++++++++++++------------- src/pages/TestPage.tsx | 21 ++++++++++++++++++++- 2 files changed, 33 insertions(+), 14 deletions(-) diff --git a/src/contexts/general.context.tsx b/src/contexts/general.context.tsx index 8ae1c3c..ca9d551 100644 --- a/src/contexts/general.context.tsx +++ b/src/contexts/general.context.tsx @@ -1,22 +1,22 @@ import { createContext, FC, ReactNode, useState } from "react"; export enum Stage { - NULL, - GENERAL_DIRECTION, - SOUND_CHECK, - TRANSITION, - TEST, + NULL = 0, + GENERAL_DIRECTION = 1, + SOUND_CHECK = 2, + TRANSITION = 3, + TEST = 4, } export enum TestPhase { - NULL, - CHOICE_REACTION_TIME, - SPACIAL_MEMORY, - MEMORY_RECALL_IMMEDIATE, - MEMORY_RECALL_DELAYED, - DIGIT_SYMBOL_MATCHING, - VISUAL_PAIRS_MEMORIZE, - VISUAL_PAIRS_RECALL, + NULL = 0, + CHOICE_REACTION_TIME = 1, + SPACIAL_MEMORY = 2, + MEMORY_RECALL_IMMEDIATE = 3, + MEMORY_RECALL_DELAYED = 4, + DIGIT_SYMBOL_MATCHING = 5, + VISUAL_PAIRS_MEMORIZE = 6, + VISUAL_PAIRS_RECALL = 7, } interface GeneralContextType { diff --git a/src/pages/TestPage.tsx b/src/pages/TestPage.tsx index 47017d6..cdee16d 100644 --- a/src/pages/TestPage.tsx +++ b/src/pages/TestPage.tsx @@ -38,9 +38,16 @@ export const TestPage: FC = () => { return; } - if (!cxt!.testPhase) { + console.log(`Participant ID: ${participantId}`); + + if (!sessionStorage.getItem("testPhase") || !sessionStorage.getItem("stage")) { + sessionStorage.setItem("testPhase", String(TestPhase.MEMORY_RECALL_IMMEDIATE)); + sessionStorage.setItem("stage", String(Stage.GENERAL_DIRECTION)); cxt!.setTestPhase(TestPhase.MEMORY_RECALL_IMMEDIATE); cxt!.setStage(Stage.GENERAL_DIRECTION); + } else { + cxt!.setTestPhase(Number(sessionStorage.getItem("testPhase")) as TestPhase); + cxt!.setStage(Number(sessionStorage.getItem("stage")) as Stage); } }, []); @@ -51,6 +58,8 @@ export const TestPage: FC = () => { return; } + sessionStorage.setItem("testPhase", String(TestPhase.VISUAL_PAIRS_MEMORIZE)); + sessionStorage.setItem("stage", String(Stage.TRANSITION)); cxt!.setTestPhase(TestPhase.VISUAL_PAIRS_MEMORIZE); cxt!.setStage(Stage.TRANSITION); }; @@ -63,6 +72,8 @@ export const TestPage: FC = () => { } if (digitSymbolMatchingIdx + 1 >= testCxt!.digitSymbolMatchingSetup.length) { + sessionStorage.setItem("testPhase", String(TestPhase.SPACIAL_MEMORY)); + sessionStorage.setItem("stage", String(Stage.TRANSITION)); cxt!.setTestPhase(TestPhase.SPACIAL_MEMORY); cxt!.setStage(Stage.TRANSITION); } else { @@ -78,6 +89,8 @@ export const TestPage: FC = () => { } if (choiceReactionTimeIdx + 1 >= testCxt!.choiceReactionTimeSetup.length) { + sessionStorage.setItem("testPhase", String(TestPhase.VISUAL_PAIRS_RECALL)); + sessionStorage.setItem("stage", String(Stage.TRANSITION)); cxt!.setTestPhase(TestPhase.VISUAL_PAIRS_RECALL); cxt!.setStage(Stage.TRANSITION); } else { @@ -93,6 +106,8 @@ export const TestPage: FC = () => { } if (spacialMemoryIdx + 1 >= testCxt!.spacialMemorySetup.length) { + sessionStorage.setItem("testPhase", String(TestPhase.MEMORY_RECALL_DELAYED)); + sessionStorage.setItem("stage", String(Stage.TRANSITION)); cxt!.setTestPhase(TestPhase.MEMORY_RECALL_DELAYED); cxt!.setStage(Stage.TRANSITION); } else { @@ -102,6 +117,8 @@ export const TestPage: FC = () => { // Transition from Visual Paired Associates Test - Memorize const visualPairsTransitionHandler = () => { + sessionStorage.setItem("testPhase", String(TestPhase.CHOICE_REACTION_TIME)); + sessionStorage.setItem("stage", String(Stage.TRANSITION)); cxt!.setTestPhase(TestPhase.CHOICE_REACTION_TIME); cxt!.setStage(Stage.TRANSITION); }; @@ -114,6 +131,8 @@ export const TestPage: FC = () => { } if (visualPairsIdx + 1 >= testCxt!.visualPairSetupImageList.length) { + sessionStorage.setItem("testPhase", String(TestPhase.DIGIT_SYMBOL_MATCHING)); + sessionStorage.setItem("stage", String(Stage.TRANSITION)); cxt!.setTestPhase(TestPhase.DIGIT_SYMBOL_MATCHING); cxt!.setStage(Stage.TRANSITION); } else { From ba25aab3122c6c876874e149ed854e87548b0bea Mon Sep 17 00:00:00 2001 From: wenhwang97 Date: Mon, 9 Sep 2024 09:09:38 -0400 Subject: [PATCH 07/10] store question index in local --- src/pages/TestPage.tsx | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/src/pages/TestPage.tsx b/src/pages/TestPage.tsx index cdee16d..9a49607 100644 --- a/src/pages/TestPage.tsx +++ b/src/pages/TestPage.tsx @@ -32,22 +32,36 @@ export const TestPage: FC = () => { useEffect(() => { const localParticipantId = sessionStorage.getItem("participantId"); if (!localParticipantId || !participantId) { - console.log("No participant ID"); - navigate(`auth/${participantId}`); return; } - console.log(`Participant ID: ${participantId}`); - if (!sessionStorage.getItem("testPhase") || !sessionStorage.getItem("stage")) { sessionStorage.setItem("testPhase", String(TestPhase.MEMORY_RECALL_IMMEDIATE)); sessionStorage.setItem("stage", String(Stage.GENERAL_DIRECTION)); + sessionStorage.setItem("questionNumber", "0"); cxt!.setTestPhase(TestPhase.MEMORY_RECALL_IMMEDIATE); cxt!.setStage(Stage.GENERAL_DIRECTION); } else { cxt!.setTestPhase(Number(sessionStorage.getItem("testPhase")) as TestPhase); cxt!.setStage(Number(sessionStorage.getItem("stage")) as Stage); + + switch (Number(sessionStorage.getItem("testPhase"))) { + case TestPhase.DIGIT_SYMBOL_MATCHING: + setDigitSymbolMatchingIdx(Number(sessionStorage.getItem("questionNumber"))); + break; + case TestPhase.CHOICE_REACTION_TIME: + setChoiceReactionTimeIdx(Number(sessionStorage.getItem("questionNumber"))); + break; + case TestPhase.SPACIAL_MEMORY: + setSpacialMemoryIdx(Number(sessionStorage.getItem("questionNumber"))); + break; + case TestPhase.VISUAL_PAIRS_RECALL: + setVisualPairsIdx(Number(sessionStorage.getItem("questionNumber"))); + break; + default: + break; + } } }, []); @@ -74,9 +88,11 @@ export const TestPage: FC = () => { if (digitSymbolMatchingIdx + 1 >= testCxt!.digitSymbolMatchingSetup.length) { sessionStorage.setItem("testPhase", String(TestPhase.SPACIAL_MEMORY)); sessionStorage.setItem("stage", String(Stage.TRANSITION)); + sessionStorage.setItem("questionNumber", "0"); cxt!.setTestPhase(TestPhase.SPACIAL_MEMORY); cxt!.setStage(Stage.TRANSITION); } else { + sessionStorage.setItem("questionNumber", String(digitSymbolMatchingIdx + 1)); setDigitSymbolMatchingIdx((idx) => idx + 1); } }; @@ -91,9 +107,11 @@ export const TestPage: FC = () => { if (choiceReactionTimeIdx + 1 >= testCxt!.choiceReactionTimeSetup.length) { sessionStorage.setItem("testPhase", String(TestPhase.VISUAL_PAIRS_RECALL)); sessionStorage.setItem("stage", String(Stage.TRANSITION)); + sessionStorage.setItem("questionNumber", "0"); cxt!.setTestPhase(TestPhase.VISUAL_PAIRS_RECALL); cxt!.setStage(Stage.TRANSITION); } else { + sessionStorage.setItem("questionNumber", String(choiceReactionTimeIdx + 1)); setChoiceReactionTimeIdx((idx) => idx + 1); } }; @@ -108,9 +126,11 @@ export const TestPage: FC = () => { if (spacialMemoryIdx + 1 >= testCxt!.spacialMemorySetup.length) { sessionStorage.setItem("testPhase", String(TestPhase.MEMORY_RECALL_DELAYED)); sessionStorage.setItem("stage", String(Stage.TRANSITION)); + sessionStorage.setItem("questionNumber", "0"); cxt!.setTestPhase(TestPhase.MEMORY_RECALL_DELAYED); cxt!.setStage(Stage.TRANSITION); } else { + sessionStorage.setItem("questionNumber", String(spacialMemoryIdx + 1)); setSpacialMemoryIdx((idx) => idx + 1); } }; @@ -133,9 +153,11 @@ export const TestPage: FC = () => { if (visualPairsIdx + 1 >= testCxt!.visualPairSetupImageList.length) { sessionStorage.setItem("testPhase", String(TestPhase.DIGIT_SYMBOL_MATCHING)); sessionStorage.setItem("stage", String(Stage.TRANSITION)); + sessionStorage.setItem("questionNumber", "0"); cxt!.setTestPhase(TestPhase.DIGIT_SYMBOL_MATCHING); cxt!.setStage(Stage.TRANSITION); } else { + sessionStorage.setItem("questionNumber", String(visualPairsIdx + 1)); setVisualPairsIdx((idx) => idx + 1); } }; From 56e9f38e6ebcd09859bea052721c54635bc9a959 Mon Sep 17 00:00:00 2001 From: wenhwang97 Date: Mon, 9 Sep 2024 14:20:45 -0400 Subject: [PATCH 08/10] change auth route to home --- src/App.tsx | 4 ++-- src/pages/TestPage.tsx | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index d1cfeed..4051fc3 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -7,8 +7,8 @@ function App() { const router = createHashRouter([ { path: "assessments/:participantId", element: }, { path: "assessments", element: }, - { path: "auth/:participantId", element: }, - { path: "auth/", element: }, + { path: "/:participantId", element: }, + { path: "/", element: }, ]); return ; diff --git a/src/pages/TestPage.tsx b/src/pages/TestPage.tsx index 9a49607..7fc5ea3 100644 --- a/src/pages/TestPage.tsx +++ b/src/pages/TestPage.tsx @@ -32,7 +32,7 @@ export const TestPage: FC = () => { useEffect(() => { const localParticipantId = sessionStorage.getItem("participantId"); if (!localParticipantId || !participantId) { - navigate(`auth/${participantId}`); + navigate(`/${participantId}`); return; } From ec941b1ad105a081450dd1154787f04fb93afe1a Mon Sep 17 00:00:00 2001 From: wenhwang97 Date: Mon, 9 Sep 2024 14:33:01 -0400 Subject: [PATCH 09/10] put content on a card --- src/pages/AuthPage.tsx | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/pages/AuthPage.tsx b/src/pages/AuthPage.tsx index 669563d..8267a59 100644 --- a/src/pages/AuthPage.tsx +++ b/src/pages/AuthPage.tsx @@ -1,4 +1,4 @@ -import { Button, Container, TextField, Typography } from "@mui/material"; +import { Button, Card, CardContent, CardHeader, TextField } from "@mui/material"; import { ChangeEvent, FC, useEffect, useState } from "react"; import { useNavigate, useParams } from "react-router-dom"; @@ -38,14 +38,14 @@ export const AuthPage: FC = () => { }; return ( - - - Enter Participant ID - - - - + + + + + + + ); }; From 5281c37ced0d4102aed1656835a289499f4e75fb Mon Sep 17 00:00:00 2001 From: wenhwang97 Date: Mon, 9 Sep 2024 15:01:37 -0400 Subject: [PATCH 10/10] fix sound check width for desktop view --- src/components/SoundCheck.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/SoundCheck.tsx b/src/components/SoundCheck.tsx index 9c72184..2d3459b 100644 --- a/src/components/SoundCheck.tsx +++ b/src/components/SoundCheck.tsx @@ -77,14 +77,14 @@ export const SoundCheck: FC = () => { }; return ( - + Sound Check - + If you can hear this message, click the announced number. - + Otherwise, please increase your speaks volume.