-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
update of the availability calendar in order to be compliant with pro…
…ject specifications
- Loading branch information
1 parent
9fbdb81
commit 1f03b29
Showing
4 changed files
with
83 additions
and
194 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -38,8 +38,8 @@ function AvailabilitiesTable({ authUser }) { | |
startDate: moment("2024-11-18T09:45:00").format(), | ||
endDate: moment("2024-11-18T10:30:00").format(), | ||
interview: { | ||
status: "published", | ||
availabilityId: 0, | ||
howManyInterviewers: 3, | ||
interviewers: [ | ||
{ | ||
firstName: "Federico", | ||
|
@@ -60,16 +60,15 @@ function AvailabilitiesTable({ authUser }) { | |
role: "", | ||
}, | ||
], | ||
applicant: null, // Slot not taken | ||
}, | ||
}, | ||
{ | ||
availabilityId: 1, | ||
startDate: moment("2024-11-20T09:45:00").format(), | ||
endDate: moment("2024-11-20T10:30:00").format(), | ||
interview: { | ||
status: "booked", | ||
availabilityId: 1, | ||
howManyInterviewers: 3, | ||
interviewers: [ | ||
{ | ||
firstName: "Federico", | ||
|
@@ -90,20 +89,15 @@ function AvailabilitiesTable({ authUser }) { | |
role: "", | ||
}, | ||
], | ||
applicant: { | ||
firstName: "Claudio", | ||
lastName: "Neri", | ||
email: "[email protected]", | ||
}, | ||
}, | ||
}, | ||
{ | ||
availabilityId: 2, | ||
startDate: moment("2024-11-21T09:45:00").format(), | ||
endDate: moment("2024-11-21T10:30:00").format(), | ||
interview: { | ||
status: "draft", | ||
availabilityId: 2, | ||
howManyInterviewers: 3, | ||
interviewers: [ | ||
{ | ||
firstName: "Federico", | ||
|
@@ -124,16 +118,15 @@ function AvailabilitiesTable({ authUser }) { | |
role: "", | ||
}, | ||
], | ||
applicant: null, | ||
}, | ||
}, | ||
{ | ||
availabilityId: 3, | ||
startDate: moment("2024-11-22T09:45:00").format(), | ||
endDate: moment("2024-11-22T10:30:00").format(), | ||
interview: { | ||
status: "draft", | ||
availabilityId: 3, | ||
howManyInterviewers: 3, | ||
interviewers: [ | ||
{ | ||
firstName: "Federico", | ||
|
@@ -154,12 +147,15 @@ function AvailabilitiesTable({ authUser }) { | |
role: "", | ||
}, | ||
], | ||
applicant: null, | ||
}, | ||
}, | ||
]; | ||
|
||
const handleAddAvailability = (timeSlotStart, timeSlotEnd) => { | ||
if (timeSlotStart.isBefore(minDate) || timeSlotStart.isAfter(maxDate)) { | ||
console.log("Date out of range. Cannot add availability."); | ||
return; | ||
} | ||
console.log( | ||
`Adding availability for ${timeSlotStart.format( | ||
"dddd D/MM/YYYY" | ||
|
@@ -175,7 +171,7 @@ function AvailabilitiesTable({ authUser }) { | |
endDate: timeSlotEnd.format(), | ||
interview: { | ||
availabilityId: id, // Unique ID for the availability | ||
status: "draft", | ||
howManyInterviewers: 1, | ||
interviewers: [ | ||
{ | ||
firstName: authUser.given_name, | ||
|
@@ -189,7 +185,6 @@ function AvailabilitiesTable({ authUser }) { | |
: "", // Enforce role presence | ||
}, | ||
], | ||
applicant: null, // Slot not taken initially | ||
}, | ||
}; | ||
|
||
|
@@ -204,6 +199,7 @@ function AvailabilitiesTable({ authUser }) { | |
...a, | ||
interview: { | ||
...a.interview, | ||
howManyInterviewers: a.interview.howManyInterviewers + 1, | ||
interviewers: [ | ||
...a.interview.interviewers, | ||
{ | ||
|
@@ -220,74 +216,22 @@ function AvailabilitiesTable({ authUser }) { | |
setAvailabilities(updatedAvailabilities); | ||
}; | ||
|
||
const handleRemoveAvailability = (availabilityId) => { | ||
console.log(`Removing availability with id: ${availabilityId}`); | ||
setAvailabilities( | ||
availabilities.filter((a) => a.availabilityId !== availabilityId) | ||
); | ||
}; | ||
|
||
const handleUnpublish = (availabilityId) => { | ||
console.log(`Unpublishing availability with ID ${availabilityId}`); | ||
|
||
const updatedAvailabilities = availabilities.map((availability) => | ||
availability.availabilityId === availabilityId | ||
? { | ||
...availability, | ||
interview: { | ||
...availability.interview, | ||
status: "draft", // Change the status to "draft" | ||
}, | ||
} | ||
: availability | ||
); | ||
|
||
setAvailabilities(updatedAvailabilities); | ||
}; | ||
|
||
const handleRemoveApplicant = (availabilityId) => { | ||
console.log( | ||
`Removing applicant from availability with id: ${availabilityId}` | ||
); | ||
const updatedAvailabilities = availabilities.map((a) => | ||
a.availabilityId === availabilityId | ||
? { | ||
...a, | ||
interview: { | ||
...a.interview, | ||
applicant: null, // Remove the applicant | ||
status: "published", // Update status to "published" | ||
}, | ||
} | ||
: a | ||
); | ||
setAvailabilities(updatedAvailabilities); | ||
}; | ||
|
||
const renderInterview = (interview) => { | ||
const isAuthUserInterviewer = interview.interviewers.some( | ||
(interviewer) => interviewer.email === authUser.email | ||
); | ||
const getBackgroundColor = () => { | ||
if (interview.status === "booked") { | ||
return "#f8d7da"; // Red: Applicant present | ||
} else if (interview.status === "published") { | ||
return "#d1e7dd"; // Green: published | ||
} else { | ||
return "#fff3cd"; // Yellow: draft | ||
} | ||
}; | ||
|
||
return ( | ||
<div | ||
style={{ | ||
padding: "10px", | ||
background: getBackgroundColor(), | ||
background: "#d1e7dd", | ||
border: "2px solid #000", // Add border to the div | ||
borderRadius: "8px", // Optional: Rounded corners for better appearance | ||
}} | ||
> | ||
{interview.interviewers && | ||
{isSupervisor && | ||
interview.interviewers && | ||
interview.interviewers.map((interviewer) => { | ||
if (interviewer.role === "board") { | ||
return ( | ||
|
@@ -313,6 +257,12 @@ function AvailabilitiesTable({ authUser }) { | |
} | ||
return null; // If the role is unexpected, render nothing | ||
})} | ||
{interview.howManyInterviewers && ( | ||
<div> | ||
In this slot {`${interview.howManyInterviewers}`} interviewers have | ||
given availability. | ||
</div> | ||
)} | ||
|
||
{interview.applicant && ( | ||
<div> | ||
|
@@ -321,25 +271,12 @@ function AvailabilitiesTable({ authUser }) { | |
</div> | ||
)} | ||
<div> | ||
{isAuthUserInterviewer && interview.applicant && ( | ||
<Button variant="info" onClick={() => {}}> | ||
<FaInfoCircle size={20} color="#fff" /> | ||
</Button> | ||
)} | ||
{isSupervisor && ( | ||
<Button | ||
variant="danger" | ||
onClick={() => handleRemoveAvailability(interview.availabilityId)} | ||
> | ||
<FaTrashAlt size={20} color="#fff" /> | ||
</Button> | ||
)} | ||
{isSupervisor && ( | ||
<Button variant="info" onClick={() => {}}> | ||
<FaEdit size={20} color="#fff" /> | ||
</Button> | ||
)} | ||
{isAuthUserInterviewer && interview.status === "draft" && ( | ||
{isAuthUserInterviewer && ( | ||
<Button | ||
variant="danger" | ||
onClick={() => | ||
|
@@ -352,67 +289,21 @@ function AvailabilitiesTable({ authUser }) { | |
<FaTrashAlt size={20} color="#fff" /> My availability | ||
</Button> | ||
)} | ||
{!isAuthUserInterviewer && interview.status === "draft" && ( | ||
{!isAuthUserInterviewer && ( | ||
<Button | ||
variant="success" | ||
onClick={() => handleAddInterviewer(interview.availabilityId)} | ||
> | ||
<FaPlus /> Join interview | ||
</Button> | ||
)} | ||
{isSupervisor && interview.applicant && ( | ||
<> | ||
<Button | ||
variant="warning" | ||
onClick={() => handleRemoveApplicant(interview.availabilityId)} | ||
> | ||
<FaTrashAlt size={20} color="#fff" /> Applicant | ||
</Button> | ||
</> | ||
)} | ||
|
||
{isSupervisor && interview.status === "published" && ( | ||
<Button | ||
variant="warning" | ||
onClick={() => handleUnpublish(interview.availabilityId)} | ||
> | ||
<FaUndo size={20} color="#fff" /> Unpublish | ||
</Button> | ||
)} | ||
{isSupervisor && interview.status === "draft" && ( | ||
<Button | ||
variant="success" | ||
onClick={() => handleMakePublic(interview.availabilityId)} | ||
> | ||
<FaGlobe /> Publish | ||
</Button> | ||
)} | ||
</div> | ||
</div> | ||
); | ||
}; | ||
|
||
const handleMakePublic = (availabilityId) => { | ||
console.log(`Making availability with ID ${availabilityId} public`); | ||
|
||
// Update the status of the selected availability | ||
const updatedAvailabilities = availabilities.map((availability) => | ||
availability.availabilityId === availabilityId | ||
? { | ||
...availability, | ||
interview: { | ||
...availability.interview, | ||
status: "published", // Set the status to "published" | ||
}, | ||
} | ||
: availability | ||
); | ||
|
||
setAvailabilities(updatedAvailabilities); // Update the state | ||
}; | ||
|
||
const handleRemoveInterviewer = (availabilityId, email) => { | ||
console.log(`Removing interviewer with email: ${(authUser, email)}`); | ||
console.log(`Removing interviewer with email: ${email}`); | ||
|
||
const updatedAvailabilities = availabilities | ||
.map((availability) => { | ||
|
@@ -427,11 +318,13 @@ function AvailabilitiesTable({ authUser }) { | |
return null; | ||
} | ||
|
||
// Otherwise, return the updated availability | ||
// Otherwise, decrement howManyInterviewers and return the updated availability | ||
return { | ||
...availability, | ||
interview: { | ||
...availability.interview, | ||
howManyInterviewers: | ||
availability.interview.howManyInterviewers - 1, | ||
interviewers: updatedInterviewers, | ||
}, | ||
}; | ||
|
@@ -444,6 +337,9 @@ function AvailabilitiesTable({ authUser }) { | |
setAvailabilities(updatedAvailabilities); | ||
}; | ||
|
||
const minDate = moment("2024-11-01"); // Earliest date to display | ||
const maxDate = moment("2024-11-30"); // Latest date to display | ||
|
||
return ( | ||
<Container fluid> | ||
<Row> | ||
|
@@ -467,12 +363,22 @@ function AvailabilitiesTable({ authUser }) { | |
: "Switch to Supervisor View"} | ||
</button> | ||
</div> | ||
<b>Start of the recruitment session: </b> | ||
{minDate.format("dddd D/MM/YYYY")} | ||
<br /> | ||
<b>End of the recruitment session: </b> | ||
{maxDate.format("dddd D/MM/YYYY")} | ||
<br /> | ||
<Row className="mb-3"> | ||
<Col> | ||
<Button | ||
onClick={() => | ||
setStartDate(startDate.clone().subtract(1, "weeks")) | ||
} | ||
disabled={startDate | ||
.clone() | ||
.subtract(1, "weeks") | ||
.isBefore(minDate, "week")} | ||
> | ||
Previous Week | ||
</Button> | ||
|
@@ -483,6 +389,10 @@ function AvailabilitiesTable({ authUser }) { | |
<Col className="text-end"> | ||
<Button | ||
onClick={() => setStartDate(startDate.clone().add(1, "weeks"))} | ||
disabled={startDate | ||
.clone() | ||
.add(1, "weeks") | ||
.isAfter(maxDate, "week")} | ||
> | ||
Next Week | ||
</Button> | ||
|
@@ -518,6 +428,13 @@ function AvailabilitiesTable({ authUser }) { | |
)} - ${rowTimeSlotEnd.format("HH:mm")}`}</td> | ||
{Array.from({ length: 5 }).map((_, j) => { | ||
const day = startDate.clone().add(j, "days"); | ||
|
||
if ( | ||
day.isBefore(minDate, "day") || | ||
day.isAfter(maxDate, "day") | ||
) { | ||
return <td key={j}></td>; // Empty cell for out-of-range dates | ||
} | ||
const timeSlotStart = day | ||
.clone() | ||
.startOf("day") | ||
|
Oops, something went wrong.