2 Commit

11 ha cambiato i file con 92 aggiunte e 70 eliminazioni
  1. +3
    -2
      src/components/CountDownTimer/useCountdown.tsx
  2. +11
    -2
      src/components/timeSlot/TimeSlot.tsx
  3. +8
    -16
      src/mockData/QuizDetails.ts
  4. +7
    -1
      src/models/QuizDetails.ts
  5. +15
    -16
      src/pages/finalInterview/FinalInterview.tsx
  6. +2
    -2
      src/pages/interviewRounds/StepDescreption.tsx
  7. +1
    -3
      src/pages/preliminaryRoundResults/PreliminaryRoundResults.tsx
  8. +10
    -6
      src/pages/quiz/Options.module.scss
  9. +11
    -6
      src/pages/quiz/Options.tsx
  10. +7
    -7
      src/pages/quiz/Quiz.tsx
  11. +17
    -9
      src/pages/technicalInterview/TechnicalInterview.tsx

+ 3
- 2
src/components/CountDownTimer/useCountdown.tsx Vedi File

@@ -1,7 +1,7 @@
import { useEffect, useState } from 'react';

const useCountdown = (targetDate: Date) => {
console.log(targetDate);
const countDownDate = new Date(targetDate).getTime();

const [countDown, setCountDown] = useState(
@@ -14,13 +14,14 @@ const useCountdown = (targetDate: Date) => {
}, 1000);

return () => clearInterval(interval);
}, []);
}, [targetDate]);

