Source: pages/History.jsx

import React, {useState, useEffect} from "react";
import SideBar from "../Components/Sidebar";
import Course from "../Components/Course";
import "../styles/home.css";

/**
 * The History component displays a historical list of courses based on term selection.
 * It allows users to view courses they have been involved with in past semesters.
 */

const History = () => {
    const [courses, setCourses] = useState([]); // State for storing courses
    const [terms, setTerms] = useState({}); // State for storing terms and associated courses
    const [currentTerm, setCurrentTerm] = useState(''); // State to track the currently selected term

    /**
     * Updates the currently selected term.
     * @param {string} newValue The new term value to set.
     */
    const updateCurrentTerm = (newValue) => {
        setCurrentTerm(newValue)
    }


    const getCurrentYear = () => {
        const date = new Date();
        return date.getFullYear();
    };

    // Using 2023-2024 course schedule
    /**
     * Determines the current semester based on the current date.
     * @returns {number} The current semester encoded as an integer (1 for Winter, 2 for Spring, 3 for Summer, 4 for Fall).
     */
    const getCurrentSemester = () => {
        const date = new Date();
        const month = date.getMonth(); // 0 for January, 1 for February, etc.
        const day = date.getDate();

        // Summer Sessions (May 30 to Aug 18)
        if (
            (month === 4 && day >= 30) ||
            (month > 4 && month < 7) ||
            (month === 7 && day <= 18)
        ) {
            return 3; // Summer
        }

        // Fall Semester (Aug 28 to Dec 20)
        if (
            (month === 7 && day >= 28) ||
            (month > 7 && month < 11) ||
            (month === 11 && day <= 20)
        ) {
            return 4; // Fall
        }

        // Winter Session (Dec 28 to Jan 19)
        if ((month === 11 && day >= 28) || (month === 0 && day <= 19)) {
            return 1; // Winter
        }

        // If none of the above conditions are met, it must be Spring (Jan 24 to May 19)
        return 2; // Spring
    };

    /**
     * Converts semester names to their corresponding integer codes.
     * @param {string} semester The name of the semester.
     * @returns {number} The integer code of the semester.
     */
    const getSemestermAsInt = (semester) => {
        if (semester === 'fall') {
            return 4;
        } else if (semester === 'summer') {
            return 3;
        } else if (semester === 'spring') {
            return 2;
        } else {
            return 1; // winter
        }
    }

    /**
     * This useEffect hook is triggered on component mount due to the empty dependency array ([]).
     * Its primary role is to fetch historical terms and the courses associated with each term from an API.
     */
    useEffect(() => {
        // First, a fetch request is made to retrieve the terms (e.g., Fall 2023, Spring 2024) for which the instructor has courses.
        fetch(
            process.env.REACT_APP_API_URL + "instructorTermsPost.php",
            {
                method: "POST",
                headers: {
                    "Content-Type": "application/x-www-form-urlencoded",
                },
                body: new URLSearchParams({
                    currentYear: getCurrentYear(),
                    currentSemester: getCurrentSemester(),
                }),
            }
        )
            .then((res) => res.json()) // Parsing the response to JSON format.
            .then((result) => { // Handling the parsed JSON data.
                const all_courses = {} // An object to store courses grouped by their terms.

                // Mapping through each term received from the first API call to fetch courses for those terms.
                const fetchCourses = result.map((term) => {

                    // Constructing a key for each term combining its name and year for easy identification and storage.
                    const term_key = term.semester.charAt(0).toUpperCase() + term.semester.slice(1) + " " + term.year
                    all_courses[term_key] = []
                    return fetch(
                        process.env.REACT_APP_API_URL + "instructorCoursesInTerm.php",
                        {
                            method: "POST",
                            headers: {
                                "Content-Type": "application/x-www-form-urlencoded",
                            },
                            body: new URLSearchParams({
                                semester: getSemestermAsInt(term.semester),
                                year: parseInt(term.year),
                            }),
                        }
                    )
                        .then((res2) => res2.json())
                        .then((result2) => {
                            all_courses[term_key].push(...result2)
                        })
                        .catch(err => {
                            console.log(err)
                        })

                });

                Promise.all(fetchCourses)
                    .then(() => {

                        const courses_only = Object.values(all_courses).flat(); // Update the terms state with all terms and courses
                        setTerms(all_courses)
                        setCourses(courses_only); // Update the courses state with all courses
                    })
                    .catch(err => {
                        console.log(err);
                    });


            })
            .catch(err => {
                console.log(err)
            })
    }, []);

    // Prepare content for the Sidebar component
    const sidebar_content = {
        Terms: Object.entries(terms).length > 0 ? Object.fromEntries(Object.entries(terms)) : [],
        Courses: courses.length > 0 ? courses.map((course) => course.code) : [],
    };

    return (
        <>
            <SideBar route="/history" content_dictionary={sidebar_content} currentTerm={currentTerm}
                     updateCurrentTerm={updateCurrentTerm}/>
            <div className="container home--container">
                {currentTerm !== "" && Object.entries(terms).length > 0 ? (
                    Object.entries(terms).map(([term, courses]) => (
                        term === currentTerm ? (
                                <div key={term} className="containerOfCourses">
                                    {courses.length > 0 ? (
                                        courses.map((course) => (
                                            <Course key={course.id} course={course} page="history"/>
                                        ))
                                    ) : (
                                        <div className="no-course">
                                            <h1>No Courses Found</h1>
                                        </div>
                                    )}
                                </div>
                            ) :
                            null
                    ))
                ) : (
                    <div className="termContainer">
                        <div className="termContent">
                            {currentTerm === "" && Object.entries(terms).length > 0 ? <h1>No Terms Selected</h1> :
                                <h1>No Terms Found</h1>}
                        </div>
                    </div>
                )}
            </div>
        </>
    );
};

export default History;