mirror of
https://github.com/UofCBaja/BajaUofCWebsite.git
synced 2025-06-16 05:44:17 -06:00
feat(InterviewBooking): added error handing, button css and defined select on date
This commit is contained in:
parent
6aade88454
commit
aa8e5c2577
@ -1,84 +1,122 @@
|
||||
:root {
|
||||
--interviewspacing: clamp(5px, 2.5svw, 200px);
|
||||
--interviewwidth: 260px;
|
||||
--interviewspacing: clamp(5px, 2.5svw, 200px);
|
||||
--interviewwidth: 260px;
|
||||
}
|
||||
#InterviewBooking header {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
background-color: lightslategray;
|
||||
justify-content: space-around;
|
||||
margin: 0px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
background-color: lightslategray;
|
||||
justify-content: space-around;
|
||||
margin: 0px;
|
||||
}
|
||||
#InterviewForm {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
width: 100%;
|
||||
justify-content: center;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
width: 100%;
|
||||
justify-content: center;
|
||||
}
|
||||
#InterviewForm div {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding-left: var(--interviewspacing);
|
||||
padding-right: var(--interviewspacing);
|
||||
text-align: start;
|
||||
width: var(--interviewwidth);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding-left: var(--interviewspacing);
|
||||
padding-right: var(--interviewspacing);
|
||||
text-align: start;
|
||||
width: var(--interviewwidth);
|
||||
}
|
||||
#InterviewForm div label {
|
||||
font-weight: 700;
|
||||
font-weight: 700;
|
||||
}
|
||||
#InterviewForm div p {
|
||||
font-size: x-small;
|
||||
margin: 0px;
|
||||
font-size: x-small;
|
||||
margin: 0px;
|
||||
}
|
||||
#InterviewForm div input {
|
||||
margin-top: 1svh;
|
||||
height: 30px;
|
||||
margin-top: 1svh;
|
||||
height: 30px;
|
||||
}
|
||||
#MainForm {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
#MainForm form {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
width: 80%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
width: 80%;
|
||||
}
|
||||
#TimeSlotSelector {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
width: 100%;
|
||||
justify-content: center;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
width: 100%;
|
||||
justify-content: center;
|
||||
}
|
||||
.TimeSlot {
|
||||
padding-left: var(--interviewspacing);
|
||||
padding-right: var(--interviewspacing);
|
||||
width: var(--interviewwidth);
|
||||
padding-left: var(--interviewspacing);
|
||||
padding-right: var(--interviewspacing);
|
||||
width: var(--interviewwidth);
|
||||
}
|
||||
.TimeSlot h4 {
|
||||
margin: 0px;
|
||||
margin-top: 30px;
|
||||
margin: 0px;
|
||||
margin-top: 30px;
|
||||
}
|
||||
.TimeSlot p {
|
||||
margin: 0px;
|
||||
margin-bottom: 20px;
|
||||
margin: 0px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
#InterviewSubmit {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
width: inherit;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
width: inherit;
|
||||
}
|
||||
#InterviewSubmit button {
|
||||
background-color: lightgreen;
|
||||
width: 20%;
|
||||
height: 5svh;
|
||||
margin-bottom: 5svh;
|
||||
font-size: large;
|
||||
border: none;
|
||||
background-color: lightgreen;
|
||||
width: 20%;
|
||||
height: 5svh;
|
||||
margin-bottom: 5svh;
|
||||
font-size: large;
|
||||
border: none;
|
||||
}
|
||||
#InterviewText {
|
||||
padding-left: var(--interviewspacing);
|
||||
padding-right: var(--interviewspacing);
|
||||
width: 80%;
|
||||
padding-left: var(--interviewspacing);
|
||||
padding-right: var(--interviewspacing);
|
||||
width: 80%;
|
||||
}
|
||||
|
||||
:root {
|
||||
/* used for editing time buttons */
|
||||
--TimeSlotSideWidth: 48%;
|
||||
--TimeSlotSidePaddingTopBottom: 1svh 0px;
|
||||
--TimeSlotSideMarginTopBottom: 0.25svh 1%;
|
||||
}
|
||||
|
||||
.TimeSlotSide0 {
|
||||
cursor: pointer;
|
||||
border: none;
|
||||
|
||||
width: var(--TimeSlotSideWidth);
|
||||
|
||||
padding: var(--TimeSlotSidePaddingTopBottom);
|
||||
margin: var(--TimeSlotSideMarginTopBottom);
|
||||
}
|
||||
|
||||
.TimeSlotSide1 {
|
||||
cursor: pointer;
|
||||
border: none;
|
||||
width: var(--TimeSlotSideWidth);
|
||||
|
||||
padding: var(--TimeSlotSidePaddingTopBottom);
|
||||
margin: var(--TimeSlotSideMarginTopBottom);
|
||||
}
|
||||
|
||||
#interviewLoading {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
text-align: center;
|
||||
height: 334.3px;
|
||||
}
|
||||
|
||||
#CurrentSelected {
|
||||
background-color: lightseagreen;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { useState, useRef } from "react";
|
||||
import TimeDateSelector from "./TimeDateSelector"; // Import the TimeSlotSelector component
|
||||
import TimeDateSelector from "./TimeDateSelector";
|
||||
|
||||
/**
|
||||
* @param {null} null - Takes in nothing
|
||||
@ -10,149 +10,181 @@ import TimeDateSelector from "./TimeDateSelector"; // Import the TimeSlotSelecto
|
||||
*/
|
||||
|
||||
const InterviewForm = () => {
|
||||
const [isButtonDisabled, setIsButtonDisabled] = useState(false);
|
||||
const dialogRef = useRef(null);
|
||||
const [selectedTimeSlot, setSelectedTimeSlot] = useState(null);
|
||||
const [getTimeDates, setGetTimeDates] = useState("");
|
||||
const [isButtonDisabled, setIsButtonDisabled] = useState(false);
|
||||
const dialogRef = useRef(null);
|
||||
const [selectedTimeSlot, setSelectedTimeSlot] = useState(null);
|
||||
const [getTimeDates, setGetTimeDates] = useState("");
|
||||
|
||||
/**
|
||||
* @param {String HTML} event - Takes in form info
|
||||
* @returns {null} null - Returns in nothing
|
||||
* @description
|
||||
* @author Ahmad <ahmadmuhammadofficial@gmail.com>
|
||||
* @todo CSS
|
||||
*/
|
||||
const formsubmit = async (event) => {
|
||||
event.preventDefault();
|
||||
/**
|
||||
* @param {String HTML} event - Takes in form info
|
||||
* @returns {null} null - Returns in nothing
|
||||
* @description submits the form with the appropriate information
|
||||
* @author Ahmad <ahmadmuhammadofficial@gmail.com>
|
||||
* @todo imporper email and other erros from backend
|
||||
*/
|
||||
const formsubmit = async (event) => {
|
||||
const errorLine = document.getElementById("InterviewError");
|
||||
|
||||
if (!selectedTimeSlot) {
|
||||
alert("Please select a time slot!");
|
||||
return;
|
||||
}
|
||||
event.preventDefault();
|
||||
|
||||
// disable button to stop multiple requests
|
||||
setIsButtonDisabled(true);
|
||||
if (selectedTimeSlot) {
|
||||
console.log(selectedTimeSlot);
|
||||
if (selectedTimeSlot.date !== null && selectedTimeSlot.startTime !== "") {
|
||||
errorLine.innerHTML = " ";
|
||||
// disable button to stop multiple requests
|
||||
setIsButtonDisabled(true);
|
||||
|
||||
// await new Promise((res) => setTimeout(res, 1000));
|
||||
const formData = new FormData(event.target);
|
||||
const formObject = Object.fromEntries(formData.entries());
|
||||
formObject.date = selectedTimeSlot["date"]; // Add the selected time slot to form data
|
||||
formObject.startTime = selectedTimeSlot["startTime"];
|
||||
console.log("Form Data:", formObject);
|
||||
const res = await fetch(
|
||||
"https://bajabackend.bajacloud.duckdns.org/SelectInterview",
|
||||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify(formObject),
|
||||
}
|
||||
);
|
||||
// const res = await fetch(
|
||||
// "http://127.0.0.1:8000/SelectInterview",
|
||||
// {
|
||||
// method: "POST",
|
||||
// headers: {
|
||||
// "Content-Type": "application/json",
|
||||
// },
|
||||
// body: JSON.stringify(formObject),
|
||||
// }
|
||||
// );
|
||||
// await new Promise((res) => setTimeout(res, 1000));
|
||||
const formData = new FormData(event.target);
|
||||
const formObject = Object.fromEntries(formData.entries());
|
||||
formObject.date = selectedTimeSlot["date"]; // Add the selected time slot to form data
|
||||
formObject.startTime = selectedTimeSlot["startTime"];
|
||||
console.log("Form Data:", formObject);
|
||||
|
||||
let data = await res.json();
|
||||
const res = await fetch(
|
||||
"https://bajabackend.bajacloud.duckdns.org/SelectInterview",
|
||||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify(formObject),
|
||||
}
|
||||
);
|
||||
// const res = await fetch(
|
||||
// "http://127.0.0.1:8000/SelectInterview",
|
||||
// {
|
||||
// method: "POST",
|
||||
// headers: {
|
||||
// "Content-Type": "application/json",
|
||||
// },
|
||||
// body: JSON.stringify(formObject),
|
||||
// }
|
||||
// );
|
||||
|
||||
if (data["body"]["Success"] === true) {
|
||||
dialogRef.current.showModal();
|
||||
} else {
|
||||
setGetTimeDates(getTimeDates + "i");
|
||||
}
|
||||
let data = await res.json();
|
||||
|
||||
setIsButtonDisabled(false);
|
||||
};
|
||||
if (data["body"]["Success"] === true) {
|
||||
dialogRef.current.showModal();
|
||||
} else {
|
||||
setGetTimeDates(getTimeDates + "i");
|
||||
}
|
||||
x;
|
||||
} else {
|
||||
formSubmitTimeErorrs(selectedTimeSlot, errorLine);
|
||||
}
|
||||
} else {
|
||||
formSubmitTimeErorrs(selectedTimeSlot, errorLine);
|
||||
}
|
||||
setIsButtonDisabled(false);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<form onSubmit={formsubmit}>
|
||||
<div id="InterviewForm">
|
||||
<div>
|
||||
<label for="name">Name:</label>
|
||||
<input
|
||||
type="text"
|
||||
id="fname"
|
||||
name="intervieweeName"
|
||||
placeholder="Jaeinceins"
|
||||
required
|
||||
/>
|
||||
<p>(what to call you)</p>
|
||||
</div>
|
||||
<div>
|
||||
<label for="email">UCalgary Email:</label>
|
||||
<input
|
||||
type="text"
|
||||
id="email"
|
||||
name="intervieweeEmail"
|
||||
placeholder="jaeinceins.bhaja@ucalgary.ca"
|
||||
required
|
||||
/>
|
||||
<p>(for interview confirmation email)</p>
|
||||
</div>
|
||||
</div>
|
||||
/**
|
||||
* @param {Object} missingError - Takes in object to find what is missing from it
|
||||
* @param {HTMLSelectElement} - display line on page
|
||||
* @returns {null} null - Returns in nothing
|
||||
* @description A separated function to handle all timeslot errors possible states and displays the appropriate message on the error line
|
||||
* @author Brock <darkicewolf50@gmail.com>
|
||||
*/
|
||||
const formSubmitTimeErorrs = (missingError, errorLine) => {
|
||||
if (!missingError) {
|
||||
errorLine.innerHTML = "Please Select a Date and a Time";
|
||||
}
|
||||
// impossible state
|
||||
/*
|
||||
else if (missingError.date === null) {
|
||||
errorLine.innerHTML = "Please Select a Date";
|
||||
*/
|
||||
else if (missingError.startTime) {
|
||||
errorLine.innerHTML = "Please Select a Time";
|
||||
}
|
||||
};
|
||||
return (
|
||||
<>
|
||||
<form onSubmit={formsubmit}>
|
||||
<div id="InterviewForm">
|
||||
<div>
|
||||
<label for="name">Name:</label>
|
||||
<input
|
||||
type="text"
|
||||
id="fname"
|
||||
name="intervieweeName"
|
||||
placeholder="Jaeinceins"
|
||||
required
|
||||
/>
|
||||
<p>(what to call you)</p>
|
||||
</div>
|
||||
<div>
|
||||
<label for="email">UCalgary Email:</label>
|
||||
<input
|
||||
type="text"
|
||||
id="email"
|
||||
name="intervieweeEmail"
|
||||
placeholder="jaeinceins.bhaja@ucalgary.ca"
|
||||
required
|
||||
/>
|
||||
<p>(for interview confirmation email)</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Time Slot Selector */}
|
||||
<TimeDateSelector
|
||||
onTimeSlotSelect={(timeSlot) => setSelectedTimeSlot(timeSlot)}
|
||||
timeDateSelectorGet={getTimeDates}
|
||||
/>
|
||||
<div id="InterviewText">
|
||||
<h4>
|
||||
What to do if I cannot make it to any of the avaliable time slots or
|
||||
need to rescedule?
|
||||
</h4>
|
||||
<p>
|
||||
While we highly encourage sceduling an interview in one of the above
|
||||
time slots, we recongize that not everyone can make it work with
|
||||
their personal and university schedules.
|
||||
</p>
|
||||
<p>
|
||||
Please email us at{" "}
|
||||
<a href="mailto:uofcbaja@gmail.com">uofcbaja@gmail.com</a> to work
|
||||
out an alternate interview time or for rescheduling.
|
||||
</p>
|
||||
</div>
|
||||
<p id="InterviewError"> </p>
|
||||
<div id="InterviewSubmit">
|
||||
<button type="submit" disabled={isButtonDisabled}>
|
||||
Submit
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
{/* Time Slot Selector */}
|
||||
<TimeDateSelector
|
||||
onTimeSlotSelect={(timeSlot) => setSelectedTimeSlot(timeSlot)}
|
||||
timeDateSelectorGet={getTimeDates}
|
||||
/>
|
||||
<div id="InterviewText">
|
||||
<h4>
|
||||
What to do if I cannot make it to any of the avaliable time slots or
|
||||
need to rescedule?
|
||||
</h4>
|
||||
<p>
|
||||
While we highly encourage sceduling an interview in one of the above
|
||||
time slots, we recongize that not everyone can make it work with
|
||||
their personal and university schedules.
|
||||
</p>
|
||||
<p>
|
||||
Please email us at{" "}
|
||||
<a href="mailto:uofcbaja@gmail.com">uofcbaja@gmail.com</a> to work
|
||||
out an alternate interview time or for rescheduling.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Success Dialog */}
|
||||
<dialog ref={dialogRef}>
|
||||
{" "}
|
||||
{/* Add the `ref` attribute */}
|
||||
<h2>Booking Successful!</h2>
|
||||
<p>
|
||||
Thank you for booking your interview slot. We’ll contact you soon.
|
||||
</p>
|
||||
<h4>
|
||||
What to do if I cannot make it to any of the avaliable time slots or
|
||||
need to rescedule?
|
||||
</h4>
|
||||
<p>
|
||||
While we highly encourage sceduling an interview in one of the above
|
||||
time slots, we recongize that not everyone can make it work with their
|
||||
personal and university schedules.
|
||||
</p>
|
||||
<p>
|
||||
Please email us at{" "}
|
||||
<a href="mailto:uofcbaja@gmail.com">uofcbaja@gmail.com</a> to work out
|
||||
an alternate interview time or for rescheduling.
|
||||
</p>
|
||||
</dialog>
|
||||
</>
|
||||
);
|
||||
<p id="InterviewError"> </p>
|
||||
|
||||
<div id="InterviewSubmit">
|
||||
<button
|
||||
type="submit"
|
||||
disabled={isButtonDisabled}>
|
||||
Submit
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
{/* Success Dialog */}
|
||||
<dialog ref={dialogRef}>
|
||||
{" "}
|
||||
{/* Add the `ref` attribute */}
|
||||
<h2>Booking Successful!</h2>
|
||||
<p>
|
||||
Thank you for booking your interview slot. We’ll contact you soon.
|
||||
</p>
|
||||
<h4>
|
||||
What to do if I cannot make it to any of the avaliable time slots or
|
||||
need to rescedule?
|
||||
</h4>
|
||||
<p>
|
||||
While we highly encourage sceduling an interview in one of the above
|
||||
time slots, we recongize that not everyone can make it work with their
|
||||
personal and university schedules.
|
||||
</p>
|
||||
<p>
|
||||
Please email us at{" "}
|
||||
<a href="mailto:uofcbaja@gmail.com">uofcbaja@gmail.com</a> to work out
|
||||
an alternate interview time or for rescheduling.
|
||||
</p>
|
||||
</dialog>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default InterviewForm;
|
||||
|
@ -2,145 +2,167 @@ import React, { useState, useEffect } from "react";
|
||||
import DatePicker from "react-datepicker";
|
||||
import "react-datepicker/dist/react-datepicker.css";
|
||||
|
||||
/**
|
||||
* @param {Function} onTimeSlotSelect - Used to pass back up the selected values from child component
|
||||
* @param {Function} timeDateSelectorGet - Used to display dates avaialable
|
||||
* @returns {JSX.element} JSX - HTML and JS functionality
|
||||
* @description Used for picking an interview date
|
||||
* @author Ahmad <ahmadmuhammadofficial@gmail.com>
|
||||
*/
|
||||
export default function TimeDateSelector({
|
||||
onTimeSlotSelect,
|
||||
timeDateSelectorGet,
|
||||
onTimeSlotSelect,
|
||||
timeDateSelectorGet,
|
||||
}) {
|
||||
const [allDatesAvailable, setAllDatesAvailable] = useState({});
|
||||
const [selectedDate, setSelectedDate] = useState(null);
|
||||
const [timeSlotsAvialable, setTimeSlotsAvialable] = useState([]);
|
||||
const [selectedTime, setSelectedTime] = useState("");
|
||||
const [allDatesAvailable, setAllDatesAvailable] = useState({});
|
||||
const [selectedDate, setSelectedDate] = useState(null);
|
||||
const [timeSlotsAvialable, setTimeSlotsAvialable] = useState([]);
|
||||
const [selectedTime, setSelectedTime] = useState("");
|
||||
const [selectedTimeButton, setSelectedTimeButton] = useState(null);
|
||||
|
||||
useEffect(() => {
|
||||
getInterviewDates();
|
||||
}, [timeDateSelectorGet]);
|
||||
useEffect(() => {
|
||||
getInterviewDates();
|
||||
}, [timeDateSelectorGet]);
|
||||
|
||||
/**
|
||||
* @param {null} null - Takes in nothing
|
||||
* @returns {null} null - Returns in nothing
|
||||
* @description Gets interview timeslots and dates from backend
|
||||
* @author Ahmad <ahmadmuhammadofficial@gmail.com>, Brock <darkicewolf50@gmail.com>
|
||||
* @todo refactor to not call backend so much, see useEffect above
|
||||
*/
|
||||
const getInterviewDates = async () => {
|
||||
const res = await fetch(
|
||||
"https://bajabackend.bajacloud.duckdns.org/getAppointments",
|
||||
{ method: "GET" }
|
||||
);
|
||||
// const res = await fetch(
|
||||
// "http://127.0.0.1:8000/getAppointments",
|
||||
// { method: "GET" }
|
||||
// );
|
||||
let json = await res.json();
|
||||
// console.log(json);
|
||||
// can input dates right away, no other requirements to show it
|
||||
let dates = await json["body"]["interviewDates"];
|
||||
setAllDatesAvailable(await dates);
|
||||
};
|
||||
/**
|
||||
* @param {null} null - Takes in nothing
|
||||
* @returns {null} null - Returns in nothing
|
||||
* @description Gets interview timeslots and dates from backend
|
||||
* @author Ahmad <ahmadmuhammadofficial@gmail.com>, Brock <darkicewolf50@gmail.com>
|
||||
* @todo refactor to not call backend so much, see useEffect above
|
||||
*/
|
||||
const getInterviewDates = async () => {
|
||||
const res = await fetch(
|
||||
"https://bajabackend.bajacloud.duckdns.org/getAppointments",
|
||||
{ method: "GET" }
|
||||
);
|
||||
// const res = await fetch(
|
||||
// "http://127.0.0.1:8000/getAppointments",
|
||||
// { method: "GET" }
|
||||
// );
|
||||
let json = await res.json();
|
||||
// console.log(json);
|
||||
// can input dates right away, no other requirements to show it
|
||||
let dates = await json["body"]["interviewDates"];
|
||||
setAllDatesAvailable(await dates);
|
||||
};
|
||||
|
||||
// helper section
|
||||
// helper section
|
||||
|
||||
/**
|
||||
* @param {Date} date - Takes in a date object from the date picker
|
||||
* @returns {null} null - Returns in nothing
|
||||
* @description checks if date is available from the backend
|
||||
* @author Brock <darkicewolf50@gmail.com>
|
||||
*/
|
||||
const isDateAvailable = (date) => {
|
||||
return Object.keys(allDatesAvailable).includes(
|
||||
date.toISOString().split("T")[0]
|
||||
);
|
||||
};
|
||||
/**
|
||||
* @param {Date} date - Takes in a date object from the date picker
|
||||
* @returns {null} null - Returns in nothing
|
||||
* @description checks if date is available from the backend
|
||||
* @author Brock <darkicewolf50@gmail.com>
|
||||
*/
|
||||
const isDateAvailable = (date) => {
|
||||
return Object.keys(allDatesAvailable).includes(
|
||||
date.toISOString().split("T")[0]
|
||||
);
|
||||
};
|
||||
|
||||
const handleDateChange = (date) => {
|
||||
setSelectedDate(date); // Capture the selected date in date object
|
||||
const selectedDateStr = date.toISOString().split("T")[0];
|
||||
const handleDateChange = (date) => {
|
||||
setSelectedDate(date); // Capture the selected date in date object
|
||||
const selectedDateStr = date.toISOString().split("T")[0];
|
||||
|
||||
// get and set time slots for a given day
|
||||
setTimeSlotsAvialable(Object.keys(allDatesAvailable[selectedDateStr]));
|
||||
setSelectedTime(""); // clear because of date change
|
||||
};
|
||||
// get and set time slots for a given day
|
||||
setTimeSlotsAvialable(Object.keys(allDatesAvailable[selectedDateStr]));
|
||||
setSelectedTime(""); // clear because of date change
|
||||
// set prematurely for better error messages
|
||||
onTimeSlotSelect({
|
||||
date: selectedDateStr,
|
||||
startTime: selectedTime,
|
||||
});
|
||||
};
|
||||
|
||||
const handleTimeSlotChange = (e) => {
|
||||
let startTime = e.target.innerHTML;
|
||||
setSelectedTime(startTime);
|
||||
const handleTimeSlotChange = (e) => {
|
||||
e.currentTarget.id = "CurrentSelected";
|
||||
|
||||
onTimeSlotSelect({
|
||||
date: selectedDate.toLocaleDateString(),
|
||||
startTime: selectedTime,
|
||||
});
|
||||
};
|
||||
if (selectedTimeButton !== null) {
|
||||
selectedTimeButton.id = "";
|
||||
}
|
||||
setSelectedTimeButton(e.currentTarget);
|
||||
|
||||
return (
|
||||
<div id="TimeSlotSelector">
|
||||
{Object.keys(allDatesAvailable).length > 0 ? (
|
||||
<>
|
||||
<div className="TimeSlot">
|
||||
<h4>Interview Date</h4>
|
||||
<label htmlFor="date-picker">
|
||||
<p>Select a Date:</p>
|
||||
</label>
|
||||
<DatePicker
|
||||
selected={selectedDate}
|
||||
onChange={handleDateChange}
|
||||
inline
|
||||
filterDate={isDateAvailable} // Filter/grey out unavailable dates
|
||||
dateFormat="yyyy-MM-dd"
|
||||
required // Make date selection required
|
||||
/>
|
||||
</div>
|
||||
<div className="TimeSlot">
|
||||
<h4>Interview Time</h4>
|
||||
{!selectedDate ? (
|
||||
<>
|
||||
<p>Available Time Slots:</p>
|
||||
<div
|
||||
style={{
|
||||
height: "241.633px",
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
}}
|
||||
>
|
||||
<p>Please select the a date to see time slots.</p>
|
||||
</div>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<label htmlFor="time-picker">
|
||||
<p>
|
||||
Available Time Slots for{" "}
|
||||
{selectedDate.toISOString().split("T")[0]}:
|
||||
</p>
|
||||
</label>
|
||||
{selectedDate === undefined ? (
|
||||
<>
|
||||
<p>Please select a date.</p>
|
||||
</>
|
||||
) : timeSlotsAvialable !== "" ? (
|
||||
<>
|
||||
{Object.values(timeSlotsAvialable).map((time) => {
|
||||
return (
|
||||
<button
|
||||
key={time}
|
||||
type="button"
|
||||
onClick={(self) => {
|
||||
handleTimeSlotChange(self);
|
||||
}}
|
||||
>
|
||||
{time}
|
||||
</button>
|
||||
);
|
||||
})}
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<p>No available time slots for the selected date.</p>
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
{/* {selectedDate && selectedTime && (
|
||||
let startTime = e.currentTarget.dataset.time;
|
||||
setSelectedTime(startTime);
|
||||
|
||||
onTimeSlotSelect({
|
||||
date: selectedDate.toLocaleDateString(),
|
||||
startTime: selectedTime,
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<div id="TimeSlotSelector">
|
||||
{Object.keys(allDatesAvailable).length > 0 ? (
|
||||
<>
|
||||
<div className="TimeSlot">
|
||||
<h4>Interview Date</h4>
|
||||
<label htmlFor="date-picker">
|
||||
<p>Select a Date:</p>
|
||||
</label>
|
||||
<DatePicker
|
||||
selected={selectedDate}
|
||||
onChange={handleDateChange}
|
||||
inline
|
||||
filterDate={isDateAvailable} // Filter/grey out unavailable dates
|
||||
dateFormat="yyyy-MM-dd"
|
||||
required // Make date selection required
|
||||
/>
|
||||
</div>
|
||||
<div className="TimeSlot">
|
||||
<h4>Interview Time</h4>
|
||||
{!selectedDate ? (
|
||||
<>
|
||||
<p>Available Time Slots:</p>
|
||||
<div
|
||||
style={{
|
||||
height: "241.633px",
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
}}>
|
||||
<p>Please select the a date to see time slots.</p>
|
||||
</div>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<label htmlFor="time-picker">
|
||||
<p>
|
||||
Available Time Slots for{" "}
|
||||
{selectedDate.toISOString().split("T")[0]}:
|
||||
</p>
|
||||
</label>
|
||||
{selectedDate === undefined ? (
|
||||
<>
|
||||
<p>Please select a date.</p>
|
||||
</>
|
||||
) : timeSlotsAvialable !== "" ? (
|
||||
<>
|
||||
{Object.values(timeSlotsAvialable).map((time) => {
|
||||
// console.log(timeSlotsAvialable.indexOf(time));
|
||||
return (
|
||||
<button
|
||||
className={
|
||||
"TimeSlotSide" +
|
||||
(timeSlotsAvialable.indexOf(time) % 2)
|
||||
}
|
||||
key={time}
|
||||
type="button"
|
||||
data-time={time}
|
||||
onClick={handleTimeSlotChange}>
|
||||
{time.slice(0, 5)}
|
||||
</button>
|
||||
);
|
||||
})}
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<p>No available time slots for the selected date.</p>
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
{/* {selectedDate && selectedTime && (
|
||||
<div>
|
||||
<p>
|
||||
You have selected:
|
||||
@ -150,10 +172,10 @@ export default function TimeDateSelector({
|
||||
Time: {selectedTime}
|
||||
</p>
|
||||
</div>)} */}
|
||||
</>
|
||||
) : (
|
||||
<p>Loading ...</p>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
</>
|
||||
) : (
|
||||
<p id="interviewLoading">Loading ...</p>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user