const days = Math.floor(countDown / (1000 * 60 * 60 * 24));
const hours = Math.floor((countDown % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
const minutes = Math.floor((countDown % (1000 * 60 * 60)) / (1000 * 60));
const seconds = Math.floor((countDown % (1000 * 60)) / 1000);


return [days, hours, minutes, seconds];
};


+ 11
- 2
src/components/timeSlot/TimeSlot.tsx Vedi File

@@ -9,6 +9,7 @@ interface OwnProps {
month: string;
getDate: () => void;
HideTimeSlot: () => void;
getTimeSlot: (date: any, time: string) => void;
}

const TimeSlot: React.FC<OwnProps> = (props) => {
@@ -16,6 +17,14 @@ const TimeSlot: React.FC<OwnProps> = (props) => {
const [highlightedDate, setHighlightedDate] = useState<Date>();
const [highlightedTime, setHighlightedTime] = useState<string>("");

const setTimeSlot = () => {
if (highlightedDate && highlightedTime !== "") {
props.getDate();
props.getTimeSlot(highlightedDate, highlightedTime);
} else {
return undefined;
}
}
const dates = Dates.map((date, key) => {
return (
<div
@@ -27,7 +36,7 @@ const TimeSlot: React.FC<OwnProps> = (props) => {
{format(date, 'eee')}
</div>
<div>
{format(date, 'e')}
{format(date, 'd')}
</div>

</div>
@@ -68,7 +77,7 @@ const TimeSlot: React.FC<OwnProps> = (props) => {
</div>
</div>

<div onClick={(highlightedDate && highlightedTime !== "") ? () => props.getDate() : undefined}
<div onClick={setTimeSlot}
className={styles.timeSlotButton + " " + (highlightedDate && highlightedTime !== "" ? styles.buttonActive : "")}>
<IonButton shape="round" expand='block' >Confirm slot</IonButton>
</div>


+ 8
- 16
src/mockData/QuizDetails.ts Vedi File

@@ -1,4 +1,5 @@
import { QuizDetails } from "../models/QuizDetails";
import { QuizDetails, OptionType } from "../models/QuizDetails";


const QUIZ_DETAILS: QuizDetails[] = [
{
@@ -12,7 +13,7 @@ const QUIZ_DETAILS: QuizDetails[] = [
answer: ["System.out.println('Hello, how are you?');"],
result: false,
timeLimit: 5,
type: "singleSelect"
type: OptionType.SINGLE_SELECT
},
{
question: "How do you write 'Hello World' in an alert box?",
@@ -25,7 +26,7 @@ const QUIZ_DETAILS: QuizDetails[] = [
answer: ["alert('Hello World');"],
result: false,
timeLimit: 10,
type: "singleSelect"
type: OptionType.SINGLE_SELECT

},
{
@@ -38,8 +39,8 @@ const QUIZ_DETAILS: QuizDetails[] = [
],
answer: ["B", "C"],
result: false,
timeLimit: 15,
type: "multiSelect"
timeLimit: 60,
type: OptionType.MULTI_SELECT
},
{
question: "Is javascript single threaded or multi threaded? enter the answer in the below box ",
@@ -47,7 +48,7 @@ const QUIZ_DETAILS: QuizDetails[] = [
answer: ["single threaded"],
result: false,
timeLimit: 60,
type: "textInput"
type: OptionType.INPUT_TEXT
},
{
question: "is javascript",
@@ -60,17 +61,8 @@ const QUIZ_DETAILS: QuizDetails[] = [
answer: ["B", "C"],
result: false,
timeLimit: 35,
type: "multiSelect"
type: OptionType.MULTI_SELECT
},
];

export let test = [
{
a: "ss"
},
{
a: "aa"
},
]

export default QUIZ_DETAILS;

+ 7
- 1
src/models/QuizDetails.ts Vedi File

@@ -1,8 +1,14 @@
export enum OptionType {
SINGLE_SELECT = "singleSelect",
MULTI_SELECT = "multiSelect",
INPUT_TEXT = "textInput"
}

export interface QuizDetails {
question: string;
options?: string[];
answer: string[];
result: boolean;
timeLimit: number;
type: string;
type: OptionType;
}

+ 15
- 16
src/pages/finalInterview/FinalInterview.tsx Vedi File

@@ -8,23 +8,28 @@ import { Link } from "react-router-dom";
import { useState } from "react";
import TimeSlot from "../../components/timeSlot/TimeSlot";
import { useCountdown } from "../../components/CountDownTimer/useCountdown";
import { addDays } from "date-fns";
import CountdownTimer from "../../components/CountDownTimer/CountdownTimer";
import { format } from "date-fns";

const FinalInterview: React.FC = () => {

const [isDateSet, setDate] = useState<boolean>(false);
const [isTimeSlot, setTimeSlot] = useState<boolean>(false);
const [isDateSet, setIsDate] = useState<boolean>(false);
const [isTimeSlot, setIsTimeSlot] = useState<boolean>(false);
const [date, setDate] = useState<Date>(new Date());

const [days, hours, minutes, seconds] = useCountdown(new Date('may 6, 2022 07:00:00'));
const [days, hours, minutes, seconds] = useCountdown(date);

const getDate = () => {
setTimeSlot(false);
setDate(true);
setIsTimeSlot(false);
setIsDate(true);
}

const HideTimeSlot = () => {
setTimeSlot(false);
setIsTimeSlot(false);
}

const getTimeSlot = (date: any, time: string) => {
setDate(new Date(`${format(date, "LLL")} ${format(date, "d")} ${format(date, "y")} ${time.substring(0, 8)}`));
}

return (
@@ -46,13 +51,6 @@ const FinalInterview: React.FC = () => {

<h4>Let's Meet in:</h4>
<div className={styles.timeLeft}>
{/* <h4 className={styles.time}>02 : 04 : 25 : 53</h4>
<div className={styles.days}>
<div>Days</div>
<div>Hrs</div>
<div>Mins</div>
<div>Secs</div>
</div> */}
<CountdownTimer
days={days}
hours={hours}
@@ -68,7 +66,7 @@ const FinalInterview: React.FC = () => {
</div>
{
!isDateSet ?
<div className={styles.techinicalInterviewBtn} onClick={() => setTimeSlot(true)}>
<div className={styles.techinicalInterviewBtn} onClick={() => setIsTimeSlot(true)}>
<IonButton shape="round" expand='block'>Find a slot</IonButton>
</div>
:
@@ -87,7 +85,8 @@ const FinalInterview: React.FC = () => {
<TimeSlot
month="April-May"
getDate={getDate}
HideTimeSlot={HideTimeSlot} />
HideTimeSlot={HideTimeSlot}
getTimeSlot={getTimeSlot} />
}

</IonContent>


+ 2
- 2
src/pages/interviewRounds/StepDescreption.tsx Vedi File

@@ -50,9 +50,9 @@ const StepsDescription: React.FC<Props> = (props) => {
</p>

{props.isRoundCompleted ?
<Link to="/interviewRounds" className={styles.button}>
<div className={styles.button}>
<IonButton shape="round" expand='block' disabled={true}>Completed</IonButton>
</Link>
</div>
:
<Link to={props.link} className={styles.button}>
<IonButton shape="round" expand='block'>{props.buttonText}</IonButton>


+ 1
- 3
src/pages/preliminaryRoundResults/PreliminaryRoundResults.tsx Vedi File

@@ -2,15 +2,13 @@ import styles from "./PreliminaryRoundResults.module.scss"

import { IonButton, IonContent, IonIcon, IonPage } from "@ionic/react";
import StepHeader from "../../components/stepsHeader/StepHeader";

import goodJobIcon from "../../assets/icons/good_job.svg";

import { closeCircle, checkmarkCircle } from "ionicons/icons";
import { Link } from "react-router-dom";
import Quiz_Details from '../../mockData/QuizDetails';


const PreliminaryRoundResults: React.FC = () => {

return (
<IonPage>
<StepHeader stepNumber={2} roundName="Preliminary Round" />


+ 10
- 6
src/pages/quiz/Options.module.scss Vedi File

@@ -30,21 +30,25 @@

// styles for multiselect checkbox
.checkBoxHolder {
border: 0.2rem solid #707070;
border: 0.2rem solid lighten($color: #707070, $amount: 20);
border-radius: 2.5rem;
width: 2rem;
height: 2rem;
margin-left: 2rem;
margin-left: 1.5rem;

.checkBox {
--background-checked: var(--primary-button-color);
--checkmark-color: var(--primary-button-color);
--border-width: 0;
margin: 0;
margin-top: 0.26rem;
margin-left: 0.27rem;
width: 1.2rem;
height: 1.2rem;
margin-top: 0.3rem;
margin-left: 0.3rem;
width: 1rem;
height: 1rem;
}

&.activeCheck {
border: 0.2rem solid var(--primary-button-color);
}
}



+ 11
- 6
src/pages/quiz/Options.tsx Vedi File

@@ -2,15 +2,15 @@ import { IonButton, IonCheckbox, IonItem, IonLabel, IonList, IonRadio, IonRadioG
import { useEffect, useRef, useState } from 'react';
import { Link } from 'react-router-dom';
import styles from './Options.module.scss';
import { OptionType } from '../../models/QuizDetails'

interface OwnProps {
options: string[] | undefined;
type: string;
type: OptionType;
answer: string[];
lastQuestion: boolean;
questionNumber: number;
updateQuestionNumber: () => void;

}

const Options: React.FC<OwnProps> = (props) => {
@@ -58,11 +58,12 @@ const Options: React.FC<OwnProps> = (props) => {
setTextInput(inputRef.current?.value!)
}

if (props.lastQuestion) {
const setAnswer = () => {
localStorage.setItem("answer", answers.toString());
}



const options = props.options!.map((option, key) => {
return (
<IonItem lines='none' key={key} className={(option === selected) ? styles.highlighted : ""}>
@@ -75,8 +76,12 @@ const Options: React.FC<OwnProps> = (props) => {
const MultiSelectOptions = props.options!.map((option, key) => {
return (
<IonItem lines='none' key={key} className={(selectedOptions.includes(option)) ? styles.highlighted : ""}>
<div className={styles.checkBoxHolder}>
<IonCheckbox slot="start" mode='ios' className={styles.checkBox} onIonChange={e => selectChecked(option)} />
<div className={(selectedOptions.includes(option)) ? (styles.activeCheck + " " + styles.checkBoxHolder) : styles.checkBoxHolder}>
<IonCheckbox
slot="start"
mode='ios'
className={styles.checkBox}
onIonChange={e => selectChecked(option)} />
</div>
<IonLabel className={styles.multiSelectLabel}>{option}</IonLabel>
</IonItem>
@@ -118,7 +123,7 @@ const Options: React.FC<OwnProps> = (props) => {
}

{props.lastQuestion &&
< Link to="/preliminaryRoundResults" className={styles.button + " " + ((selected || selectedOptions.length > 0 || textInput) ? styles.active : "")}>
< Link to="/preliminaryRoundResults" onClick={setAnswer} className={styles.button + " " + ((selected || selectedOptions.length > 0 || textInput) ? styles.active : "")}>
<IonButton shape="round" expand='block'>Next Step</IonButton>
</Link>
}


+ 7
- 7
src/pages/quiz/Quiz.tsx Vedi File

@@ -1,6 +1,6 @@
import styles from './Quiz.module.scss';

import { IonButton, IonIcon } from '@ionic/react';
import { IonIcon } from '@ionic/react';
import Options from './Options';
import { closeOutline } from 'ionicons/icons'
import { Link } from 'react-router-dom';
@@ -11,7 +11,7 @@ import QUIZ_DETAILS from '../../mockData/QuizDetails';
const Quiz: React.FC = () => {

const [questionNumber, setQuestionNumber] = useState<number>(1);
const timeLimit = QUIZ_DETAILS[questionNumber - 1].timeLimit;
const currentQuestion = QUIZ_DETAILS[questionNumber - 1];

const updateQuestionNumber = () => {
if (QUIZ_DETAILS.length > questionNumber) {
@@ -30,9 +30,9 @@ const Quiz: React.FC = () => {
</header>

<Question
question={QUIZ_DETAILS[questionNumber - 1].question}
question={currentQuestion.question}
questionNumber={questionNumber}
timeLimit={timeLimit}
timeLimit={currentQuestion.timeLimit}
updateQuestionNumber={updateQuestionNumber} />

</div>
@@ -40,10 +40,10 @@ const Quiz: React.FC = () => {
<div className={styles.quizOptions}>
<div className={styles.options}>
<Options
options={QUIZ_DETAILS[questionNumber - 1].options}
options={currentQuestion.options}
updateQuestionNumber={updateQuestionNumber}
type={QUIZ_DETAILS[questionNumber - 1].type}
answer={QUIZ_DETAILS[questionNumber - 1].answer}
type={currentQuestion.type}
answer={currentQuestion.answer}
lastQuestion={QUIZ_DETAILS.length === questionNumber}
questionNumber={questionNumber} />
</div>


+ 17
- 9
src/pages/technicalInterview/TechnicalInterview.tsx Vedi File

@@ -5,27 +5,34 @@ import StepHeader from "../../components/stepsHeader/StepHeader";
import techinicalInterview from "../../assets/icons/Technical_Interview.svg";
import linkIcon from "../../assets/icons/link.svg";
import { Link } from "react-router-dom";
import { useState } from "react";
import { useEffect, useState } from "react";
import TimeSlot from "../../components/timeSlot/TimeSlot";
import { useCountdown } from "../../components/CountDownTimer/useCountdown";
import CountdownTimer from "../../components/CountDownTimer/CountdownTimer";
import { format } from "date-fns";

const TechnicalInterview: React.FC = () => {

const [isDateSet, setDate] = useState<boolean>(false);
const [isTimeSlot, setTimeSlot] = useState<boolean>(false);
const [isDateSet, setIsDate] = useState<boolean>(false);
const [isTimeSlot, setIsTimeSlot] = useState<boolean>(false);
const [date, setDate] = useState<Date>(new Date());

const [days, hours, minutes, seconds] = useCountdown(new Date('may 7, 2022 07:00:00'));
const [days, hours, minutes, seconds] = useCountdown(date);

const getDate = () => {
setTimeSlot(false);
setDate(true);
setIsTimeSlot(false);
setIsDate(true);
}

const HideTimeSlot = () => {
setTimeSlot(false);
setIsTimeSlot(false);
}

const getTimeSlot = (date: any, time: string) => {
setDate(new Date(`${format(date, "LLL")} ${format(date, "d")} ${format(date, "y")} ${time.substring(0, 8)}`));
}


return (
<IonPage>
<StepHeader stepNumber={3} roundName="Technical Interview" />
@@ -60,7 +67,7 @@ const TechnicalInterview: React.FC = () => {
</div>
{
!isDateSet ?
<div className={styles.techinicalInterviewBtn} onClick={() => setTimeSlot(true)}>
<div className={styles.techinicalInterviewBtn} onClick={() => setIsTimeSlot(true)}>
<IonButton shape="round" expand='block'>Find a slot</IonButton>
</div>
:
@@ -79,7 +86,8 @@ const TechnicalInterview: React.FC = () => {
<TimeSlot
month="April-May"
getDate={getDate}
HideTimeSlot={HideTimeSlot} />
HideTimeSlot={HideTimeSlot}
getTimeSlot={getTimeSlot} />
}

</IonContent>


Caricamento…
Annulla
Salva