Skip to content

🖥️ Website Code

Yaremadzulynsky edited this page Jun 30, 2024 · 1 revision

Main Pages

HomePage

The HomePage component is responsible for rendering the home page of a drone management application. It displays a map with registered drones, telemetry data, and a search bar to search for a specific drone.

export default function HomePage(): JSX.Element {

    const {
        selectedDrone,
        setSelectedDrone,
        allRegisteredDrones,
        droneIsolated
    } = useContext(GlobalContext).droneContext;

    const dronesToRender: IFlightData[] = [...allRegisteredDrones];

    return (
        <AuthorizationRequired>
            <HomePageBoilerplate>
                <>
                    <LeftColumnWrapper>
                        <>
                            <h2>
                                <Link to="/data">
                                    {selectedDrone.droneID}
                                </Link>
                            <NavigationBar floatLeft={false}/>
                            </h2>
                            {/*<LogoutButton />*/}
                            {/*<Menu/>*/}

                            <h3 style={{marginBottom: "14px"}}>Telemetry Data</h3>

                            {/* This section displays the telemetry data in a table format */}
                            <TelemetryTable onDataPage={false} flightData={selectedDrone}/>

                            {/* This section allows users to search for a specific drone */}
                            <SearchBar/>
                        </>
                    </LeftColumnWrapper>
                    <RightColumnWrapper>
                        {/* This section displays the map with all registered drones */}
                        <Map mapContainerClassName={"map"} zoom={7} latLng={{lat: 0, lng: 0}}>
                            {droneVisualJSX(dronesToRender, setSelectedDrone, droneIsolated, selectedDrone)}
                        </Map>
                    </RightColumnWrapper>
                </>
            </HomePageBoilerplate>
        </AuthorizationRequired>
    );
}

In the HomePage component:

  • The useContext hook is used to access the GlobalContext and retrieve relevant drone data, such as the selectedDrone, setSelectedDrone, allRegisteredDrones, and droneIsolated.
  • A new array of IFlightData objects is created, called dronesToRender, which contains a shallow copy of allRegisteredDrones.
  • The HomePage component renders the AuthorizationRequired, HomePageBoilerplate, LeftColumnWrapper, and RightColumnWrapper components.
  • Inside the LeftColumnWrapper, a link to the drone's data page, the navigation bar, telemetry data table, and search bar are rendered.
  • Inside the RightColumnWrapper, a Map component is rendered with the registered drones displayed on the map using the droneVisualJSX function.

DataPage

The DataPage function component is responsible for rendering the data page of the drone management application. It displays a map with the drone's flight path, telemetry data, a time slider to control the displayed data, and a list of missions.

function DataPage() {
    const {user} = useContext(GlobalContext).authContext;
    if (user === null || user === undefined) {
        console.log("DataPage: props.user: ", user)
        return <Navigate to="/login"/>;
    }

    const navigate = useNavigate();
    const {selectedDrone, setSelectedDrone, allRegisteredDrones} = useContext(GlobalContext).droneContext;
    const dronesToRender: IFlightData[] = [...allRegisteredDrones];
    const [selectedMission, setSelectedMission] = useState<IFlightLog>();
    const [loading, setLoading] = useState<boolean>(true);
    const [time, setTime] = useState<number>(0);

    // ...

    useEffect(() => {
        // ...
    }, []);

    useEffect(() => {
        // ...
    }, [selectedMission]);

    return (
        <div className="ui container">
            <div className="flight-info">
                <h2 style={{display: "flex", justifyContent: "center", padding: "10px"}} id="flightNumber">
                    <Link to="/data">{selectedDrone.droneID} </Link>
                    // ...
                </h2>

                <Map latLng={selectedDrone.coordinate} zoom={7} mapContainerClassName={"dataMap"}>
                    {droneVisualJSX(dronesToRender, setSelectedDrone, true, selectedDrone)}
                    <Path path={pathArray}/>
                </Map>
                {loading ? <div>Loading...</div> :
                    <TimeSlider min={0} max={pathArray.length} step={1} width={"100%"} setTime={setTime}/>}

                {loading ? <div>Loading...</div> :
                    <TelemetryTable onDataPage={true} flightData={flightLog.flightLog[time]}/>}

                <Missions rows={
                    // ...
                } handleClick={
                    (mission) => {
                        setSelectedMission(DataCastHelper.flightLogFromDBToFlightLog(mission));
                        console.log("clicked: " + mission)
                    }
                }/>
            </div>
        </div>
    );
}

