Skip to content

Commit

Permalink
feat: add validation and replace s3 client (#19)
Browse files Browse the repository at this point in the history
* add study id validation

* replace s3 client with object url

* add trail limit to recall test and remove printing stmt

* update new env vir to workflow
  • Loading branch information
wenhwang97 authored Oct 15, 2024
1 parent 6245a85 commit 3cc3357
Show file tree
Hide file tree
Showing 7 changed files with 100 additions and 78 deletions.
7 changes: 3 additions & 4 deletions .github/workflows/build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,9 @@ jobs:
- name: Build
run: npm run build
env:
VITE_S3_REGION: ${{ secrets.VITE_S3_REGION }}
VITE_S3_BUCKET_NAME: ${{ secrets.VITE_S3_BUCKET_NAME }}
VITE_S3_ACCESS_KEY: ${{ secrets.VITE_S3_ACCESS_KEY }}
VITE_S3_SECRET: ${{ secrets.VITE_S3_SECRET }}
VITE_SOUND_CHECK_AUDIO_URL: ${{ secrets.VITE_SOUND_CHECK_AUDIO_URL }}
VITE_RECALL_INST_AUDIO_URL: ${{ secrets.VITE_RECALL_INST_AUDIO_URL }}
VITE_VALIDATE_ENDPOINT: ${{ secrets.VITE_VALIDATE_ENDPOINT }}
VITE_TEST_ENDPOINT: ${{ secrets.VITE_TEST_ENDPOINT }}

- name: Upload Artifact
Expand Down
36 changes: 25 additions & 11 deletions src/components/SoundCheck.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { FC, useContext, useEffect, useState } from "react";
import { soundCheckConfig as uiConfig } from "../config/ui.config";
import { GeneralContext, Stage } from "../contexts/general.context";
import { styled } from "@mui/system";
import { playAudioFromS3 } from "../utils/aws.utils";
import PlayCircleIcon from "@mui/icons-material/PlayCircle";

const AnimatedBox = styled(Box)(() => ({
Expand Down Expand Up @@ -57,12 +56,19 @@ export const SoundCheck: FC = () => {

const playHandler = () => {
setHide(true);
playAudioFromS3(`audios/soundcheck-${cxt!.soundCheckNumber + 1}`).then(
(audio) =>
(audio!.onended = () => {
const audioUrl = import.meta.env.VITE_SOUND_CHECK_AUDIO_URL;
const audio = new Audio(audioUrl.replace("{number}", String(cxt!.soundCheckNumber + 1)));

audio
.play()
.then(() => {
audio.onended = () => {
setDisabled(false);
})
);
};
})
.catch((error) => {
console.error("Error playing audio", error);
});
};

const clickHandler = (index: number) => {
Expand Down Expand Up @@ -99,11 +105,19 @@ export const SoundCheck: FC = () => {
setTimeout(() => {
cxt?.setSoundCheckNumber(() => {
const randomNum = Math.floor(Math.random() * 9);
playAudioFromS3(`audios/soundcheck-${randomNum + 1}`).then((audio) => {
audio!.onended = () => {
setDisabled(false);
};
});
const newAudioUrl = import.meta.env.VITE_SOUND_CHECK_AUDIO_URL.replace("{number}", String(randomNum + 1));
const newAudio = new Audio(newAudioUrl);

newAudio
.play()
.then(() => {
newAudio.onended = () => {
setDisabled(false);
};
})
.catch((error) => {
console.error("Error playing audio", error);
});

return randomNum;
});
Expand Down
9 changes: 5 additions & 4 deletions src/components/tests/MemoryRecallMain.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import { memoryRecallConfig as testConfig } from "../../config/test.config";
import { memoryRecallConfig as uiConfig } from "../../config/ui.config";
import { TestPhase } from "../../contexts/general.context";
import { TestContext } from "../../contexts/test.context";
import { playAudioFromS3 } from "../../utils/aws.utils";
import PlayCircleIcon from "@mui/icons-material/PlayCircle";
import { DelayedRecallResult, ImmediateRecallResult } from "../../contexts/types/result.type";

Expand Down Expand Up @@ -63,11 +62,13 @@ export const MemoryRecallMain: FC<MemoryRecallMainProps> = ({ phase, toTestPhase

const playHandler = () => {
setShowPlayButton(false);
playAudioFromS3("audios/memory-recall").then((audio) => {
const audioUrl = import.meta.env.VITE_RECALL_INST_AUDIO_URL;
const audio = new Audio(audioUrl);
audio.play().then(() => {
setTimeout(() => {
setShowInstruction(true);
}, 16500);
audio!.onended = () => {
audio.onended = () => {
setShowOptions(true);
setStartTime(Date.now());
};
Expand Down Expand Up @@ -123,7 +124,7 @@ export const MemoryRecallMain: FC<MemoryRecallMainProps> = ({ phase, toTestPhase

sessionStorage.setItem("results", JSON.stringify(answer as ImmediateRecallResult));

if (result) {
if (result || trail >= testConfig.maxTrial - 1) {
if (trail === 0) {
answer["ir_score"] = 2;
} else if (trail === 1) {
Expand Down
1 change: 1 addition & 0 deletions src/config/test.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ export const spatialMemoryConfig = {
* @property options - List of options to select from
*/
export const memoryRecallConfig = {
maxTrial: 3,
maxSelection: 5,
options: [
"Octopus",
Expand Down
85 changes: 66 additions & 19 deletions src/pages/AuthPage.tsx
Original file line number Diff line number Diff line change
@@ -1,51 +1,98 @@
import { Button, Card, CardContent, CardHeader, TextField } from "@mui/material";
import { Alert, Button, Card, CardContent, CardHeader, TextField, Typography } from "@mui/material";
import { ChangeEvent, FC, useEffect, useState } from "react";
import { useNavigate, useParams } from "react-router-dom";
import { styled } from "@mui/system";

const AnimatedAlert = styled(Alert)(() => ({
"&.fadeOut": {
animation: "fadeOut 0.3s forwards",
},
"@keyframes fadeOut": {
from: { opacity: 1 },
to: { opacity: 0 },
},
}));

export const AuthPage: FC = () => {
const { studyId } = useParams<{ studyId: string }>();
const [input, setInput] = useState<string>("");
const [animationClass, setAnimationClass] = useState<string>("");
const [showAlert, setShowAlert] = useState<boolean>(false);
const navigate = useNavigate();

useEffect(() => {
if (validateStudyId(studyId)) {
sessionStorage.setItem("studyId", studyId!);
console.log(`Study ID ${studyId} is validated`);
navigate(`/assessments/${studyId}`);
}
validateStudyId(studyId).then((result) => {
if (result) {
sessionStorage.setItem("studyId", studyId!);
console.log(`Study ID ${studyId} is validated`);
navigate(`/assessments/${studyId}`);
}
});
}, []);

const inputChangeHandler = (event: ChangeEvent<HTMLTextAreaElement | HTMLInputElement>) => {
setInput(event.target.value);
};

const submitHandler = () => {
if (!validateStudyId(input)) {
const submitHandler = async () => {
if (!(await validateStudyId(input))) {
setInput("");
setShowAlert(true);
setAnimationClass("");
setTimeout(() => {
setAnimationClass("fadeOut");
}, 5000);

return;
}

sessionStorage.setItem("studyId", input);
navigate(`/assessments/${input}`);
};

const validateStudyId = (id: string | undefined) => {
const validateStudyId = async (id: string | undefined) => {
if (!id || id === "undefined") {
return false;
}
// TODO: validate study ID

const response = await fetch(`${import.meta.env.VITE_VALIDATE_ENDPOINT}/${id}`, {
method: "GET",
});

if (response.status !== 200) {
return false;
}

return true;
};

return (
<Card>
<CardHeader title="Enter Study ID" sx={{ paddingBottom: 0 }} />
<CardContent sx={{ paddingTop: 0 }}>
<TextField label="Study ID" variant="outlined" fullWidth margin="normal" onChange={inputChangeHandler} />
<Button variant="contained" color="primary" onClick={submitHandler}>
Submit
</Button>
</CardContent>
</Card>
<>
{showAlert && (
<AnimatedAlert
variant="filled"
severity="error"
className={animationClass}
sx={{
position: "fixed",
width: "calc(100% - 4rem)",
margin: "1rem",
top: 0,
left: 0,
}}
>
<Typography>Invalid Study ID</Typography>
</AnimatedAlert>
)}
<Card>
<CardHeader title="Enter Study ID" sx={{ paddingBottom: 0 }} />
<CardContent sx={{ paddingTop: 0 }}>
<TextField label="Study ID" variant="outlined" fullWidth margin="normal" onChange={inputChangeHandler} />
<Button variant="contained" color="primary" onClick={submitHandler}>
Submit
</Button>
</CardContent>
</Card>
</>
);
};
2 changes: 0 additions & 2 deletions src/pages/TestPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@ export const TestPage: FC = () => {
const navigate = useNavigate();

useEffect(() => {
console.log(`Submitting results to ${import.meta.env.VITE_TEST_ENDPOINT}`);

const localStudyId = sessionStorage.getItem("studyId");
if (!localStudyId || !studyId) {
navigate(`/${studyId}`);
Expand Down
38 changes: 0 additions & 38 deletions src/utils/aws.utils.ts

This file was deleted.

0 comments on commit 3cc3357

Please sign in to comment.