| Autor | SHA1 | Nachricht | Datum |
|---|---|---|---|
|
|
8f58e134b5 | updated mock data variable name | vor 3 Jahren |
|
|
3a2d11b798 | created models folder and moved interfaces to models | vor 3 Jahren |
|
|
c61bb49f58 | added hide timeslot to hide timeslot when backchevron is clicked | vor 3 Jahren |
|
|
897d31a77f | fixed timeslot dates and created mock data for timeslot | vor 3 Jahren |
|
|
6df5a6df83 | created assignment form validation toast | vor 3 Jahren |
|
|
78c2466f66 | created a Countdown time component | vor 3 Jahren |
|
|
22450e8d60 | created mock quiz data and logic changes to quiz component | vor 3 Jahren |
|
|
86daddec15 | created mock data for interview rounds add checkicon for completed rounds and hidden round discreption for locked rounds | vor 3 Jahren |
| @@ -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'; | import { IonReactRouter } from '@ionic/react-router'; | ||||
| /* Core CSS required for Ionic components to work properly */ | /* Core CSS required for Ionic components to work properly */ | ||||
| @@ -22,7 +22,7 @@ import './App.scss'; | |||||
| import InterviewRounds from './pages/interviewRounds/InterviewRounds'; | import InterviewRounds from './pages/interviewRounds/InterviewRounds'; | ||||
| import SkillInformationStep from './pages/skillInformationStep/SkillInformationStep'; | import SkillInformationStep from './pages/skillInformationStep/SkillInformationStep'; | ||||
| import PreliminaryRound from './pages/preliminaryRound/PreliminaryRound'; | 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 PreliminaryRoundResults from './pages/preliminaryRoundResults/PreliminaryRoundResults'; | ||||
| import TechnicalInterview from './pages/technicalInterview/TechnicalInterview'; | import TechnicalInterview from './pages/technicalInterview/TechnicalInterview'; | ||||
| import Assignment from './pages/assignment/Assignment'; | import Assignment from './pages/assignment/Assignment'; | ||||
| @@ -30,8 +30,8 @@ import AssignmentDetails from './pages/assignment/AssignmentDetails'; | |||||
| import SubmitAssignment from './pages/assignment/SubmitAssignment'; | import SubmitAssignment from './pages/assignment/SubmitAssignment'; | ||||
| import ReviewAssignment from './pages/assignment/ReviewAssignment'; | import ReviewAssignment from './pages/assignment/ReviewAssignment'; | ||||
| import AssignmentCompleted from './pages/assignment/AssignmentCompleted'; | 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 ClosingDocs from './pages/closingDocs/ClosingDocs'; | ||||
| import VerifiedDocs from './pages/closingDocs/VerifiedDocs'; | import VerifiedDocs from './pages/closingDocs/VerifiedDocs'; | ||||
| import JoiningLetter from './pages/joiningLetter/JoiningLetter'; | import JoiningLetter from './pages/joiningLetter/JoiningLetter'; | ||||
| @@ -40,75 +40,74 @@ import SignaturePhoto from './pages/joiningLetter/SignaturePhoto'; | |||||
| import TechinicalInterviewResults from './pages/technicalInterview/TechinicalInterviewResults'; | import TechinicalInterviewResults from './pages/technicalInterview/TechinicalInterviewResults'; | ||||
| setupIonicReact(); | setupIonicReact(); | ||||
| const App: React.FC = () => ( | const App: React.FC = () => ( | ||||
| <IonApp> | <IonApp> | ||||
| <IonReactRouter> | <IonReactRouter> | ||||
| <IonRouterOutlet> | <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> | </IonRouterOutlet> | ||||
| </IonReactRouter> | </IonReactRouter> | ||||
| </IonApp> | </IonApp> | ||||
| @@ -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; | |||||
| } | |||||
| } | |||||
| @@ -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; | |||||
| @@ -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 }; | |||||
| @@ -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; | |||||
| } | |||||
| } | |||||
| @@ -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; | |||||
| @@ -1,14 +1,26 @@ | |||||
| import styles from './Input.module.scss'; | import styles from './Input.module.scss'; | ||||
| import { IonIcon, IonInput, IonItem, IonLabel } from '@ionic/react'; | import { IonIcon, IonInput, IonItem, IonLabel } from '@ionic/react'; | ||||
| import { useEffect, useState } from 'react'; | |||||
| interface Props { | interface Props { | ||||
| placeholder?: string; | placeholder?: string; | ||||
| type?: "text" | "email" | "password" | "number"; | type?: "text" | "email" | "password" | "number"; | ||||
| icon?: string; | icon?: string; | ||||
| text?: string; | text?: string; | ||||
| isInputSet?: (isSet: boolean) => void; | |||||
| } | } | ||||
| const Input: React.FC<Props> = (props) => { | 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 ( | return ( | ||||
| <div className={styles.inputContainer}> | <div className={styles.inputContainer}> | ||||
| <div className={styles.inputHolderContainer}> | <div className={styles.inputHolderContainer}> | ||||
| @@ -21,7 +33,8 @@ const Input: React.FC<Props> = (props) => { | |||||
| <IonLabel>{props.text}</IonLabel> | <IonLabel>{props.text}</IonLabel> | ||||
| } | } | ||||
| <IonInput type={props.type ? props.type : "text"} | <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> | </IonItem> | ||||
| </div> | </div> | ||||
| @@ -1,39 +1,22 @@ | |||||
| import { IonButton, IonContent, IonIcon, IonPage } from "@ionic/react"; | import { IonButton, IonContent, IonIcon, IonPage } from "@ionic/react"; | ||||
| import styles from "./TimeSlot.module.scss"; | 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 { 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 { | interface OwnProps { | ||||
| month: string; | month: string; | ||||
| dates: dates[]; | |||||
| timeSlots: string[]; | |||||
| getDate: (date: string) => void; | |||||
| getDate: () => void; | |||||
| HideTimeSlot: () => void; | |||||
| } | } | ||||
| const TimeSlot: React.FC<OwnProps> = (props) => { | const TimeSlot: React.FC<OwnProps> = (props) => { | ||||
| const [highlightedDate, setHighlightedDate] = useState<dates>(); | |||||
| const [highlightedDate, setHighlightedDate] = useState<Date>(); | |||||
| const [highlightedTime, setHighlightedTime] = useState<string>(""); | 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 ( | return ( | ||||
| <div | <div | ||||
| className={styles.date + " " + (date === highlightedDate ? styles.active : "")} | className={styles.date + " " + (date === highlightedDate ? styles.active : "")} | ||||
| @@ -41,17 +24,18 @@ const TimeSlot: React.FC<OwnProps> = (props) => { | |||||
| onClick={() => setHighlightedDate(date)}> | onClick={() => setHighlightedDate(date)}> | ||||
| <div className={styles.day}> | <div className={styles.day}> | ||||
| {daysMap.get(day.getDay())} | |||||
| {format(date, 'eee')} | |||||
| </div> | </div> | ||||
| <div> | <div> | ||||
| {day.getDate()} | |||||
| {format(date, 'e')} | |||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| ); | ); | ||||
| }); | }); | ||||
| const timeSlots = props.timeSlots.map((timeSlot, key) => { | |||||
| const timeSlots = Time_Slots.map((timeSlot, key) => { | |||||
| return ( | return ( | ||||
| <div | <div | ||||
| className={styles.time + " " + (timeSlot === highlightedTime ? styles.activeTime : "")} | className={styles.time + " " + (timeSlot === highlightedTime ? styles.activeTime : "")} | ||||
| @@ -65,7 +49,7 @@ const TimeSlot: React.FC<OwnProps> = (props) => { | |||||
| return ( | return ( | ||||
| <IonPage> | <IonPage> | ||||
| <header className={styles.header}> | <header className={styles.header}> | ||||
| <IonIcon icon={chevronBack} /> | |||||
| <IonIcon icon={chevronBack} onClick={props.HideTimeSlot} /> | |||||
| <h4>Find a Slot</h4> | <h4>Find a Slot</h4> | ||||
| </header> | </header> | ||||
| @@ -84,7 +68,7 @@ const TimeSlot: React.FC<OwnProps> = (props) => { | |||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| <div onClick={(highlightedDate && highlightedTime !== "") ? () => props.getDate("test") : undefined} | |||||
| <div onClick={(highlightedDate && highlightedTime !== "") ? () => props.getDate() : undefined} | |||||
| className={styles.timeSlotButton + " " + (highlightedDate && highlightedTime !== "" ? styles.buttonActive : "")}> | className={styles.timeSlotButton + " " + (highlightedDate && highlightedTime !== "" ? styles.buttonActive : "")}> | ||||
| <IonButton shape="round" expand='block' >Confirm slot</IonButton> | <IonButton shape="round" expand='block' >Confirm slot</IonButton> | ||||
| </div> | </div> | ||||
| @@ -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; | |||||
| @@ -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; | |||||
| @@ -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"]; | |||||
| @@ -0,0 +1,7 @@ | |||||
| export interface QuizDetails { | |||||
| question: string; | |||||
| options?: string[]; | |||||
| answer: string[]; | |||||
| result: boolean; | |||||
| timeLimit: number; | |||||
| } | |||||
| @@ -0,0 +1,9 @@ | |||||
| export interface StepDetail { | |||||
| stepNumber: number; | |||||
| stepName: string; | |||||
| descriptionImage: string; | |||||
| buttonText: string; | |||||
| isUnlocked: boolean; | |||||
| link: string; | |||||
| isRoundCompleted: boolean; | |||||
| } | |||||
| @@ -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,7 +1,7 @@ | |||||
| .assignment { | .assignment { | ||||
| .description { | .description { | ||||
| height: 75vh; | |||||
| height: 74vh; | |||||
| .icon { | .icon { | ||||
| margin-top: 4rem; | margin-top: 4rem; | ||||
| @@ -1,3 +1,5 @@ | |||||
| $matt-black: #151515; | |||||
| .assignmentDetails { | .assignmentDetails { | ||||
| .assignmentTask { | .assignmentTask { | ||||
| @@ -29,7 +31,7 @@ | |||||
| display: flex; | display: flex; | ||||
| flex-direction: column; | flex-direction: column; | ||||
| justify-content: space-around; | justify-content: space-around; | ||||
| background-color: #151515; | |||||
| background-color: $matt-black; | |||||
| background-image: url("../../assets/icons/desktop-particles-2.svg"); | background-image: url("../../assets/icons/desktop-particles-2.svg"); | ||||
| background-repeat: no-repeat; | background-repeat: no-repeat; | ||||
| background-position: 25% 30%; | background-position: 25% 30%; | ||||
| @@ -43,7 +45,7 @@ | |||||
| right: 0; | right: 0; | ||||
| left: 0; | left: 0; | ||||
| bottom: 0; | bottom: 0; | ||||
| background-color: #151515; | |||||
| background-color: $matt-black; | |||||
| height: 30vh; | height: 30vh; | ||||
| transform: skewY(5deg); | transform: skewY(5deg); | ||||
| z-index: -1; | z-index: -1; | ||||
| @@ -2,7 +2,7 @@ | |||||
| .description { | .description { | ||||
| height: 50vh; | height: 50vh; | ||||
| .icon { | .icon { | ||||
| margin-top: 4rem; | |||||
| padding-top: 4rem; | |||||
| display: flex; | display: flex; | ||||
| justify-content: center; | justify-content: center; | ||||
| ion-icon { | ion-icon { | ||||
| @@ -32,16 +32,15 @@ | |||||
| } | } | ||||
| } | } | ||||
| .inputHolder { | .inputHolder { | ||||
| // margin-top: 5rem; | |||||
| width: 95%; | width: 95%; | ||||
| margin: 0 auto; | margin: 0 auto; | ||||
| height: 25vh; | |||||
| } | } | ||||
| .submitAssigment { | .submitAssigment { | ||||
| text-decoration: none; | text-decoration: none; | ||||
| ion-button { | ion-button { | ||||
| width: 90%; | width: 90%; | ||||
| margin: 0 auto; | margin: 0 auto; | ||||
| margin-top: 12rem; | |||||
| --background: var(--primary-button-color); | --background: var(--primary-button-color); | ||||
| } | } | ||||
| } | } | ||||
| @@ -1,15 +1,32 @@ | |||||
| import styles from "./SubmitAssignment.module.scss"; | 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 assignmentImage from "../../assets/icons/Assignment.svg"; | ||||
| import StepHeader from "../../components/stepsHeader/StepHeader"; | import StepHeader from "../../components/stepsHeader/StepHeader"; | ||||
| import Input from "../../components/formInput/Input"; | 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 { Link } from "react-router-dom"; | ||||
| import { useState } from "react"; | |||||
| const SubmitAssignment: React.FC = () => { | 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 ( | return ( | ||||
| <IonPage> | <IonPage> | ||||
| <StepHeader roundName="Assignment" stepNumber={4} /> | <StepHeader roundName="Assignment" stepNumber={4} /> | ||||
| @@ -19,7 +36,6 @@ const SubmitAssignment: React.FC = () => { | |||||
| <div className={styles.description}> | <div className={styles.description}> | ||||
| <div className={styles.icon}> | <div className={styles.icon}> | ||||
| <IonIcon src={assignmentImage} /> | <IonIcon src={assignmentImage} /> | ||||
| </div> | </div> | ||||
| <div className={styles.stepDescription}> | <div className={styles.stepDescription}> | ||||
| @@ -31,12 +47,17 @@ const SubmitAssignment: React.FC = () => { | |||||
| </div> | </div> | ||||
| <div className={styles.inputHolder}> | <div className={styles.inputHolder}> | ||||
| <Input placeholder="Insert the project Link" icon={linkOutline} /> | |||||
| <Input | |||||
| placeholder="Insert the project Link" | |||||
| icon={linkOutline} | |||||
| isInputSet={isInputSet} /> | |||||
| </div> | </div> | ||||
| <Link to="/ReviewAssignment" | |||||
| className={styles.submitAssigment}> | |||||
| <Link to={isInput ? "/ReviewAssignment" : "/SubmitAssignment"} | |||||
| className={styles.submitAssigment} | |||||
| onClick={showToast}> | |||||
| <IonButton shape="round" expand='block'>Submit</IonButton> | <IonButton shape="round" expand='block'>Submit</IonButton> | ||||
| </Link> | </Link> | ||||
| </IonContent> | </IonContent> | ||||
| </IonPage> | </IonPage> | ||||
| ); | ); | ||||
| @@ -7,44 +7,25 @@ import locationIcon from "../../assets/icons/location.svg"; | |||||
| import { Link } from "react-router-dom"; | import { Link } from "react-router-dom"; | ||||
| import { useState } from "react"; | import { useState } from "react"; | ||||
| import TimeSlot from "../../components/timeSlot/TimeSlot"; | 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 FinalInterview: React.FC = () => { | ||||
| const [isDateSet, setDate] = useState<boolean>(false); | const [isDateSet, setDate] = useState<boolean>(false); | ||||
| const [isTimeSlot, setTimeSlot] = 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); | setTimeSlot(false); | ||||
| setDate(true); | setDate(true); | ||||
| } | } | ||||
| const HideTimeSlot = () => { | |||||
| setTimeSlot(false); | |||||
| } | |||||
| return ( | return ( | ||||
| <IonPage> | <IonPage> | ||||
| <StepHeader roundName="Final Interview" stepNumber={5} /> | <StepHeader roundName="Final Interview" stepNumber={5} /> | ||||
| @@ -99,9 +80,8 @@ const FinalInterview: React.FC = () => { | |||||
| isTimeSlot && | isTimeSlot && | ||||
| <TimeSlot | <TimeSlot | ||||
| month="April-May" | month="April-May" | ||||
| dates={dates} | |||||
| timeSlots={timeSlots} | |||||
| getDate={getDate} /> | |||||
| getDate={getDate} | |||||
| HideTimeSlot={HideTimeSlot} /> | |||||
| } | } | ||||
| </IonContent> | </IonContent> | ||||
| @@ -4,92 +4,11 @@ import { useState } from 'react'; | |||||
| import Header from "./Header"; | import Header from "./Header"; | ||||
| import { IonContent, IonPage } from '@ionic/react'; | import { IonContent, IonPage } from '@ionic/react'; | ||||
| import Steps from './Steps'; | 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); | const [stepNo, setStep] = useState(1); | ||||
| @@ -97,7 +16,7 @@ const InterviewRounds: React.FC = () => { | |||||
| setStep(stepNumbera); | setStep(stepNumbera); | ||||
| } | } | ||||
| const stepsList = steps.map((step, key) => { | |||||
| const stepsList = Step_Details.map((step, key) => { | |||||
| return ( | return ( | ||||
| <Steps | <Steps | ||||
| key={key} | key={key} | ||||
| @@ -107,8 +26,9 @@ const InterviewRounds: React.FC = () => { | |||||
| descriptionImage={step.descriptionImage} | descriptionImage={step.descriptionImage} | ||||
| buttonText={step.buttonText} | buttonText={step.buttonText} | ||||
| setDescription={setDescription} | setDescription={setDescription} | ||||
| showDescription={(stepNo === step.stepNumber) ? true : false} | |||||
| showDescription={(stepNo === step.stepNumber && step.isUnlocked === true) ? true : false} | |||||
| link={step.link} | link={step.link} | ||||
| isRoundCompleted={step.isRoundCompleted} | |||||
| /> | /> | ||||
| ); | ); | ||||
| }); | }); | ||||
| @@ -17,6 +17,17 @@ | |||||
| animation-iteration-count: 1; | animation-iteration-count: 1; | ||||
| animation-fill-mode: forwards; | animation-fill-mode: forwards; | ||||
| ion-icon { | |||||
| color: var(--primary-button-color); | |||||
| width: 1.5rem; | |||||
| height: 1.5rem; | |||||
| } | |||||
| .checkIcon { | |||||
| width: 2rem; | |||||
| height: 2rem; | |||||
| } | |||||
| .stepName { | .stepName { | ||||
| display: flex; | display: flex; | ||||
| justify-content: center; | justify-content: center; | ||||
| @@ -72,14 +83,6 @@ | |||||
| } | } | ||||
| } | } | ||||
| ion-icon { | |||||
| color: var(--primary-button-color); | |||||
| width: 1.5rem; | |||||
| height: 1.5rem; | |||||
| } | |||||
| @keyframes fadeInAnimation { | @keyframes fadeInAnimation { | ||||
| 0% { | 0% { | ||||
| @@ -1,7 +1,7 @@ | |||||
| import styles from './StepDescreption.module.scss'; | import styles from './StepDescreption.module.scss'; | ||||
| import { IonButton, IonIcon } from '@ionic/react'; | 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 { useEffect, useRef } from 'react'; | ||||
| import { Link } from 'react-router-dom'; | import { Link } from 'react-router-dom'; | ||||
| @@ -12,6 +12,7 @@ interface Props { | |||||
| buttonText: string; | buttonText: string; | ||||
| descriptionImage: string; | descriptionImage: string; | ||||
| link: string; | link: string; | ||||
| isRoundCompleted: boolean; | |||||
| } | } | ||||
| const StepsDescription: React.FC<Props> = (props) => { | 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.stepDescription} ref={itemRef}> | ||||
| <div className={styles.header}> | <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.stepName}> | ||||
| <div className={styles.step}>step {props.stepNumber}</div> | <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. | Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. | ||||
| </p> | </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> | </div> | ||||
| ); | ); | ||||
| @@ -19,6 +19,12 @@ ion-item { | |||||
| width: 1.5rem; | width: 1.5rem; | ||||
| height: 1.5rem; | height: 1.5rem; | ||||
| } | } | ||||
| .checkIcon { | |||||
| width: 1.8rem; | |||||
| height: 1.8rem; | |||||
| color: var(--primary-button-color); | |||||
| } | |||||
| .stepName { | .stepName { | ||||
| display: flex; | display: flex; | ||||
| @@ -32,6 +38,7 @@ ion-item { | |||||
| font-size: 1.4rem; | font-size: 1.4rem; | ||||
| font-weight: 600; | font-weight: 600; | ||||
| } | } | ||||
| .heading { | .heading { | ||||
| margin: 0; | margin: 0; | ||||
| color: #363636; | color: #363636; | ||||
| @@ -1,9 +1,9 @@ | |||||
| import styles from './Steps.module.scss'; | 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 { IonIcon, IonItem } from '@ionic/react'; | ||||
| import StepDescription from './StepDescreption'; | import StepDescription from './StepDescreption'; | ||||
| interface Props { | |||||
| interface OwnProps { | |||||
| stepNumber: number; | stepNumber: number; | ||||
| roundName: string; | roundName: string; | ||||
| isUnlocked: boolean; | isUnlocked: boolean; | ||||
| @@ -11,11 +11,12 @@ interface Props { | |||||
| buttonText: string; | buttonText: string; | ||||
| descriptionImage: string; | descriptionImage: string; | ||||
| link: string; | link: string; | ||||
| isRoundCompleted: boolean; | |||||
| setDescription: (stepNumber: number) => void; | setDescription: (stepNumber: number) => void; | ||||
| // rename to select step | // rename to select step | ||||
| } | } | ||||
| const Steps: React.FC<Props> = (props) => { | |||||
| const Steps: React.FC<OwnProps> = (props) => { | |||||
| return ( | return ( | ||||
| <IonItem lines='none' onClick={() => props.setDescription(props.stepNumber)}> | <IonItem lines='none' onClick={() => props.setDescription(props.stepNumber)}> | ||||
| @@ -27,9 +28,13 @@ const Steps: React.FC<Props> = (props) => { | |||||
| buttonText={props.buttonText} | buttonText={props.buttonText} | ||||
| descriptionImage={props.descriptionImage} | descriptionImage={props.descriptionImage} | ||||
| link={props.link} | link={props.link} | ||||
| isRoundCompleted={props.isRoundCompleted} | |||||
| /> : | /> : | ||||
| <div className={styles.stepHolder}> | <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.stepName}> | ||||
| <div className={styles.step}>step {props.stepNumber}</div> | <div className={styles.step}>step {props.stepNumber}</div> | ||||
| @@ -39,7 +39,7 @@ const PreliminaryRound: React.FC = () => { | |||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| <Link to="./quiz"> | |||||
| <Link to="/quiz"> | |||||
| <IonButton shape="round" expand='block'>Start quiz</IonButton> | <IonButton shape="round" expand='block'>Start quiz</IonButton> | ||||
| </Link> | </Link> | ||||
| @@ -47,7 +47,7 @@ const PreliminaryRound: React.FC = () => { | |||||
| </div> | </div> | ||||
| </IonContent> | </IonContent> | ||||
| </IonPage> | </IonPage> | ||||
| ) | |||||
| ); | |||||
| } | } | ||||
| export default PreliminaryRound; | export default PreliminaryRound; | ||||
| @@ -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); | |||||
| } | |||||
| } | |||||
| } | } | ||||
| @@ -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 { useState } from 'react'; | ||||
| import styles from './Options.module.scss'; | import styles from './Options.module.scss'; | ||||
| interface OwnProps { | interface OwnProps { | ||||
| options: string[]; | |||||
| isSelected: (option: string) => void; | |||||
| options: string[] | undefined; | |||||
| updateQuestionNumber: () => void; | |||||
| } | } | ||||
| const Options: React.FC<OwnProps> = (props) => { | 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 ( | return ( | ||||
| <IonItem lines='none' key={key} className={(option === selected) ? styles.highlighted : ""}> | <IonItem lines='none' key={key} className={(option === selected) ? styles.highlighted : ""}> | ||||
| <IonLabel>{option}</IonLabel> | <IonLabel>{option}</IonLabel> | ||||
| @@ -29,6 +29,11 @@ const Options: React.FC<OwnProps> = (props) => { | |||||
| {options} | {options} | ||||
| </IonRadioGroup> | </IonRadioGroup> | ||||
| </IonList> | </IonList> | ||||
| <div className={styles.button + " " + (selected ? styles.active : "")} | |||||
| onClick={() => props.updateQuestionNumber()}> | |||||
| <IonButton shape="round" expand='block'>Next</IonButton> | |||||
| </div> | |||||
| </div> | </div> | ||||
| ); | ); | ||||
| } | } | ||||
| @@ -1,43 +1,43 @@ | |||||
| import { useEffect, useState } from "react"; | import { useEffect, useState } from "react"; | ||||
| import styles from "./Question.module.scss"; | import styles from "./Question.module.scss"; | ||||
| import { CountdownCircleTimer } from 'react-countdown-circle-timer'; | import { CountdownCircleTimer } from 'react-countdown-circle-timer'; | ||||
| import { secondsToMinutes } from "date-fns"; | |||||
| interface OwnProp { | interface OwnProp { | ||||
| questionNumber: number; | questionNumber: number; | ||||
| question: string; | question: string; | ||||
| timeLimit: number; | timeLimit: number; | ||||
| updateQuestionNumber: () => void; | |||||
| } | } | ||||
| let timeout: NodeJS.Timeout; | let timeout: NodeJS.Timeout; | ||||
| const Question: React.FC<OwnProp> = (props) => { | 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 displaySeconds = seconds % 60; | ||||
| const displayMinutes = Math.floor(seconds / 60); | |||||
| useEffect(() => { | 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 = () => { | const renderTime = () => { | ||||
| return ( | return ( | ||||
| <div className={styles.time}> | <div className={styles.time}> | ||||
| {`${displayMinutes < 10 ? "0" : ""}${displayMinutes}:${displaySeconds < 10 ? "0" : ""}${displaySeconds}`} | |||||
| { | |||||
| `${secondsToMinutes(seconds).toString().padStart(2, '0')}: | |||||
| ${displaySeconds.toString().padStart(2, '0')}` | |||||
| } | |||||
| </div> | </div> | ||||
| ); | ); | ||||
| } | } | ||||
| @@ -56,9 +56,14 @@ const Question: React.FC<OwnProp> = (props) => { | |||||
| <CountdownCircleTimer | <CountdownCircleTimer | ||||
| isPlaying | isPlaying | ||||
| duration={COUNTDOWN_AMOUNT_TOTAL} | |||||
| duration={props.timeLimit} | |||||
| colors={'#6BD534'} | colors={'#6BD534'} | ||||
| size={60} | size={60} | ||||
| onComplete={() => { | |||||
| // setSeconds(COUNTDOWN_AMOUNT_TOTAL); | |||||
| // props.updateQuestionNumber(); | |||||
| return { shouldRepeat: true } | |||||
| }} | |||||
| strokeWidth={5} > | strokeWidth={5} > | ||||
| {renderTime} | {renderTime} | ||||
| @@ -72,6 +72,10 @@ | |||||
| } | } | ||||
| } | } | ||||
| // ion-activated { | |||||
| // --background: var(--primary-button-color); | |||||
| // } | |||||
| .active { | .active { | ||||
| ion-button { | ion-button { | ||||
| --background: var(--primary-button-color); | --background: var(--primary-button-color); | ||||
| @@ -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; | |||||
| @@ -46,22 +46,22 @@ | |||||
| letter-spacing: 0.024rem; | letter-spacing: 0.024rem; | ||||
| } | } | ||||
| .timeLeft { | .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 { | .icon { | ||||
| width: 6rem; | width: 6rem; | ||||
| @@ -5,8 +5,11 @@ import StepHeader from "../../components/stepsHeader/StepHeader"; | |||||
| import techinicalInterview from "../../assets/icons/Technical_Interview.svg"; | import techinicalInterview from "../../assets/icons/Technical_Interview.svg"; | ||||
| import linkIcon from "../../assets/icons/link.svg"; | import linkIcon from "../../assets/icons/link.svg"; | ||||
| import { Link } from "react-router-dom"; | import { Link } from "react-router-dom"; | ||||
| import { useState } from "react"; | |||||
| import { useEffect, useState } from "react"; | |||||
| import TimeSlot from "../../components/timeSlot/TimeSlot"; | 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 { | interface dates { | ||||
| date: string; | date: string; | ||||
| @@ -18,33 +21,18 @@ const TechnicalInterview: React.FC = () => { | |||||
| const [isDateSet, setDate] = useState<boolean>(false); | const [isDateSet, setDate] = useState<boolean>(false); | ||||
| const [isTimeSlot, setTimeSlot] = 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); | setTimeSlot(false); | ||||
| setDate(true); | setDate(true); | ||||
| } | } | ||||
| const HideTimeSlot = () => { | |||||
| setTimeSlot(false); | |||||
| } | |||||
| return ( | return ( | ||||
| <IonPage> | <IonPage> | ||||
| <StepHeader stepNumber={3} roundName="Technical Interview" /> | <StepHeader stepNumber={3} roundName="Technical Interview" /> | ||||
| @@ -64,13 +52,18 @@ const TechnicalInterview: React.FC = () => { | |||||
| <h4>Let's Meet in:</h4> | <h4>Let's Meet in:</h4> | ||||
| <div className={styles.timeLeft}> | <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>Days</div> | ||||
| <div>Hrs</div> | <div>Hrs</div> | ||||
| <div>Mins</div> | <div>Mins</div> | ||||
| <div>Secs</div> | <div>Secs</div> | ||||
| </div> | |||||
| </div> */} | |||||
| </div> | </div> | ||||
| <h4>Join us on Google Meet</h4> | <h4>Join us on Google Meet</h4> | ||||
| <div className={styles.icon}> | <div className={styles.icon}> | ||||
| @@ -98,10 +91,9 @@ const TechnicalInterview: React.FC = () => { | |||||
| { | { | ||||
| isTimeSlot && | isTimeSlot && | ||||
| <TimeSlot | <TimeSlot | ||||
| month="April -May" | |||||
| dates={dates} | |||||
| timeSlots={timeSlots} | |||||
| getDate={getDate} /> | |||||
| month="April-May" | |||||
| getDate={getDate} | |||||
| HideTimeSlot={HideTimeSlot} /> | |||||
| } | } | ||||
| </IonContent> | </IonContent> | ||||