In the DataPage component:

  • The useContext hook is used to access the GlobalContext and retrieve the authenticated user and drone data.
  • The component checks if the user is authenticated and redirects to the login page if not.
  • The component uses various useEffect hooks to fetch drone flight data, update the selected drone and mission, and manage the state.
  • The DataPage component renders a map with the drone's flight path using the Map and Path components, and a time slider to control the displayed data.
  • The telemetry data table is rendered with the corresponding flight data.
  • The list of missions is rendered using the Missions component with a click handler to update the selected mission.

SettingsPage

The SettingsPage component allows users to customize display options through a series of checkboxes. This component checks if the user is authenticated and, if not, redirects them to the login page.

/**
 * The SettingsPage component.
 * @returns {JSX.Element} A component containing checkboxes for the user to customize display options.
 */
export default function SettingsPage() {
    // If the user is not authenticated, redirects to the login page.
    const {user} = useContext(GlobalContext).authContext;
    if (user === null || user === undefined) {
        console.log("SettingsPage: user: ", user)
        return <Navigate to="/login"/>;
    }

    const {displayOptions, setDisplayOptions} = useContext(GlobalContext).optionsContext;

    /**
     * Handles the change event of the checkboxes and updates the state with the new value of the changed option.
     * @param {React.FormEvent<HTMLInputElement>} event - The event object generated when the checkbox is changed.
     */
    function onCheckboxChange(event: React.FormEvent<HTMLInputElement>) {
        // ...
    }

    console.log(displayOptions);

    // Return the JSX for the SettingsPage
    return (
        <AuthorizationRequired>
            <div style={{display: 'flex', flexDirection: 'column', alignItems: 'left'}}>
                <NavigationBar floatLeft={true}/>
                <h1 style={{fontSize: '2rem', margin: '2rem'}}>
                    Settings
                </h1>

                <div style={{display: 'flex', flexDirection: 'column', alignItems: 'flex-start', margin: '1rem'}}>
                    {/* Map through displayOptions to render checkboxes */}
                    {displayOptions.map((option) => (
                        // ...
                    ))}
                </div>
            </div>
        </AuthorizationRequired>
    );
}

In the SettingsPage component:

  • The useContext hook is used to access the GlobalContext and retrieve the authenticated user and display options.
  • The component checks if the user is authenticated and redirects to the login page if not.
  • The onCheckboxChange function is defined to handle changes in the state of the checkboxes.
  • The component renders the NavigationBar, a title, and a series of checkboxes based on the displayOptions array. Each checkbox has an onChange event handler that triggers the onCheckboxChange function.

LoginPage Component

The LoginPage component displays a login form and handles user authentication with email and password, or Google Sign-In.

import React, {useContext, useState} from "react";
import styled from "styled-components";
import {Grid} from "semantic-ui-react";
import {GoogleAuthProvider, signInWithEmailAndPassword, signInWithPopup, User} from "firebase/auth";
import {GlobalContext} from "../providers/GlobalProvider";
import {useNavigate} from "react-router-dom";

// Styled components
const LoginPageContainer = styled.div`
  // ...
`;
const LoginPageCard = styled.div`
  // ...
`;
const LoginPageButton = styled.button`
  // ...
`;
const LoginPageInput = styled.input`
  // ...
`;

/**
 * LoginPage component displays a login form and handles user authentication with email and password, or Google Sign-In.
 * @returns {JSX.Element}
 */
export default function LoginPage(): JSX.Element {
    // useState hooks and useContext
    // ...

    const navigate = useNavigate();

    /**
     * Sign in with email and password
     * @param {React.FormEvent<HTMLFormElement>} event - The event object for the form submission
     */
    function signInWithEmailAndPasswordHandler(event: React.FormEvent<HTMLFormElement>): void {
        // ...
    }

    /**
     * Sign in with Google
     */
    function signInWithGoogle(): void {
        // ...
    };

    return (
        <LoginPageContainer>
            <LoginPageCard>
                <Grid columns={3} divided={true}>
                    {/* Form and other elements */}
                    // ...
                </Grid>
            </LoginPageCard>
        </LoginPageContainer>
    );
}

In the LoginPage:

  • Styled-components are used to style the login page, including the container, card, button, and input elements.
  • The useContext hook is used to access the GlobalContext and retrieve authentication-related functions and state.
  • The useNavigate hook from react-router-dom is used for navigation.
  • The signInWithEmailAndPasswordHandler function is defined to handle email and password sign-in.
  • The signInWithGoogle function is defined to handle Google Sign-In.
  • The component renders a form with email and password input fields and buttons for email/password and Google authentication.