Skip to content

Commit

Permalink
update of the availability calendar in order to be compliant with pro…
Browse files Browse the repository at this point in the history
…ject specifications
  • Loading branch information
giovannidemaria committed Dec 13, 2024
1 parent 9fbdb81 commit 1f03b29
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 194 deletions.
181 changes: 49 additions & 132 deletions frontend/src/components/AvailabilitiesTable.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand All @@ -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",
Expand All @@ -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",
Expand All @@ -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",
Expand All @@ -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"
Expand All @@ -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,
Expand All @@ -189,7 +185,6 @@ function AvailabilitiesTable({ authUser }) {
: "", // Enforce role presence
},
],
applicant: null, // Slot not taken initially
},
};

Expand All @@ -204,6 +199,7 @@ function AvailabilitiesTable({ authUser }) {
...a,
interview: {
...a.interview,
howManyInterviewers: a.interview.howManyInterviewers + 1,
interviewers: [
...a.interview.interviewers,
{
Expand All @@ -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 (
Expand All @@ -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>
Expand All @@ -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={() =>
Expand All @@ -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) => {
Expand All @@ -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,
},
};
Expand All @@ -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>
Expand All @@ -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>
Expand All @@ -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>
Expand Down Expand Up @@ -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")
Expand Down
Loading

0 comments on commit 1f03b29

Please sign in to comment.