8 коммитов

36 измененных файлов: 678 добавлений и 375 удалений
  1. +67
    -68
      src/App.tsx
  2. +18
    -0
      src/components/CountDownTimer/CountdownTimer.module.scss
  3. +32
    -0
      src/components/CountDownTimer/CountdownTimer.tsx
  4. +27
    -0
      src/components/CountDownTimer/useCountdown.tsx
  5. +56
    -0
      src/components/Toast/Toast.module.scss
  6. +48
    -0
      src/components/Toast/Toast.tsx
  7. +14
    -1
      src/components/formInput/Input.tsx
  8. +13
    -29
      src/components/timeSlot/TimeSlot.tsx
  9. +50
    -0
      src/mockData/QuizDetails.ts
  10. +86
    -0
      src/mockData/StepDetails.ts
  11. +7
    -0
      src/mockData/TimeSlotDetails.ts
  12. +7
    -0
      src/models/QuizDetails.ts
  13. +9
    -0
      src/models/StepDetails.ts
  14. +0
    -59
      src/pages/Quiz/Quiz.tsx
  15. +1
    -1
      src/pages/assignment/Assignment.module.scss
  16. +4
    -2
      src/pages/assignment/AssignmentDetails.module.scss
  17. +2
    -3
      src/pages/assignment/SubmitAssignment.module.scss
  18. +30
    -9
      src/pages/assignment/SubmitAssignment.tsx
  19. +0
    -0
      src/pages/finalInterview/FInalInterview.module.scss
  20. +10
    -30
      src/pages/finalInterview/FinalInterview.tsx
  21. +0
    -0
      src/pages/finalInterview/FinalInterviewResult.module.scss
  22. +0
    -0
      src/pages/finalInterview/FinalInterviewResult.tsx
  23. +5
    -85
      src/pages/interviewRounds/InterviewRounds.tsx
  24. +11
    -8
      src/pages/interviewRounds/StepDescreption.module.scss
  25. +16
    -5
      src/pages/interviewRounds/StepDescreption.tsx
  26. +7
    -0
      src/pages/interviewRounds/Steps.module.scss
  27. +9
    -4
      src/pages/interviewRounds/Steps.tsx
  28. +2
    -2
      src/pages/preliminaryRound/PreliminaryRound.tsx
  29. +16
    -0
      src/pages/quiz/Options.module.scss
  30. +11
    -6
      src/pages/quiz/Options.tsx
  31. +0
    -0
      src/pages/quiz/Question.module.scss
  32. +23
    -18
      src/pages/quiz/Question.tsx
  33. +4
    -0
      src/pages/quiz/Quiz.module.scss
  34. +56
    -0
      src/pages/quiz/Quiz.tsx
  35. +16
    -16
      src/pages/technicalInterview/TechnicalInterview.module.scss
  36. +21
    -29
      src/pages/technicalInterview/TechnicalInterview.tsx

+ 67
- 68
src/App.tsx Просмотреть файл

@@ -1,5 +1,5 @@
import { Redirect, Route } from 'react-router-dom';
import { IonApp, IonRouterOutlet, setupIonicReact } from '@ionic/react';
import { Redirect, Route, Switch } from 'react-router-dom';
import { IonApp, IonItem, IonRouterOutlet, setupIonicReact } from '@ionic/react';
import { IonReactRouter } from '@ionic/react-router';

/* Core CSS required for Ionic components to work properly */
@@ -22,7 +22,7 @@ import './App.scss';
import InterviewRounds from './pages/interviewRounds/InterviewRounds';
import SkillInformationStep from './pages/skillInformationStep/SkillInformationStep';
import PreliminaryRound from './pages/preliminaryRound/PreliminaryRound';
import Quiz from './pages/Quiz/Quiz';
import Quiz from './pages/quiz/Quiz';
import PreliminaryRoundResults from './pages/preliminaryRoundResults/PreliminaryRoundResults';
import TechnicalInterview from './pages/technicalInterview/TechnicalInterview';
import Assignment from './pages/assignment/Assignment';
@@ -30,8 +30,8 @@ import AssignmentDetails from './pages/assignment/AssignmentDetails';
import SubmitAssignment from './pages/assignment/SubmitAssignment';
import ReviewAssignment from './pages/assignment/ReviewAssignment';
import AssignmentCompleted from './pages/assignment/AssignmentCompleted';
import FinalInterview from './pages/FinalInterview/FinalInterview';
import FinalInterviewResult from './pages/FinalInterview/FinalInterviewResult';
import FinalInterview from './pages/finalInterview/FinalInterview';
import FinalInterviewResult from './pages/finalInterview/FinalInterviewResult';
import ClosingDocs from './pages/closingDocs/ClosingDocs';
import VerifiedDocs from './pages/closingDocs/VerifiedDocs';
import JoiningLetter from './pages/joiningLetter/JoiningLetter';
@@ -40,75 +40,74 @@ import SignaturePhoto from './pages/joiningLetter/SignaturePhoto';
import TechinicalInterviewResults from './pages/technicalInterview/TechinicalInterviewResults';



setupIonicReact();

