diff --git a/src/Modules/CandidateAssessment/CandidateAssessment.tsx b/src/Modules/CandidateAssessment/CandidateAssessment.tsx
index e0a0fc2..15f4fad 100644
--- a/src/Modules/CandidateAssessment/CandidateAssessment.tsx
+++ b/src/Modules/CandidateAssessment/CandidateAssessment.tsx
@@ -76,7 +76,8 @@ const CandidateAssessment = () => {
const userData = {
emailId: values.email,
name: values.name,
- };
+ examId: examId
+ };
createCandidate(userData)
.then((candidateData: Candidate) => {
setLoading(false);
diff --git a/src/Modules/CandidateAssessment/QuestionsPage.tsx b/src/Modules/CandidateAssessment/QuestionsPage.tsx
index 0bff2c4..be302be 100644
--- a/src/Modules/CandidateAssessment/QuestionsPage.tsx
+++ b/src/Modules/CandidateAssessment/QuestionsPage.tsx
@@ -16,6 +16,7 @@ import CommonUtils from '../common/utils/Common.utils';
const { Title } = Typography;
const ChallengesListComponent = () => {
+ const navigate = useNavigate();
const { examId, candidateId } = useParams();
const candidate = useSelector((state: IRootState) => state.candidate);
const [loading, setLoading] = useState(true);
@@ -69,6 +70,11 @@ const ChallengesListComponent = () => {
}
};
+ const handleTimeout = ()=>{
+ dispatch.assessment.clear();
+ navigate(ROUTES.ASSESSMENT_OVER);
+ }
+
const expiry = (jwt_decode(candidate?.token) as { exp: number })?.exp;
const now = Date.now() / 1000;
const timeLeft = Math.round(expiry - now);
@@ -78,7 +84,7 @@ const ChallengesListComponent = () => {
Welcome to the Assessment
Instructions
-
+
Welcome to the coding test for your interview! Please select a challenge from the list below to begin.
diff --git a/src/Modules/CandidateAssessment/components/Timer.tsx b/src/Modules/CandidateAssessment/components/Timer.tsx
index 98500a5..46c27b1 100644
--- a/src/Modules/CandidateAssessment/components/Timer.tsx
+++ b/src/Modules/CandidateAssessment/components/Timer.tsx
@@ -1,9 +1,11 @@
import { Typography } from 'antd';
import { useState, useEffect } from 'react';
+import { toast } from 'react-toastify';
const { Title } = Typography;
interface IProps {
timeLeft: number;
+ onTimeout: () => void;
}
const Timer: React.FC = (props: IProps) => {
@@ -15,26 +17,47 @@ const Timer: React.FC = (props: IProps) => {
useEffect(() => {
const timer = setInterval(() => {
- setTimeLeft((prevTimeLeft) => prevTimeLeft - 1);
+ setTimeLeft((prevTimeLeft) => {
+ if (prevTimeLeft === 0) return 0;
+ return prevTimeLeft - 1;
+ });
}, 1000);
return () => clearInterval(timer);
}, []);
+ useEffect(() => {
+ const hours = Math.floor(timeLeft / 3600);
+ const minutes = Math.floor((timeLeft % 3600) / 60);
+ const seconds = timeLeft % 60;
+
+ if (hours === 0 && minutes === 5 && seconds === 0) toast.warning('Only 5 minutes left');
+
+ if (hours === 0 && minutes === 1 && seconds === 0) toast.warning('Only 1 minutes left');
+
+ if(hours === 0 && minutes === 0 && seconds === 20) toast.warning("Assessment will be submitted automatically in 10 seconds");
+
+ if(hours === 0 && minutes === 0 && seconds === 10){
+ props.onTimeout();
+ toast.success("Assessment submitted successfully!")
+ }
+
+ }, [timeLeft]);
+
const formatTime = (time: number) => {
const hours = Math.floor(time / 3600);
const minutes = Math.floor((time % 3600) / 60);
const seconds = time % 60;
- return `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${seconds
+ return `${hours.toString().padStart(2, '0')} : ${minutes.toString().padStart(2, '0')} : ${seconds
.toString()
.padStart(2, '0')}`;
};
return (
-
-
- Time Left
{formatTime(timeLeft)}
+
+
+ Time Left : {formatTime(timeLeft)}
);
diff --git a/src/Modules/CandidateAssessment/styles/Assessment.css b/src/Modules/CandidateAssessment/styles/Assessment.css
index 89fc3fb..a4ea126 100644
--- a/src/Modules/CandidateAssessment/styles/Assessment.css
+++ b/src/Modules/CandidateAssessment/styles/Assessment.css
@@ -2,6 +2,10 @@
background-color: var(--lumel-brand-color) !important;
}
+.timer{
+ color: var(--lumel-brand-color) !important;
+}
+
.timer span {
min-width: 100px;
margin-left: 10px;
diff --git a/src/Modules/Exam/ExamDetail.tsx b/src/Modules/Exam/ExamDetail.tsx
index a234903..8c634ea 100644
--- a/src/Modules/Exam/ExamDetail.tsx
+++ b/src/Modules/Exam/ExamDetail.tsx
@@ -13,12 +13,18 @@ import { ExamAPIService } from './services/Exam.API';
import { ROUTES } from '../../constants/Route.constants';
export type ChallengeResult = Awaited
>;
+interface Time {
+ hr: number,
+ min: number
+}
const ExamDetail = () => {
const { state } = useLocation();
const exam = state?.exam as ExamQueryResult[number];
const [name, setName] = useState(exam?.name || '');
const [challenges, setChallenges] = useState([]);
+ const [time, setTime] = useState
diff --git a/src/Modules/Exam/ExamList.tsx b/src/Modules/Exam/ExamList.tsx
index 056bc0d..8286e23 100644
--- a/src/Modules/Exam/ExamList.tsx
+++ b/src/Modules/Exam/ExamList.tsx
@@ -150,6 +150,9 @@ const ExamList = () => {
+
+
+
diff --git a/src/Modules/Exam/components/ExamSettings.tsx b/src/Modules/Exam/components/ExamSettings.tsx
index d382531..b55314b 100644
--- a/src/Modules/Exam/components/ExamSettings.tsx
+++ b/src/Modules/Exam/components/ExamSettings.tsx
@@ -2,30 +2,25 @@ import { Button, Form, Layout, Popconfirm, Select, Space } from 'antd';
const { Option } = Select;
-const handleTimeLimitChange = (value) => {
- // Handle the selected time limit
- console.log(value);
-};
-
-const ExamSettings = ({ onChange, onDelete }) => {
+const ExamSettings = ({ addDuration, onDelete, duration }) => {
return (
-
diff --git a/src/Modules/Exam/services/Exam.API.ts b/src/Modules/Exam/services/Exam.API.ts
index b858966..08526fb 100644
--- a/src/Modules/Exam/services/Exam.API.ts
+++ b/src/Modules/Exam/services/Exam.API.ts
@@ -40,6 +40,7 @@ export class ExamAPIService {
return data || null;
}
+
static async create(exam: ExamInsertDto) {
const { data, error } = await supabase.from('exam').insert(exam).select('*,challenge(*)');
if (error) {
diff --git a/src/Modules/common/CodeEditor/Editor.tsx b/src/Modules/common/CodeEditor/Editor.tsx
index a1d7d18..174a33d 100644
--- a/src/Modules/common/CodeEditor/Editor.tsx
+++ b/src/Modules/common/CodeEditor/Editor.tsx
@@ -29,6 +29,8 @@ import { ROUTES } from '../../../constants/Route.constants';
import './styles/Editor.css';
import { Typography } from 'antd';
import { invokeSupabaseFunction } from '../../API/APIUtils';
+import jwt_decode from 'jwt-decode';
+import Timer from '../../CandidateAssessment/components/Timer';
const { Title } = Typography;
interface IProps {
@@ -50,6 +52,9 @@ const Editor = ({ challenge, assessment, candidate }: IProps) => {
const [saveLoading, setSaveLoading] = useState(false);
const [testCaseLoading, setTestCaseLoading] = useState(false);
const [lastSaved, setlastSaved] = useState(null);
+ const expiry = (jwt_decode(candidate?.token) as { exp: number })?.exp;
+ const now = Date.now() / 1000;
+ const timeLeft = Math.round(expiry - now);
const evaluator = new CodeEvaluator(
selectEditorLanguage.name,
@@ -183,6 +188,10 @@ const Editor = ({ challenge, assessment, candidate }: IProps) => {
setSubmitLoading(false);
};
+ const handleTimeout = ()=>{
+ handleSubmit();
+ }
+
useAutosave({ data: code, onSave: saveCode, interval: 1000 });
return (
@@ -213,7 +222,10 @@ const Editor = ({ challenge, assessment, candidate }: IProps) => {
/>
-
+ {expiry &&
+
+
}
+