From cbc80198f24da2430f1ea7ce1e048961d6b8f08a Mon Sep 17 00:00:00 2001
From: Luis Felipe Risch <lfr20@inf.ufpr.br>
Date: Fri, 26 Feb 2021 12:06:39 -0300
Subject: [PATCH] Finish to build aprove teacher List

---
 .../Pages/Pages/SubPages/AproveTeacher.js     | 612 ++++++++++++++++++
 1 file changed, 612 insertions(+)
 create mode 100644 src/Admin/Pages/Pages/SubPages/AproveTeacher.js

diff --git a/src/Admin/Pages/Pages/SubPages/AproveTeacher.js b/src/Admin/Pages/Pages/SubPages/AproveTeacher.js
new file mode 100644
index 00000000..22747f11
--- /dev/null
+++ b/src/Admin/Pages/Pages/SubPages/AproveTeacher.js
@@ -0,0 +1,612 @@
+/*Copyright (C) 2019 Centro de Computacao Cientifica e Software Livre
+Departamento de Informatica - Universidade Federal do Parana
+
+This file is part of Plataforma Integrada MEC.
+
+Plataforma Integrada MEC is free software: you can redistribute it and/or modify
+it under the terms of the GNU Affero General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+Plataforma Integrada MEC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU Affero General Public License for more details.
+
+You should have received a copy of the GNU Affero General Public License
+along with Plataforma Integrada MEC.  If not, see <http://www.gnu.org/licenses/>.*/
+
+import React, { useEffect, useState, useContext } from "react";
+import moment from "moment";
+//imports from local files
+import TableData from "../../../Components/Components/Table";
+import SnackBar from "../../../../Components/SnackbarComponent";
+import { Url } from "../../../Filters";
+import { Store } from "../../../../Store";
+import LoadingSpinner from "../../../../Components/LoadingSpinner";
+import { getRequest, postRequest } from "../../../../Components/HelperFunctions/getAxiosConfig";
+//imports from material ui
+import { withStyles } from "@material-ui/core/styles";
+import TableBody from "@material-ui/core/TableBody";
+import TableCell from "@material-ui/core/TableCell";
+import MenuItem from "@material-ui/core/MenuItem";
+import TableRow from "@material-ui/core/TableRow";
+import TextField from "@material-ui/core/TextField";
+import IconButton from "@material-ui/core/IconButton";
+import { Button, Typography, Paper, Grid } from "@material-ui/core";
+import CircularProgress from "@material-ui/core/CircularProgress";
+import AddRoundedIcon from "@material-ui/icons/AddRounded";
+import UpdateRoundedIcon from "@material-ui/icons/UpdateRounded";
+import FilterListRoundedIcon from "@material-ui/icons/FilterListRounded";
+import VisibilityIcon from "@material-ui/icons/Visibility";
+import CheckRoundedIcon from "@material-ui/icons/CheckRounded";
+import CloseRoundedIcon from "@material-ui/icons/CloseRounded";
+//routers
+import { Link } from "react-router-dom";
+import Unauthorized from "../../../Components/Components/Unauthorized";
+
+let currPage = 0;
+let currContentState = "requested";
+let currContentName = "";
+let currContentEmail = "";
+
+const StyledTableCell = withStyles((theme) => ({
+    head: {
+        backgroundColor: theme.palette.common.black,
+        color: theme.palette.common.white,
+    },
+    body: {
+        fontSize: 14,
+    },
+}))(TableCell);
+
+const StyledTableRow = withStyles((theme) => ({
+    root: {
+        "&:nth-of-type(odd)": {
+            backgroundColor: theme.palette.action.hover,
+        },
+    },
+}))(TableRow);
+
+const AproveTeacher = () => {
+    const { state, dispatch } = useContext(Store);
+
+    const ADD_ONE_LENGHT = [""];
+    const TOP_LABELS = [
+        "ESTADO DO PEDIDO",
+        "ID",
+        "NOME",
+        "EMAIL",
+        "PEDIDO EM(MM/DD/YYYY)",
+        "VISUALIZAR",
+        "AÇÕES",
+    ]; //Labels from Table
+
+    const [error, setError] = useState(null); //Necessary to consult the API, catch errors
+    const [isLoaded, setIsLoaded] = useState(false); //Necessary to consult the API, wait until complete
+    const [items, setItems] = useState([]); //Necessary to consult the API, data
+
+    const [isLoadingMoreItems, setIsLoadingMoreItems] = useState(false); //controlls the state of loadind more data
+    const [isUpdating, setIsUpdating] = useState(false); //controlls the state of updating data
+
+    const [showFilter, setShowFilter] = useState(false);
+
+    const [option, setOption] = useState("Pendente");
+    const [name, setName] = useState("");
+    const [email, setEmail] = useState("");
+
+    const [snackInfo, setSnackInfo] = useState({
+        message: "",
+        icon: "",
+        open: false,
+        color: "",
+    });
+
+    const StateOptions = [
+        { id: "requested", name: "Pendente" },
+        { id: "accepted", name: "Aceito" },
+        { id: "rejected", name: "Rejeitado" },
+    ];
+
+    //handle snack info
+    const HandleSnack = (message, state, icon, color) => {
+        setSnackInfo({
+            message: message,
+            icon: icon,
+            open: state,
+            color: color,
+        });
+    };
+
+    const CheckUserPermission = () => {
+        let canUserEdit = false;
+
+        if (state.userIsLoggedIn) {
+            const roles = [...state.currentUser.roles];
+            for (let i = 0; i < roles.length; i++)
+                if (roles[i].name === "admin" || roles[i].name === "editor")
+                    canUserEdit = true;
+        } else {
+            canUserEdit = false;
+        }
+
+        return canUserEdit;
+    };
+
+    //handle load more items
+    const LoadMoreItens = async (api) => {
+        setIsLoadingMoreItems(true);
+        getRequest(
+            api,
+            (data, header) => {
+                const arrData = [...data];
+                if (arrData.length === 0) {
+                    HandleSnack(
+                        "Não há mais dados para serem carregados",
+                        true,
+                        "warning",
+                        "#FFC125"
+                    );
+                } else {
+                    const arrItems = [...items];
+                    arrItems.pop(); //Deleting the last position, that was used to display the button of load more items
+                    const arrResult = arrItems.concat(arrData);
+                    setItems(arrResult.concat(ADD_ONE_LENGHT));
+                }
+                setIsLoadingMoreItems(false);
+            },
+            (error) => {
+                HandleSnack("Erro ao carregar os dados", true, "warning", "#FA8072");
+                setIsLoadingMoreItems(false);
+            }
+        );
+    };
+
+    // handle update list data
+    const UpdateHandler = async (api) => {
+        setIsUpdating(true);
+        getRequest(
+            api,
+            (data, header) => {
+                HandleSnack(
+                    "A lista de dados foi atualizada",
+                    true,
+                    "success",
+                    "#228B22"
+                );
+                const arrData = [...data];
+                setItems(arrData.concat(ADD_ONE_LENGHT));
+                setIsUpdating(false);
+            },
+            (error) => {
+                HandleSnack("Erro ao carregar os dados", true, "warning", "#FA8072");
+                setIsUpdating(false);
+            }
+        );
+    };
+
+    const handleChange = (e, type) => {
+        const value = e.target.value;
+        console.log(e);
+        setOption(value);
+    };
+
+    const ApplyFilter = (id, type) => {
+        currPage = 0;
+        currContentState = id;
+        getRequest(
+            Url(
+                "users",
+                `"submitter_request":"${currContentState}","name":"${currContentName}","email":"${currContentEmail}"`,
+                `${currPage}`,
+                "DESC"
+            ),
+            (data, header) => {
+                const arrData = [...data];
+                setItems(arrData.concat(ADD_ONE_LENGHT));
+                HandleSnack("Filtro aplicado com sucesso", true, "success", "#228B22");
+                setIsLoaded(true);
+            },
+            (error) => {
+                HandleSnack("Erro ao carregar os dados", true, "warning", "#FA8072");
+                setIsLoaded(true);
+            }
+        );
+    };
+
+    const NameHandler = (e) => {
+        currPage = 0;
+        currContentName = e.target.value;
+        getRequest(
+            Url(
+                "users",
+                `"submitter_request":"${currContentState}","name":"${currContentName}","email":"${currContentEmail}"`,
+                `${currPage}`,
+                "DESC"
+            ),
+            (data, header) => {
+                const arrData = [...data];
+                setItems(arrData.concat(ADD_ONE_LENGHT));
+                HandleSnack("Filtro aplicado com sucesso", true, "success", "#228B22");
+                setIsLoaded(true);
+            },
+            (error) => {
+                HandleSnack("Erro ao carregar os dados", true, "warning", "#FA8072");
+                setIsLoaded(true);
+            }
+        );
+    };
+
+    const EmailHandler = (e) => {
+        currPage = 0;
+        currContentEmail = e.target.value;
+        getRequest(
+            Url(
+                "users",
+                `"submitter_request":"${currContentState}","name":"${currContentName}","email":"${currContentEmail}"`,
+                `${currPage}`,
+                "DESC"
+            ),
+            (data, header) => {
+                const arrData = [...data];
+                setItems(arrData.concat(ADD_ONE_LENGHT));
+                HandleSnack("Filtro aplicado com sucesso", true, "success", "#228B22");
+                setIsLoaded(true);
+            },
+            (error) => {
+                HandleSnack("Erro ao carregar os dados", true, "warning", "#FA8072");
+                setIsLoaded(true);
+            }
+        );
+    };
+
+    const ComplaintStatus = (status) => {
+        switch (status) {
+            case "accepted":
+                return (
+                    <Paper
+                        style={{
+                            textAlign: "center",
+                            padding: "0.5em",
+                            backgroundColor: "#228B22",
+                            fontWeight: "500",
+                            color: "#FFFAFA",
+                        }}
+                    >
+                        ACEITO
+                    </Paper>
+                );
+            case "requested":
+                return (
+                    <Paper
+                        style={{
+                            textAlign: "center",
+                            padding: "0.5em",
+                            backgroundColor: "#FF8C00",
+                            fontWeight: "500",
+                            color: "#FFFAFA",
+                        }}
+                    >
+                        PENDENTE
+                    </Paper>
+                );
+            case "rejected":
+                return (
+                    <Paper
+                        style={{
+                            textAlign: "center",
+                            padding: "0.5em",
+                            backgroundColor: "#FA8072",
+                            fontWeight: "500",
+                            color: "#FFFAFA",
+                        }}
+                    >
+                        Rejeitado
+                    </Paper>
+                );
+            default:
+                return (
+                    <Paper
+                        style={{
+                            textAlign: "center",
+                            padding: "0.5em",
+                            backgroundColor: "#797D7F ",
+                            fontWeight: "500",
+                            color: "#FFFAFA",
+                        }}
+                    >
+                        Não requisitado
+                    </Paper>
+                )
+        }
+    };
+
+    const DisplayDate = (date) => {
+        const convertedData = moment.utc(date);
+        return moment(convertedData)
+            .format("LLL")
+            .toString();
+    };
+
+    const handleAprove = (userId, userName) => {
+        const url = `/users/${userId}/add_teacher`
+        const body = {
+            "approves" : true
+        }
+        postRequest(
+            url,
+            body,
+            (data) => {
+                HandleSnack(`${userName} aceito como professor!`, true, "success", "#228B22");
+            },
+            (error) => {
+                HandleSnack("Erro!", true, "warning", "#FA8072");
+            }
+        )
+    }
+
+    const handleReject = (userId, userName) => {
+        const url = `/users/${userId}/add_teacher`
+        const body = {
+            "user" : {
+                "approves" : false
+            }
+        }
+        postRequest(
+            url,
+            body,
+            (data) => {
+                HandleSnack(`${userName} rejeitado como professor!`, true, "success", "#228B22");
+            },
+            (error) => {
+                HandleSnack("Erro!", true, "warning", "#FA8072");
+            }
+        )
+    }
+
+    //getting data from server
+    useEffect(() => {
+        getRequest(
+            Url(
+                "users",
+                `"submitter_request":"${currContentState}","name":"${currContentName}","email":"${currContentEmail}"`,
+                `${currPage}`,
+                "DESC"
+            ),
+            (data, header) => {
+                const arrData = [...data];
+                setItems(arrData.concat(ADD_ONE_LENGHT));
+                setIsLoaded(true);
+                setError(false);
+            },
+            (error) => {
+                HandleSnack("Erro ao carregar os dados", true, "warning", "#FA8072");
+                setIsLoaded(true);
+                setError(true);
+            }
+        );
+    }, []);
+
+    if (error) {
+        return <div>Error: {error.message}</div>;
+    } else if (!isLoaded) {
+        return <LoadingSpinner text="Carregando..." />;
+    } else if (CheckUserPermission()) {
+        return (
+            <>
+                <SnackBar
+                    severity={snackInfo.icon}
+                    text={snackInfo.message}
+                    snackbarOpen={snackInfo.open}
+                    color={snackInfo.color}
+                    handleClose={() =>
+                        setSnackInfo({
+                            message: "",
+                            icon: "",
+                            open: false,
+                            color: "",
+                        })
+                    }
+                />
+
+                <Paper style={{ padding: "1em" }}>
+                    <Grid container spacing={3} direction="row" alignItems="center">
+                        <Grid item xs={6}>
+                            <Typography variant="h4">
+                                Lista de pedidos para professores
+                            </Typography>
+                        </Grid>
+
+                        <Grid item xs={6}>
+                            <Grid container justify="flex-end" spacing={3}>
+                                <Grid item>
+                                    <Button
+                                        variant="contained"
+                                        color="secondary"
+                                        disabled={isUpdating}
+                                        onClick={() => {
+                                            currPage = 0;
+                                            UpdateHandler(
+                                                Url(
+                                                    "users",
+                                                    `"submitter_request":"${currContentState}","name":"${currContentName}","email":"${currContentEmail}"`,
+                                                    `${currPage}`,
+                                                    "DESC"
+                                                ),
+                                            );
+                                        }}
+                                        startIcon={<UpdateRoundedIcon />}
+                                    >
+                                        {isUpdating ? <CircularProgress size={24} /> : "Atualizar"}
+                                    </Button>
+                                </Grid>
+                                <Grid item>
+                                    <Button
+                                        variant="contained"
+                                        color="secondary"
+                                        onClick={() => {
+                                            currPage = 0;
+                                            UpdateHandler(
+                                                Url(
+                                                    "users",
+                                                    `"submitter_request":"${currContentState}","name":"${currContentName}","email":"${currContentEmail}"`,
+                                                    `${currPage}`,
+                                                    "DESC"
+                                                ),
+                                            );
+                                            setShowFilter(!showFilter);
+                                        }}
+                                        startIcon={<FilterListRoundedIcon />}
+                                    >
+                                        Filtrar
+                                    </Button>
+                                </Grid>
+                            </Grid>
+                        </Grid>
+                    </Grid>
+
+                    {showFilter ? (
+                        <Grid
+                            container
+                            direction="row"
+                            justify="space-between"
+                            alignItems="center"
+                            alignContent="flex-end"
+                            spacing={3}
+                            xs={12}
+                        >
+                            <Grid item>
+                                <TextField
+                                    select
+                                    label="Estado"
+                                    value={option ? option : ""}
+                                    onChange={handleChange}
+                                    helperText="Por favor, selecione uma das opções"
+                                >
+                                    {StateOptions.map((option, index) => (
+                                        <MenuItem
+                                            key={option.id}
+                                            value={option.name}
+                                            name={option.id}
+                                            onClick={() =>
+                                                ApplyFilter(option.id, "submitter_request")
+                                            }
+                                        >
+                                            {option.name}
+                                        </MenuItem>
+                                    ))}
+                                </TextField>
+                            </Grid>
+                            <Grid item>
+                                <TextField label="Nome" onBlur={NameHandler} value={name} onChange={(e) => {setName(e.target.value)}} />
+                            </Grid>
+                            <Grid item>
+                                <TextField label="Email" onBlur={EmailHandler} value={email} onChange={(e) => {setEmail(e.target.value)}} />
+                            </Grid>
+                        </Grid>
+                    ) : null}
+                </Paper>
+
+                <div style={{ height: "2em" }}></div>
+
+                <Grid xs={12} container>
+                    <TableData top={TOP_LABELS}>
+                        <TableBody>
+                            {items.map((row, index) =>
+                                index === items.length - 1 ? (
+                                    <StyledTableRow key={index}>
+                                        {/* Button to load more data */}
+                                        <StyledTableCell>
+                                            <Button
+                                                color="primary"
+                                                variant="text"
+                                                // disabled={isLoadingMoreItems}
+                                                startIcon={<AddRoundedIcon />}
+                                                disabled={isLoadingMoreItems}
+                                                onClick={() => {
+                                                    currPage++;
+                                                    LoadMoreItens(
+                                                        Url(
+                                                            "users",
+                                                            `"submitter_request":"${currContentState}","name":"${currContentName}","email":"${currContentEmail}"`,
+                                                            `${currPage}`,
+                                                            "DESC"
+                                                        ),
+                                                    )
+                                                }}
+                                            >
+                                                {isLoadingMoreItems ? (
+                                                    <CircularProgress size={24} />
+                                                ) : (
+                                                        "Carregar mais itens"
+                                                    )}
+                                            </Button>
+                                        </StyledTableCell>
+                                    </StyledTableRow>
+                                ) : (
+                                        <StyledTableRow
+                                            key={index}
+                                            style={{ flex: 1, width: "100%" }}
+                                        >
+                                            <StyledTableCell component="th" scope="row">
+                                                {ComplaintStatus(row.submitter_request)}
+                                            </StyledTableCell>
+                                            <StyledTableCell align="right">{row.id}</StyledTableCell>
+                                            <StyledTableCell align="right">{row.name}</StyledTableCell>
+                                            <StyledTableCell align="right">{row.email}</StyledTableCell>
+                                            <StyledTableCell align="right">
+                                                {DisplayDate(row.created_at)}
+                                            </StyledTableCell>
+                                            <StyledTableCell align="right">
+                                                <Link to={`/admin/user/${row.id}`}>
+                                                    <IconButton
+                                                        onClick={() => {
+                                                            currPage = 0;
+                                                        }}
+                                                    >
+                                                        <VisibilityIcon style={{ fill: "#00bcd4" }} />
+                                                    </IconButton>
+                                                </Link>
+                                            </StyledTableCell>
+                                            <StyledTableCell align="right">
+                                                <Button
+                                                    variant="contained"
+                                                    color="secondary"
+                                                    style={{ width: "100%" }}
+                                                    disabled={
+                                                        row.submitter_request === "requested" ? false : true
+                                                    }
+                                                    startIcon={
+                                                        <CloseRoundedIcon style={{ fill: "#FFFAFA" }} />
+                                                    }
+                                                    onClick={() => {handleReject(row.id, row.name)}}
+                                                >
+                                                    Recusar
+                                                </Button>
+                                                <div style={{ height: "0.5em" }} />
+                                                <Button
+                                                    variant="contained"
+                                                    color="primary"
+                                                    style={{ width: "100%" }}
+                                                    disabled={
+                                                        row.submitter_request === "requested" ? false : true
+                                                    }
+                                                    startIcon={
+                                                        <CheckRoundedIcon style={{ fill: "#FFFAFA" }} />
+                                                    }
+                                                    onClick={() => {handleAprove(row.id, row.name)}}
+                                                >
+                                                    Aceitar
+                                                </Button>
+                                            </StyledTableCell>
+                                        </StyledTableRow>
+                                    )
+                            )}
+                        </TableBody>
+                    </TableData>
+                </Grid>
+            </>
+        );
+    } else return <Unauthorized />;
+};
+export default AproveTeacher;
-- 
GitLab