const App: React.FC = () => (
<IonApp>
<IonReactRouter>
<IonRouterOutlet>
<Route exact path="/interviewRounds">
<InterviewRounds />
</Route>
<Route exact path="/skillInformationStep">
<SkillInformationStep />
</Route>
<Route exact path="/quiz">
<Quiz />
</Route>
<Route exact path="/preliminaryRound">
<PreliminaryRound />
</Route>
<Route exact path="/preliminaryRoundResults">
<PreliminaryRoundResults />
</Route>
<Route exact path="/technicalInterview">
<TechnicalInterview />
</Route>
<Route exact path="/technicalInterview/techinicalInterviewResults">
<TechinicalInterviewResults />
</Route>
<Route exact path="/assignment">
<Assignment />
</Route>
<Route exact path="/assignmentDetails">
<AssignmentDetails />
</Route>
<Route exact path="/SubmitAssignment">
<SubmitAssignment />
</Route>
<Route exact path="/ReviewAssignment">
<ReviewAssignment />
</Route>
<Route exact path="/assignmentCompleted">
<AssignmentCompleted />
</Route>
<Route exact path="/finalInterview">
<FinalInterview />
</Route>
<Route exact path="/finalInterview/results">
<FinalInterviewResult />
</Route>
<Route exact path="/closingDocs">
<ClosingDocs />
</Route>
<Route exact path="/verifiedDocs">
<VerifiedDocs />
</Route>
<Route exact path="/joiningLetter">
<JoiningLetter />
</Route>
<Route exact path="/joiningLetter/signaturePhoto">
<SignaturePhoto />
</Route>
<Route exact path="/celebration">
<Celebration />
</Route>
<Route exact path="/">
<Redirect to="/interviewRounds" />
</Route>
<Switch>
<Route exact path="/interviewRounds">
<InterviewRounds />
</Route>
<Route exact path="/skillInformationStep">
<SkillInformationStep />
</Route>
<Route exact path="/quiz">
<Quiz />
</Route>
<Route exact path="/preliminaryRound">
<PreliminaryRound />
</Route>
<Route exact path="/preliminaryRoundResults">
<PreliminaryRoundResults />
</Route>
<Route exact path="/technicalInterview">
<TechnicalInterview />
</Route>
<Route exact path="/technicalInterview/techinicalInterviewResults">
<TechinicalInterviewResults />
</Route>
<Route exact path="/assignment">
<Assignment />
</Route>
<Route exact path="/assignmentDetails">
<AssignmentDetails />
</Route>
<Route exact path="/SubmitAssignment">
<SubmitAssignment />
</Route>
<Route exact path="/ReviewAssignment">
<ReviewAssignment />
</Route>
<Route exact path="/assignmentCompleted">
<AssignmentCompleted />
</Route>
<Route exact path="/finalInterview">
<FinalInterview />
</Route>
<Route exact path="/finalInterview/results">
<FinalInterviewResult />
</Route>
<Route exact path="/closingDocs">
<ClosingDocs />
</Route>
<Route exact path="/verifiedDocs">
<VerifiedDocs />
</Route>
<Route exact path="/joiningLetter">
<JoiningLetter />
</Route>
<Route exact path="/joiningLetter/signaturePhoto">
<SignaturePhoto />
</Route>
<Route exact path="/celebration">
<Celebration />
</Route>
<Route exact path="/">
<Redirect to="/interviewRounds" />
</Route>
</Switch>
</IonRouterOutlet>
</IonReactRouter>
</IonApp>


+ 18
- 0
src/components/CountDownTimer/CountdownTimer.module.scss Просмотреть файл

@@ -0,0 +1,18 @@
.CountdownTimerHolder {
.time {
font-size: 3.6rem;
font-weight: 600;
color: #363636;
letter-spacing: 0.036rem;
}
.days {
font-size: 1.3rem;
color: #9F9F9F;
display: flex;
justify-content: space-between;
align-items: center;
// width: 95%;
margin: 0 auto;
text-align: center;
}
}

+ 32
- 0
src/components/CountDownTimer/CountdownTimer.tsx Просмотреть файл

@@ -0,0 +1,32 @@
import styles from "./CountdownTimer.module.scss";

interface OwnProp {
days: number;
hours: number;
minutes: number;
seconds: number;
}

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

return (
<div className={styles.CountdownTimerHolder}>
<h4 className={styles.time}>
{
`${props.days < 10 ? "0" : ""}${props.days} :
${props.hours < 10 ? "0" : ""}${props.hours} :
${props.minutes < 10 ? "0" : ""}${props.minutes} :
${props.seconds < 10 ? "0" : ""}${props.seconds}`
}
</h4>
<div className={styles.days}>
<div>Days</div>
<div>Hrs</div>
<div>Mins</div>
<div>Secs</div>
</div>
</div>
);
}

export default CountdownTimer;

+ 27
- 0
src/components/CountDownTimer/useCountdown.tsx Просмотреть файл

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

