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
@ -82,3 +82,41 @@
|
|||||||
padding-right: var(--interviewspacing);
|
padding-right: var(--interviewspacing);
|
||||||
width: 80%;
|
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 { useState, useRef } from "react";
|
||||||
import TimeDateSelector from "./TimeDateSelector"; // Import the TimeSlotSelector component
|
import TimeDateSelector from "./TimeDateSelector";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {null} null - Takes in nothing
|
* @param {null} null - Takes in nothing
|
||||||
@ -18,18 +18,19 @@ const InterviewForm = () => {
|
|||||||
/**
|
/**
|
||||||
* @param {String HTML} event - Takes in form info
|
* @param {String HTML} event - Takes in form info
|
||||||
* @returns {null} null - Returns in nothing
|
* @returns {null} null - Returns in nothing
|
||||||
* @description
|
* @description submits the form with the appropriate information
|
||||||
* @author Ahmad <ahmadmuhammadofficial@gmail.com>
|
* @author Ahmad <ahmadmuhammadofficial@gmail.com>
|
||||||
* @todo CSS
|
* @todo imporper email and other erros from backend
|
||||||
*/
|
*/
|
||||||
const formsubmit = async (event) => {
|
const formsubmit = async (event) => {
|
||||||
|
const errorLine = document.getElementById("InterviewError");
|
||||||
|
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
|
||||||
if (!selectedTimeSlot) {
|
if (selectedTimeSlot) {
|
||||||
alert("Please select a time slot!");
|
console.log(selectedTimeSlot);
|
||||||
return;
|
if (selectedTimeSlot.date !== null && selectedTimeSlot.startTime !== "") {
|
||||||
}
|
errorLine.innerHTML = " ";
|
||||||
|
|
||||||
// disable button to stop multiple requests
|
// disable button to stop multiple requests
|
||||||
setIsButtonDisabled(true);
|
setIsButtonDisabled(true);
|
||||||
|
|
||||||
@ -39,6 +40,7 @@ const InterviewForm = () => {
|
|||||||
formObject.date = selectedTimeSlot["date"]; // Add the selected time slot to form data
|
formObject.date = selectedTimeSlot["date"]; // Add the selected time slot to form data
|
||||||
formObject.startTime = selectedTimeSlot["startTime"];
|
formObject.startTime = selectedTimeSlot["startTime"];
|
||||||
console.log("Form Data:", formObject);
|
console.log("Form Data:", formObject);
|
||||||
|
|
||||||
const res = await fetch(
|
const res = await fetch(
|
||||||
"https://bajabackend.bajacloud.duckdns.org/SelectInterview",
|
"https://bajabackend.bajacloud.duckdns.org/SelectInterview",
|
||||||
{
|
{
|
||||||
@ -67,10 +69,36 @@ const InterviewForm = () => {
|
|||||||
} else {
|
} else {
|
||||||
setGetTimeDates(getTimeDates + "i");
|
setGetTimeDates(getTimeDates + "i");
|
||||||
}
|
}
|
||||||
|
x;
|
||||||
|
} else {
|
||||||
|
formSubmitTimeErorrs(selectedTimeSlot, errorLine);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
formSubmitTimeErorrs(selectedTimeSlot, errorLine);
|
||||||
|
}
|
||||||
setIsButtonDisabled(false);
|
setIsButtonDisabled(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @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 (
|
return (
|
||||||
<>
|
<>
|
||||||
<form onSubmit={formsubmit}>
|
<form onSubmit={formsubmit}>
|
||||||
@ -120,9 +148,13 @@ const InterviewForm = () => {
|
|||||||
out an alternate interview time or for rescheduling.
|
out an alternate interview time or for rescheduling.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p id="InterviewError"> </p>
|
<p id="InterviewError"> </p>
|
||||||
|
|
||||||
<div id="InterviewSubmit">
|
<div id="InterviewSubmit">
|
||||||
<button type="submit" disabled={isButtonDisabled}>
|
<button
|
||||||
|
type="submit"
|
||||||
|
disabled={isButtonDisabled}>
|
||||||
Submit
|
Submit
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
@ -2,6 +2,13 @@ import React, { useState, useEffect } from "react";
|
|||||||
import DatePicker from "react-datepicker";
|
import DatePicker from "react-datepicker";
|
||||||
import "react-datepicker/dist/react-datepicker.css";
|
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({
|
export default function TimeDateSelector({
|
||||||
onTimeSlotSelect,
|
onTimeSlotSelect,
|
||||||
timeDateSelectorGet,
|
timeDateSelectorGet,
|
||||||
@ -10,6 +17,7 @@ export default function TimeDateSelector({
|
|||||||
const [selectedDate, setSelectedDate] = useState(null);
|
const [selectedDate, setSelectedDate] = useState(null);
|
||||||
const [timeSlotsAvialable, setTimeSlotsAvialable] = useState([]);
|
const [timeSlotsAvialable, setTimeSlotsAvialable] = useState([]);
|
||||||
const [selectedTime, setSelectedTime] = useState("");
|
const [selectedTime, setSelectedTime] = useState("");
|
||||||
|
const [selectedTimeButton, setSelectedTimeButton] = useState(null);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
getInterviewDates();
|
getInterviewDates();
|
||||||
@ -59,10 +67,22 @@ export default function TimeDateSelector({
|
|||||||
// get and set time slots for a given day
|
// get and set time slots for a given day
|
||||||
setTimeSlotsAvialable(Object.keys(allDatesAvailable[selectedDateStr]));
|
setTimeSlotsAvialable(Object.keys(allDatesAvailable[selectedDateStr]));
|
||||||
setSelectedTime(""); // clear because of date change
|
setSelectedTime(""); // clear because of date change
|
||||||
|
// set prematurely for better error messages
|
||||||
|
onTimeSlotSelect({
|
||||||
|
date: selectedDateStr,
|
||||||
|
startTime: selectedTime,
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleTimeSlotChange = (e) => {
|
const handleTimeSlotChange = (e) => {
|
||||||
let startTime = e.target.innerHTML;
|
e.currentTarget.id = "CurrentSelected";
|
||||||
|
|
||||||
|
if (selectedTimeButton !== null) {
|
||||||
|
selectedTimeButton.id = "";
|
||||||
|
}
|
||||||
|
setSelectedTimeButton(e.currentTarget);
|
||||||
|
|
||||||
|
let startTime = e.currentTarget.dataset.time;
|
||||||
setSelectedTime(startTime);
|
setSelectedTime(startTime);
|
||||||
|
|
||||||
onTimeSlotSelect({
|
onTimeSlotSelect({
|
||||||
@ -99,8 +119,7 @@ export default function TimeDateSelector({
|
|||||||
height: "241.633px",
|
height: "241.633px",
|
||||||
display: "flex",
|
display: "flex",
|
||||||
alignItems: "center",
|
alignItems: "center",
|
||||||
}}
|
}}>
|
||||||
>
|
|
||||||
<p>Please select the a date to see time slots.</p>
|
<p>Please select the a date to see time slots.</p>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
@ -119,15 +138,18 @@ export default function TimeDateSelector({
|
|||||||
) : timeSlotsAvialable !== "" ? (
|
) : timeSlotsAvialable !== "" ? (
|
||||||
<>
|
<>
|
||||||
{Object.values(timeSlotsAvialable).map((time) => {
|
{Object.values(timeSlotsAvialable).map((time) => {
|
||||||
|
// console.log(timeSlotsAvialable.indexOf(time));
|
||||||
return (
|
return (
|
||||||
<button
|
<button
|
||||||
|
className={
|
||||||
|
"TimeSlotSide" +
|
||||||
|
(timeSlotsAvialable.indexOf(time) % 2)
|
||||||
|
}
|
||||||
key={time}
|
key={time}
|
||||||
type="button"
|
type="button"
|
||||||
onClick={(self) => {
|
data-time={time}
|
||||||
handleTimeSlotChange(self);
|
onClick={handleTimeSlotChange}>
|
||||||
}}
|
{time.slice(0, 5)}
|
||||||
>
|
|
||||||
{time}
|
|
||||||
</button>
|
</button>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
@ -152,7 +174,7 @@ export default function TimeDateSelector({
|
|||||||
</div>)} */}
|
</div>)} */}
|
||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
<p>Loading ...</p>
|
<p id="interviewLoading">Loading ...</p>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user