From 2f536a7927e609f0ef81506cc1b34aac35ca6ffa Mon Sep 17 00:00:00 2001 From: Rose Wang Date: Sat, 10 Dec 2022 12:36:47 -0500 Subject: [PATCH 1/9] new branhc --- .../src/Question/Components/AnswerButton.tsx | 74 +++++++++++++++ client/src/Question/Components/BackButton.tsx | 52 +++++++++++ .../Question/Components/ConfirmationModal.tsx | 91 +++++++++++++++++++ client/src/Question/Components/NextButton.tsx | 52 +++++++++++ .../Question/Components/ResourceDropdown.tsx | 58 ++++++++++++ .../Question/Components/StartOverButton.tsx | 38 ++++++++ 6 files changed, 365 insertions(+) create mode 100644 client/src/Question/Components/AnswerButton.tsx create mode 100644 client/src/Question/Components/BackButton.tsx create mode 100644 client/src/Question/Components/ConfirmationModal.tsx create mode 100644 client/src/Question/Components/NextButton.tsx create mode 100644 client/src/Question/Components/ResourceDropdown.tsx create mode 100644 client/src/Question/Components/StartOverButton.tsx diff --git a/client/src/Question/Components/AnswerButton.tsx b/client/src/Question/Components/AnswerButton.tsx new file mode 100644 index 00000000..aedd53db --- /dev/null +++ b/client/src/Question/Components/AnswerButton.tsx @@ -0,0 +1,74 @@ +/* eslint-disable no-underscore-dangle */ +import * as React from 'react'; +import { Button } from '@mui/material'; +import { IAnswer } from '../../util/types/answer'; + +interface AnswerButtonProps { + answer: IAnswer; + onClick: any; +} + +function AnswerButton(props: AnswerButtonProps) { + const { answer, onClick } = props; + + const [isHover, setIsHover] = React.useState(false); + // const [questionIndex, setQuestionIndex] = React.useState(0); + // const [allAnswers, setAllAnswers] = React.useState([]); + + // // temp click handler -- this should appear on page that has the entire question component along with the state + // const clickHandler = ( + // // event: any, + // answerId: string, + // // resultantQuestionId: string, + // ) => { + // // these should be part of state (as done above) + // if (allAnswers.length === questionIndex) { + // setAllAnswers((current) => [...current, answerId]); + // } else { + // setAllAnswers( + // allAnswers.map((a, i) => { + // if (i === questionIndex) { + // // Update answer at question index + // return answerId; + // } + // return a; + // }), + // ); + // } + // setQuestionIndex(questionIndex + 1); + // // get new question info from backend route (using resultantQuestionId) + + // // actual one should make next component (with ref field) + // }; + + const handleMouseEnter = () => { + setIsHover(true); + }; + + const handleMouseLeave = () => { + setIsHover(false); + }; + + return ( + + ); +} + +export default AnswerButton; diff --git a/client/src/Question/Components/BackButton.tsx b/client/src/Question/Components/BackButton.tsx new file mode 100644 index 00000000..a1f97283 --- /dev/null +++ b/client/src/Question/Components/BackButton.tsx @@ -0,0 +1,52 @@ +import * as React from 'react'; +import { Button } from '@mui/material'; + +interface BackButtonProps { + onClick: any; +} + +function BackButton(props: BackButtonProps) { + const { onClick } = props; + + const [isHover, setIsHover] = React.useState(false); + + const handleMouseEnter = () => { + setIsHover(true); + }; + + const handleMouseLeave = () => { + setIsHover(false); + }; + + return ( + + ); +} + +export default BackButton; diff --git a/client/src/Question/Components/ConfirmationModal.tsx b/client/src/Question/Components/ConfirmationModal.tsx new file mode 100644 index 00000000..58bf7248 --- /dev/null +++ b/client/src/Question/Components/ConfirmationModal.tsx @@ -0,0 +1,91 @@ +import React from 'react'; +import Button from '@mui/material/Button'; +import Dialog from '@mui/material/Dialog'; +import DialogActions from '@mui/material/DialogActions'; +import DialogContent from '@mui/material/DialogContent'; +import DialogContentText from '@mui/material/DialogContentText'; +import DialogTitle from '@mui/material/DialogTitle'; + +interface IConfirmModal { + buttonText: string; + title: string; + body: string; + // eslint-disable-next-line @typescript-eslint/ban-types + onConfirm: Function; +} +/** + * A modal component that displays a confirmation message and a button to confirm the action or cancel the action. + * @param buttonText - the text to display on the confirmation button + * @param title - the title of the modal + * @param body - the body of the modal + * @param onConfirm - the function to call when the confirmation button is clicked + */ +export default function ConfirmModal({ + buttonText, + title, + body, + onConfirm, +}: IConfirmModal) { + const [open, setOpen] = React.useState(false); + + const handleClickOpen = () => { + setOpen(true); + }; + + const handleClose = () => { + setOpen(false); + }; + + const handleConfirm = () => { + onConfirm(); + handleClose(); + }; + + return ( +
+ + + {title} + + + {body} + + + + + + + +
+ ); +} diff --git a/client/src/Question/Components/NextButton.tsx b/client/src/Question/Components/NextButton.tsx new file mode 100644 index 00000000..9d023736 --- /dev/null +++ b/client/src/Question/Components/NextButton.tsx @@ -0,0 +1,52 @@ +import * as React from 'react'; +import { Button } from '@mui/material'; + +interface NextButtonProps { + onClick: any; +} + +function NextButton(props: NextButtonProps) { + const { onClick } = props; + + const [isHover, setIsHover] = React.useState(false); + + const handleMouseEnter = () => { + setIsHover(true); + }; + + const handleMouseLeave = () => { + setIsHover(false); + }; + + return ( + + ); +} + +export default NextButton; diff --git a/client/src/Question/Components/ResourceDropdown.tsx b/client/src/Question/Components/ResourceDropdown.tsx new file mode 100644 index 00000000..f6afbffb --- /dev/null +++ b/client/src/Question/Components/ResourceDropdown.tsx @@ -0,0 +1,58 @@ +import * as React from 'react'; +import { useState } from 'react'; +import Card from '@mui/material/Card'; +import CardHeader from '@mui/material/CardHeader'; +import CardContent from '@mui/material/CardContent'; +import Container from '@mui/material/Container'; +import IconButton from '@mui/material/IconButton'; +import Collapse from '@mui/material/Collapse'; +import KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown'; +import KeyboardArrowUpIcon from '@mui/icons-material/KeyboardArrowUp'; +import { Button, Grid, Typography } from '@mui/material'; + +interface ResourceDropdownProps { + title: string; + content: string; +} + +export default function ResourceDropdown(props: ResourceDropdownProps) { + const [open, setOpen] = useState(false); + const { title, content } = props; + return ( + + setOpen(!open)} + aria-label="expand" + size="small" + > + {open ? ( + + ) : ( + + )} + + } + /> +
+ + + {content} + + + + + +
+
+ ); +} diff --git a/client/src/Question/Components/StartOverButton.tsx b/client/src/Question/Components/StartOverButton.tsx new file mode 100644 index 00000000..08caa65e --- /dev/null +++ b/client/src/Question/Components/StartOverButton.tsx @@ -0,0 +1,38 @@ +import * as React from 'react'; +import { Button } from '@mui/material'; +import { Navigate, useNavigate } from 'react-router-dom'; +import ConfirmationModal from './ConfirmationModal'; + +interface StartOverButtonProps { + onClick: any; +} +function StartOverButton(props: StartOverButtonProps) { + const { onClick } = props; + + const [isHover, setIsHover] = React.useState(false); + + const handleMouseEnter = () => { + setIsHover(true); + }; + + const handleMouseLeave = () => { + setIsHover(false); + }; + + const navigate = useNavigate(); + + async function handleNav() { + navigate('/home'); + } + + return ( + handleNav()} + /> + ); +} + +export default StartOverButton; From faa926342ef4af4de31963e5fde09b88b616fdd3 Mon Sep 17 00:00:00 2001 From: Rose Wang Date: Sat, 10 Dec 2022 16:19:02 -0500 Subject: [PATCH 2/9] TODO: Fix index updates --- client/src/App.tsx | 93 +++++---- client/src/Home/HomePage.tsx | 3 +- client/src/Question/Components/BackButton.tsx | 2 +- .../Question/Components/StartOverButton.tsx | 9 +- client/src/Question/QuestionComponent.tsx | 56 +++--- client/src/Question/QuestionPage.tsx | 179 ++++++++++++------ client/src/Question/ResourceComponent.tsx | 2 +- client/src/components/ResourceDropdown.tsx | 7 +- .../components/sidebar/SidebarComponent.tsx | 14 +- 9 files changed, 219 insertions(+), 146 deletions(-) diff --git a/client/src/App.tsx b/client/src/App.tsx index b91e7e69..cf93feac 100644 --- a/client/src/App.tsx +++ b/client/src/App.tsx @@ -3,7 +3,6 @@ import { ThemeProvider } from '@mui/material/styles'; import { CssBaseline } from '@mui/material'; import { BrowserRouter, Routes, Route } from 'react-router-dom'; import { Provider } from 'react-redux'; -import { PersistGate } from 'redux-persist/integration/react'; import theme from './assets/theme'; import { store, persistor } from './util/redux/store'; import NotFoundPage from './NotFound/NotFoundPage'; @@ -21,6 +20,7 @@ import RegisterPage from './Authentication/RegisterPage'; import LoginPage from './Authentication/LoginPage'; import EmailResetPasswordPage from './Authentication/EmailResetPasswordPage'; import ResetPasswordPage from './Authentication/ResetPasswordPage'; +import QuestionPage from './Question/QuestionPage'; function App() { /* const testa = { @@ -39,52 +39,52 @@ function App() {
- - - - - {/* Routes accessed only if user is not authenticated */} - }> - } /> - } /> - } - /> - } - /> - } - /> - {/* }> */} - {/* } /> */} - {/* */} - - {/* Routes accessed only if user is authenticated */} - {/* }> */} - }> - } /> - - - {/* Route which redirects to a different page depending on if the user is an authenticated or not by utilizing the DynamicRedirect component */} + + + + {/* Routes accessed only if user is not authenticated */} + }> + } /> + } /> - } + path="/verify-account/:token" + element={} + /> + } + /> + } /> + {/* }> */} + {/* } /> */} + {/* */} + + {/* Routes accessed only if user is authenticated */} + {/* }> */} + }> + } /> + + + {/* Route which redirects to a different page depending on if the user is an authenticated or not by utilizing the DynamicRedirect component */} + + } + /> - {/* Route which is accessed if no other route is matched */} - } /> + } /> - } /> - } /> + {/* Route which is accessed if no other route is matched */} + } /> + } /> + } /> - {/* @@ -95,12 +95,11 @@ function App() { } /> */} - {/* } /> */} - {/* } /> */} - - - - + {/* } /> */} + {/* } /> */} + + +
diff --git a/client/src/Home/HomePage.tsx b/client/src/Home/HomePage.tsx index 6e4d5612..b4f3b143 100644 --- a/client/src/Home/HomePage.tsx +++ b/client/src/Home/HomePage.tsx @@ -2,6 +2,7 @@ import React, { useState } from 'react'; import Button from '@mui/material/Button'; import { Typography, Grid } from '@mui/material'; import Box from '@mui/system/Box'; +import { useNavigate } from 'react-router-dom'; import ScreenGrid from '../components/ScreenGrid'; import Footer from '../components/Footer'; import NavBar from '../components/NavBar'; @@ -42,7 +43,7 @@ function HomePage() { - diff --git a/client/src/Question/Components/BackButton.tsx b/client/src/Question/Components/BackButton.tsx index a1f97283..04119a44 100644 --- a/client/src/Question/Components/BackButton.tsx +++ b/client/src/Question/Components/BackButton.tsx @@ -21,7 +21,7 @@ function BackButton(props: BackButtonProps) { return ( - ); -} - -export default AnswerButton; diff --git a/client/src/Question/Components/BackButton.tsx b/client/src/Question/Components/BackButton.tsx index 04119a44..4d9166c8 100644 --- a/client/src/Question/Components/BackButton.tsx +++ b/client/src/Question/Components/BackButton.tsx @@ -32,11 +32,11 @@ function BackButton(props: BackButtonProps) { color: 'rgba(0, 0, 0, 0.87)', padding: '6px 16px 6px 12px', gap: '8px', - position: 'absolute', + position: 'fixed', left: '4.72%', right: '88.61%', - top: '80.45%', - bottom: '15.74%', + top: '75.45%', + bottom: '10.74%', fontFamily: 'Roboto', fontStyle: 'normal', fontWeight: '500', diff --git a/client/src/Question/Components/NextButton.tsx b/client/src/Question/Components/NextButton.tsx index 9d023736..57349fda 100644 --- a/client/src/Question/Components/NextButton.tsx +++ b/client/src/Question/Components/NextButton.tsx @@ -32,11 +32,11 @@ function NextButton(props: NextButtonProps) { color: 'rgba(0, 0, 0, 0.87)', padding: '6px 16px 6px 12px', gap: '8px', - position: 'absolute', - left: '88.61%', - right: '4.72%', - top: '80.45%', - bottom: '15.74%', + position: 'fixed', + left: '66.61%', + right: '26.72%', + top: '75.45%', + bottom: '10.74%', fontFamily: 'Roboto', fontStyle: 'normal', fontWeight: '500', diff --git a/client/src/Question/Components/ResourceDropdown.tsx b/client/src/Question/Components/ResourceDropdown.tsx index f6afbffb..be41aa38 100644 --- a/client/src/Question/Components/ResourceDropdown.tsx +++ b/client/src/Question/Components/ResourceDropdown.tsx @@ -21,12 +21,8 @@ export default function ResourceDropdown(props: ResourceDropdownProps) { return ( setOpen(!open)} diff --git a/client/src/Question/Components/StartOverButton.tsx b/client/src/Question/Components/StartOverButton.tsx index f5f3d33b..ba5cdb5f 100644 --- a/client/src/Question/Components/StartOverButton.tsx +++ b/client/src/Question/Components/StartOverButton.tsx @@ -1,6 +1,11 @@ import * as React from 'react'; import { useNavigate } from 'react-router-dom'; -import ConfirmationModal from './ConfirmationModal'; +import Button from '@mui/material/Button'; +import Dialog from '@mui/material/Dialog'; +import DialogActions from '@mui/material/DialogActions'; +import DialogContent from '@mui/material/DialogContent'; +import DialogContentText from '@mui/material/DialogContentText'; +import DialogTitle from '@mui/material/DialogTitle'; function StartOverButton() { const navigate = useNavigate(); @@ -9,13 +14,69 @@ function StartOverButton() { navigate('/home'); } + const [open, setOpen] = React.useState(false); + + const handleClickOpen = () => { + setOpen(true); + }; + + const handleClose = () => { + setOpen(false); + }; + + const handleConfirm = () => { + handleNav(); + handleClose(); + }; + return ( - handleNav()} - /> +
+ + + + Are you sure you want to start over? + + + + You will lose all progress and return to the home page. + + + + + + + +
); } diff --git a/client/src/Question/QuestionComponent.tsx b/client/src/Question/QuestionComponent.tsx index 68d8a921..1a409245 100644 --- a/client/src/Question/QuestionComponent.tsx +++ b/client/src/Question/QuestionComponent.tsx @@ -1,6 +1,6 @@ import React from 'react'; import { Typography, Grid } from '@mui/material'; -import AnswerButton from './AnswerButton'; +import AnswerButton from './Components/AnswerButton'; import { IQuestion } from '../util/types/question'; interface QuestionComponentProps { @@ -37,13 +37,20 @@ function QuestionComponent(props: QuestionComponentProps) {
{question.resultantAnswers.map((answer) => { return ( - { - // eslint-disable-next-line no-underscore-dangle - handleClick(answer._id); - }} - /> + + { + // eslint-disable-next-line no-underscore-dangle + handleClick(answer._id); + }} + /> + ); })} diff --git a/client/src/Question/QuestionPage.tsx b/client/src/Question/QuestionPage.tsx index 3b3d50d6..c7a0b58f 100644 --- a/client/src/Question/QuestionPage.tsx +++ b/client/src/Question/QuestionPage.tsx @@ -1,14 +1,12 @@ /* eslint-disable no-underscore-dangle */ import React, { useEffect, useState } from 'react'; -import { Box, Grid, Typography } from '@mui/material'; -import zIndex from '@mui/material/styles/zIndex'; +import { Box } from '@mui/material'; import ScreenGrid from '../components/ScreenGrid'; import QuestionComponent from './QuestionComponent'; import ResourceComponent from './ResourceComponent'; import { IQuestion } from '../util/types/question'; import { getData } from '../util/api'; import SidebarComponent from '../components/sidebar/SidebarComponent'; -import Footer from '../components/Footer'; import BackButton from './Components/BackButton'; import NextButton from './Components/NextButton'; import StartOverButton from './Components/StartOverButton'; @@ -73,7 +71,6 @@ function QuestionPage() { // truncate both the answers array and the questions array at that index // and then do the following code if (questionIndex !== allQuestions.length - 1) { - console.log('truncate'); allQuestions.length = questionIndex + 1; } @@ -92,8 +89,6 @@ function QuestionPage() { resultantAnswers: res.data.resultantAnswers, } as IQuestion); incrementIndex(); - console.log(questionIndex); - console.log(allQuestions); }; fetchData(); })(); @@ -101,23 +96,16 @@ function QuestionPage() { const handleBack = () => { const newQID = allQuestions.at(questionIndex - 1); - console.log(allQuestions); if (newQID) { getNextFromID(newQID); decrementIndex(); - console.log(questionIndex); - console.log(allQuestions); - } else { - console.log('index or q array wrong'); } }; const handleNext = () => { const newQID = allQuestions[questionIndex + 1]; getNextFromID(newQID); - decrementIndex(); - console.log(questionIndex); - console.log(allQuestions); + incrementIndex(); }; useEffect(() => { @@ -148,12 +136,13 @@ function QuestionPage() { return ( - - -