const useCountdown = (targetDate: Date) => {

const countDownDate = new Date(targetDate).getTime();

const [countDown, setCountDown] = useState(
countDownDate - new Date().getTime()
);

useEffect(() => {
const interval = setInterval(() => {
setCountDown(countDownDate - new Date().getTime());
}, 1000);

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

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

export { useCountdown };

+ 56
- 0
src/components/Toast/Toast.module.scss Просмотреть файл

@@ -0,0 +1,56 @@
.toastContent {
width: 90%;
position: fixed;
bottom:5%;
left: 5%;
z-index: 10;

.toastHolder {
display: flex;
align-items: center;
justify-content: space-between;
border: 0.1rem solid transparent;
border-radius: 2.5rem;
background-color: white;
min-height: 4rem;
.messageHolder {
display: flex;
align-items: center;
margin-left: 1.5rem;

.text {
margin-left: 1rem;
font-size: 1.4rem;
}
}

.closeIcon {
color: #ec0b6d;
min-width: 20px;
height: 20px;
margin-right: 10px;
}

.checkIcon {
width: 20px;
height: 20px;
color: #00ae8d;
}
.errorIcon {
min-width: 20px;
height: 20px;
color: #ea7a7a;
}
}

.error {
box-shadow: 0 0 15px #ea7a7a;
}

.success {
box-shadow: 0 0 15px #00ae8d;
}

}

+ 48
- 0
src/components/Toast/Toast.tsx Просмотреть файл

@@ -0,0 +1,48 @@
import { IonIcon, IonItem } from "@ionic/react";
import styles from "./Toast.module.scss";
import { checkmarkCircle, closeCircle, alertCircle } from 'ionicons/icons';
import { useEffect, useState } from "react";


interface OwnProps {
message: string;
messageType: string;
showToast: boolean;
}

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

const [showToast, setShowToast] = useState(props.showToast);
console.log("show props", props.showToast);

useEffect(() => {
setShowToast(props.showToast);
}, [props.showToast]);

// const [showToast, setShowToast] = useState(props.showToast);
console.log(showToast)

const closeToast = () => {
setShowToast(false);
}

setTimeout(() => {
closeToast();
}, 3000);



return (
<div className={styles.toastContent}>
{showToast && < div className={styles.toastHolder + " " + styles.error} >
<div className={styles.messageHolder}>
<IonIcon className={styles.errorIcon} icon={alertCircle} />
<div className={styles.text}>invalid Input</div>
</div>
<IonIcon className={styles.closeIcon} icon={closeCircle} />
</div>}
</div >
);
}

export default Toast;

+ 14
- 1
src/components/formInput/Input.tsx Просмотреть файл

@@ -1,14 +1,26 @@
import styles from './Input.module.scss';
import { IonIcon, IonInput, IonItem, IonLabel } from '@ionic/react';
import { useEffect, useState } from 'react';

interface Props {
placeholder?: string;
type?: "text" | "email" | "password" | "number";
icon?: string;
text?: string;
isInputSet?: (isSet: boolean) => void;
}

const Input: React.FC<Props> = (props) => {
const [inputText, setInputText] = useState<string | number | undefined>(undefined);

useEffect(() => {
if (inputText) {
props.isInputSet!(true);
} else {
props.isInputSet!(false);
}
}, [inputText])

return (
<div className={styles.inputContainer}>
<div className={styles.inputHolderContainer}>
@@ -21,7 +33,8 @@ const Input: React.FC<Props> = (props) => {
<IonLabel>{props.text}</IonLabel>
}
<IonInput type={props.type ? props.type : "text"}
placeholder={props.placeholder ? props.placeholder : ""}></IonInput>
placeholder={props.placeholder ? props.placeholder : ""}
onIonChange={e => setInputText(e.detail.value!)}></IonInput>
</IonItem>

</div>


+ 13
- 29
src/components/timeSlot/TimeSlot.tsx Просмотреть файл

@@ -1,39 +1,22 @@
import { IonButton, IonContent, IonIcon, IonPage } from "@ionic/react";
import styles from "./TimeSlot.module.scss";
import { chevronBack, key } from 'ionicons/icons'
import { Link } from "react-router-dom";
import { chevronBack } from 'ionicons/icons'
import { useState } from "react";
import { addDays } from "date-fns";


interface dates {
date: string;
day: string;
}

import { format } from "date-fns";
import { Dates, Time_Slots } from "../../mockData/TimeSlotDetails";

interface OwnProps {
month: string;
dates: dates[];
timeSlots: string[];
getDate: (date: string) => void;
getDate: () => void;
HideTimeSlot: () => void;
}

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

const [highlightedDate, setHighlightedDate] = useState<dates>();
const [highlightedDate, setHighlightedDate] = useState<Date>();
const [highlightedTime, setHighlightedTime] = useState<string>("");

const daysMap = new Map([[0, "Sun"], [1, "Mon"], [2, "Tue"], [3, "Wed"], [4, "Thu"], [5, "Fri"], [6, "Sat"]]);

const dates = props.dates.map((date, key) => {
const currentDate = new Date();
let day = addDays(currentDate, key + 1)
// if (daysMap.get(day) === "Thu") { // sat
// day = addDays(currentDate, key + 3).getDay();
// } else if (daysMap.get(day) === "Fri") {
// day = addDays(currentDate, key + 3).getDay();
// }
const dates = Dates.map((date, key) => {
return (
<div
className={styles.date + " " + (date === highlightedDate ? styles.active : "")}
@@ -41,17 +24,18 @@ const TimeSlot: React.FC<OwnProps> = (props) => {
onClick={() => setHighlightedDate(date)}>

<div className={styles.day}>
{daysMap.get(day.getDay())}
{format(date, 'eee')}
</div>
<div>
{day.getDate()}
{format(date, 'e')}
</div>

</div>
);
});

const timeSlots = props.timeSlots.map((timeSlot, key) => {
const timeSlots = Time_Slots.map((timeSlot, key) => {

return (
<div
className={styles.time + " " + (timeSlot === highlightedTime ? styles.activeTime : "")}
@@ -65,7 +49,7 @@ const TimeSlot: React.FC<OwnProps> = (props) => {
return (
<IonPage>
<header className={styles.header}>
<IonIcon icon={chevronBack} />
<IonIcon icon={chevronBack} onClick={props.HideTimeSlot} />
<h4>Find a Slot</h4>
</header>

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

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


+ 50
- 0
src/mockData/QuizDetails.ts Просмотреть файл

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

const Quiz_Details: QuizDetails[] = [
{
question: "How would you correctly display, “Hello, how are you?”?",
options: [
"System.out.println('Hello, how are you?');",
"println('Hello, how are you?');",
"out.print(Hello, how are you?);",
"System.out.println(Hello, how are you?);"
],
answer: ["System.out.println('Hello, how are you?');"],
result: false,
timeLimit: 10
},
{
question: "How do you write 'Hello World' in an alert box?",
options: [
"msgBox('Hello World')",
"alertBox('Hello World');",
"msg('Hello World');",
"alert('Hello World');"
],
answer: ["alert('Hello World');"],
result: false,
timeLimit: 25
},
{
question: "is javascript",
options: [
"A",
"B",
"C",
"D"
],
answer: ["B", "C"],
result: false,
timeLimit: 35
},
{
question: "Is javascript single threaded or multi threaded? enter the answer in the below box ",
options: [],
answer: ["single threaded"],
result: false,
timeLimit: 40
}
];


export default Quiz_Details;

+ 86
- 0
src/mockData/StepDetails.ts Просмотреть файл

@@ -0,0 +1,86 @@
import skillInfo from '../assets/icons/skill_Information.svg';
import preliminaryRound from '../assets/icons/Preliminary_Round.svg';
import technicalInterview from '../assets/icons/Technical_Interview.svg';
import assignment from '../assets/icons/Assignment.svg';
import finalInterview from '../assets/icons/Final_Interview.svg';
import closingDocs from '../assets/icons/Closing_Docs.svg';
import joiningLetter from '../assets/icons/Joining_Letter.svg';
import Celebrations from '../assets/icons/Celebrations.svg';
import { StepDetail } from "../models/StepDetails";

const Step_Details: StepDetail[] = [
{
stepNumber: 1,
stepName: "Skill Information",
descriptionImage: skillInfo,
buttonText: "Let's start now",
isUnlocked: true,
link: "/skillInformationStep",
isRoundCompleted: true
},
{
stepNumber: 2,
stepName: "Preliminary Round",
descriptionImage: preliminaryRound,
buttonText: "Let's do this",
isUnlocked: true,
link: "/preliminaryRound",
isRoundCompleted: true
},
{
stepNumber: 3,
stepName: "Technical Interview",
descriptionImage: technicalInterview,
buttonText: "Schedule meeting",
isUnlocked: true,
link: "/technicalInterview",
isRoundCompleted: false
},
{
stepNumber: 4,
stepName: "Assignment",
descriptionImage: assignment,
buttonText: "Show details",
isUnlocked: false,
link: "/assignment",
isRoundCompleted: false
},
{
stepNumber: 5,
stepName: "Final Interview",
descriptionImage: finalInterview,
buttonText: "Schedule meeting",
isUnlocked: false,
link: "/finalInterview",
isRoundCompleted: false
},
{
stepNumber: 6,
stepName: "Closing Docs",
descriptionImage: closingDocs,
buttonText: "Upload docs",
isUnlocked: false,
link: "/closingDocs",
isRoundCompleted: false
},
{
stepNumber: 7,
stepName: "Joining Letter",
descriptionImage: joiningLetter,
buttonText: "Show details",
isUnlocked: false,
link: "/joiningLetter",
isRoundCompleted: false
},
{
stepNumber: 8,
stepName: "Celebrations",
descriptionImage: Celebrations,
buttonText: "Join Workex",
isUnlocked: false,
link: "/celebration",
isRoundCompleted: false
},
];

export default Step_Details;

+ 7
- 0
src/mockData/TimeSlotDetails.ts Просмотреть файл

@@ -0,0 +1,7 @@
import { addBusinessDays } from "date-fns";

const currentDate = new Date();

export const Dates = [addBusinessDays(currentDate, 1), addBusinessDays(currentDate, 2), addBusinessDays(currentDate, 3), addBusinessDays(currentDate, 4)];

export const Time_Slots = ["11:00 AM - 1:00 pm", "1:00 PM - 3:00 pm", "3:00 PM - 5:00 pm"];

+ 7
- 0
src/models/QuizDetails.ts Просмотреть файл

@@ -0,0 +1,7 @@
export interface QuizDetails {
question: string;
options?: string[];
answer: string[];
result: boolean;
timeLimit: number;
}

+ 9
- 0
src/models/StepDetails.ts Просмотреть файл

@@ -0,0 +1,9 @@
export interface StepDetail {
stepNumber: number;
stepName: string;
descriptionImage: string;
buttonText: string;
isUnlocked: boolean;
link: string;
isRoundCompleted: boolean;
}

+ 0
- 59
src/pages/Quiz/Quiz.tsx Просмотреть файл

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

import { IonButton, IonIcon } from '@ionic/react';
import Options from './Options';
import { closeOutline } from 'ionicons/icons'
import { Link } from 'react-router-dom';
import { useState } from 'react';
import Question from './Question';


const options: string[] = [
"System.out.println(“Hello, how are you?”);",
"println('Hello, how are you?');",
"out.print(Hello, how are you?);",
"System.out.println(Hello, how are you?);"
];

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

const [selected, setSelected] = useState<boolean>(false);

const isSelected = (option: string) => {

if (option !== "null") {
setSelected(true);
}
}

return (
<div className={styles.quizContainer}>
<div className={styles.upfold}>
<header className={styles.header}>
<h4 className={styles.heading}>Quiz</h4>
<Link to="/interviewRounds" >
<IonIcon icon={closeOutline} />
</Link>
</header>

<Question question='How would you correctly display, “Hello, how are you?”?'
questionNumber={1}
timeLimit={1} />

</div>

<div className={styles.quizOptions}>
<div className={styles.options}>
<Options options={options} isSelected={isSelected} />
</div>

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

</div>
);
}

export default Quiz;

+ 1
- 1
src/pages/assignment/Assignment.module.scss Просмотреть файл

@@ -1,7 +1,7 @@
.assignment {

.description {
height: 75vh;
height: 74vh;

.icon {
margin-top: 4rem;


+ 4
- 2
src/pages/assignment/AssignmentDetails.module.scss Просмотреть файл

@@ -1,3 +1,5 @@
$matt-black: #151515;

.assignmentDetails {

.assignmentTask {
@@ -29,7 +31,7 @@
display: flex;
flex-direction: column;
justify-content: space-around;
background-color: #151515;
background-color: $matt-black;
background-image: url("../../assets/icons/desktop-particles-2.svg");
background-repeat: no-repeat;
background-position: 25% 30%;
@@ -43,7 +45,7 @@
right: 0;
left: 0;
bottom: 0;
background-color: #151515;
background-color: $matt-black;
height: 30vh;
transform: skewY(5deg);
z-index: -1;


+ 2
- 3
src/pages/assignment/SubmitAssignment.module.scss Просмотреть файл

@@ -2,7 +2,7 @@
.description {
height: 50vh;
.icon {
margin-top: 4rem;
padding-top: 4rem;
display: flex;
justify-content: center;
ion-icon {
@@ -32,16 +32,15 @@
}
}
.inputHolder {
// margin-top: 5rem;
width: 95%;
margin: 0 auto;
height: 25vh;
}
.submitAssigment {
text-decoration: none;
ion-button {
width: 90%;
margin: 0 auto;
margin-top: 12rem;
--background: var(--primary-button-color);
}
}

+ 30
- 9
src/pages/assignment/SubmitAssignment.tsx Просмотреть файл

@@ -1,15 +1,32 @@
import styles from "./SubmitAssignment.module.scss";
import { IonButton, IonContent, IonIcon, IonPage } from "@ionic/react"
import { IonButton, IonContent, IonIcon, IonPage, useIonToast } from "@ionic/react"
import assignmentImage from "../../assets/icons/Assignment.svg";
import StepHeader from "../../components/stepsHeader/StepHeader";
import Input from "../../components/formInput/Input";
import linkIcon from "../../assets/icons/link.svg";
import time from "../../assets/icons/time.svg";
import { linkOutline } from 'ionicons/icons'
import { linkOutline } from 'ionicons/icons';
import { Link } from "react-router-dom";
import { useState } from "react";

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

const [isInput, setIsInput] = useState(false);
const [present, dismiss] = useIonToast();

const isInputSet = (isSet: boolean) => {
setIsInput(isSet);
}


const showToast = () => {
if (!isInput) {
present({
buttons: [{ text: 'close', handler: () => dismiss() }],
message: 'insert project link to submit',
duration: 2000
})
}
}

return (
<IonPage>
<StepHeader roundName="Assignment" stepNumber={4} />
@@ -19,7 +36,6 @@ const SubmitAssignment: React.FC = () => {
<div className={styles.description}>
<div className={styles.icon}>
<IonIcon src={assignmentImage} />

</div>

<div className={styles.stepDescription}>
@@ -31,12 +47,17 @@ const SubmitAssignment: React.FC = () => {
</div>

<div className={styles.inputHolder}>
<Input placeholder="Insert the project Link" icon={linkOutline} />
<Input
placeholder="Insert the project Link"
icon={linkOutline}
isInputSet={isInputSet} />
</div>
<Link to="/ReviewAssignment"
className={styles.submitAssigment}>
<Link to={isInput ? "/ReviewAssignment" : "/SubmitAssignment"}
className={styles.submitAssigment}
onClick={showToast}>
<IonButton shape="round" expand='block'>Submit</IonButton>
</Link>

</IonContent>
</IonPage>
);


src/pages/FinalInterview/FInalInterview.module.scss → src/pages/finalInterview/FInalInterview.module.scss Просмотреть файл


src/pages/FinalInterview/FinalInterview.tsx → src/pages/finalInterview/FinalInterview.tsx Просмотреть файл

@@ -7,44 +7,25 @@ import locationIcon from "../../assets/icons/location.svg";
import { Link } from "react-router-dom";
import { useState } from "react";
import TimeSlot from "../../components/timeSlot/TimeSlot";

interface dates {
date: string;
day: string;
}
import { useCountdown } from "../../components/CountDownTimer/useCountdown";
import { addDays } from "date-fns";

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

const [isDateSet, setDate] = useState<boolean>(false);
const [isTimeSlot, setTimeSlot] = useState<boolean>(false);

const timeSlots = ["11:00 AM - 1:00 pm", "1:00 PM - 3:00 pm", "3:00 PM - 5:00 pm"];

const dates: dates[] = [
{
date: "27",
day: "Tue"
},
{
date: "29",
day: "Sat"
},
{
date: "01",
day: "Mon"
},
{
date: "03",
day: "Wed"
},
];
const [days, hours, minutes, seconds] = useCountdown(addDays(new Date(), 3));

const getDate = (date: string) => {
console.log(date);
const getDate = () => {
setTimeSlot(false);
setDate(true);
}

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

return (
<IonPage>
<StepHeader roundName="Final Interview" stepNumber={5} />
@@ -99,9 +80,8 @@ const FinalInterview: React.FC = () => {
isTimeSlot &&
<TimeSlot
month="April-May"
dates={dates}
timeSlots={timeSlots}
getDate={getDate} />
getDate={getDate}
HideTimeSlot={HideTimeSlot} />
}

</IonContent>

src/pages/FinalInterview/FinalInterviewResult.module.scss → src/pages/finalInterview/FinalInterviewResult.module.scss Просмотреть файл


src/pages/FinalInterview/FinalInterviewResult.tsx → src/pages/finalInterview/FinalInterviewResult.tsx Просмотреть файл


+ 5
- 85
src/pages/interviewRounds/InterviewRounds.tsx Просмотреть файл

@@ -4,92 +4,11 @@ import { useState } from 'react';
import Header from "./Header";
import { IonContent, IonPage } from '@ionic/react';
import Steps from './Steps';
import skillInfo from '../../assets/icons/skill_Information.svg';
import preliminaryRound from '../../assets/icons/Preliminary_Round.svg';
import technicalInterview from '../../assets/icons/Technical_Interview.svg';
import assignment from '../../assets/icons/Assignment.svg';
import finalInterview from '../../assets/icons/Final_Interview.svg';
import closingDocs from '../../assets/icons/Closing_Docs.svg';
import joiningLetter from '../../assets/icons/Joining_Letter.svg';
import Celebrations from '../../assets/icons/Celebrations.svg';

interface stepDetail {
stepNumber: number;
stepName: string;
descriptionImage: string;
buttonText: string;
isUnlocked: boolean;
link: string;
}
import Step_Details from "../../mockData/StepDetails";

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

let steps: stepDetail[] = [
{
stepNumber: 1,
stepName: "Skill Information",
descriptionImage: skillInfo,
buttonText: "Let's start now",
isUnlocked: true,
link: "/skillInformationStep"
},
{
stepNumber: 2,
stepName: "Preliminary Round",
descriptionImage: preliminaryRound,
buttonText: "Let's do this",
isUnlocked: false,
link: "/preliminaryRound"
},
{
stepNumber: 3,
stepName: "Technical Interview",
descriptionImage: technicalInterview,
buttonText: "Schedule meeting",
isUnlocked: false,
link: "/technicalInterview"
},
{
stepNumber: 4,
stepName: "Assignment",
descriptionImage: assignment,
buttonText: "Show details",
isUnlocked: false,
link: "/assignment"
},
{
stepNumber: 5,
stepName: "Final Interview",
descriptionImage: finalInterview,
buttonText: "Schedule meeting",
isUnlocked: false,
link: "/finalInterview"
},
{
stepNumber: 6,
stepName: "Closing Docs",
descriptionImage: closingDocs,
buttonText: "Upload docs",
isUnlocked: false,
link: "/closingDocs"
},
{
stepNumber: 7,
stepName: "Joining Letter",
descriptionImage: joiningLetter,
buttonText: "Show details",
isUnlocked: false,
link: "/joiningLetter"
},
{
stepNumber: 8,
stepName: "Celebrations",
descriptionImage: Celebrations,
buttonText: "Join Workex",
isUnlocked: false,
link: "/celebration"
},
];
const InterviewRounds: React.FC = () => {

const [stepNo, setStep] = useState(1);

@@ -97,7 +16,7 @@ const InterviewRounds: React.FC = () => {
setStep(stepNumbera);
}

const stepsList = steps.map((step, key) => {
const stepsList = Step_Details.map((step, key) => {
return (
<Steps
key={key}
@@ -107,8 +26,9 @@ const InterviewRounds: React.FC = () => {
descriptionImage={step.descriptionImage}
buttonText={step.buttonText}
setDescription={setDescription}
showDescription={(stepNo === step.stepNumber) ? true : false}
showDescription={(stepNo === step.stepNumber && step.isUnlocked === true) ? true : false}
link={step.link}
isRoundCompleted={step.isRoundCompleted}
/>
);
});


+ 11
- 8
src/pages/interviewRounds/StepDescreption.module.scss Просмотреть файл

@@ -17,6 +17,17 @@
animation-iteration-count: 1;
animation-fill-mode: forwards;

ion-icon {
color: var(--primary-button-color);
width: 1.5rem;
height: 1.5rem;
}

.checkIcon {
width: 2rem;
height: 2rem;
}

.stepName {
display: flex;
justify-content: center;
@@ -72,14 +83,6 @@
}
}

ion-icon {
color: var(--primary-button-color);
width: 1.5rem;
height: 1.5rem;

}



@keyframes fadeInAnimation {
0% {


+ 16
- 5
src/pages/interviewRounds/StepDescreption.tsx Просмотреть файл

@@ -1,7 +1,7 @@
import styles from './StepDescreption.module.scss';

import { IonButton, IonIcon } from '@ionic/react';
import { lockOpen, lockClosed } from 'ionicons/icons';
import { lockOpen, lockClosed, checkmarkCircle } from 'ionicons/icons';
import { useEffect, useRef } from 'react';
import { Link } from 'react-router-dom';

@@ -12,6 +12,7 @@ interface Props {
buttonText: string;
descriptionImage: string;
link: string;
isRoundCompleted: boolean;
}

const StepsDescription: React.FC<Props> = (props) => {
@@ -29,7 +30,11 @@ const StepsDescription: React.FC<Props> = (props) => {
<div className={styles.stepDescription} ref={itemRef}>
<div className={styles.header}>

{props.isUnlocked ? <IonIcon icon={lockOpen} /> : <IonIcon icon={lockClosed} color="dark" />}
{
props.isRoundCompleted ?
<IonIcon icon={checkmarkCircle} className={styles.checkIcon} />
:
<IonIcon icon={lockOpen} />}

<div className={styles.stepName}>
<div className={styles.step}>step {props.stepNumber}</div>
@@ -44,9 +49,15 @@ const StepsDescription: React.FC<Props> = (props) => {
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
</p>

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

</div>
);


+ 7
- 0
src/pages/interviewRounds/Steps.module.scss Просмотреть файл

@@ -19,6 +19,12 @@ ion-item {
width: 1.5rem;
height: 1.5rem;
}

.checkIcon {
width: 1.8rem;
height: 1.8rem;
color: var(--primary-button-color);
}
.stepName {
display: flex;
@@ -32,6 +38,7 @@ ion-item {
font-size: 1.4rem;
font-weight: 600;
}
.heading {
margin: 0;
color: #363636;


+ 9
- 4
src/pages/interviewRounds/Steps.tsx Просмотреть файл

@@ -1,9 +1,9 @@
import styles from './Steps.module.scss';
import { lockOpen, lockClosed } from 'ionicons/icons';
import { lockOpen, lockClosed, checkmarkCircle } from 'ionicons/icons';
import { IonIcon, IonItem } from '@ionic/react';
import StepDescription from './StepDescreption';

interface Props {
interface OwnProps {
stepNumber: number;
roundName: string;
isUnlocked: boolean;
@@ -11,11 +11,12 @@ interface Props {
buttonText: string;
descriptionImage: string;
link: string;
isRoundCompleted: boolean;
setDescription: (stepNumber: number) => void;
// rename to select step
}

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

return (
<IonItem lines='none' onClick={() => props.setDescription(props.stepNumber)}>
@@ -27,9 +28,13 @@ const Steps: React.FC<Props> = (props) => {
buttonText={props.buttonText}
descriptionImage={props.descriptionImage}
link={props.link}
isRoundCompleted={props.isRoundCompleted}
/> :
<div className={styles.stepHolder}>
<IonIcon icon={props.isUnlocked ? lockOpen : lockClosed} color={props.isUnlocked ? '' : "dark"} ></IonIcon>
{/* <IonIcon icon={props.isUnlocked ? lockOpen : lockClosed} color={props.isUnlocked ? '' : "dark"} ></IonIcon> */}
{props.isUnlocked && !props.isRoundCompleted && <IonIcon icon={lockOpen}></IonIcon>}
{!props.isUnlocked && <IonIcon icon={lockClosed} color='dark'></IonIcon>}
{props.isRoundCompleted && <IonIcon icon={checkmarkCircle} className={styles.checkIcon}></IonIcon>}

<div className={styles.stepName}>
<div className={styles.step}>step {props.stepNumber}</div>


+ 2
- 2
src/pages/preliminaryRound/PreliminaryRound.tsx Просмотреть файл

@@ -39,7 +39,7 @@ const PreliminaryRound: React.FC = () => {
</div>
</div>

<Link to="./quiz">
<Link to="/quiz">
<IonButton shape="round" expand='block'>Start quiz</IonButton>
</Link>

@@ -47,7 +47,7 @@ const PreliminaryRound: React.FC = () => {
</div>
</IonContent>
</IonPage>
)
);
}

export default PreliminaryRound;

src/pages/Quiz/Options.module.scss → src/pages/quiz/Options.module.scss Просмотреть файл

@@ -36,5 +36,21 @@
}
}

.button {
text-decoration: none;
width: 100%;
margin-top: 4rem;
ion-button {
--background: #DDDDDD;
width: 90%;
margin: 0 auto;
}
}

.active {
ion-button {
--background: var(--primary-button-color);
}
}

}

src/pages/Quiz/Options.tsx → src/pages/quiz/Options.tsx Просмотреть файл

@@ -1,19 +1,19 @@
import { IonItem, IonLabel, IonList, IonRadio, IonRadioGroup } from '@ionic/react';
import { IonButton, IonItem, IonLabel, IonList, IonRadio, IonRadioGroup } from '@ionic/react';
import { useState } from 'react';
import styles from './Options.module.scss';

interface OwnProps {
options: string[];
isSelected: (option: string) => void;
options: string[] | undefined;
updateQuestionNumber: () => void;
}

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

const [selected, setSelected] = useState<string>("null");
const [selected, setSelected] = useState<string | undefined>(undefined);

if (selected !== "null") props.isSelected(selected);
// console.log(selected);

const options = props.options.map((option, key) => {
const options = props.options!.map((option, key) => {
return (
<IonItem lines='none' key={key} className={(option === selected) ? styles.highlighted : ""}>
<IonLabel>{option}</IonLabel>
@@ -29,6 +29,11 @@ const Options: React.FC<OwnProps> = (props) => {
{options}
</IonRadioGroup>
</IonList>

<div className={styles.button + " " + (selected ? styles.active : "")}
onClick={() => props.updateQuestionNumber()}>
<IonButton shape="round" expand='block'>Next</IonButton>
</div>
</div>
);
}

src/pages/Quiz/Question.module.scss → src/pages/quiz/Question.module.scss Просмотреть файл


src/pages/Quiz/Question.tsx → src/pages/quiz/Question.tsx Просмотреть файл

@@ -1,43 +1,43 @@
import { useEffect, useState } from "react";
import styles from "./Question.module.scss";
import { CountdownCircleTimer } from 'react-countdown-circle-timer';
import { secondsToMinutes } from "date-fns";

interface OwnProp {
questionNumber: number;
question: string;
timeLimit: number;
updateQuestionNumber: () => void;
}


let timeout: NodeJS.Timeout;

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

const COUNTDOWN_AMOUNT_TOTAL = props.timeLimit * 60;

const [seconds, setSeconds] = useState<number>(COUNTDOWN_AMOUNT_TOTAL);

const [seconds, setSeconds] = useState<number>(props.timeLimit);
const displaySeconds = seconds % 60;
const displayMinutes = Math.floor(seconds / 60);

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

if (seconds > 0) {
timeout = setTimeout(() => {
setSeconds((state) => state - 1);
}, 1000);
} else {
clearTimeout(timeout);
}

return () => clearTimeout(timeout);;
}, [seconds]);

const renderTime = () => {
return (
<div className={styles.time}>
{`${displayMinutes < 10 ? "0" : ""}${displayMinutes}:${displaySeconds < 10 ? "0" : ""}${displaySeconds}`}
{
`${secondsToMinutes(seconds).toString().padStart(2, '0')}:
${displaySeconds.toString().padStart(2, '0')}`
}
</div>
);
}
@@ -56,9 +56,14 @@ const Question: React.FC<OwnProp> = (props) => {

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

{renderTime}

src/pages/Quiz/Quiz.module.scss → src/pages/quiz/Quiz.module.scss Просмотреть файл

@@ -72,6 +72,10 @@
}
}

// ion-activated {
// --background: var(--primary-button-color);
// }

.active {
ion-button {
--background: var(--primary-button-color);

+ 56
- 0
src/pages/quiz/Quiz.tsx Просмотреть файл

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

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 Question from './Question';
import Quiz_Details from '../../mockData/QuizDetails';

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

const [questionNumber, setQuestionNumber] = useState<number>(1);

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

return (
<div className={styles.quizContainer}>
<div className={styles.upfold}>
<header className={styles.header}>
<h4 className={styles.heading}>Quiz</h4>
<Link to="/interviewRounds" >
<IonIcon icon={closeOutline} />
</Link>
</header>

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

</div>

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

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

</div>

</div>
);
}

export default Quiz;

+ 16
- 16
src/pages/technicalInterview/TechnicalInterview.module.scss Просмотреть файл

@@ -46,22 +46,22 @@
letter-spacing: 0.024rem;
}
.timeLeft {
.time {
font-size: 3.6rem;
font-weight: 600;
color: #363636;
letter-spacing: 0.036rem;
}
.days {
font-size: 1.3rem;
color: #9F9F9F;
display: flex;
justify-content: space-between;
align-items: center;
width: 95%;
margin: 0 auto;
text-align: center;
}
// .time {
// font-size: 3.6rem;
// font-weight: 600;
// color: #363636;
// letter-spacing: 0.036rem;
// }
// .days {
// font-size: 1.3rem;
// color: #9F9F9F;
// display: flex;
// justify-content: space-between;
// align-items: center;
// width: 95%;
// margin: 0 auto;
// text-align: center;
// }
}
.icon {
width: 6rem;


+ 21
- 29
src/pages/technicalInterview/TechnicalInterview.tsx Просмотреть файл

@@ -5,8 +5,11 @@ 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 { addDays, min } from "date-fns";
import CountdownTimer from "../../components/CountDownTimer/CountdownTimer";

interface dates {
date: string;
@@ -18,33 +21,18 @@ const TechnicalInterview: React.FC = () => {
const [isDateSet, setDate] = useState<boolean>(false);
const [isTimeSlot, setTimeSlot] = useState<boolean>(false);

const timeSlots = ["11:00 AM - 1:00 pm", "1:00 PM - 3:00 pm", "3:00 PM - 5:00 pm"];

const dates: dates[] = [
{
date: "27",
day: "Tue"
},
{
date: "29",
day: "Sat"
},
{
date: "01",
day: "Mon"
},
{
date: "03",
day: "Wed"
},
];
const [days, hours, minutes, seconds] = useCountdown(addDays(new Date(), 3));

const getDate = (date: string) => {
console.log(date);
const getDate = () => {
setTimeSlot(false);
setDate(true);
}

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

return (
<IonPage>
<StepHeader stepNumber={3} roundName="Technical Interview" />
@@ -64,13 +52,18 @@ const TechnicalInterview: 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}>
{/* <h4 className={styles.time}>{`${days} : ${hours} : ${minutes} : ${seconds}`}</h4> */}
<CountdownTimer
days={days}
hours={hours}
minutes={minutes}
seconds={seconds} />
{/* <div className={styles.days}>
<div>Days</div>
<div>Hrs</div>
<div>Mins</div>
<div>Secs</div>
</div>
</div> */}
</div>
<h4>Join us on Google Meet</h4>
<div className={styles.icon}>
@@ -98,10 +91,9 @@ const TechnicalInterview: React.FC = () => {
{
isTimeSlot &&
<TimeSlot
month="April -May"
dates={dates}
timeSlots={timeSlots}
getDate={getDate} />
month="April-May"
getDate={getDate}
HideTimeSlot={HideTimeSlot} />
}

</IonContent>


Загрузка…
Отмена
Сохранить