diff --git a/frontend/src/components/admin/assessment-creation/AssessmentPreview.tsx b/frontend/src/components/admin/assessment-creation/AssessmentPreview.tsx index 24063ab5e..4dca67ddb 100644 --- a/frontend/src/components/admin/assessment-creation/AssessmentPreview.tsx +++ b/frontend/src/components/admin/assessment-creation/AssessmentPreview.tsx @@ -2,18 +2,20 @@ import type { ReactNode } from "react"; import React, { useEffect } from "react"; import { Button } from "@chakra-ui/react"; -import { EditOutlineIcon } from "../../../assets/icons"; +import { ArrowBackOutlineIcon } from "../../../assets/icons"; import type { Question } from "../../../types/QuestionTypes"; import AssessmentExperience from "../../student/AssessmentExperience"; type AssessmentPreviewProps = { questions: Question[]; goBack: () => void; + backButtonText: string; }; const AssessmentPreview = ({ questions, goBack, + backButtonText, }: AssessmentPreviewProps): ReactNode => { useEffect(() => { if (!questions.length) { @@ -26,8 +28,12 @@ const AssessmentPreview = ({ } const closeAssessmentPreviewButton = ( - ); diff --git a/frontend/src/components/admin/assessment-status/EditStatusButtons/PreviewButton.tsx b/frontend/src/components/admin/assessment-status/EditStatusButtons/PreviewButton.tsx new file mode 100644 index 000000000..41a767990 --- /dev/null +++ b/frontend/src/components/admin/assessment-status/EditStatusButtons/PreviewButton.tsx @@ -0,0 +1,46 @@ +import React from "react"; +import { useHistory } from "react-router-dom"; +import { useQuery } from "@apollo/client"; + +import { GET_TEST } from "../../../../APIClients/queries/TestQueries"; +import type { TestResponse } from "../../../../APIClients/types/TestClientTypes"; +import * as Routes from "../../../../constants/Routes"; +import useToast from "../../../common/info/useToast"; +import PopoverButton from "../../../common/popover/PopoverButton"; + +interface PreviewButtonProps { + assessmentId: string; +} + +const PreviewButton = ({ + assessmentId, +}: PreviewButtonProps): React.ReactElement => { + const history = useHistory(); + const { data } = useQuery<{ test: TestResponse }>(GET_TEST, { + fetchPolicy: "cache-and-network", + variables: { id: assessmentId }, + }); + const { showToast } = useToast(); + + return ( + { + if (data) { + history.push({ + pathname: Routes.ASESESSMENT_PREVIEW_PAGE({ assessmentId }), + state: data.test, + }); + } else { + showToast({ + message: + "This assessment cannot be previewed at this time. Please try again.", + status: "error", + }); + } + }} + /> + ); +}; + +export default PreviewButton; diff --git a/frontend/src/components/admin/assessment-status/EditStatusPopover.tsx b/frontend/src/components/admin/assessment-status/EditStatusPopover.tsx index c54a5d0a7..bf8466579 100644 --- a/frontend/src/components/admin/assessment-status/EditStatusPopover.tsx +++ b/frontend/src/components/admin/assessment-status/EditStatusPopover.tsx @@ -8,6 +8,7 @@ import ArchiveButton from "./EditStatusButtons/ArchiveButton"; import DeleteButton from "./EditStatusButtons/DeleteButton"; import DuplicateButton from "./EditStatusButtons/DuplicateButton"; import EditButton from "./EditStatusButtons/EditButton"; +import PreviewButton from "./EditStatusButtons/PreviewButton"; import PublishButton from "./EditStatusButtons/PublishButton"; import UnarchiveButton from "./EditStatusButtons/UnarchiveButton"; @@ -38,6 +39,7 @@ const EditStatusPopover = ({ )} + diff --git a/frontend/src/components/pages/admin/AdminRouting.tsx b/frontend/src/components/pages/admin/AdminRouting.tsx index 9d1a7d84d..97cbdb7ac 100644 --- a/frontend/src/components/pages/admin/AdminRouting.tsx +++ b/frontend/src/components/pages/admin/AdminRouting.tsx @@ -10,6 +10,7 @@ import Navbar from "../../common/navigation/Navbar"; import NotFound from "../NotFound"; import AssessmentEditorPage from "./AssessmentEditorPage"; +import AssessmentPreviewPage from "./AssessmentPreviewPage"; import DisplayAssessmentsPage from "./DisplayAssessmentsPage"; import UsersPage from "./UsersPage"; @@ -33,6 +34,13 @@ const AdminRouting = (): React.ReactElement => { path={Routes.ASSESSMENT_EDITOR_BASE({ assessmentId: ":assessmentId" })} roles={["Admin"]} /> + diff --git a/frontend/src/components/pages/admin/AssessmentEditorPage/AssessmentEditor.tsx b/frontend/src/components/pages/admin/AssessmentEditorPage/AssessmentEditor.tsx index b9cfda60a..88cd720f6 100644 --- a/frontend/src/components/pages/admin/AssessmentEditorPage/AssessmentEditor.tsx +++ b/frontend/src/components/pages/admin/AssessmentEditorPage/AssessmentEditor.tsx @@ -278,6 +278,7 @@ const AssessmentEditor = ({ state }: AssessmentEditorProps): ReactElement => { })} > disableEditorPrompt(history.push)( Routes.ASSESSMENT_EDITOR_PAGE({ diff --git a/frontend/src/components/pages/admin/AssessmentPreviewPage.tsx b/frontend/src/components/pages/admin/AssessmentPreviewPage.tsx new file mode 100644 index 000000000..c92e8ddd7 --- /dev/null +++ b/frontend/src/components/pages/admin/AssessmentPreviewPage.tsx @@ -0,0 +1,56 @@ +import React, { useMemo } from "react"; +import { useLocation, useParams } from "react-router-dom"; +import { useHistory } from "react-router-dom"; +import { useQuery } from "@apollo/client"; +import { Box } from "@chakra-ui/react"; + +import { GET_TEST } from "../../../APIClients/queries/TestQueries"; +import type { TestResponse } from "../../../APIClients/types/TestClientTypes"; +import { ASSESSMENTS_PAGE } from "../../../constants/Routes"; +import { formatQuestionsResponse } from "../../../utils/QuestionUtils"; +import AssessmentPreview from "../../admin/assessment-creation/AssessmentPreview"; +import QueryStateHandler from "../../common/QueryStateHandler"; + +const AssessmentPreviewPage = () => { + const history = useHistory(); + + // Data could come from the previous page. + const { state: locationState } = useLocation(); + + // If data is not available from the previous page, then we have to fetch it. + const { assessmentId } = useParams<{ assessmentId?: string }>(); + const { + data: testData, + loading, + error, + } = useQuery<{ + test: TestResponse; + }>(GET_TEST, { + variables: { id: assessmentId }, + skip: !!locationState || !assessmentId, + }); + + const test = locationState || testData?.test; + const state = useMemo( + () => + test && { + ...test, + questions: formatQuestionsResponse(test.questions), + }, + [test], + ); + + return ( + + + history.push(ASSESSMENTS_PAGE)} + questions={state?.questions || []} + /> + + + ); +}; + +export default AssessmentPreviewPage; diff --git a/frontend/src/constants/Routes.ts b/frontend/src/constants/Routes.ts index 3250f5d6a..b45abe20a 100644 --- a/frontend/src/constants/Routes.ts +++ b/frontend/src/constants/Routes.ts @@ -55,6 +55,12 @@ export const ASSESSMENT_EDITOR_QUESTION_PREVIEW_PAGE = ({ ASSESSMENT_EDITOR_QUESTION_EDITOR_BASE({ assessmentId, questionIndex }) + "/preview"; +export const ASESESSMENT_PREVIEW_PAGE = ({ + assessmentId, +}: { + assessmentId: string; +}) => "/admin/assessment/" + assessmentId; + // Private Teacher Routes export const TEACHER_LANDING_PAGE = "/teacher"; export const TEACHER_DASHBOARD_PAGE = "/teacher/dashboard";