import React, {useEffect, useState} from "react";
import "../styles/course.css";
import "../styles/modal.css";
import "../styles/extendsurvey.css";
import "../styles/deletesurvey.css";
import "../styles/duplicatesurvey.css";
import "../styles/addsurvey.css";
import Modal from "./Modal";
import Toast from "./Toast";
import ViewResults from "./ViewResults";
import {RadioButton} from "primereact/radiobutton";
import Team from "../assets/pairingmodes/TEAM.png"
import TeamSelf from "../assets/pairingmodes/TEAM+SELF.png"
import TeamSelfManager from "../assets/pairingmodes/TEAM+SELF+MANAGER.png"
import PM from "../assets/pairingmodes/PM.png"
import SinglePairs from "../assets/pairingmodes/SinglePairs.png"
// import SurveyForm from "./pages/SurveyForm"
import { Link, NavLink } from "react-router-dom";
import { useNavigate } from "react-router-dom";
/**
* @component
* @param {Object} course
* @param {String} page // What page the component is being used on. Either Home or History
* @returns
*/
const Course = ({course, page}) => {
const [surveys, setSurveys] = useState([]);
/**
* Perform a POST call to courseSurveysQueries
*/
function updateAllSurveys() {
fetch(process.env.REACT_APP_API_URL + "courseSurveysQueries.php", {
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
body: new URLSearchParams({
"course-id": course.id,
}),
})
.then((res) => res.json())
.then((result) => {
console.log(result);
const activeSurveys = result.active.map((survey_info) => ({
...survey_info,
expired: false,
}));
console.log(result);
const expiredSurveys = result.expired.map((survey_info) => ({
...survey_info,
expired: true,
}));
const upcomingSurveys = result.upcoming.map((survey_info) => ({
...survey_info,
expired: false,
}));
console.log(result);
setSurveys([...activeSurveys, ...expiredSurveys, ...upcomingSurveys]);
})
.catch((err) => {
console.log(err);
});
}
// MODAL CODE
const [actionsButtonValue, setActionsButtonValue] = useState("");
const [currentSurveyEndDate, setCurrentSurveyEndDate] = useState("");
const [extendModal, setExtendModal] = useState(false);
const [duplicateModal, setDuplicateModel] = useState(false);
const [emptyOrWrongDeleteNameError, setemptyOrWrongDeleteNameError] =
useState(false);
const [deleteModal, setDeleteModal] = useState(false);
const [modalIsOpen, setModalIsOpen] = useState(false);
const [modalIsOpenError, setModalIsOpenError] = useState(false);
const [errorsList, setErrorsList] = useState([]);
const [modalIsOpenSurveyConfirm, setModalIsOpenSurveyConfirm] =
useState(false);
const [showUpdateModal, setShowUpdateModal] = useState(false);
const [currentSurvey, setCurrentSurvey] = useState("");
const [showViewResultsModal, setViewResultsModal] = useState(false);
const [viewingCurrentSurvey, setViewingCurrentSurvey] = useState(null);
const [rosterFile, setRosterFile] = useState(null);
const [updateRosterOption, setUpdateRosterOption] = useState("replace");
const [updateRosterError, setUpdateRosterError] = useState([]);
const [showErrorModal, setShowErrorModal] = useState(false);
const [showToast, setShowToast] = useState(false);
const [rubricNames, setNames] = useState([]);
const [rubricIDandDescriptions, setIDandDescriptions] = useState([]);
const [pairingModesFull, setPairingModesFull] = useState([]);
const [pairingModesNames, setPairingModesNames] = useState([]);
const [RosterArray, setRosterArray] = useState([]);
const [NonRosterArray, setNonRosterArray] = useState([]);
//START:Error codes for modal frontend
const [emptySurveyNameError, setEmptyNameError] = useState(false);
const [emptyStartTimeError, setEmptyStartTimeError] = useState(false);
const [emptyEndTimeError, setEmptyEndTimeError] = useState(false);
const [emptyStartDateError, setEmptyStartDateError] = useState(false);
const [emptyEndDateError, setEmptyEndDateError] = useState(false);
const [emptyCSVFileError, setEmptyCSVFileError] = useState(false);
const [startDateBoundError, setStartDateBoundError] = useState(false);
const [startDateBound1Error, setStartDateBound1Error] = useState(false);
const [endDateBoundError, setEndDateBoundError] = useState(false);
const [endDateBound1Error, setEndDateBound1Error] = useState(false);
const [StartAfterCurrentError, setStartAfterCurrentError] = useState(false);
const [StartDateGreaterError, setStartDateGreaterError] = useState(false);
const [StartTimeSameDayError, setStartTimeSameDayError] = useState(false);
const [StartHourSameDayError, setStartHourSameDayError] = useState(false);
const [StartHourAfterEndHourError, setStartHourAfterEndHourError] =
useState(false);
const [StartTimeHoursBeforeCurrent, setStartTimeHoursBeforeCurrent] =
useState(false);
const [StartTimeMinutesBeforeCurrent, setStartTimeMinutesBeforeCurrent] =
useState(false);
//END:Error codes for modal frontend
const [surveyNameConfirm, setSurveyNameConfirm] = useState();
const [rubricNameConfirm, setRubricNameConfirm] = useState();
const [startDateConfirm, setStartDateConfirm] = useState();
const [endDateConfirm, setEndDateConfirm] = useState();
const updateRosterformData = new FormData();
/**
* Perform a GET call to rubricsGet.php to fetch names and ID of the rubrics.
*/
const fetchRubrics = () => {
fetch(process.env.REACT_APP_API_URL + "rubricsGet.php", {
method: "GET",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
})
.then((res) => res.json())
.then((result) => {
//this is an array of objects of example elements {rubricId: 1, rubricDesc: 'exampleDescription'}
let rubricIDandDescriptions = result.rubrics.map((element) => element);
//An array of just the rubricDesc
let rubricNames = result.rubrics.map((element) => element.rubricDesc);
setNames(rubricNames);
setIDandDescriptions(rubricIDandDescriptions);
})
.catch((err) => {
console.log(err);
});
};
/**
* Perform a GET call to surveryTypesGet.php to fetch pairing modes for each surver, stored in pairingModesFull and pairingModesNames
*/
const fetchPairingModes = () => {
fetch(process.env.REACT_APP_API_URL + "surveyTypesGet.php", {
method: "GET",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
})
.then((res) => res.json())
.then((result) => {
let allPairingModeArray = result.survey_types.mult.concat(
result.survey_types.no_mult
);
let pairingModeNames = allPairingModeArray.map(
(element) => element.description
);
let pairingModeFull1 = result.survey_types;
setPairingModesFull(pairingModeFull1);
setPairingModesNames(pairingModeNames);
})
.catch((err) => {
console.log(err);
});
};
const openModal = () => {
setModalIsOpen(true);
fetchRubrics();
fetchPairingModes();
};
const closeModal = () => {
setModalIsOpen(false);
setEmptyNameError(false);
setEmptyStartTimeError(false);
setEmptyEndTimeError(false);
setEmptyStartDateError(false);
setEmptyEndDateError(false);
setEmptyCSVFileError(false);
setStartDateBoundError(false);
setStartDateBound1Error(false);
setEndDateBoundError(false);
setEndDateBound1Error(false);
setStartAfterCurrentError(false);
setStartDateGreaterError(false);
setStartTimeSameDayError(false);
setStartHourSameDayError(false);
setStartHourAfterEndHourError(false);
setStartTimeHoursBeforeCurrent(false);
setStartTimeMinutesBeforeCurrent(false);
};
const closeModalError = () => {
setModalIsOpenError(false);
};
const closeModalSurveyConfirm = () => {
setModalIsOpenSurveyConfirm(false);
};
const handleErrorModalClose = () => {
setRosterFile(null); // sets the file to null
setShowErrorModal(false); // close the error modal
setShowUpdateModal(true); // open the update modal again
};
const getInitialStateRubric = () => {
const value = "Select Rubric";
return value;
};
const getInitialStatePairing = () => {
const value = "TEAM";
return value;
};
const [valueRubric, setValueRubric] = useState(getInitialStateRubric);
const [valuePairing, setValuePairing] = useState(getInitialStatePairing);
const [multiplierNumber, setMultiplierNumber] = useState("one");
const [validPairingModeForMultiplier, setMultiplier] = useState(false);
const [pairingImage, setPairingImage] = useState(Team);
const handleChangeRubric = (e) => {
setValueRubric(e.target.value);
};
const handleChangeMultiplierNumber = (e) => {
setMultiplierNumber(e.target.value);
};
const handleUpdateImage = (e) => {
console.log(e.target.value);
switch(e.target.value) {
case 'TEAM':
setPairingImage(Team);
break;
case 'TEAM + SELF':
setPairingImage(TeamSelf);
break;
case 'TEAM + SELF + MANAGER':
setPairingImage(TeamSelfManager);
break;
case 'Single Pairs':
setPairingImage(SinglePairs);
break;
case 'PM':
setPairingImage(PM);
break;
default:
console.log('Unexpected pairing mode: ${pairingMode}');
break;
}
}
const handleChangePairing = (e) => {
var boolean = false;
let multiplierCheckArray = pairingModesFull.mult.map(
(element) => element.description
);
if (multiplierCheckArray.includes(e.target.value)) {
boolean = true;
}
handleUpdateImage(e);
setValuePairing(e.target.value);
setMultiplier(boolean);
};
async function fetchRosterNonRoster() {
let fetchHTTP = process.env.REACT_APP_API_URL + "confirmationForSurvey.php";
console.log(fetchHTTP);
//let response = await fetch(fetchHTTP,{method: "POST", body: formData});
try {
const response = await fetch(fetchHTTP, {
method: "GET",
});
const result = await response.json();
return result; // Return the result directly
} catch (err) {
console.log("goes to error");
console.error(err);
throw err; // Re-throw to be handled by the caller
}
}
async function fetchAddSurveyToDatabaseComplete(data) {
console.log(data);
let fetchHTTP = process.env.REACT_APP_API_URL + "confirmationForSurvey.php";
//let response = await fetch(fetchHTTP,{method: "POST", body: formData});
try {
const response = await fetch(fetchHTTP, {
method: "POST",
body: data,
});
const result = await response.json();
console.log(result);
return result; // Return the result directly
} catch (err) {
throw err; // Re-throw to be handled by the caller
}
}
async function confirmSurveyComplete() {
let formData2 = new FormData();
formData2.append("save-survey", "1");
let any = await fetchAddSurveyToDatabaseComplete(formData2);
updateAllSurveys();
closeModalSurveyConfirm();
return;
}
async function getAddSurveyResponse(formData) {
console.log("this is before the addsurveyResponse function fetch call");
let fetchHTTP =
process.env.REACT_APP_API_URL +
"addSurveyToCourse.php?course=" +
course.id;
//let response = await fetch(fetchHTTP,{method: "POST", body: formData});
try {
const response = await fetch(fetchHTTP, {
method: "POST",
body: formData,
});
const result = await response.json();
return result; // Return the result directly
} catch (err) {
console.error(err);
throw err; // Re-throw to be handled by the caller
}
}
async function duplicateSurveyBackend(formdata) {
let fetchHTTP =
process.env.REACT_APP_API_URL +
"duplicateExistingSurvey.php?survey=" +
currentSurvey.id;
//let response = await fetch(fetchHTTP,{method: "POST", body: formData});
try {
const response = await fetch(fetchHTTP, {
method: "POST",
body: formdata,
});
const result = await response.text();
console.log(currentSurvey);
console.log(result);
return result; // Return the result directly
} catch (err) {
console.error(err);
throw err; // Re-throw to be handled by the caller
}
}
async function verifyDuplicateSurvey() {
setEmptyNameError(false);
setEmptyStartTimeError(false);
setEmptyEndTimeError(false);
setEmptyStartDateError(false);
setEmptyEndDateError(false);
setEmptyCSVFileError(false);
setStartDateBoundError(false);
setStartDateBound1Error(false);
setEndDateBoundError(false);
setEndDateBound1Error(false);
setStartAfterCurrentError(false);
setStartDateGreaterError(false);
setStartTimeSameDayError(false);
setStartHourSameDayError(false);
setStartHourAfterEndHourError(false);
setStartTimeHoursBeforeCurrent(false);
setStartTimeMinutesBeforeCurrent(false);
var surveyName = document.getElementById("survey-name").value;
var startTime = document.getElementById("start-time").value;
var endTime = document.getElementById("end-time").value;
var startDate = document.getElementById("start-date").value;
var endDate = document.getElementById("end-date").value;
var rubric = document.getElementById("rubric-type").value;
var dictNameToInputValue = {
"Survey name": surveyName,
"Start time": startTime,
"End time": endTime,
"Start date": startDate,
"End date": endDate,
};
for (let k in dictNameToInputValue) {
if (dictNameToInputValue[k] === "") {
if (k === "Survey name") {
setEmptyNameError(true);
return;
}
if (k === "Start time") {
setEmptyStartTimeError(true);
return;
}
if (k === "End time") {
setEmptyEndTimeError(true);
return;
}
if (k === "Start date") {
setEmptyStartDateError(true);
return;
}
if (k === "End date") {
setEmptyEndDateError(true);
return;
}
}
}
//date and time keyboard typing bound checks.
// let minDateObject = new Date("2023-08-31T00:00:00"); //first day of class
// let maxDateObject = new Date("2023-12-31T00:00:00"); //last day of class
let startDateObject = new Date(startDate + "T00:00:00"); //inputted start date.
let endDateObject = new Date(endDate + "T00:00:00"); //inputted end date.
// if (startDateObject < minDateObject) {
// setStartDateBoundError(true);
// return;
// }
// if (startDateObject > maxDateObject) {
// setStartDateBound1Error(true);
// return;
// }
// if (endDateObject < minDateObject) {
// setEndDateBoundError(true);
// return;
// }
// if (endDateObject > maxDateObject) {
// setStartDateBound1Error(true);
// return;
// }
//END:date and time keyboard typing bound checks.
//special startdate case. Startdate cannot be before the current day.
let timestamp = new Date(Date.now());
timestamp.setHours(0, 0, 0, 0); //set hours/minutes/seconds/etc to be 0. Just want to deal with the calendar date
if (startDateObject < timestamp) {
setStartAfterCurrentError(true);
return;
}
//END:special startdate case. Startdate cannot be before the current day.
//Start date cannot be greater than End date.
if (startDateObject > endDateObject) {
setStartDateGreaterError(true);
return;
}
//END:Start date cannot be greater than End date.
//If on the same day, start time must be before end time
if (startDate === endDate) {
if (startTime === endTime) {
setStartTimeSameDayError(true);
return;
}
let startHour = parseInt(startTime.split(":")[0]);
let endHour = parseInt(endTime.split(":")[0]);
if (startHour === endHour) {
setStartHourSameDayError(true);
return;
}
if (startHour > endHour) {
setStartHourAfterEndHourError(true);
return;
}
}
//Start time must be after current time if start date is the current day.
if (
startDateObject.getDate(startDateObject) === timestamp.getDate(timestamp)
) {
let timestampWithHour = new Date(Date.now());
let currentHour = timestampWithHour.getHours(timestampWithHour);
let currentMinutes = timestampWithHour.getMinutes(timestampWithHour);
let startHourNew = parseInt(startTime.split(":")[0]);
let startMinutes = parseInt(startTime.split(":")[1]);
if (startHourNew < currentHour) {
setStartTimeHoursBeforeCurrent(true);
return;
}
if (startHourNew === currentHour) {
if (startMinutes < currentMinutes) {
setStartTimeMinutesBeforeCurrent(true);
return;
}
}
//End:Start time must be after current time
}
//Now it's time to send data to the backend
let formData3 = new FormData();
let rubricId;
let pairingId;
let multiplier;
for (const element of rubricIDandDescriptions) {
if (element.rubricDesc === rubric) {
rubricId = element.rubricId;
}
}
formData3.append("survey-id", currentSurvey.id);
formData3.append("survey-name", surveyName);
formData3.append("rubric-id", rubricId);
formData3.append("start-date", startDate);
formData3.append("start-time", startTime);
formData3.append("end-date", endDate);
formData3.append("end-time", endTime);
//form data is set. Call the post request
let awaitedResponse = await duplicateSurveyBackend(formData3);
updateAllSurveys();
closeModalDuplicate();
}
async function verifySurvey() {
setEmptyNameError(false);
setEmptyStartTimeError(false);
setEmptyEndTimeError(false);
setEmptyStartDateError(false);
setEmptyEndDateError(false);
setEmptyCSVFileError(false);
setStartDateBoundError(false);
setStartDateBound1Error(false);
setEndDateBoundError(false);
setEndDateBound1Error(false);
setStartAfterCurrentError(false);
setStartDateGreaterError(false);
setStartTimeSameDayError(false);
setStartHourSameDayError(false);
setStartHourAfterEndHourError(false);
setStartTimeHoursBeforeCurrent(false);
setStartTimeMinutesBeforeCurrent(false);
var surveyName = document.getElementById("survey-name").value;
var startTime = document.getElementById("start-time").value;
var endTime = document.getElementById("end-time").value;
var startDate = document.getElementById("start-date").value;
var endDate = document.getElementById("end-date").value;
var csvFile = document.getElementById("csv-file").value;
var rubric = document.getElementById("rubric-type").value;
var dictNameToInputValue = {
"Survey name": surveyName,
"Start time": startTime,
"End time": endTime,
"Start date": startDate,
"End date": endDate,
"Csv file": csvFile,
};
for (let k in dictNameToInputValue) {
if (dictNameToInputValue[k] === "") {
if (k === "Survey name") {
setEmptyNameError(true);
return;
}
if (k === "Start time") {
setEmptyStartTimeError(true);
return;
}
if (k === "End time") {
setEmptyEndTimeError(true);
return;
}
if (k === "Start date") {
setEmptyStartDateError(true);
return;
}
if (k === "End date") {
setEmptyEndDateError(true);
return;
}
if (k === "Csv file") {
setEmptyCSVFileError(true);
return;
}
}
}
//date and time keyboard typing bound checks.
// let minDateObject = new Date("2023-08-31T00:00:00"); //first day of class
// let maxDateObject = new Date("2023-12-31T00:00:00"); //last day of class
let startDateObject = new Date(startDate + "T00:00:00"); //inputted start date.
let endDateObject = new Date(endDate + "T00:00:00"); //inputted end date.
// if (startDateObject < minDateObject) {
// setStartDateBoundError(true);
// return;
// }
// if (startDateObject > maxDateObject) {
// setStartDateBound1Error(true);
// return;
// }
// if (endDateObject < minDateObject) {
// setEndDateBoundError(true);
// return;
// }
// if (endDateObject > maxDateObject) {
// setStartDateBound1Error(true);
// return;
// }
//END:date and time keyboard typing bound checks.
//special startdate case. Startdate cannot be before the current day.
let timestamp = new Date(Date.now());
timestamp.setHours(0, 0, 0, 0); //set hours/minutes/seconds/etc to be 0. Just want to deal with the calendar date
if (startDateObject < timestamp) {
setStartAfterCurrentError(true);
return;
}
//END:special startdate case. Startdate cannot be before the current day.
//Start date cannot be greater than End date.
if (startDateObject > endDateObject) {
setStartDateGreaterError(true);
return;
}
//END:Start date cannot be greater than End date.
//If on the same day, start time must be before end time
if (startDate === endDate) {
if (startTime === endTime) {
setStartTimeSameDayError(true);
return;
}
let startHour = parseInt(startTime.split(":")[0]);
let endHour = parseInt(endTime.split(":")[0]);
if (startHour === endHour) {
setStartHourSameDayError(true);
return;
}
if (startHour > endHour) {
setStartHourAfterEndHourError(true);
return;
}
}
//Start time must be after current time if start date is the current day.
if (
startDateObject.getDate(startDateObject) === timestamp.getDate(timestamp)
) {
let timestampWithHour = new Date(Date.now());
let currentHour = timestampWithHour.getHours(timestampWithHour);
let currentMinutes = timestampWithHour.getMinutes(timestampWithHour);
let startHourNew = parseInt(startTime.split(":")[0]);
let startMinutes = parseInt(startTime.split(":")[1]);
if (startHourNew < currentHour) {
setStartTimeHoursBeforeCurrent(true);
return;
}
if (startHourNew === currentHour) {
if (startMinutes < currentMinutes) {
setStartTimeMinutesBeforeCurrent(true);
return;
}
}
//End:Start time must be after current time
}
//Now it's time to send data to the backend
let formData = new FormData();
let rubricId;
let pairingId;
let multiplier;
for (const element of rubricIDandDescriptions) {
if (element.rubricDesc === rubric) {
rubricId = element.rubricId;
}
}
for (const element in pairingModesFull.no_mult) {
if (
pairingModesFull.no_mult[element].description ===
document.getElementById("pairing-mode").value
) {
pairingId = pairingModesFull.no_mult[element].id;
console.log(pairingId);
multiplier = 1;
}
}
for (const element in pairingModesFull.mult) {
if (
pairingModesFull.mult[element].description ===
document.getElementById("pairing-mode").value
) {
pairingId = pairingModesFull.mult[element].id;
multiplier = document.getElementById("multiplier-type").value;
console.log("This is the multipler underneath");
console.log(multiplier);
}
}
let file = document.getElementById("csv-file").files[0];
formData.append("survey-name", surveyName);
formData.append("course-id", course.id);
formData.append("rubric-id", rubricId);
formData.append("pairing-mode", pairingId);
formData.append("start-date", startDate);
formData.append("start-time", startTime);
formData.append("end-date", endDate);
formData.append("end-time", endTime);
formData.append("pm-mult", multiplier);
formData.append("pairing-file", file);
//form data is set. Call the post request
let awaitedResponse = await getAddSurveyResponse(formData);
//let errorsObject = errorOrSuccessResponse.errors;
let errorsObject = awaitedResponse.errors;
let dataObject = awaitedResponse.data;
if (errorsObject.length === 0) {
//succesful survey.
let rosterDataAll = await fetchRosterNonRoster();
let rosterData = rosterDataAll.data;
if (rosterData) {
let rostersArrayHere = rosterData["roster-students"];
let nonRosterArrayHere = rosterData["non-roster-students"];
setRosterArray(rostersArrayHere);
setNonRosterArray(nonRosterArrayHere);
setSurveyNameConfirm(surveyName);
setRubricNameConfirm(rubric);
setStartDateConfirm(startDate + " at " + startTime);
setEndDateConfirm(endDate + " at " + endTime);
closeModal();
setModalIsOpenSurveyConfirm(true);
return;
}
return;
}
if (dataObject.length === 0) {
let errorKeys = Object.keys(errorsObject);
let pairingFileStrings = [];
let anyOtherStrings = [];
let i = 0;
while (i < errorKeys.length) {
if (errorKeys[i] === "pairing-file") {
pairingFileStrings = errorsObject["pairing-file"].split("
");
} else {
let error = errorKeys[i];
anyOtherStrings.push(errorsObject[error]);
}
i++;
}
const allErrorStrings = pairingFileStrings.concat(anyOtherStrings);
setErrorsList(allErrorStrings);
closeModal();
setModalIsOpenError(true);
return;
}
return;
}
let Navigate = useNavigate();
const handleActionButtonChange = (e, survey) => {
setActionsButtonValue(e.target.value);
if (e.target.value === "Duplicate") {
fetchRubrics();
setCurrentSurvey(survey);
setDuplicateModel(true);
}
if (e.target.value === "Delete") {
setCurrentSurvey(survey);
setDeleteModal(true);
}
if (e.target.value === "Extend") {
setCurrentSurvey(survey);
setExtendModal(true);
}
if (e.target.value == "View Results") {
handleViewResultsModalChange(survey);
}
if (e.target.value == "Preview Survey") {
Navigate("/SurveyPreview", {state:{survey_name: survey.name, rubric_id: survey.rubric_id, course: course.code}});
console.log(survey.name);
console.log(survey.rubric_id);
console.log(course.code);
}
setActionsButtonValue("");
};
function formatRosterError(input) {
// Split the string into an array on the "Line" pattern, then filter out empty strings
const lines = input
.split(/(Line \d+)/)
.filter((line) => line.trim() !== "");
// Combine adjacent elements so that each "Line #" and its message are in the same element
const combinedLines = [];
for (let i = 0; i < lines.length; i += 2) {
combinedLines.push(lines[i] + (lines[i + 1] || ""));
}
return combinedLines
}
const handleUpdateRosterSubmit = (e) => {
e.preventDefault();
updateRosterformData.append("roster-file", rosterFile);
updateRosterformData.append("course-id", course.id);
updateRosterformData.append("update-type", updateRosterOption);
fetch(process.env.REACT_APP_API_URL + "rosterUpdate.php", {
method: "POST",
body: updateRosterformData,
})
.then((res) => res.text())
.then((result) => {
if (typeof result === "string" && result !== "") {
try {
const parsedResult = JSON.parse(result);
console.log("Parsed as JSON object: ", parsedResult);
if (
parsedResult.hasOwnProperty("error") &&
parsedResult["error"] !== ""
) {
const updatedError = formatRosterError(
parsedResult["error"]
);
setUpdateRosterError(updatedError);
setShowUpdateModal(false); // close the update modal
setShowErrorModal(true); // show the error modal
}
} catch (e) {
console.log("Failed to parse JSON: ", e);
}
} else {
// no error
// Roster is valid to update, so we can close the pop-up modal
setShowUpdateModal(false);
// show toast on success
setShowToast(true);
}
})
.catch((err) => {
console.log(err);
});
};
//MODAL CODE
useEffect(() => {
fetch(process.env.REACT_APP_API_URL + "courseSurveysQueries.php", {
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
body: new URLSearchParams({
"course-id": course.id,
}),
})
.then((res) => res.json())
.then((result) => {
const activeSurveys = result.active.map((survey_info) => ({
...survey_info,
expired: false,
}));
const expiredSurveys = result.expired.map((survey_info) => ({
...survey_info,
expired: true,
}));
const upcomingSurveys = result.upcoming.map((survey_info) => ({
...survey_info,
expired: false,
}));
setSurveys([...activeSurveys, ...expiredSurveys, ...upcomingSurveys]);
})
.catch((err) => {
console.log(err);
});
}, []);
function closeModalDuplicate() {
setDuplicateModel(false);
setEmptyNameError(false);
setEmptyStartTimeError(false);
setEmptyEndTimeError(false);
setEmptyStartDateError(false);
setEmptyEndDateError(false);
setEmptyCSVFileError(false);
setStartDateBoundError(false);
setStartDateBound1Error(false);
setEndDateBoundError(false);
setEndDateBound1Error(false);
setStartAfterCurrentError(false);
setStartDateGreaterError(false);
setStartTimeSameDayError(false);
setStartHourSameDayError(false);
setStartHourAfterEndHourError(false);
setStartTimeHoursBeforeCurrent(false);
setStartTimeMinutesBeforeCurrent(false);
}
async function verifyDeleteBackendGet(id) {
let fetchHTTP =
process.env.REACT_APP_API_URL + "deleteSurvey.php?survey=" + id;
//let response = await fetch(fetchHTTP,{method: "POST", body: formData});
try {
const response = await fetch(fetchHTTP, {
method: "GET",
});
const result = await response.json();
console.log(result);
return result; // Return the result directly
} catch (err) {
throw err; // Re-throw to be handled by the caller
}
}
async function verifyDeleteBackend(formdata, id) {
let fetchHTTP =
process.env.REACT_APP_API_URL + "deleteSurvey.php?survey=" + id;
//let response = await fetch(fetchHTTP,{method: "POST", body: formData});
try {
const response = await fetch(fetchHTTP, {
method: "POST",
body: formdata,
});
const result = await response.json();
console.log(result);
return result; // Return the result directly
} catch (err) {
throw err; // Re-throw to be handled by the caller
}
}
async function extendSurveyBackendGet(id) {
let fetchHTTP =
process.env.REACT_APP_API_URL + "extendSurvey.php?survey=" + id;
//let response = await fetch(fetchHTTP,{method: "POST", body: formData});
try {
const response = await fetch(fetchHTTP, {
method: "GET",
});
const result = await response.text();
console.log(result);
return result; // Return the result directly
} catch (err) {
throw err; // Re-throw to be handled by the caller
}
}
async function extendSurveyBackendPost(id, formdata) {
let fetchHTTP =
process.env.REACT_APP_API_URL + "extendSurvey.php?survey=" + id;
//let response = await fetch(fetchHTTP,{method: "POST", body: formData});
try {
const response = await fetch(fetchHTTP, {
method: "POST",
body: formdata,
});
const result = await response.json();
console.log(result);
return result; // Return the result directly
} catch (err) {
throw err; // Re-throw to be handled by the caller
}
}
const [extendEmptyFieldsError, setExtendEmptyFieldsError] = useState(false);
const [extendStartDateGreater, setExtendStartDateGreater] = useState(false);
const [extendStartHourIsGreater, setExtendStartHourIsGreater] = useState(false);
const [extendMustBeAfterCurrentTime, setExtendMustBeAfterCurrentTime] = useState(false);
const [extendNewEndMustComeAfterOldEnd, setExtendNewEndMustComeAfterOldEnd] = useState(false);
async function verifyExtendModal() {
setExtendEmptyFieldsError(false);
setExtendStartDateGreater(false);
setExtendStartHourIsGreater(false);
setExtendMustBeAfterCurrentTime(false);
setExtendNewEndMustComeAfterOldEnd(false);
let newEndDate = document.getElementById("new-endDate").value;
let newEndTime = document.getElementById("new-endTime").value;
//empty fields check
if (newEndDate === "") {
setExtendEmptyFieldsError(true);
return;
}
if (newEndTime === "") {
setExtendEmptyFieldsError(true);
return;
}
let startDate = currentSurvey.sort_start_date.split(' ')[0]
let currentTime = currentSurvey.sort_start_date.split(' ')[1]
currentTime = currentTime.split(':');
currentTime = currentTime[0] + ':' + currentTime[1];
let startDateTimeObject = new Date(startDate + "T00:00:00"); //inputted start date.
let endDateTimeObject = new Date(newEndDate + "T00:00:00"); //inputted end date.
let timestamp = new Date(Date.now());
timestamp.setHours(0, 0, 0, 0); //set hours/minutes/seconds/etc to be 0. Just want to deal with the calendar date
//if the selected end date occurs in the past error
if (endDateTimeObject < timestamp) {
setExtendMustBeAfterCurrentTime(true);
return;
}
//new end date must come after old end date
let oldEndDate = currentSurvey.sort_expiration_date.split(' ')[0]
let oldEndTimeHours = currentSurvey.sort_expiration_date.split(' ')[1]
oldEndTimeHours = oldEndTimeHours.split(':');
oldEndTimeHours = oldEndTimeHours[0] + ':' + oldEndTimeHours[1];
let oldEndDateTimeObject = new Date(oldEndDate + "T00:00:00")
//conditional to check if old end calendar date isnt ahead of the new one
if (oldEndDateTimeObject > endDateTimeObject) {
setExtendNewEndMustComeAfterOldEnd(true);
return;
}
//conditional to check if new end time hours is greater than old
if (oldEndDateTimeObject.getDate(oldEndDateTimeObject) === endDateTimeObject.getDate(endDateTimeObject)) { //same date new hours should be ahead of old
if (oldEndDateTimeObject.getMonth(oldEndDateTimeObject) === endDateTimeObject.getMonth(endDateTimeObject)) {
if (parseInt(oldEndTimeHours.split(':')[0]) >= parseInt(newEndTime.split(':')[0])) {
console.log('goes through here')
setExtendNewEndMustComeAfterOldEnd(true);
return;
}
}
}
//selected end date is in the current day. Hours and minutes must be after current h/m
if (endDateTimeObject.getDate(endDateTimeObject) === timestamp.getDate(timestamp)) {
if (endDateTimeObject.getMonth(endDateTimeObject) === timestamp.getMonth(timestamp)) {
console.log('goes through here')
let timestampWithHour = new Date(Date.now());
console.log(timestampWithHour)
let currentHour = timestampWithHour.getHours(timestampWithHour);
console.log(currentHour)
let currentMinutes = timestampWithHour.getMinutes(timestampWithHour);
console.log(currentMinutes)
let endHours = parseInt(newEndTime.split(":")[0]);
console.log(endHours)
let endMinutes = parseInt(newEndTime.split(":")[1]);
console.log(endMinutes)
if (endHours < currentHour) {
setExtendMustBeAfterCurrentTime(true);
return;
}
if (endHours === currentHour) {
if (endMinutes <= currentMinutes) {
setExtendMustBeAfterCurrentTime(true);
return;
}
}
}
}
//start date comes after end date error
if (startDateTimeObject > endDateTimeObject) {
setExtendStartDateGreater(true);
return
}
// same date. End date hours must be ahead
if (startDateTimeObject === endDateTimeObject) {
console.log('goes through hour check');
console.log(currentTime);
console.log(newEndTime);
//hour check. Start date hour must be less than end date hour
if (parseInt(currentTime.split(':')[0]) >= parseInt(newEndTime.split(':')[0])) {
setExtendStartHourIsGreater(true);
return;
}
}
let surveyId = currentSurvey.id;
let formData5 = new FormData();
formData5.append('survey-id', surveyId);
formData5.append('end-date', newEndDate);
formData5.append('end-time', newEndTime);
formData5.append('rubric-id', currentSurvey.rubric_id)
formData5.append('start-date', currentSurvey.sort_start_date.split(' ')[0]);
formData5.append("start-time", currentTime);
let pre = await extendSurveyBackendGet(surveyId);
let post = await extendSurveyBackendPost(surveyId, formData5);
if (
post.errors["end-date"] ||
post.errors["end-time"] ||
post.errors["start-date"] ||
post.errors["start-time"]
) {
//there are errors
let errorList = [];
if (post.errors["end-date"]) {
errorList.push(post.errors["end-date"]);
}
if (post.errors["start-date"]) {
errorList.push(post.errors["start-date"]);
}
if (post.errors["end-time"]) {
errorList.push(post.errors["end-time"]);
}
if (post.errors["start-time"]) {
errorList.push(post.errors["start-time"]);
}
extendModalClose();
setErrorsList(errorList);
setModalIsOpenError(true);
return;
}
updateAllSurveys();
extendModalClose();
}
async function verifyDelete() {
setemptyOrWrongDeleteNameError(false);
let inputtedText = document.getElementById("delete-name").value;
if (inputtedText !== currentSurvey.name) {
setemptyOrWrongDeleteNameError(true);
} else {
let form = new FormData();
form.append("agreement", 1);
let surveyId = currentSurvey.id;
let pre = await verifyDeleteBackendGet(surveyId);
let final = await verifyDeleteBackend(form, surveyId);
updateAllSurveys();
deleteModalClose();
}
}
function extendModalClose() {
setExtendModal(false);
setExtendEmptyFieldsError(false);
setExtendStartDateGreater(false);
setExtendStartHourIsGreater(false);
setExtendMustBeAfterCurrentTime(false);
setExtendNewEndMustComeAfterOldEnd(false);
}
function deleteModalClose() {
setemptyOrWrongDeleteNameError(false);
setDeleteModal(false);
}
const handleUpdateModalChange = () => {
setShowUpdateModal((prev) => !prev);
};
const handleViewResultsModalChange = (survey) => {
setViewResultsModal((prev) => !prev);
setViewingCurrentSurvey(survey);
};
return (
Name | Reviewing Others | Being Reviewed | |||
---|---|---|---|---|---|
{entry.student_email} | {entry.student_name} | {entry.reviewing ?Yes | :No | } {entry.reviewed ?Yes | :No | }
Name | Reviewing Others | Being Reviewed | |||
---|---|---|---|---|---|
{entry.student_email} | {entry.student_name} | {entry.reviewing ?Yes | :No | } {entry.reviewed ?Yes | :No | }
Survey Name | Dates Available | Completion Rate | Survey Actions |
---|---|---|---|
{survey.name} |
Begins: {survey.start_date}
Ends: {survey.end_date} |
{survey.completion} | {page === "home" ? ( ) : page === "history" ? ( ) : null} {/* Add more options as needed */} |
{err}
)) }