Source: HomePage.js

/**
 * @module HomePage
 */
import React, { useState, useEffect } from 'react';
import TrashImage from './assets/trash.png';
import AddAreaImage from "./assets/add.png";
import LogoImage from "./assets/logo.png";
import LogoSpotify from "./assets/spotify.png"
import LogoIss from "./assets/iss.png"
import LogoStrava from './assets/strava.png';
import LogoTwitch from './assets/twitch.png';
import LogoTwitter from './assets/twitter.png';
import LogoGoogle from './assets/google.png';
import LogoMeteo from './assets/meteo.png';
import LogoNasa from './assets/nasa.png';
import SettingsImage from "./assets/avatar.png";
import { useNavigate } from "react-router-dom"
import { authWithCache } from './Common/Login'
import Popup from 'reactjs-popup';

/**
 * @brief Return the Home page for AREA
 * This page will be updated soon
 */
export default function HomePage(props) {
    const [asked, setAsked] = useState(false)
    const [location, setLocation] = useState({ latitude: props.userInformation.coord.latitude, longitude: props.userInformation.coord.longitude, city: props.userInformation.coord.city })
    const navigate = useNavigate();

    let logo = {
        "spotify": LogoSpotify,
        "iss": LogoIss,
        "nasa": LogoNasa,
        "twitter": LogoTwitter,
        "google": LogoGoogle,
        "météo": LogoMeteo,
        "twitch": LogoTwitch,
        "strava": LogoStrava
    }

    const addArea = () => {
        navigate('/addArea')
    }

    const goSettings = () => {
        navigate('/settings')
    }

    useEffect(() => {
        try {
            authWithCache(props.setUserInformation, props);
            console.log("Already logged in")
        } catch (error) {
            console.log("Unable to login" + error);
            navigate("/auth")
        }
    }, [])

    useEffect(() => {
        const fetchData = () => {
            console.log(props.userInformation.id)
            fetch(props.userInformation.ip + "/getAreas/" + props.userInformation.id)
                .then(response => {
                    response.json().then(data => {
                        let areaArray = []
                        for (const area in data.areas) {
                            let action = data.areas[area].Action
                            let reaction = data.areas[area].Reaction
                            let id = data.areas[area].id
                            areaArray.push({ action: action, reaction: reaction, id: id })
                        }
                        props.setAllAreas(areaArray)
                    })
                })
                .catch(error => {
                    console.error(error);
                })
        };
        fetchData();
        if (props.userInformation.locationAccept === false && navigator.geolocation) {
            props.userInformation.locationAccept = true
        }
        if (props.userInformation.locationAccept) {
            navigator.geolocation.getCurrentPosition((position) => {
                props.setUserInformation({
                    mail: props.userInformation.mail,
                    locationAccept: props.userInformation.locationAccept,
                    coord: {
                        latitude: position.coords.latitude,
                        longitude: position.coords.longitude,
                        city: props.userInformation.coord.city
                    },
                    id: props.userInformation.id,
                    services: {
                        spotifyId: props.userInformation.services.spotifyId,
                        googleId: props.userInformation.services.googleId,
                        twitterId: props.userInformation.services.twitterId,
                        twitchId: props.userInformation.services.twitchId,
                        stravaId: props.userInformation.services.stravaId
                    },
                    ip: props.userInformation.ip
                })
                setLocation({ latitude: position.coords.latitude, longitude: position.coords.longitude, city: props.userInformation.coord.city })
            })
        }
    }, [props.userInformation.id])

    useEffect(() => {
        if (asked === false) {
            fetch("https://api-adresse.data.gouv.fr/reverse/?lon=" + location.longitude + "&lat=" + location.latitude)
                .then((res) => {
                    res.json()
                        .then((jsonRes) => {
                            if (jsonRes && jsonRes.features && jsonRes.features[0] && jsonRes.features[0].properties) {
                                setLocation({ latitude: location.latitude, longitude: location.longitude, city: jsonRes.features[0].properties.city });
                            } else {
                                setLocation({ latitude: location.latitude, longitude: location.longitude, city: location.city });
                                console.log("Une erreur a été rencontrée en essayant de trouver votre ville à partir de votre localisation. Vos données ont tout de même été mises à jour.")
                            }
                        })
                }).catch((err) => {
                    console.warn("error while fetching city from location: ", err)
                })
            setAsked(true)
            props.setUserInformation({
                mail: props.userInformation.mail,
                locationAccept: props.userInformation.locationAccept,
                coord: {
                    latitude: location.latitude,
                    longitude: location.longitude,
                    city: location.city
                },
                id: props.userInformation.id,
                services: {
                    spotifyId: props.userInformation.services.spotifyId,
                    googleId: props.userInformation.services.googleId,
                    twitterId: props.userInformation.services.twitterId,
                    twitchId: props.userInformation.services.twitchId,
                    stravaId: props.userInformation.services.stravaId
                },
                ip: props.userInformation.ip
            })
        }

    }, [location])
    /**
    * @description Remove an area from the list of areas
    * @function removeAreaFromList
    * @param {*} index The index of the area to remove
    */
    function removeAreaFromList(index) {
        async function supressArea() {
            try {
                const requestOptions = {
                    method: 'POST',
                    headers: { 'Content-Type': 'application/json' },
                    body: JSON.stringify({ uid: props.userInformation.id, id: props.allAreas[index].id })
                }

                await fetch(props.userInformation.ip + "/remove/area", requestOptions).then(response => {
                    if (response.status === 200) {
                        let copyAreas = [...props.allAreas]
                        copyAreas.splice(index, 1)
                        props.setAllAreas(copyAreas)
                    } else {
                        console.log("Error")
                    }
                })
            } catch (error) {
                console.log(error);
            }
        }
        supressArea()
    }

    /**
     * @description Display an area
     * @function DisplayArea
     * @param {*} props The props of the area
     * @returns The area to display
     */
    function DisplayArea(props) {
        const title = (props.area.title) ? props.area.title : "AREA " + props.index;
        const action = (props.area.action) ? props.area.action : "Action";
        const reaction = (props.area.reaction) ? props.area.reaction : "Reaction";
        const global = {
            position: "relative",
            backgroundColor: "lightgrey",
            padding: "10px",
            borderRadius: "10px",
            diplsay: "flex",
            flexDirection: "column",
            alignItems: "center",
            justifyContent: "center",
            textAlign: "center",
            opacity: "0.9",

            title: {
                fontSize: "20px",
                fontWeight: "bold",
            },
            action: {
                fontSize: "15px",
            },
            reaction: {
                fontSize: "15px",
            },
            trash: {
                position: "relative",
                width: "30px",
                height: "30px",
                cursor: "pointer",
                border: "1px solid black",
                borderRadius: "20%",
            }

        }
        return (
            <div style={global}>
                <div style={global.title}>{title}</div>
                <div style={global.action}>{action.description}.</div>
                <div style={global.reaction}>{reaction.description}.</div>
                <img src={TrashImage} alt={"trash image"} style={global.trash} onClick={() => removeAreaFromList(props.index)} />
            </div>
        )
    }

    /**
     * @description Display the list of areas
     * @function DisplayAreas
     * @param {*} props The props of the list of areas
     * @returns The area block to display
     */
    function AreaBlock(props) {
        const title = (props.area.title) ? props.area.title : "AREA ";
        const actionLogo = (props.area.action.logo) ? props.area.action.logo : "https://www.flaticon.com/svg/static/icons/svg/25/25231.svg";
        const reactionLogo = (props.area.reaction.logo) ? props.area.reaction.logo : "https://www.flaticon.com/svg/static/icons/svg/25/25231.svg";
        const style = {
            areaBlock: {
                position: "relative",
                display: "flex",
                flexDirection: "column",
                alignItems: "center",
                backgroundColor: "lightgrey",
                width: "300px",
                height: "400px",
                borderRadius: "20px",
                margin: "10px",
                cursor: "pointer",

                title: {
                    position: "relative",
                    fontSize: "32px",
                    margin: "5px",
                },
                content: {
                    position: "relative",
                    display: "flex",
                    flexDirection: "column",
                    justifyContent: "space-around",
                    alignItems: "center",
                    backgroundColor: "#5281B7",
                    width: "100%",
                    height: "150%",
                    borderRadius: "20px",
                    paddingVertical: "10px",
                },
                trash: {
                    position: "relative",
                    width: "30px",
                    height: "30px",
                    cursor: "pointer",
                    border: "1px solid black",
                    borderRadius: "20%",
                }
            }
        }

        return (
            <div style={style.areaBlock}>
                <div style={{ display: "flex", justifyContent: "space-around", flexDirection: "row", width: "100%" }}>
                    <img src={logo[props.area.action.serviceName]} alt={"Logo de l'action"} style={{ width: "30px", height: "30px", padding: "5px" }} />
                    <p style={style.areaBlock.title}>{title}</p>
                    <img src={logo[props.area.reaction.serviceName]} alt={"Logo de la réaction"} style={{ width: "30px", height: "30px", padding: "5px" }} />
                </div>
                <div style={style.areaBlock.content}>
                    <div style={{ padding: "5px", height: "50px" }}>
                        <p style={{ textAlign: "center", paddingLeft: "10px", paddingRight: "10px", fontSize: 24 }}>{props.area.action.description}</p>
                    </div>
                    <div style={{ padding: "5px", height: "50px" }}>
                        <p style={{ textAlign: "center", paddingLeft: "10px", paddingRight: "10px", fontSize: 24 }}>{props.area.reaction.description}</p>
                    </div>
                    <img src={TrashImage} alt={"trash image"} style={style.areaBlock.trash} onClick={() => removeAreaFromList(props.index)} />
                </div>
            </div>
        )
    }

    /**
     * @description Display the list of areas
     * @function DisplayAreas
     * @returns The list of areas to display
     */
    function DisplayAreas() {
        const style = {
            displayAreas: {
                position: "relative",
                display: "grid",
                gridAutoColumns: "3",
                gridTemplateColumns: "repeat(3, auto)",
                justifyContent: "space-around",
                alignItems: "safe center",
                width: "minmax(300px, 100%)",
                height: "100%",
                padding: "10px",
            },
            noArea: {
                position: "relative",
            }
        }

        if (props.allAreas.length !== 0) {
            return (
                <div style={style.displayAreas}>{
                    props.allAreas.map((item, index) => {
                        return (
                            <AreaBlock area={item} index={index} />
                        )
                    })
                }</div>
            )
        }
        return (
            <div style={style.displayAreas}>
                <h3 style={style.noArea}>Tu n'as pas encore créé d'AREA 🥺</h3>
            </div>
        )
    }

    /**
     * @description Display the header of the page
     * @function Header
     * @returns The header of the page
     */
    function Header() {
        const mail = props.userInformation.mail;
        const [buttonHoverState, setButtonHoverState] = useState(false);
        const style = {
            header: {
                position: "relative",
                display: "flex",
                flexDirection: "row",
                justifyContent: "flex-start",
                alignItems: "center",
                height: "50px",
                padding: "10px",

                logo: {
                    position: "relative",
                    width: "50px",
                    height: "50px",
                    cursor: "pointer",
                },
                title: {
                    position: "relative",
                    paddingLeft: "10px",
                },
                settings: {
                    position: "relative",
                    width: "50px",
                    height: "50px",
                    marginLeft: "auto",
                    borderRadius: "50%",
                    cursor: "pointer",
                },
                button: {
                    all: "unset",
                    position: "relative",
                    border: "1px solid black",
                    padding: "10px",
                    borderRadius: "10px",
                    cursor: "pointer",
                    backgroundColor: buttonHoverState ? "lightgrey" : "transparent",
                }
            },
        }

        function mouseEnterButton() {
            setButtonHoverState(true);
            console.log("mouse enter");
        }
        function mouseLeaveButton() {
            setButtonHoverState(false);
            console.log("mouse leave");
        }
        return (
            <div style={{ position: "relative" }}>
                <div style={style.header}>
                    <img src={LogoImage} style={style.header.logo} alt="logo" />
                    <h1 style={style.header.title}>Re-Bonjour, {(mail) ? mail : "MAIL UNDEFINED"} !</h1>
                    <img src={SettingsImage} style={style.header.settings} onClick={goSettings} alt="settings" />
                </div>
                <div style={{ position: "relative", display: "flex", alignItems: "center", justifyContent: "center" }}>
                    <a style={style.header.button} onMouseEnter={mouseEnterButton} onMouseLeave={mouseLeaveButton} href='client.apk'>Télécharger client.apk</a>
                </div>
            </div>
        )
    }

    /**
     * @description Display the body of the page
     * @function Body
     * @returns The body of the page
     */
    function Body() {
        const style = {
            body: {
                position: "relative",
                display: "flex",
                flexDirection: "column",
                justifyContent: "flex-start",
                alignItems: "center",
                title: {
                    position: "relative",
                    fontSize: "32px",
                },
                addArea: {
                    position: "relative",
                    width: "50px",
                    height: "50px",
                    cursor: "pointer",
                },
            },
        }

        return (
            <div style={style.body}>
                <p style={style.body.title}>AREAS</p>
                <img style={style.body.addArea} src={AddAreaImage} onClick={addArea} alt="addArea" />
                <DisplayAreas />
            </div>
        )
    }
    const globalStyle = {
        position: "relative",
        fontFamily: "Avenir Next,Avenir Next W01, Avenir,helvetica,arial,sans-serif",
    }
    return (
        <div id="global" style={globalStyle}>
            <Header />
            <Body />
        </div>
    )
}