From 1f57ade5fac2bc07948ea61e1a4f1f4ebe51309c Mon Sep 17 00:00:00 2001 From: Bahati Date: Mon, 2 Dec 2024 03:11:59 +0200 Subject: [PATCH] Implement Interview inviation --- .../Invitation/ScheduleInterview.tsx | 98 +++++++++++-------- src/pages/TraineApplicant/ApplicantStages.tsx | 31 +++++- src/redux/actions/applicationStage.ts | 79 ++------------- src/redux/actions/deletetraine.ts | 1 + src/utils/exports/exportToExcel.ts | 2 +- 5 files changed, 95 insertions(+), 116 deletions(-) diff --git a/src/components/Invitation/ScheduleInterview.tsx b/src/components/Invitation/ScheduleInterview.tsx index f4d63247..158e9945 100644 --- a/src/components/Invitation/ScheduleInterview.tsx +++ b/src/components/Invitation/ScheduleInterview.tsx @@ -22,7 +22,7 @@ const ScheduleInterview: React.FC = ({ status, onClose, technicalInterviews = [], - availableStatuses = ["Scheduled", "Completed", "No show", "cancelled"], + availableStatuses = ["Scheduled", "Completed", "No show", "Cancelled"], }) => { const dispatch = useAppDispatch(); const [isModelOpen, setIsModelOpen] = useState(false); @@ -60,10 +60,8 @@ const ScheduleInterview: React.FC = ({ useEffect(() => { // Ensure technicalInterviews is an array and has length if (Array.isArray(technicalInterviews) && technicalInterviews.length > 0) { - // Set the ID of the first interview in the array setSelectedInterviewId(technicalInterviews[0]._id); } else { - // Ensure we have a fallback setSelectedInterviewId(""); } }, [technicalInterviews]); @@ -120,35 +118,6 @@ const ScheduleInterview: React.FC = ({ }); }; - // const handleStatusUpdate = async (event: React.FormEvent) => { - // event.preventDefault(); - - // console.log("Current technicalInterviews:", technicalInterviews); - // console.log("Current selectedInterviewId:", selectedInterviewId); - - // if (!newStatus) { - // setError("Please select a status"); - // return; - // } - - // // If no interview exists, prevent status update - // if (!selectedInterviewId) { - // setError("No interview found. Please schedule an interview first."); - // return; - // } - - // try { - // setIsLoading(true); - // await dispatch(updateInterviewStatuses(selectedInterviewId, newStatus)); - // onClose(); - // setIsLoading(false); - // } catch (err) { - // console.error("Error updating interview status:", err); - // setError("Failed to update status"); - // setIsLoading(false); - // } - // }; - const handleStatusUpdate = async (event: React.FormEvent) => { event.preventDefault(); @@ -157,13 +126,11 @@ const ScheduleInterview: React.FC = ({ return; } - // If no interview exists, prevent status update if (!selectedInterviewId) { setError("No interview found. Please schedule an interview first."); return; } - // Get the current interview's status const currentInterview = technicalInterviews.find( (interview) => interview._id === selectedInterviewId ); @@ -171,12 +138,11 @@ const ScheduleInterview: React.FC = ({ // Define valid status transitions const validStatusTransitions = { Scheduled: ["Completed", "No show", "Cancelled"], - Completed: [], // No further transitions from Completed - Cancelled: [], // No further transitions from Cancelled - "No show": ["Scheduled"], // Can reschedule after a no-show + Completed: [], + Cancelled: [], + "No show": [], }; - // Check if the status transition is valid if (currentInterview) { const currentStatus = currentInterview.status; const allowedNextStatuses = validStatusTransitions[currentStatus] || []; @@ -209,11 +175,13 @@ const ScheduleInterview: React.FC = ({ stage === "Rejected" || stage === "Admitted" || (technicalInterviews.length > 0 && - technicalInterviews[0].status === "Completed") + (technicalInterviews[0].status === "Completed" || + technicalInterviews[0].status === "Cancelled")) } className={`px-4 py-2 w-full text-sm font-medium text-white ${ technicalInterviews.length > 0 && - technicalInterviews[0].status === "Completed" + (technicalInterviews[0].status === "Completed" || + technicalInterviews[0].status === "Cancelled") ? "bg-gray-400 cursor-not-allowed" : " bg-[#0c6a0c] hover:bg-[#367a4e] dark:bg-[#1bf84b8d] dark:hover:bg-emerald-700 dark:hover:text-gray-100 cursor-pointer" } focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-green-500`} @@ -338,7 +306,30 @@ const ScheduleInterview: React.FC = ({ type="submit" className="text-white bg-[#0c6a0c] dark:bg-[#56C870] hover:bg-[#4ab862] focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-lg text-sm w-full px-5 py-2.5 text-center" > - {isLoading ? "Sending..." : "Send Invite"} + {isLoading ? ( + <> + + sending... + + ) : ( + "Send Invitation" + )} )} @@ -374,7 +365,30 @@ const ScheduleInterview: React.FC = ({ type="submit" className="text-white bg-[#0c6a0c] dark:bg-[#56C870] hover:bg-[#4ab862] focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-lg text-sm w-full px-5 py-2.5 text-center" > - {isLoading ? "Updating..." : "Update"} + {isLoading ? ( + <> + + updating... + + ) : ( + "Update" + )} )} diff --git a/src/pages/TraineApplicant/ApplicantStages.tsx b/src/pages/TraineApplicant/ApplicantStages.tsx index c5400745..9dca4922 100644 --- a/src/pages/TraineApplicant/ApplicantStages.tsx +++ b/src/pages/TraineApplicant/ApplicantStages.tsx @@ -183,6 +183,17 @@ const ApplicantStages = (props: any) => { return dateObj.toLocaleDateString(); }; + const handleConvertInterviewDate = (date: string | number) => { + const timestamp = + typeof date === "string" && /^\d+$/.test(date) ? parseInt(date) : date; + + const dateObj = new Date(timestamp); + + return !isNaN(dateObj.getTime()) + ? dateObj.toLocaleDateString() + : "Invalid Date"; + }; + const handleTurnCutText = (text: string) => { if (text.length > 10) { return text.slice(0, 10) + "..."; @@ -324,7 +335,10 @@ const ApplicantStages = (props: any) => {