5 Revīzijas

12 mainītis faili ar 268 papildinājumiem un 75 dzēšanām
Dalītais skats
  1. +15
    -0
      package-lock.json
  2. +1
    -0
      package.json
  3. +33
    -7
      src/mockData/QuizDetails.ts
  4. +1
    -0
      src/models/QuizDetails.ts
  5. +1
    -1
      src/pages/interviewRounds/StepDescreption.tsx
  6. +5
    -3
      src/pages/preliminaryRoundResults/PreliminaryRoundResults.tsx
  7. +64
    -1
      src/pages/quiz/Options.module.scss
  8. +97
    -11
      src/pages/quiz/Options.tsx
  9. +4
    -0
      src/pages/quiz/Question.module.scss
  10. +32
    -38
      src/pages/quiz/Question.tsx
  11. +14
    -13
      src/pages/quiz/Quiz.tsx
  12. +1
    -1
      src/pages/technicalInterview/TechnicalInterview.tsx

+ 15
- 0
package-lock.json Parādīt failu

@@ -29,6 +29,7 @@
"node": "^17.7.2",
"node-sass": "^7.0.1",
"react": "^17.0.1",
"react-circular-progressbar": "^2.0.4",
"react-countdown-circle-timer": "^3.0.9",
"react-dom": "^17.0.1",
"react-router": "^5.2.0",
@@ -13121,6 +13122,14 @@
"node": ">=14"
}
},
"node_modules/react-circular-progressbar": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/react-circular-progressbar/-/react-circular-progressbar-2.0.4.tgz",
"integrity": "sha512-OfX0ThSxRYEVGaQSt0DlXfyl5w4DbXHsXetyeivmoQrh9xA9bzVPHNf8aAhOIiwiaxX2WYWpLDB3gcpsDJ9oww==",
"peerDependencies": {
"react": "^0.14.0 || ^15.0.0 || ^16.0.0 || ^17.0.0"
}
},
"node_modules/react-countdown-circle-timer": {
"version": "3.0.9",
"resolved": "https://registry.npmjs.org/react-countdown-circle-timer/-/react-countdown-circle-timer-3.0.9.tgz",
@@ -26126,6 +26135,12 @@
"whatwg-fetch": "^3.6.2"
}
},
"react-circular-progressbar": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/react-circular-progressbar/-/react-circular-progressbar-2.0.4.tgz",
"integrity": "sha512-OfX0ThSxRYEVGaQSt0DlXfyl5w4DbXHsXetyeivmoQrh9xA9bzVPHNf8aAhOIiwiaxX2WYWpLDB3gcpsDJ9oww==",
"requires": {}
},
"react-countdown-circle-timer": {
"version": "3.0.9",
"resolved": "https://registry.npmjs.org/react-countdown-circle-timer/-/react-countdown-circle-timer-3.0.9.tgz",


+ 1
- 0
package.json Parādīt failu

@@ -24,6 +24,7 @@
"node": "^17.7.2",
"node-sass": "^7.0.1",
"react": "^17.0.1",
"react-circular-progressbar": "^2.0.4",
"react-countdown-circle-timer": "^3.0.9",
"react-dom": "^17.0.1",
"react-router": "^5.2.0",


+ 33
- 7
src/mockData/QuizDetails.ts Parādīt failu

@@ -1,6 +1,6 @@
import { QuizDetails } from "../models/QuizDetails";

const Quiz_Details: QuizDetails[] = [
const QUIZ_DETAILS: QuizDetails[] = [
{
question: "How would you correctly display, “Hello, how are you?”?",
options: [
@@ -11,7 +11,8 @@ const Quiz_Details: QuizDetails[] = [
],
answer: ["System.out.println('Hello, how are you?');"],
result: false,
timeLimit: 10
timeLimit: 5,
type: "singleSelect"
},
{
question: "How do you write 'Hello World' in an alert box?",
@@ -23,7 +24,9 @@ const Quiz_Details: QuizDetails[] = [
],
answer: ["alert('Hello World');"],
result: false,
timeLimit: 25
timeLimit: 10,
type: "singleSelect"

},
{
question: "is javascript",
@@ -35,16 +38,39 @@ const Quiz_Details: QuizDetails[] = [
],
answer: ["B", "C"],
result: false,
timeLimit: 35
timeLimit: 15,
type: "multiSelect"
},
{
question: "Is javascript single threaded or multi threaded? enter the answer in the below box ",
options: [],
answer: ["single threaded"],
result: false,
timeLimit: 40
}
timeLimit: 40,
type: "textInput"
},
{
question: "is javascript",
options: [
"A",
"B",
"C",
"D"
],
answer: ["B", "C"],
result: false,
timeLimit: 35,
type: "multiSelect"
},
];

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

export default Quiz_Details;
export default QUIZ_DETAILS;

+ 1
- 0
src/models/QuizDetails.ts Parādīt failu

@@ -4,4 +4,5 @@ export interface QuizDetails {
answer: string[];
result: boolean;
timeLimit: number;
type: string;
}

+ 1
- 1
src/pages/interviewRounds/StepDescreption.tsx Parādīt failu

@@ -51,7 +51,7 @@ const StepsDescription: React.FC<Props> = (props) => {

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


+ 5
- 3
src/pages/preliminaryRoundResults/PreliminaryRoundResults.tsx Parādīt failu

@@ -7,6 +7,8 @@ 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 (
@@ -18,7 +20,7 @@ const PreliminaryRoundResults: React.FC = () => {
<IonIcon src={goodJobIcon} />
<div className={styles.score}>
<h5>You have scored</h5>
<h5 className={styles.result}>85%</h5>
<h5 className={styles.result}>{(parseInt(localStorage.getItem("answer")!) / Quiz_Details.length) * 100}%</h5>
</div>
<p className={styles.description}>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt.
@@ -29,11 +31,11 @@ const PreliminaryRoundResults: React.FC = () => {
<div className={styles.resultsHolder}>
<div className={styles.correct}>
<IonIcon icon={checkmarkCircle} />
<div>17 Questions</div>
<div>{localStorage.getItem("answer")} Questions</div>
</div>
<div className={styles.wrong}>
<IonIcon icon={closeCircle} />
<div>3 Questions</div>
<div>{Quiz_Details.length - parseInt(localStorage.getItem("answer")!)} Questions</div>
</div>
</div>
<div className={styles.buttonHolder}>


+ 64
- 1
src/pages/quiz/Options.module.scss Parādīt failu

@@ -1,12 +1,75 @@
.optionHolder {
ion-list {
ion-radio-group {

ion-item {
width: 99%;
margin: 0 auto;
--background: white;
border: 1px solid #DBDBDB;
border-radius: 25px;

ion-label {
--color: #626262;
font-size: 1.2rem !important;
font-weight: 200;
}
ion-radio {
--color-checked: var(--primary-button-color);
margin-left: 1.5rem;
}
}

.highlighted {
box-shadow: 0px 0px 10px #00000029;

ion-radio {
--color: var(--primary-button-color);
}
}

// styles for multiselect checkbox
.checkBoxHolder {
border: 0.2rem solid #707070;
border-radius: 2.5rem;
width: 2rem;
height: 2rem;
margin-left: 2rem;

.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;
}
}

.multiSelectLabel {
margin-left: 2rem;
}

.options {
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-around;
height: 40vh;


.textInput {
width: 95%;
margin: 0 auto;
width: 30rem;
height: 4rem;
font-size: 1.4rem;
border-radius: 2.5rem;
padding-left: 2rem;
}

ion-item {
width: 99%;
margin: 0 auto;


+ 97
- 11
src/pages/quiz/Options.tsx Parādīt failu

@@ -1,17 +1,67 @@
import { IonButton, IonItem, IonLabel, IonList, IonRadio, IonRadioGroup } from '@ionic/react';
import { useState } from 'react';
import { IonButton, IonCheckbox, IonItem, IonLabel, IonList, IonRadio, IonRadioGroup } from '@ionic/react';
import { useEffect, useRef, useState } from 'react';
import { Link } from 'react-router-dom';
import styles from './Options.module.scss';

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

}

const Options: React.FC<OwnProps> = (props) => {

const [selected, setSelected] = useState<string | undefined>(undefined);
const [selectedOptions, setSelectedOptions] = useState<string[]>([]);
const [textInput, setTextInput] = useState<string>("");
const [answers, setAnswers] = useState<number>(0);
const inputRef = useRef<HTMLInputElement>(null);

useEffect(() => {
setSelected(undefined);
setSelectedOptions([]);
setTextInput("");
}, [props.options]);

const selectChecked = (option: string) => {
let newOption: string[] = [];
if (selectedOptions.includes(option)) {
newOption = selectedOptions.filter(oldOption => oldOption !== option);
} else {
newOption = selectedOptions.concat([option]);
}
setSelectedOptions(newOption);
}

const validateAnswer = () => {
if (props.type === "singleSelect") {
if (props.answer.includes(selected!)) {
setAnswers(answers + 1);
}
} else if (props.type === "multiSelect") {
if (props.answer.length === selectedOptions.length && props.answer.sort().join(',') === selectedOptions.sort().join(',')) {

setAnswers(answers + 1);
}
} else if (props.type === "textInput") {
if (props.answer.includes(textInput)) {
setAnswers(answers + 1);
}
}
}

const handleInput = () => {
setTextInput(inputRef.current?.value!)
}

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

// console.log(selected);

const options = props.options!.map((option, key) => {
return (
@@ -22,19 +72,55 @@ 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>
<IonLabel className={styles.multiSelectLabel}>{option}</IonLabel>
</IonItem>
);
});

return (
<div className={styles.optionHolder}>
<IonList>
<IonRadioGroup onIonChange={e => setSelected(e.detail.value)}>
{options}
</IonRadioGroup>
{props.type === "singleSelect" &&
<IonRadioGroup onIonChange={e => setSelected(e.detail.value)} allowEmptySelection={true} className={styles.options}>
{options}
</IonRadioGroup>
}
{props.type === "multiSelect" &&
<div className={styles.options}>
{MultiSelectOptions}
</div>
}
{props.type === "textInput" &&
<div className={styles.options}>
<input
type="text"
className={styles.textInput}
placeholder="enter your answer"
ref={inputRef}
onChange={handleInput} />
</div>
}
</IonList>

<div className={styles.button + " " + (selected ? styles.active : "")}
onClick={() => props.updateQuestionNumber()}>
<IonButton shape="round" expand='block'>Next</IonButton>
</div>
</div>
{!props.lastQuestion &&
<div className={styles.button + " " + ((selected || selectedOptions.length > 0 || textInput) ? styles.active : "")}
onClick={(selected || selectedOptions.length > 0 || textInput) ? () => { props.updateQuestionNumber(); validateAnswer(); } : undefined}>
<IonButton shape="round" expand='block'>Next</IonButton>
</div>
}

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


+ 4
- 0
src/pages/quiz/Question.module.scss Parādīt failu

@@ -28,6 +28,10 @@ section {
.time {
font-size: 1.4rem;
}
.progressBar{
width: 5.5rem;
height: 5.5rem;
}
}
}
}

+ 32
- 38
src/pages/quiz/Question.tsx Parādīt failu

@@ -1,7 +1,8 @@
import { useEffect, useState } from "react";
import styles from "./Question.module.scss";
import { CountdownCircleTimer } from 'react-countdown-circle-timer';
import { secondsToMinutes } from "date-fns";
import { CircularProgressbar, buildStyles } from 'react-circular-progressbar';
import 'react-circular-progressbar/dist/styles.css';

interface OwnProp {
questionNumber: number;
@@ -10,37 +11,34 @@ interface OwnProp {
updateQuestionNumber: () => void;
}


let timeout: NodeJS.Timeout;

const Question: React.FC<OwnProp> = (props) => {

const [seconds, setSeconds] = useState<number>(props.timeLimit);
const [duration, setDuration] = useState<number>(props.timeLimit);
const displaySeconds = seconds % 60;
const percentage = Math.round(seconds / props.timeLimit * 100);
const time = `${secondsToMinutes(seconds).toString().padStart(2, '0')}:${displaySeconds.toString().padStart(2, '0')}`


useEffect(() => {
setTimeout(() => {
if (seconds <= 0) {
props.updateQuestionNumber();
console.log(props.timeLimit);
setSeconds(5)
} else {
setSeconds(props.timeLimit);
setDuration(props.timeLimit);
}, [props.questionNumber]);

useEffect(() => {

const timeOut = setTimeout(() => {
if (seconds > 0) {
setSeconds(seconds - 1);
} else {
props.updateQuestionNumber();
}
}, 500);
}, [seconds]);
}, 1000);

return () => clearInterval(timeOut);

}, [seconds]);

const renderTime = () => {
return (
<div className={styles.time}>
{
`${secondsToMinutes(seconds).toString().padStart(2, '0')}:
${displaySeconds.toString().padStart(2, '0')}`
}
</div>
);
}

return (
<section>
@@ -53,22 +51,18 @@ const Question: React.FC<OwnProp> = (props) => {
</div>

<div className={styles.quizTimer}>

<CountdownCircleTimer
isPlaying
duration={props.timeLimit}
colors={'#6BD534'}
size={60}
onComplete={() => {
// setSeconds(COUNTDOWN_AMOUNT_TOTAL);
// props.updateQuestionNumber();
return { shouldRepeat: true }
}}
strokeWidth={5} >

{renderTime}

</CountdownCircleTimer>
<div className={styles.progressBar}>
<CircularProgressbar
value={percentage}
text={`${time}`}
counterClockwise={true}
styles={buildStyles({
trailColor: '#ffff',
pathColor: '#6BD534',
textColor: "#ffff",
textSize: "2.4rem"
})} />;
</div>
</div>
</div>
</section>


+ 14
- 13
src/pages/quiz/Quiz.tsx Parādīt failu

@@ -4,22 +4,20 @@ import { IonButton, IonIcon } from '@ionic/react';
import Options from './Options';
import { closeOutline } from 'ionicons/icons'
import { Link } from 'react-router-dom';
import { useEffect, useState } from 'react';
import { useState } from 'react';
import Question from './Question';
import Quiz_Details from '../../mockData/QuizDetails';
import QUIZ_DETAILS from '../../mockData/QuizDetails';

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

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

const updateQuestionNumber = () => {
console.log("update")
if (Quiz_Details.length > questionNumber) {
if (QUIZ_DETAILS.length > questionNumber) {
setQuestionNumber((questionNumber) => questionNumber + 1);
}
}
console.log("no", questionNumber);
console.log(Quiz_Details[questionNumber - 1]);

return (
<div className={styles.quizContainer}>
@@ -31,22 +29,25 @@ const Quiz: React.FC = () => {
</Link>
</header>

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

</div>

<div className={styles.quizOptions}>
<div className={styles.options}>
<Options options={Quiz_Details[questionNumber - 1].options} updateQuestionNumber={updateQuestionNumber} />
<Options
options={QUIZ_DETAILS[questionNumber - 1].options}
updateQuestionNumber={updateQuestionNumber}
type={QUIZ_DETAILS[questionNumber - 1].type}
answer={QUIZ_DETAILS[questionNumber - 1].answer}
lastQuestion={QUIZ_DETAILS.length === questionNumber}
questionNumber={questionNumber} />
</div>

{/* <Link to="/" className={styles.button + " " + (selected ? styles.active : "")}>
<IonButton shape="round" expand='block'>Next</IonButton>
</Link> */}

</div>

</div>


+ 1
- 1
src/pages/technicalInterview/TechnicalInterview.tsx Parādīt failu

@@ -15,7 +15,7 @@ const TechnicalInterview: React.FC = () => {
const [isDateSet, setDate] = useState<boolean>(false);
const [isTimeSlot, setTimeSlot] = useState<boolean>(false);

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

const getDate = () => {
setTimeSlot(false);


Notiek ielāde…
Atcelt
Saglabāt