diff --git a/Models/SessionCandidateModels.ts b/Models/SessionCandidateModels.ts new file mode 100644 index 0000000..78368a1 --- /dev/null +++ b/Models/SessionCandidateModels.ts @@ -0,0 +1,13 @@ +export interface CandidateTestStatus { + testName: string; + testStatus: string; +} +export interface SessionCandidate { + firstName: string; + lastName: string; + testStatuses: CandidateTestStatus[]; +} +export interface NewTestSubmission{ + testId: number; + testAnswer: string; +} diff --git a/api/candidateApiClient.module.ts b/api/candidateApiClient.module.ts deleted file mode 100644 index 72af19a..0000000 --- a/api/candidateApiClient.module.ts +++ /dev/null @@ -1,45 +0,0 @@ -import getConfig from "next/config"; -import fetch from "node-fetch"; - -export interface SessionCandidate { - firstName: string; - lastName: string; - testStatuses: CandidateTestStatus[]; -} - -export interface CandidateTestStatus { - testName: string; - testStatus: string; -} -export interface NewTestSubmission{ - testId: number; - testAnswer: string; -} -export async function getSessionCandidate(token: string): Promise { - const {publicRuntimeConfig} = getConfig(); - const baseUrl = publicRuntimeConfig.API_URL; - try { - const result = await fetch( - `${baseUrl}/sessions/${token}` - ); - const data = await result.json(); - return data; - } catch (error) { - console.error(error); - return error.message; - } -} -export async function addTestSubmisson( tokenId: string,newTestSubmission: NewTestSubmission) { - const { publicRuntimeConfig } = getConfig(); - const apiURL=publicRuntimeConfig.API_URL; - - const response = await fetch(`${apiURL}/sessions/${tokenId}`, { - method: "POST", - headers: { - "Content-Type": "application/json" - }, - body: JSON.stringify(newTestSubmission), - }); - return await response; - -} \ No newline at end of file diff --git a/api/candidateApiClientModule.ts b/api/candidateApiClientModule.ts new file mode 100644 index 0000000..db731d2 --- /dev/null +++ b/api/candidateApiClientModule.ts @@ -0,0 +1,44 @@ +import getConfig from 'next/config'; +import fetch, {Response} from "node-fetch"; +import {ServerResponse} from "http"; +import {ParsedUrlQuery} from "querystring"; +import {NewTestSubmission, SessionCandidate} from "../Models/SessionCandidateModels"; + +const {publicRuntimeConfig} = getConfig(); +const baseUrl = publicRuntimeConfig.API_URL; + +export async function checkToken(token: string): Promise { + const response = await fetch(`${baseUrl}/sessions/${token}`); + return response.ok;} + +export async function assertTokenIsValid(query: ParsedUrlQuery, response: ServerResponse): Promise { + const token = query.token as string; + const tokenIsValid = await checkToken(token); + if (!tokenIsValid) { + response.statusCode = 404; + response.end(); + } + return token; +} + +export async function getSessionCandidate(token: string | string[] | undefined): Promise { + const {publicRuntimeConfig} = getConfig(); + const baseUrl = publicRuntimeConfig.API_URL; + const result = await fetch( + `${baseUrl}/sessions/${token}` + ); + return await result.json(); +} + +export async function addTestSubmission( tokenId: string, newTestSubmission: NewTestSubmission): Promise { + const { publicRuntimeConfig } = getConfig(); + const apiURL = publicRuntimeConfig.API_URL; + return await fetch(`${apiURL}/sessions/${tokenId}`, { + method: "POST", + headers: { + "Content-Type": "application/json" + }, + body: JSON.stringify(newTestSubmission), + }); +} + diff --git a/api/sessionClient.ts b/api/sessionClient.ts deleted file mode 100644 index 295c822..0000000 --- a/api/sessionClient.ts +++ /dev/null @@ -1,10 +0,0 @@ -import getConfig from 'next/config'; -import fetch from "node-fetch"; - -export async function checkToken(token: string): Promise { - const {publicRuntimeConfig} = getConfig(); - const baseUrl = publicRuntimeConfig.API_URL; - - const response = await fetch(`${baseUrl}/sessions/${token}`); - return response.ok; -} \ No newline at end of file diff --git a/components/CandidateTestView/CandidateTestView.tsx b/components/CandidateTestView/CandidateTestView.tsx index 97132a9..abed2d1 100644 --- a/components/CandidateTestView/CandidateTestView.tsx +++ b/components/CandidateTestView/CandidateTestView.tsx @@ -9,18 +9,16 @@ interface CandidateTestViewProps { token: string; } const CandidateTestView = (candidateTestViewProps: CandidateTestViewProps): JSX.Element => ( -

Test {candidateTestViewProps.test.number}: {candidateTestViewProps.test.title}

-

{candidateTestViewProps.test.title}

{InstructionsBlock(candidateTestViewProps.test)}
- ); -export default CandidateTestView; \ No newline at end of file +export default CandidateTestView; diff --git a/components/CandidateTestView/Instructions/Instructions.module.scss b/components/CandidateTestView/Instructions/Instructions.module.scss index fe00c8f..2c732eb 100644 --- a/components/CandidateTestView/Instructions/Instructions.module.scss +++ b/components/CandidateTestView/Instructions/Instructions.module.scss @@ -1,14 +1,37 @@ -.sampleInputOutput { - margin: 5px; - padding: 5px; - top: 78vh; - left: 46vw; - display: inline-block; - position: absolute; - overflow: hidden; -} +@import "pageStyles/constants"; + .testInstructions { - height: 500px; - max-width: 50vw; + box-sizing: border-box; + color: $techSwitchWhite; + white-space: pre-wrap; + font-size: $desktopBodyFontSize; + text-align: left; + padding-right: 1rem; + padding-left: 5rem; + margin-right: 2rem; + line-height: 130%; + width: 700px; +} +.instructionsSubheader { + font-size: $desktopSubHeaderFontSize; + line-height: 1rem; +} + +@media (max-width: $mediaLowResMaxWidth) { + //Low Resolution 900px and below + .instructionsHeader { + font-size: $lowResSubHeaderFontSize; + } + .instructionsSubheader { + box-sizing: border-box; + font-size: $lowResSubHeaderFontSize; + } + .testInstructions { + font-size: $lowResBodyFontSize; + box-sizing: border-box; + padding-left: 0.5rem; + padding-right: 0.5rem; + width: 300px; + } +} -} \ No newline at end of file diff --git a/components/CandidateTestView/Instructions/Instructions.tsx b/components/CandidateTestView/Instructions/Instructions.tsx index 5795745..a45ea80 100644 --- a/components/CandidateTestView/Instructions/Instructions.tsx +++ b/components/CandidateTestView/Instructions/Instructions.tsx @@ -3,16 +3,17 @@ import scss from "../Instructions/Instructions.module.scss"; import {CandidateTestModel} from "../../../Models/CandidateTestModel"; const InstructionsBlock = (testModel: CandidateTestModel): JSX.Element => ( -
-

{testModel.brief}

-

Example

-

{testModel.example}

-

Input/Output

-
    +
    +

    {testModel.title}

    +

    {testModel.brief}

    +

    Example

    +

    {testModel.example}

    +

    Input/Output

    +
    • [input] {testModel.inputType}
      {testModel.inputDescription}
    • [output] {testModel.outputType}
      {testModel.outputDescription}
    ); -export default InstructionsBlock; \ No newline at end of file +export default InstructionsBlock; diff --git a/components/CandidateTestView/candidateTestView.module.scss b/components/CandidateTestView/candidateTestView.module.scss index 26e9b5b..4ae38d2 100644 --- a/components/CandidateTestView/candidateTestView.module.scss +++ b/components/CandidateTestView/candidateTestView.module.scss @@ -1,82 +1,53 @@ @import "../../pageStyles/constants"; .testPage { - max-height: 800px; + box-sizing: border-box; + max-height: 100vh; max-width: 100vw; display: flex; - flex-direction: column; - flex-wrap: wrap; - margin-top: 2vh; -} - -.testInstructions { - height: 500px; - max-width: 50vw; - -} -.instructionList { - margin-bottom: 1em; -} - -.testInstructionsHeader { - color: $techSwitchWhite; - font-size: $desktopSubHeaderFontSize; - margin-bottom: 12px; - padding: 5px; -} - -.testInstructions { - color: $techSwitchWhite; - white-space: pre-wrap; - font-size: $bodyFontSize; - justify-content: left; - text-align: left; - width: 40vw; - line-height: 1.5; - padding-left: 3vw; - margin-top: 12px; - margin-bottom: 24px; - margin-right: 5px; - margin-left: 5px; -} - -.textEditor { - color: $techSwitchWhite; - font-size: $buttonFontSize; - justify-content: right; - margin-top: 5vh; - margin-right: 1vw; + flex-direction: row; + justify-content: center; + align-items: flex-start; + margin-top: 70px; } .testTitle { + box-sizing: border-box; color: $techSwitchYellow; - font-size: 30pt; - max-width: 40vw; + font-size: $desktopHeaderFontSize; white-space: nowrap; - margin: 5px; - padding: 5px; - top: 1vh; - right: 2vw; - overflow: hidden; position: absolute; + top: 1px; + right: 100px; + margin-right: 1px; text-align: right; } -.editorBox { - border-style: solid; - border-width: 5px; - border-color: $techSwitchYellow; -} - -.sampleInputOutput { - margin: 5px; - padding: 5px; - top: 85vh; - left: 46vw; - display: flex; - flex-direction: column; - line-height: 0; - position: absolute; - overflow: hidden; -} + @media (max-width: $mediaLowResMaxWidth){ + //Low Resolution 900px and below + .testPage { + box-sizing: border-box; + width: 100vw; + display: flex; + flex-direction: column; + align-items: center; + margin-top: 50px; + } + + .testTitle { + font-size: $lowResHeaderFontSize; + white-space: normal; + overflow-wrap: break-spaces; + position: absolute; + top: 1px; + right: 1px; + padding: 0; + margin: 0; + text-align: right; + } + .buttonYellow{ + @include techSwitchButton($techSwitchYellow, $techSwitchBlack, $lowResBodyFontSize); + width: 120px; + } + } diff --git a/components/Layout/layout.module.scss b/components/Layout/layout.module.scss index f3bda09..d361e73 100644 --- a/components/Layout/layout.module.scss +++ b/components/Layout/layout.module.scss @@ -3,30 +3,18 @@ .layout { background-color: $techSwitchBlack; box-sizing: border-box; - padding: 0; - margin: 0; border-style: none; font-family: $techSwitchFont; -} - -body { + min-height: 100vh; + width: 100vw; margin: 0; + padding: 0; } .logoHeader { - width: 100px; - padding: 15px; - margin: 6px; + box-sizing: border-box; + width: 180px; + padding: 0.2rem; + margin: 0.2rem; align-self: flex-start; } - -@media (min-width: 768px){ - .logoHeader{ - width: 200px; - } -} - -.layoutHeader { - width: 100vw; - text-align: left; -} \ No newline at end of file diff --git a/components/Layout/layout.tsx b/components/Layout/layout.tsx index afaef94..f9e0853 100644 --- a/components/Layout/layout.tsx +++ b/components/Layout/layout.tsx @@ -4,9 +4,8 @@ import scss from './layout.module.scss'; type LayoutProps = {children: React.ReactNode }; const Layout = ({children}: LayoutProps): JSX.Element => (
    -
    - TechSwitch - +
    + TechSwitch
    {children} diff --git a/components/TestLibraryStepper/TestLibraryStepper.tsx b/components/TestLibraryStepper/TestLibraryStepper.tsx index a589b32..b20c1fb 100644 --- a/components/TestLibraryStepper/TestLibraryStepper.tsx +++ b/components/TestLibraryStepper/TestLibraryStepper.tsx @@ -4,33 +4,28 @@ import {MuiThemeProvider} from '@material-ui/core/styles'; import TestSwitchStepIcon from "../TestLibraryStepperIcons/TestLibraryStepperIcons"; import {h1Style, TestSwitchConnector, TestSwitchTheme} from "../TestLibraryOverrides/TestLibraryOverrides" import scss from '../TestLibraryStepper/TestLibraryStepper.module.scss'; +import {TestList} from "../CandidateTestView/Tests/TestList"; import TokenLink from "../TokenLink/TokenLink"; - -interface CandidateTestStatus { - testName: string; - testStatus: string; -} - -interface TestLibraryStepperProps { +import {CandidateTestStatus} from "../../Models/SessionCandidateModels"; +export interface TestLibraryStepperProps { candidateTestStatuses: CandidateTestStatus[]; } - -function getSteps(testArr: CandidateTestStatus[]): string[] { +function getSteps(): string[] { //set labels for steps - return testArr.map(test => test.testName); + const testLabelArray = TestList.map(test => test.title) + const dummyTest = testLabelArray.shift(); + return testLabelArray; } -function getActiveStep(testArr: CandidateTestStatus[]): number { +export function getActiveStep(sessionCandidate: CandidateTestStatus[]): number { //check for number of completed tests - const completedTests = (testArr.filter(({testStatus}) => testStatus === "Completed")); + const completedTests = (sessionCandidate.filter(({testStatus}) => testStatus === "Completed")); return completedTests.length; } - export default function TestLibraryStepper(props: TestLibraryStepperProps): JSX.Element { - const steps = getSteps(props.candidateTestStatuses); + const steps = getSteps(); const activeStep = getActiveStep(props.candidateTestStatuses); - return ( ) } - + diff --git a/components/TextEditor/TextEditorContainer.module.scss b/components/TextEditor/TextEditorContainer.module.scss index d9a7b44..a7d3f7a 100644 --- a/components/TextEditor/TextEditorContainer.module.scss +++ b/components/TextEditor/TextEditorContainer.module.scss @@ -1,9 +1,17 @@ @import "../../pageStyles/constants"; .editorBox { + box-sizing: border-box; border-style: solid; border-width: 5px; + min-width: 700px; + max-width: 2200px; width: 50vw; border-color: $techSwitchYellow; + color: $techSwitchWhite; + font-size: $desktopBodyFontSize; + margin-right: 5rem; + margin-left: 2rem; + padding: 0; } .buttonBlack{ @@ -11,6 +19,23 @@ display: block; } +@media (max-width: $mediaLowResMaxWidth) { + //Low Resolution 900px and below + .editorBox { + box-sizing: border-box; + border-width: 0.2rem; + width: 300px; + margin: 0; + padding: 0; + } + + .buttonBlack{ + font-size: $lowResBodyFontSize; + border-width: 0.2rem; + max-width: 150px; + } +} + .error{ color: $errorMessage; -} \ No newline at end of file +} diff --git a/components/TextEditor/TextEditorContainer.tsx b/components/TextEditor/TextEditorContainer.tsx index 265c387..4a60735 100644 --- a/components/TextEditor/TextEditorContainer.tsx +++ b/components/TextEditor/TextEditorContainer.tsx @@ -2,16 +2,11 @@ import React, {FunctionComponent, MutableRefObject, useRef, useState} from "reac import Editor from "@monaco-editor/react"; import {TextEditorSettings} from "./TextEditorSettings"; import scss from "../TextEditor/TextEditorContainer.module.scss"; -import Link from "next/link"; -import TokenLink from "../TokenLink/TokenLink"; -import {addTestSubmisson} from "../../api/candidateApiClient.module"; import {useRouter} from "next/router"; -import {Response} from "node-fetch"; +import {addTestSubmission} from "../../api/candidateApiClientModule"; type EditorContentGetter = () => string; - - interface TextEditorContainerProps { height: string; width: string; @@ -24,29 +19,33 @@ const TextEditorContainer: FunctionComponent = ({heigh const [error, setError] = useState(""); const getEditorContentIfMountedRef: MutableRefObject = useRef(() => ""); const router=useRouter(); - + function handleIsEditorMounted(_getEditorContents: EditorContentGetter): void { setIsEditorReady(true); + if(isEditorReady) { getEditorContentIfMountedRef.current = _getEditorContents; - } + }} - - function submitForm() { - const testAnswer=getEditorContentIfMountedRef.current(); - addTestSubmisson(token,{testId,testAnswer}) - .then((response)=>{ + + function submitForm(): void { + const testAnswer = getEditorContentIfMountedRef.current(); + const url = "/testlibrary"; + addTestSubmission(token,{testId,testAnswer}) + .then((response)=>{ if (response.ok) { - router.push(`/submitted?token=${token}`); + router.push(`${url}?token=${token}`); } else { throw Error(response.statusText); } - }) + }) .catch(error=>{console.log(error); setError("There was an error submitting your test")}); - } - + const handleSubmit = () => { + submitForm(); + } return ( +

    {error}

    @@ -58,15 +57,13 @@ const TextEditorContainer: FunctionComponent = ({heigh value={defaultText} editorDidMount={handleIsEditorMounted} options={TextEditorSettings} - + />
    - - - +
    - + ); }; -export default TextEditorContainer; \ No newline at end of file +export default TextEditorContainer; diff --git a/components/TextEditor/TextEditorSettings.ts b/components/TextEditor/TextEditorSettings.ts index b454ebc..fa920a4 100644 --- a/components/TextEditor/TextEditorSettings.ts +++ b/components/TextEditor/TextEditorSettings.ts @@ -1,4 +1,5 @@ import {editor} from "monaco-editor"; + type TextEditorOptions = editor.IEditorOptions; const TextEditorSettings: TextEditorOptions = { @@ -9,11 +10,11 @@ const TextEditorSettings: TextEditorOptions = { enabled: false }, folding: false, - fontSize: 26, minimap: { enabled: true, scale: 100 }, + fontSize: 18, scrollBeyondLastLine: false, suggest: { showMethods: false, @@ -44,4 +45,4 @@ const TextEditorSettings: TextEditorOptions = { maxVisibleSuggestions: 5, } }; -export {TextEditorSettings}; \ No newline at end of file +export {TextEditorSettings} diff --git a/components/TokenLink/TokenLink.tsx b/components/TokenLink/TokenLink.tsx index 53bf2c7..96c4512 100644 --- a/components/TokenLink/TokenLink.tsx +++ b/components/TokenLink/TokenLink.tsx @@ -2,18 +2,17 @@ import {useRouter} from "next/router"; import Link from "next/link"; +type TokenLinkProps = {href: string}; -type TokenLinkProps = {children: React.ReactNode; href: string} +const TokenLink: React.FunctionComponent = ({children, href}) => { + const router = useRouter(); + const token = router.query.token; + const hrefLink = `${href}?token=${token}`; + return ( + + {children} + + ) +} -const TokenLink: React.FunctionComponent = ({children, href}: TokenLinkProps) => { - const router = useRouter(); - - return ( - - {children} - - ) - -}; - -export default TokenLink; \ No newline at end of file +export default TokenLink; diff --git a/helpers/tokenHelpers.ts b/helpers/tokenHelpers.ts deleted file mode 100644 index c1db993..0000000 --- a/helpers/tokenHelpers.ts +++ /dev/null @@ -1,13 +0,0 @@ -import {ServerResponse} from "http"; -import {ParsedUrlQuery} from "querystring"; -import {checkToken} from "../api/sessionClient"; - -export async function assertTokenIsValid(query: ParsedUrlQuery, response: ServerResponse): Promise { - const token = query.token as string; - const tokenIsValid = await checkToken(token); - - if (!tokenIsValid) { - response.statusCode = 404; - response.end(); - } -} diff --git a/next-env.d.ts b/next-env.d.ts index 7b7aa2c..c5038bd 100644 --- a/next-env.d.ts +++ b/next-env.d.ts @@ -1,2 +1,3 @@ /// /// + diff --git a/next.config.js b/next.config.js index d17fb67..784a869 100644 --- a/next.config.js +++ b/next.config.js @@ -6,9 +6,3 @@ module.exports = withSass({ } }); -WebFontConfig = { - google: { - families: ['Open Sans'] - }, - timeout: 2000 -}; diff --git a/pageStyles/404Error.module.scss b/pageStyles/404Error.module.scss new file mode 100644 index 0000000..f2fb70a --- /dev/null +++ b/pageStyles/404Error.module.scss @@ -0,0 +1,56 @@ +@import "constants"; + +.errorHeader { + color: $techSwitchYellow; + font-size: $desktopHeaderFontSize; +} + +.thankyou { + color: $techSwitchYellow; + font-size: $desktopHeaderFontSize; +} + +.errorMessage { + color: $techSwitchWhite; + font-size: $desktopSubHeaderFontSize; + max-width: 600px; +} + +.content { + width: 100vw; + max-height: 700px; + min-height: 400px; + text-align: center; + align-items: center; + display: flex; + flex-direction: column; + flex-wrap: nowrap; + justify-content: stretch; + padding: 3px; + font-family: Open Sans, sans-serif; + text-decoration: none; +} + + +//Media Queries + +@media (max-width: $mediaLowResMaxWidth){ + //Low Resolution 900px and below + .errorHeader { + font-size: $lowResHeaderFontSize; + margin: 0.2em; + padding: 0.5rem; + } + .thankyou { + font-size: $lowResSubHeaderFontSize; + margin: 0.2em; + padding: 0.5rem; + } + .errorMessage { + font-size: $lowResBodyFontSize; + line-height: 150%; + margin: 0.2em; + padding: 0.5rem; + } + +} diff --git a/pageStyles/constants.scss b/pageStyles/constants.scss index 433cdb2..1c1be79 100644 --- a/pageStyles/constants.scss +++ b/pageStyles/constants.scss @@ -1,6 +1,4 @@ -//Default Header Width -$welcomeHeaderWidth: 760px; -//Site Colours +//Site Colours $techSwitchBlack: rgb(24, 24, 24); $techSwitchYellow: rgb(255, 193, 0); $techSwitchWhite: rgb(255, 255, 255); @@ -8,13 +6,18 @@ $techSwitchWhite: rgb(255, 255, 255); $errorMessage:rgb(226,25,100); //Fonts $techSwitchFont: Open Sans, sans-serif; -$desktopHeaderFontSize: 60px; -$desktopSubHeaderFontSize: 36px; -$buttonFontSize: 27px; -$bodyFontSize: 20px; + + $desktopHeaderFontSize: 2rem; + $desktopSubHeaderFontSize: 1.5rem; + $desktopBodyFontSize: 1.2rem; + + $mediaLowResMaxWidth: 900px; + $lowResHeaderFontSize: 1.3rem; + $lowResSubHeaderFontSize: 1rem; + $lowResBodyFontSize: 0.8rem; //Buttons -@mixin techSwitchButton($backgroundColour: $techSwitchBlack, $inverseColour: $techSwitchYellow) { +@mixin techSwitchButton($backgroundColour: $techSwitchBlack, $inverseColour: $techSwitchYellow, $fontSize: $desktopBodyFontSize) { width: 180px; height: 1.3em; margin-top: 20px; @@ -24,9 +27,9 @@ $bodyFontSize: 20px; border: 5px solid $techSwitchYellow; color: $inverseColour; font-family: $techSwitchFont; - font-size: $buttonFontSize; + font-size: $fontSize; text-align: center; - text-decoration: none; + text-decoration: none; transition: all 250ms ease; background: $backgroundColour; diff --git a/pageStyles/index.module.scss b/pageStyles/index.module.scss index 9eb25d8..18f76c1 100644 --- a/pageStyles/index.module.scss +++ b/pageStyles/index.module.scss @@ -3,20 +3,19 @@ .welcome { color: $techSwitchYellow; font-size: $desktopHeaderFontSize; - max-width: $welcomeHeaderWidth; - margin: 5px; - padding: 5px; + margin: 1rem; + padding: 1rem; + width: 500px; } .content { - width: 100%; + width: 100vw; align-items: center; display: flex; flex-direction: column; - flex-wrap: wrap; - justify-content: center; - padding: 3px; - font-family: Open Sans, sans-serif; + flex-wrap: nowrap; + justify-content: space-between; + font-family: $techSwitchFont; text-decoration: none; text-align: center; } @@ -24,27 +23,48 @@ .instructionsHeader { color: $techSwitchWhite; font-size: $desktopSubHeaderFontSize; - margin-top: 24px; - margin-bottom: 12px; - padding: 5px; } .instructions { color: $techSwitchWhite; - font-size: $buttonFontSize; + font-size: $desktopBodyFontSize; justify-content: left; text-align: left; - padding: 5px; - margin-top: 12px; - margin-bottom: 24px; - margin-right: 5px; - margin-left: 5px; - max-width: $welcomeHeaderWidth; + width: 500px; } .buttonYellow{ - @include techSwitchButton($techSwitchYellow, $techSwitchBlack) + @include techSwitchButton($techSwitchYellow, $techSwitchBlack, $desktopBodyFontSize) } + //Media Queries + + @media (max-width: $mediaLowResMaxWidth){ + //Low Resolution 900px and below + .welcome { + font-size: $lowResHeaderFontSize; + margin: 0.2em; + padding: 0.5rem; + max-width: 500px; + min-width: 250px; + } + .instructionsHeader { + font-size: $lowResSubHeaderFontSize; + max-width: 500px; + min-width: 250px; + } + + .instructions { + width: 50vw; + font-size: $lowResBodyFontSize; + max-width: 500px; + min-width: 250px; + } + .buttonYellow{ + @include techSwitchButton($techSwitchYellow, $techSwitchBlack, $lowResBodyFontSize); + max-width: 80px; + } + } + diff --git a/pageStyles/submitted.module.scss b/pageStyles/submitted.module.scss index c00e385..9f61d66 100644 --- a/pageStyles/submitted.module.scss +++ b/pageStyles/submitted.module.scss @@ -13,16 +13,44 @@ .submitMessage { color: $techSwitchWhite; font-size: $desktopSubHeaderFontSize; + max-width: 600px; } .content { - width: 100%; + width: 100vw; + max-height: 700px; + min-height: 400px; + text-align: center; align-items: center; display: flex; flex-direction: column; - flex-wrap: wrap; - justify-content: center; + flex-wrap: nowrap; + justify-content: stretch; padding: 3px; font-family: Open Sans, sans-serif; text-decoration: none; } + + +//Media Queries + +@media (max-width: $mediaLowResMaxWidth){ + //Low Resolution 900px and below + .submitHeader { + font-size: $lowResHeaderFontSize; + margin: 0.2em; + padding: 0.5rem; + } + .thankyou { + font-size: $lowResSubHeaderFontSize; + margin: 0.2em; + padding: 0.5rem; + } + .submitMessage { + font-size: $lowResBodyFontSize; + line-height: 150%; + margin: 0.2em; + padding: 0.5rem; + } + +} diff --git a/pages/404Error.tsx b/pages/404Error.tsx new file mode 100644 index 0000000..6b6461e --- /dev/null +++ b/pages/404Error.tsx @@ -0,0 +1,16 @@ +import {NextPage} from 'next'; +import Layout from "../components/Layout/layout"; +import scss from "../pageStyles/404Error.module.scss"; +import React from "react"; + +const AccessDenied: NextPage = () => ( + +
    +

    404 Error: Page Cannot be Found

    +

    Please use the unique link sent to you by email to access your tests

    +

    Thank You!

    +
    +
    +); + +export default AccessDenied; diff --git a/pages/_document.tsx b/pages/_document.tsx index 7c555e7..72892af 100644 --- a/pages/_document.tsx +++ b/pages/_document.tsx @@ -9,7 +9,6 @@ class MyDocument extends Document { const initialProps = await Document.getInitialProps(ctx); return {...initialProps} } - render(): JSX.Element { return ( @@ -23,4 +22,4 @@ class MyDocument extends Document { } } -export default MyDocument \ No newline at end of file +export default MyDocument diff --git a/pages/index.tsx b/pages/index.tsx index fafc456..3e04bd3 100644 --- a/pages/index.tsx +++ b/pages/index.tsx @@ -1,38 +1,27 @@ import React from "react"; -import {GetServerSideProps, NextPage} from 'next'; import scss from '../pageStyles/index.module.scss'; import Layout from "../components/Layout/layout"; -import {CandidateTestModel} from "../Models/CandidateTestModel"; -import {TestList} from "../components/CandidateTestView/Tests/TestList"; -import {assertTokenIsValid} from "../helpers/tokenHelpers"; import TokenLink from "../components/TokenLink/TokenLink"; +import {GetServerSideProps, NextPage} from "next"; +import {assertTokenIsValid} from "../api/candidateApiClientModule"; -export const testToRender: CandidateTestModel = TestList[1]; const Home: NextPage = () =>

    Welcome to the Test Zone

    Test Instructions

      -
    • There is no time limit for this test, but time taken will be reviewed as part of our assessment. -
    • +
    • There is no time limit for this test, but time taken will be reviewed as part of our assessment.
    • You must complete the test in one sitting
    • When you are ready and sure you won’t be disturbed, please click “Start”
    - + Start
    ; - export const getServerSideProps: GetServerSideProps = async ({res, query}) => { await assertTokenIsValid(query, res); return { props: {}}; }; - export default Home; - - - - - diff --git a/pages/submitted.tsx b/pages/submitted.tsx index bb0be82..1af0ead 100644 --- a/pages/submitted.tsx +++ b/pages/submitted.tsx @@ -2,7 +2,7 @@ import Layout from "../components/Layout/layout"; import scss from "../pageStyles/submitted.module.scss"; import React from "react"; -import {assertTokenIsValid} from "../helpers/tokenHelpers"; +import {assertTokenIsValid} from "../api/candidateApiClientModule"; const Submitted: NextPage = () => ( @@ -13,10 +13,10 @@ const Submitted: NextPage = () => (
    ); - export const getServerSideProps: GetServerSideProps = async ({res, query}) => { await assertTokenIsValid(query, res); return { props: {}}; }; -export default Submitted; \ No newline at end of file +export default Submitted; + diff --git a/pages/testlibrary.tsx b/pages/testlibrary.tsx index 0786dd2..5524f44 100644 --- a/pages/testlibrary.tsx +++ b/pages/testlibrary.tsx @@ -2,26 +2,21 @@ import {GetServerSideProps, NextPage} from "next"; import Head from "next/head"; import TestLibraryStepper from "../components/TestLibraryStepper/TestLibraryStepper"; -import {getSessionCandidate, SessionCandidate} from "../api/candidateApiClient.module" import Layout from "../components/Layout/layout"; -import {assertTokenIsValid} from "../helpers/tokenHelpers"; +import {assertTokenIsValid, getSessionCandidate} from "../api/candidateApiClientModule"; +import {SessionCandidate} from "../Models/SessionCandidateModels"; -interface TestlibraryProps { +interface TestLibraryProps { sessionCandidate: SessionCandidate; } -const TestLibrary: NextPage = ({sessionCandidate}) => { - const [key, setKey] = React.useState(0); - - React.useEffect(() => { - setKey(1); - }, []); +const TestLibrary: NextPage = ({sessionCandidate}) => { return ( TestSwitch Test Library - + ); }; @@ -29,13 +24,12 @@ const TestLibrary: NextPage = ({sessionCandidate}) => { export const getServerSideProps: GetServerSideProps = async ({query, res}) => { await assertTokenIsValid(query, res); const token = query.token as string; - const sessionData = getSessionCandidate(token); - return { props: { - sessionCandidate: await sessionData + sessionCandidate: await getSessionCandidate(token) } } }; -export default TestLibrary; \ No newline at end of file +export default TestLibrary; + diff --git a/pages/testpage.tsx b/pages/testpage.tsx index 41b8254..5b920ed 100644 --- a/pages/testpage.tsx +++ b/pages/testpage.tsx @@ -1,25 +1,39 @@ -import {GetServerSideProps, NextPage} from 'next'; -import React from "react"; +import React from "react"; import Layout from "../components/Layout/layout"; import CandidateTestView from "../components/CandidateTestView/CandidateTestView"; import {CandidateTestModel} from "../Models/CandidateTestModel"; -import {testToRender} from "./index"; -import {assertTokenIsValid} from "../helpers/tokenHelpers"; +import {GetServerSideProps, NextPage} from "next"; import {useRouter} from "next/router"; +import {getActiveStep} from "../components/TestLibraryStepper/TestLibraryStepper"; +import {TestList} from "../components/CandidateTestView/Tests/TestList"; +import {assertTokenIsValid, getSessionCandidate} from "../api/candidateApiClientModule"; +import {SessionCandidate} from "../Models/SessionCandidateModels"; -const TestPage: NextPage = () => { +interface TestPageProps { + sessionCandidate: SessionCandidate; +} +export function getTestToRender(sessionCandidate: SessionCandidate): CandidateTestModel { + const activeStep = getActiveStep(sessionCandidate.testStatuses); + return (TestList[activeStep + 1]); +} + +const TestPage: NextPage = ({sessionCandidate}) => { const router = useRouter(); const token = router.query.token as string; + const testToRender = getTestToRender(sessionCandidate); return ( ) }; - -export const getServerSideProps: GetServerSideProps = async ({res, query}) => { +export const getServerSideProps: GetServerSideProps = async ({query, res}) => { await assertTokenIsValid(query, res); - return { props: {}}; + const token = query.token as string; + return { + props: { + sessionCandidate: await getSessionCandidate(token) + } + } }; - -export default TestPage; \ No newline at end of file +export default TestPage; diff --git a/tsconfig.json b/tsconfig.json index f8fc34e..e7e0f29 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,6 +1,6 @@ { "compilerOptions": { - "target": "es5", + "target": "es2017", "lib": [ "dom", "dom.iterable",