diff --git a/src/Admin/Components/Components/AppBar.js b/src/Admin/Components/Components/AppBar.js new file mode 100644 index 0000000000000000000000000000000000000000..b596c35f59484e8754b79c68d787feced4011913 --- /dev/null +++ b/src/Admin/Components/Components/AppBar.js @@ -0,0 +1,73 @@ +import React from 'react'; +import PropTypes from "prop-types"; +import Typography from "@material-ui/core/Typography"; +import Box from "@material-ui/core/Box"; +import AppBar from "@material-ui/core/AppBar"; +import { Tab, Tabs } from "@material-ui/core"; +import { Link } from 'react-router-dom' +import { TabsItens } from '../../Pages/AdminLabelTabs/LabelTabs' + +function TabPanel(props) { + const { children, value, index, ...other } = props; + + return ( + <div + role="tabpanel" + hidden={value !== index} + id={`nav-tabpanel-${index}`} + aria-labelledby={`nav-tab-${index}`} + {...other} + > + {value === index && ( + <Box p={3}> + <Typography>{children}</Typography> + </Box> + )} + </div> + ); +} + +TabPanel.propTypes = { + children: PropTypes.node, + index: PropTypes.any.isRequired, + value: PropTypes.any.isRequired, +}; + +function a11yProps(index) { + return { + id: `nav-tab-${index}`, + "aria-controls": `nav-tabpanel-${index}`, + }; +} +export default function AppBarAdmin() { + const [value, setValue] = React.useState(0); + + const handleChange = (event, newValue) => { + setValue(newValue); + }; + + return ( + <AppBar position="sticky" color="default"> + <Tabs + variant="scrollable" + scrollButtons="on" + value={value} + onChange={handleChange} + aria-label="nav tabs example" + > + { + TabsItens.map((label, index) => ( + <Tab + key={label.href} + label={label.label} + to={label.href} + icon={label.icon} + component={Link} + {...a11yProps(index)} + /> + )) + } + </Tabs> + </AppBar> + ) +} \ No newline at end of file diff --git a/src/Admin/Components/Components/DataCards/ActivityCard.js b/src/Admin/Components/Components/DataCards/ActivityCard.js index d3bdcbe1d1f8d11122a150950099243f1a9cf510..915df2f99fdb31c17741d362555721f14a3753f9 100644 --- a/src/Admin/Components/Components/DataCards/ActivityCard.js +++ b/src/Admin/Components/Components/DataCards/ActivityCard.js @@ -32,7 +32,7 @@ import { getRequest } from '../../../../Components/HelperFunctions/getAxiosConfi import { Link } from 'react-router-dom' import LoadingSpinner from '../../../../Components/LoadingSpinner'; -const ActivityCard = ({ match }) => { +const ActivityCard = () => { const classes = useStyles(); const [error, setError] = useState(null); //Necessary to consult the API, catch errors @@ -48,7 +48,9 @@ const ActivityCard = ({ match }) => { //getting data from server useEffect(() => { - getRequest(GetAData("activities", match.params.id), + const urlParams = new URLSearchParams(window.location.search); + const query = urlParams.get("activity"); + getRequest(GetAData("activities", query), (data, header) => { setItem(data); setIsLoaded(true); @@ -120,7 +122,7 @@ const ActivityCard = ({ match }) => { </Link> </Grid> </Grid> - <div style={{height: "1em"}}/> + <div style={{ height: "1em" }} /> {DATA.map((info, index) => ( <div className={classes.displayColumn} key={index}> <Typography color="initial" className={classes.subTitle}> diff --git a/src/Admin/Components/Components/DataCards/CollectionCard.js b/src/Admin/Components/Components/DataCards/CollectionCard.js index fa06198a87093ad05ca72addaed66fd26e566b0f..a4ef28da2b30bdff799545b79d7936b5415e19ca 100644 --- a/src/Admin/Components/Components/DataCards/CollectionCard.js +++ b/src/Admin/Components/Components/DataCards/CollectionCard.js @@ -36,9 +36,11 @@ import LoadingSpinner from '../../../../Components/LoadingSpinner'; import SnackBar from '../../../../Components/SnackbarComponent'; import { getRequest, deleteRequest } from '../../../../Components/HelperFunctions/getAxiosConfig'; -const CollectionCard = ({ match }) => { +const CollectionCard = () => { let history = useHistory() const classes = useStyles(); + const urlParams = new URLSearchParams(window.location.search); + const id = urlParams.get("collection"); 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 @@ -69,7 +71,6 @@ const CollectionCard = ({ match }) => { //Called when user want to delete one institution async function DeleteHandler() { - const id = match.params.id deleteRequest( DeleteFilter("collections", id), (data) => { @@ -93,7 +94,7 @@ const CollectionCard = ({ match }) => { useEffect(() => { getRequest( - GetAData("collections", match.params.id), + GetAData("collections", id), (data, header) => { setItem(data); setIsLoaded(true); @@ -178,14 +179,14 @@ const CollectionCard = ({ match }) => { </Button> </Link> - <Link style={{ textDecoration: 'none' }} to={`/admin/EditCollection/${item.id}`}> + <Link style={{ textDecoration: 'none' }} to={`/admin/EditCollection?collection=${item.id}`}> <Button startIcon={<EditRoundedIcon />} color="primary" variant="outlined" > Editar - </Button> + </Button> </Link> <Button @@ -198,7 +199,7 @@ const CollectionCard = ({ match }) => { </Button> </Grid> </Grid> - <div style={{height: "1em"}}/> + <div style={{ height: "1em" }} /> {DATA.map((info, index) => ( <div className={classes.displayColumn} key={index}> <Typography color="initial" className={classes.subTitle}> diff --git a/src/Admin/Components/Components/DataCards/CommunityQuestionCard.js b/src/Admin/Components/Components/DataCards/CommunityQuestionCard.js index 4ee4a1448f3a4f1efb90df90e9bcd63bd4164ffc..b8ae952c3dabc4ff4c7fd73ceb45a6d3123972b1 100644 --- a/src/Admin/Components/Components/DataCards/CommunityQuestionCard.js +++ b/src/Admin/Components/Components/DataCards/CommunityQuestionCard.js @@ -36,7 +36,7 @@ import Unauthorized from "../Unauthorized"; import { getRequest } from '../../../../Components/HelperFunctions/getAxiosConfig' import LoadingSpinner from '../../../../Components/LoadingSpinner'; -const CommunityQuestions = ({ match }) => { +const CommunityQuestions = () => { const { state } = useContext(Store); const classes = useStyles(); @@ -68,8 +68,10 @@ const CommunityQuestions = ({ match }) => { } useEffect(() => { + const urlParams = new URLSearchParams(window.location.search); + const query = urlParams.get("question"); getRequest( - GetAData("contacts", match.params.id), + GetAData("contacts", query), (data, header) => { setItem(data); setIsLoaded(true); @@ -100,7 +102,7 @@ const CommunityQuestions = ({ match }) => { subTitle: "Email", prop: item.email ? - <Link to={`/admin/sendEmail/${item.email}`} style={{ textDecoration: 'none' }}> + <Link to={`/admin/sendEmail/?email=${item.email}`} style={{ textDecoration: 'none' }}> <Button variant='text' color='primary' diff --git a/src/Admin/Components/Components/DataCards/ComplaintsCard.js b/src/Admin/Components/Components/DataCards/ComplaintsCard.js index 17f7623e403413685bd15f2e2a56474f736b1dcd..4c3fc1337f6c2a18d26e20b9191f46bfe003ed1a 100644 --- a/src/Admin/Components/Components/DataCards/ComplaintsCard.js +++ b/src/Admin/Components/Components/DataCards/ComplaintsCard.js @@ -51,8 +51,10 @@ import { getRequest, postRequest } from '../../../../Components/HelperFunctions/ const PORTAL_MEC = "https://plataformaintegrada.mec.gov.br/"; -const CollectionCard = ({ match }) => { +const CollectionCard = () => { const classes = useStyles(); + const urlParams = new URLSearchParams(window.location.search); + const id = urlParams.get("id"); const [error, setError] = useState(null); //Necessary to consult the API, catch errors @@ -179,7 +181,7 @@ const CollectionCard = ({ match }) => { const reloadData = () => { setIsLoaded(false) getRequest( - GetAData("complaints", match.params.id), + GetAData("complaints", id), (data, header) => { setItem(data) setIsLoaded(true); @@ -212,7 +214,7 @@ const CollectionCard = ({ match }) => { HandleSnack('Alteração feito com sucesso!', true, 'success', '#228B22') reloadData() } - }, + }, (error) => { HandleSnack('Ocorreu algum erro', true, 'warning', '#FA8072') } @@ -357,7 +359,7 @@ const CollectionCard = ({ match }) => { case "User": return ( <CardActions> - <Link to={`/admin/user/${item.complainable_id}`}> + <Link to={`/admin/user?id=${item.complainable_id}`}> <Button variant="contained" color="primary" @@ -566,13 +568,12 @@ const CollectionCard = ({ match }) => { const HandleComplainObj = async (method) => { postRequest( - MethodsToComplain("complaints", match.params.id, method), + MethodsToComplain("complaints", id, method), {}, (data) => { if (data.errors) HandleSnack('Ocorreu algum erro', true, 'warning', '#FA8072') - else - { + else { HandleSnack('Alteração feito com sucesso', true, 'success', '#228B22') reloadData() } @@ -595,7 +596,7 @@ const CollectionCard = ({ match }) => { useEffect(() => { getRequest( - GetAData("complaints", match.params.id), + GetAData("complaints", id), (data, header) => { setItem(data) setIsLoaded(true); @@ -685,7 +686,7 @@ const CollectionCard = ({ match }) => { > { - item.complainable_type === "User" ? `Usuário #${item.complainable_id}` : `Recurso #${item.complainable_id}` + item.complainable_type === "User" ? `Usuário #${item.complainable_id}` : `Recurso #${item.complainable_id}` } </Typography> </Grid> @@ -704,7 +705,7 @@ const CollectionCard = ({ match }) => { </Link> </Grid> </Grid> - <div style={{height: "1em"}}/> + <div style={{ height: "1em" }} /> {DATA.map((info, index) => ( <div className={classes.displayColumn} key={index}> <Typography color="initial" className={classes.subTitle}> diff --git a/src/Admin/Components/Components/DataCards/EducationalObjectsCard.js b/src/Admin/Components/Components/DataCards/EducationalObjectsCard.js index 493f577fa3f1b2a31a0724312e1c24923af61e98..08a8f3255e1015758e98373e8c2d7e25c70cd05e 100644 --- a/src/Admin/Components/Components/DataCards/EducationalObjectsCard.js +++ b/src/Admin/Components/Components/DataCards/EducationalObjectsCard.js @@ -41,9 +41,11 @@ import { } from "../../../../Components/HelperFunctions/getAxiosConfig"; import SnackBar from "../../../../Components/SnackbarComponent"; -const CommunityQuestions = ({ match }) => { +const CommunityQuestions = () => { const classes = useStyles(); let history = useHistory(); + const urlParams = new URLSearchParams(window.location.search); + const id = urlParams.get("learnObj"); 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 @@ -73,7 +75,6 @@ const CommunityQuestions = ({ match }) => { }); async function DeleteHandler() { - const id = match.params.id; deleteRequest( DeleteFilter("learning_objects", id), (data) => { @@ -97,7 +98,7 @@ const CommunityQuestions = ({ match }) => { useEffect(() => { getRequest( - GetAData("learning_objects", match.params.id), + GetAData("learning_objects", id), (data, header) => { setItem(data); setIsLoaded(true); @@ -264,7 +265,7 @@ const CommunityQuestions = ({ match }) => { href={ apiUrl + "/learning_objects/" + - match.params.id + + id + "/download" } > @@ -273,7 +274,7 @@ const CommunityQuestions = ({ match }) => { </Button> <Link style={{ textDecoration: "none" }} - to={`/admin/learningObjectEdit/${item.id}`} + to={`/admin/learningObjectEdit?learnObj=${item.id}`} > <Button startIcon={<EditRoundedIcon />} @@ -293,7 +294,7 @@ const CommunityQuestions = ({ match }) => { </Button> </Grid> </Grid> - <div style={{height: "1em"}}/> + <div style={{ height: "1em" }} /> {item.thumbnail ? ( <div style={{ marginTop: "1em", marginBottom: "1em" }}> <a target="_blank" rel="noreferrer" href={apiDomain + item.thumbnail}> diff --git a/src/Admin/Components/Components/DataCards/InstitutionsCard.js b/src/Admin/Components/Components/DataCards/InstitutionsCard.js index 817fcfad40a7b73678cb2b9dfd6637df166980c7..b4981b7bb93715a8bbfa0bc94f8d85e628df3416 100644 --- a/src/Admin/Components/Components/DataCards/InstitutionsCard.js +++ b/src/Admin/Components/Components/DataCards/InstitutionsCard.js @@ -36,9 +36,12 @@ import { Link, useHistory } from 'react-router-dom'; import LoadingSpinner from '../../../../Components/LoadingSpinner'; import SnackBar from '../../../../Components/SnackbarComponent'; -const InstitutionCard = ({ match }) => { +const InstitutionCard = () => { const classes = useStyles(); - let history = useHistory() + let history = useHistory(); + const urlParams = new URLSearchParams(window.location.search); + const id = urlParams.get("institution"); + 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 @@ -68,7 +71,6 @@ const InstitutionCard = ({ match }) => { }); async function DeleteHandler() { - const id = match.params.id deleteRequest( DeleteFilter("institutions", id), (data) => { @@ -92,7 +94,7 @@ const InstitutionCard = ({ match }) => { useEffect(() => { getRequest( - GetAData('institutions', match.params.id), + GetAData('institutions', id), (data, header) => { setIsLoaded(true); setItem(data); @@ -176,7 +178,7 @@ const InstitutionCard = ({ match }) => { </Button> </Link> - <Link style={{ textDecoration: 'none' }} to={`/admin/institutionEdit/${item.id}`}> + <Link style={{ textDecoration: 'none' }} to={`/admin/institutionEdit?institution=${item.id}`}> <Button startIcon={<EditRoundedIcon />} color="primary" @@ -196,7 +198,7 @@ const InstitutionCard = ({ match }) => { </Button> </Grid> </Grid> - <div style={{height: "1em"}}/> + <div style={{ height: "1em" }} /> {DATA.map((info, index) => ( <div className={classes.displayColumn} key={index}> <Typography color="initial" className={classes.subTitle}> diff --git a/src/Admin/Components/Components/DataCards/NoteVarCard.js b/src/Admin/Components/Components/DataCards/NoteVarCard.js index 6b72bddfa0ebd118b13bba0dfc0866b135b14ae4..7c7b4356f9f174607e330987ee15081724b080e8 100644 --- a/src/Admin/Components/Components/DataCards/NoteVarCard.js +++ b/src/Admin/Components/Components/DataCards/NoteVarCard.js @@ -34,9 +34,10 @@ import { getRequest } from '../../../../Components/HelperFunctions/getAxiosConfi import { Link } from 'react-router-dom'; import LoadingSpinner from '../../../../Components/LoadingSpinner'; -const NoteCard = ({ match }) => { - console.log(match); +const NoteCard = () => { const classes = useStyles(); + const urlParams = new URLSearchParams(window.location.search); + const id = urlParams.get("id"); 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 @@ -52,7 +53,7 @@ const NoteCard = ({ match }) => { useEffect(() => { getRequest( - GetAData('scores', match.params.id), + GetAData('scores', id), (data, header) => { setIsLoaded(true); setItem(data); @@ -116,7 +117,7 @@ const NoteCard = ({ match }) => { </Button> </Link> - <Link style={{ textDecoration: 'none' }} to={`/admin/noteVarEdit/${item.id}`}> + <Link style={{ textDecoration: 'none' }} to={`/admin/noteVarEdit?id=${item.id}`}> <Button startIcon={<EditRoundedIcon />} color="primary" diff --git a/src/Admin/Components/Components/DataCards/RatingCard.js b/src/Admin/Components/Components/DataCards/RatingCard.js index c333b56c6c5946e87370693780eb622288338b7c..b5f69a53c800dce0324ec0afb274a97ce315fc8e 100644 --- a/src/Admin/Components/Components/DataCards/RatingCard.js +++ b/src/Admin/Components/Components/DataCards/RatingCard.js @@ -36,9 +36,11 @@ import { Link, useHistory } from 'react-router-dom'; import LoadingSpinner from '../../../../Components/LoadingSpinner'; import SnackBar from '../../../../Components/SnackbarComponent'; -const RatingCard = ({ match }) => { +const RatingCard = () => { const classes = useStyles(); - let history = useHistory() + let history = useHistory(); + const urlParams = new URLSearchParams(window.location.search); + const id = urlParams.get("rating"); 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 @@ -68,7 +70,6 @@ const RatingCard = ({ match }) => { }; async function DeleteHandler() { - const id = match.params.id deleteRequest( DeleteFilter("ratings", id), (data) => { @@ -93,7 +94,7 @@ const RatingCard = ({ match }) => { useEffect(() => { getRequest( - GetAData('ratings', match.params.id), + GetAData('ratings', id), (data, header) => { setIsLoaded(true); setItem(data); @@ -165,7 +166,7 @@ const RatingCard = ({ match }) => { </Button> </Link> - <Link style={{ textDecoration: 'none' }} to={`/admin/EditRating/${item.id}`}> + <Link style={{ textDecoration: 'none' }} to={`/admin/EditRating?rating=${item.id}`}> <Button startIcon={<EditRoundedIcon />} color="primary" @@ -185,7 +186,7 @@ const RatingCard = ({ match }) => { </Button> </Grid> </Grid> - <div style={{height: "1em"}}/> + <div style={{ height: "1em" }} /> {DATA.map((info, index) => ( <div className={classes.displayColumn} key={index}> <Typography color="initial" className={classes.subTitle}> diff --git a/src/Admin/Components/Components/DataCards/UserCard.js b/src/Admin/Components/Components/DataCards/UserCard.js index d4e82906c3470fdaac4fbbbfd0308d5bd7baf0e3..a34f96b390a075eed4c3aed1a28b3baacc968734 100644 --- a/src/Admin/Components/Components/DataCards/UserCard.js +++ b/src/Admin/Components/Components/DataCards/UserCard.js @@ -45,9 +45,12 @@ import { getRequest, postRequest, deleteRequest, putRequest } from '../../../../ //styles import styled from 'styled-components'; -const CollectionCard = ({ match }, props) => { +const CollectionCard = () => { let history = useHistory() const classes = useStyles(); + const urlParams = new URLSearchParams(window.location.search); + const id = urlParams.get("id"); + 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 [item, setItem] = useState({}); @@ -138,7 +141,7 @@ const CollectionCard = ({ match }, props) => { const reloadData = () => { setIsLoaded(false) getRequest( - GetAData("users", match.params.id), + GetAData("users", id), (data, header) => { setItem(data) setIsLoaded(true); @@ -159,13 +162,12 @@ const CollectionCard = ({ match }, props) => { url, body, (data) => { - if(data.errors) + if (data.errors) HandleSnack("Erro!", true, "warning", "#FA8072"); - else - { + else { HandleSnack(`${userName} aceito como professor!`, true, "success", "#228B22"); reloadData() - } + } }, (error) => { HandleSnack("Erro!", true, "warning", "#FA8072"); @@ -182,13 +184,12 @@ const CollectionCard = ({ match }, props) => { url, body, (data) => { - if(data.errors) + if (data.errors) HandleSnack("Erro!", true, "warning", "#FA8072"); - else - { - HandleSnack(`${userName} rejeitado como professor!`, true, "success", "#228B22"); - reloadData() - } + else { + HandleSnack(`${userName} rejeitado como professor!`, true, "success", "#228B22"); + reloadData() + } }, (error) => { HandleSnack("Erro!", true, "warning", "#FA8072"); @@ -200,10 +201,9 @@ const CollectionCard = ({ match }, props) => { deleteRequest( `/users/${userId}`, (data) => { - if(data.errors) + if (data.errors) HandleSnack("Erro!", true, "warning", "#FA8072") - else - { + else { HandleSnack(`${item.name} deletado com sucesso!`, true, "success", "#228B22"); history.goBack() } @@ -243,8 +243,8 @@ const CollectionCard = ({ match }, props) => { </Button> ) } - return <Typography color="textSecondary"> - Usuário não bloqueado + return <Typography color="textSecondary"> + Usuário não bloqueado </Typography> } @@ -294,16 +294,15 @@ const CollectionCard = ({ match }, props) => { const ReactiveUser = () => { putRequest( - `/users/${match.params.id}/reactivate_user`, + `/users/${id}/reactivate_user`, {}, (data) => { - if(data.errors) + if (data.errors) HandleSnack('Erro ao tentar reativar usuário!', true, 'warning', '#FA8072') - else - { + else { HandleSnack('Usuário foi reativado com sucesso!', true, 'success', '#228B22') reloadData() - } + } }, (error) => { HandleSnack('Erro ao tentar reativar usuário!', true, 'warning', '#FA8072') @@ -313,7 +312,7 @@ const CollectionCard = ({ match }, props) => { useEffect(() => { getRequest( - GetAData("users", match.params.id), + GetAData("users", id), (data, header) => { setItem(data) setIsLoaded(true); @@ -390,7 +389,7 @@ const CollectionCard = ({ match }, props) => { </Button> </Grid> <Grid item> - <Link to={`/admin/EditUser/${item.id}`} style={{ textDecoration: "none" }}> + <Link to={`/admin/EditUser?id=${item.id}`} style={{ textDecoration: "none" }}> <Button startIcon={<EditRoundedIcon />} color="primary" @@ -425,7 +424,7 @@ const CollectionCard = ({ match }, props) => { </Typography> { item.email ? - <Link to={`/admin/sendEmail/${item.email}`} style={{ textDecoration: 'none' }}> + <Link to={`/admin/sendEmail?email=${item.email}`} style={{ textDecoration: 'none' }}> <Button variant='text' color='primary' diff --git a/src/Admin/Components/Components/DisplayIcon.js b/src/Admin/Components/Components/DisplayIcon.js deleted file mode 100644 index 5336574d7124413e47603fd0fc63122c12853f2e..0000000000000000000000000000000000000000 --- a/src/Admin/Components/Components/DisplayIcon.js +++ /dev/null @@ -1,79 +0,0 @@ -/*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 from "react"; -import ListItemIcon from "@material-ui/core/ListItemIcon"; -import HomeIcon from "@material-ui/icons/Home"; -import PeopleRoundedIcon from "@material-ui/icons/PeopleRounded"; -import ContactSupportRoundedIcon from "@material-ui/icons/ContactSupportRounded"; -import LanguageRoundedIcon from "@material-ui/icons/LanguageRounded"; -import AccountBalanceRoundedIcon from "@material-ui/icons/AccountBalanceRounded"; -import MenuBookRoundedIcon from "@material-ui/icons/MenuBookRounded"; -import StarRoundedIcon from "@material-ui/icons/StarRounded"; -import AccountCircleRoundedIcon from "@material-ui/icons/AccountCircleRounded"; -import TrendingUpRoundedIcon from "@material-ui/icons/TrendingUpRounded"; -import HelpRoundedIcon from "@material-ui/icons/HelpRounded"; -import CheckRoundedIcon from "@material-ui/icons/CheckRounded"; -import PersonRoundedIcon from "@material-ui/icons/PersonRounded"; -import BlockRoundedIcon from "@material-ui/icons/BlockRounded"; -import AnnouncementRoundedIcon from "@material-ui/icons/AnnouncementRounded"; -import EmailRoundedIcon from "@material-ui/icons/EmailRounded"; -import TimelineRoundedIcon from "@material-ui/icons/TimelineRounded"; -import SettingsRoundedIcon from "@material-ui/icons/SettingsRounded"; -import ExitToAppRoundedIcon from "@material-ui/icons/ExitToAppRounded"; -import AllOutIcon from "@material-ui/icons/AllOut"; -import SportsEsportsRoundedIcon from '@material-ui/icons/SportsEsportsRounded'; - -//This file manipulate the icon that will be displayed in the left navigation menu - -const orange = "#ff7f00"; -const pink = "#e81f4f"; -const purple = "#673ab7"; -const blue = "#00bcd4"; - -const icons = [ - <HomeIcon style={{ fill: orange }} />, - <PeopleRoundedIcon style={{ fill: pink }} />, - <AllOutIcon style={{ fill: purple }} />, - <ContactSupportRoundedIcon style={{ fill: blue }} />, - <AccountBalanceRoundedIcon style={{ fill: orange }} />, - <LanguageRoundedIcon style={{ fill: pink }} />, - <MenuBookRoundedIcon style={{ fill: purple }} />, - <StarRoundedIcon style={{ fill: blue }} />, - <AccountCircleRoundedIcon style={{ fill: orange }} />, - <TrendingUpRoundedIcon style={{ fill: pink }} />, - <HelpRoundedIcon style={{ fill: purple }} />, - <CheckRoundedIcon style={{ fill: blue }} />, - <PersonRoundedIcon style={{ fill: orange }} />, - <BlockRoundedIcon style={{ fill: pink }} />, - <AnnouncementRoundedIcon style={{ fill: purple }} />, - <EmailRoundedIcon style={{ fill: blue }} />, - <SportsEsportsRoundedIcon style={{fill: orange }}/>, - <TimelineRoundedIcon style={{ fill: orange }} />, - <SettingsRoundedIcon style={{ fill: pink }} />, - <ExitToAppRoundedIcon style={{ fill: purple }} />, -]; - -const DisplayIcon = (props) => { - return( - <ListItemIcon> - {icons[props.i]} - </ListItemIcon> - ); -}; -export default DisplayIcon; diff --git a/src/Admin/Components/Components/Inputs/CreateInstitution.js b/src/Admin/Components/Components/Inputs/CreateInstitution.js index 9520845704b1986e1cba74a687c9e84184452e91..b4f001f083f15aa192319a899cbad7dcac96421a 100644 --- a/src/Admin/Components/Components/Inputs/CreateInstitution.js +++ b/src/Admin/Components/Components/Inputs/CreateInstitution.js @@ -138,18 +138,21 @@ const CreateInstitution = (props) => { if (data.id) HandleSnack('A instituição foi criada com sucesso', true, 'success', '#228B22') else { - if(data.errors){ + if (data.errors) { HandleSnack(`${data.errors[0]}`, true, 'warning', '#FA8072') } - if (data.name) { - let nameError = ""; - data.name.map((msg) => ( - nameError = nameError + msg + " e " - )) - setErrorInName({ - error: true, - message: nameError - }) + else { + if (data.name) { + let nameError = ""; + data.name.map((msg) => ( + nameError = nameError + msg + " e " + )) + setErrorInName({ + error: true, + message: nameError + }) + } + HandleSnack('Você precisa preencher algumas informações obrigatórias', true, 'warning', '#FFC125') } } setIsLoading(false) diff --git a/src/Admin/Components/Components/Inputs/CreateLanguage.js b/src/Admin/Components/Components/Inputs/CreateLanguage.js index 4e40599bd6ab48da253d6c5b7618c71774870e73..c9a6590184ea0695d365aa6a58e3119c5dfa4051 100644 --- a/src/Admin/Components/Components/Inputs/CreateLanguage.js +++ b/src/Admin/Components/Components/Inputs/CreateLanguage.js @@ -123,28 +123,31 @@ const CreateLanguage = (props) => { if (data.id) HandleSnack('A linguagem foi criada com sucesso', true, 'success', '#228B22') else { - if(data.errors){ + if (data.errors) { HandleSnack(`${data.errors[0]}`, true, 'warning', '#FA8072') } - if (data.name) { - let nameError = ""; - data.name.map((msg) => ( - nameError = nameError + msg + " e " - )) - setErrorInName({ - error: true, - message: nameError - }) - } - if (data.code) { - let codeError = ""; - data.code.map((msg) => ( - codeError = codeError + msg + " e " - )) - setErrorInCode({ - error: true, - message: codeError - }) + else { + if (data.name) { + let nameError = ""; + data.name.map((msg) => ( + nameError = nameError + msg + " e " + )) + setErrorInName({ + error: true, + message: nameError + }) + } + if (data.code) { + let codeError = ""; + data.code.map((msg) => ( + codeError = codeError + msg + " e " + )) + setErrorInCode({ + error: true, + message: codeError + }) + } + HandleSnack('Você precisa preencher algumas informações obrigatórias', true, 'warning', '#FFC125') } } setIsLoading(false) diff --git a/src/Admin/Components/Components/Inputs/CreateRole.js b/src/Admin/Components/Components/Inputs/CreateRole.js index 042616ca42bef887952fc897dfd57483ff8d170c..94afb02479f83a1f9830f659c77d478247a62c26 100644 --- a/src/Admin/Components/Components/Inputs/CreateRole.js +++ b/src/Admin/Components/Components/Inputs/CreateRole.js @@ -124,18 +124,21 @@ const CreateRole = (props) => { if (data.id) HandleSnack('A role foi criada com sucesso!', true, 'success', '#228B22') else { - if(data.errors){ + if (data.errors) { HandleSnack(`${data.errors[0]}`, true, 'warning', '#FA8072') } - if (data.name) { - let errorName = ""; - data.name.map((err) => ( - errorName = errorName + err + " e " - )) - setErrorInName({ - error: true, - message: errorName - }) + else { + if (data.name) { + let errorName = ""; + data.name.map((err) => ( + errorName = errorName + err + " e " + )) + setErrorInName({ + error: true, + message: errorName + }) + } + HandleSnack('Você precisa preencher algumas informações obrigatórias', true, 'warning', '#FFC125') } } setIsLoading(false) diff --git a/src/Admin/Components/Components/Inputs/EditCollection.js b/src/Admin/Components/Components/Inputs/EditCollection.js index 67917eb60ac05c634de6f5b5bb0d9d317bdf2938..13aabcf16dac0ebc5f77ca965b60cfa6b5508395 100644 --- a/src/Admin/Components/Components/Inputs/EditCollection.js +++ b/src/Admin/Components/Components/Inputs/EditCollection.js @@ -38,14 +38,15 @@ import { Link } from 'react-router-dom'; import ClassicEditor from "@ckeditor/ckeditor5-build-classic" import { CKEditor } from '@ckeditor/ckeditor5-react'; -const EditCollection = ({ match }) => { +const EditCollection = () => { const { state } = useContext(Store); + const urlParams = new URLSearchParams(window.location.search); + const id = urlParams.get("collection"); 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 [isLoading, setIsLoading] = useState(false); - const id = match.params.id const [name, setName] = useState('') const [privacy, setPrivacy] = useState('') const [description, setDescription] = useState(''); @@ -149,10 +150,10 @@ const EditCollection = ({ match }) => { api, body, (data) => { - if(data.errors){ + if (data.errors) { HandleSnack(`${data.errors[0]}`, true, 'warning', '#FA8072') } - else{ + else { HandleSnack('A Coleção foi alterada com sucesso', true, 'success', '#228B22') } setIsLoading(false) @@ -166,7 +167,7 @@ const EditCollection = ({ match }) => { useEffect(() => { getRequest( - GetAData("collections", match.params.id), + GetAData("collections", id), (data, header) => { setIsLoaded(true); setError(false); diff --git a/src/Admin/Components/Components/Inputs/EditEducationalObect.js b/src/Admin/Components/Components/Inputs/EditEducationalObect.js index f5eca6838ec49afecb190b9cff6928b7a475352c..5996383029e0fc08a2b770c8fe7aa32a6b6f2b9e 100644 --- a/src/Admin/Components/Components/Inputs/EditEducationalObect.js +++ b/src/Admin/Components/Components/Inputs/EditEducationalObect.js @@ -62,14 +62,14 @@ const useStyles = makeStyles((theme) => ({ let text; -const EditEducationalObject = ({ match }) => { +const EditEducationalObject = () => { const { state } = useContext(Store); + const urlParams = new URLSearchParams(window.location.search); + const id = urlParams.get("learnObj"); const theme = useTheme(); const classes = useStyles(); - const id = match.params.id; - 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 [isLoading, setIsLoading] = useState(false); //is loading to submit @@ -275,7 +275,7 @@ const EditEducationalObject = ({ match }) => { "#228B22" ); } else { - if(data.errors){ + if (data.errors) { HandleSnack(`${data.errors[0]}`, true, 'warning', '#FA8072') } if (data.author) { @@ -399,7 +399,7 @@ const EditEducationalObject = ({ match }) => { useEffect(() => { const urls = [ - `/learning_objects/${match.params.id}`, + `/learning_objects/${id}`, "/languages", "/object_types", ]; diff --git a/src/Admin/Components/Components/Inputs/EditLanguage.js b/src/Admin/Components/Components/Inputs/EditLanguage.js index 8215429e0c0a0f0cbcedbccf9122295dd5b3e970..44df71ceed76a2846983700ced3f66f60143e7e4 100644 --- a/src/Admin/Components/Components/Inputs/EditLanguage.js +++ b/src/Admin/Components/Components/Inputs/EditLanguage.js @@ -37,15 +37,16 @@ import DeleteRoundedIcon from "@material-ui/icons/DeleteRounded"; import { Link, useHistory } from 'react-router-dom'; import Unauthorized from '../Unauthorized'; -const EditLanguage = ({ match }) => { +const EditLanguage = () => { const { state } = useContext(Store); let history = useHistory() + const urlParams = new URLSearchParams(window.location.search); + const id = urlParams.get("language"); 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 [isLoading, setIsLoading] = useState(false); - const id = match.params.id const [name, setName] = useState() const [code, setCode] = useState() @@ -67,7 +68,6 @@ const EditLanguage = ({ match }) => { }) async function DeleteHandler() { - const id = match.params.id deleteRequest( DeleteFilter("languages", id), (data) => { @@ -180,7 +180,7 @@ const EditLanguage = ({ match }) => { if (data.id) HandleSnack('A linguagem foi alterada com sucesso!', true, 'success', '#228B22') else { - if(data.errors){ + if (data.errors) { HandleSnack(`${data.errors[0]}`, true, 'warning', '#FA8072') } if (data.name) { @@ -215,7 +215,7 @@ const EditLanguage = ({ match }) => { useEffect(() => { getRequest( - GetAData("languages", match.params.id), + GetAData("languages", id), (data, header) => { setIsLoaded(true); setName(data.name) diff --git a/src/Admin/Components/Components/Inputs/EditRating.js b/src/Admin/Components/Components/Inputs/EditRating.js index a42363d639aacd2ea9051c60eb07f02e0ef23075..1b8e0e6fd7c2c054f389dd7f62316778c4aebfa1 100644 --- a/src/Admin/Components/Components/Inputs/EditRating.js +++ b/src/Admin/Components/Components/Inputs/EditRating.js @@ -33,17 +33,18 @@ import LoadingSpinner from '../../../../Components/LoadingSpinner'; import { getRequest, putRequest } from '../../../../Components/HelperFunctions/getAxiosConfig' import { EditFilter, GetAData } from '../../../Filters'; //routers -import {Link} from 'react-router-dom'; +import { Link } from 'react-router-dom'; import Unauthorized from '../Unauthorized'; -const EditRating = ({ match }) => { +const EditRating = () => { const { state } = useContext(Store); + const urlParams = new URLSearchParams(window.location.search); + const id = urlParams.get("rating"); 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 [isLoading, setIsLoading] = useState(false); - const id = match.params.id const [name, setName] = useState() const [description, setDescription] = useState() @@ -161,7 +162,7 @@ const EditRating = ({ match }) => { api, body, (data, header) => { - if(data.errors) + if (data.errors) HandleSnack('Ocorreu algum erro', true, 'warning', '#FA8072') else HandleSnack('O rating foi alterada com sucesso', true, 'success', '#228B22') @@ -193,7 +194,7 @@ const EditRating = ({ match }) => { useEffect(() => { getRequest( - GetAData("ratings", match.params.id), + GetAData("ratings", id), (data, header) => { setIsLoaded(true); setName(data.name) @@ -209,8 +210,8 @@ const EditRating = ({ match }) => { if (error) { return <div> Houve um erro... </div> } else if (!isLoaded) { - return <LoadingSpinner text="Carregando..."/> - } else if(CheckUserPermission()){ + return <LoadingSpinner text="Carregando..." /> + } else if (CheckUserPermission()) { return ( <Card> <SnackBar @@ -233,7 +234,7 @@ const EditRating = ({ match }) => { </Typography> </Grid> <Grid item> - <Link style={{textDecoration: 'none'}} to={'/admin/Ratings'}> + <Link style={{ textDecoration: 'none' }} to={'/admin/Ratings'}> <Button startIcon={<ListRoundedIcon />} variant='outlined' @@ -282,7 +283,7 @@ const EditRating = ({ match }) => { </CardAction> </Card> ) - } else return <Unauthorized/> + } else return <Unauthorized /> } export default EditRating; \ No newline at end of file diff --git a/src/Admin/Components/Components/Inputs/EditRoles.js b/src/Admin/Components/Components/Inputs/EditRoles.js index 9b2ecaa148bbc29ba1c0a7aefa5da22111767042..4b3aa488a8d6f8d2334d29a55680b49ed8020787 100644 --- a/src/Admin/Components/Components/Inputs/EditRoles.js +++ b/src/Admin/Components/Components/Inputs/EditRoles.js @@ -38,15 +38,16 @@ import { EditFilter, GetAData, DeleteFilter } from '../../../Filters'; import { Link, useHistory } from 'react-router-dom'; import Unauthorized from '../Unauthorized'; -const EditLanguage = ({ match }) => { +const EditLanguage = () => { const { state } = useContext(Store); let history = useHistory() + const urlParams = new URLSearchParams(window.location.search); + const id = urlParams.get("role"); 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 [isLoading, setIsLoading] = useState(false); - const id = match.params.id const [name, setName] = useState() const [desc, setDesc] = useState() const [snackInfo, setSnackInfo] = useState({ @@ -157,18 +158,21 @@ const EditLanguage = ({ match }) => { if (data.id) HandleSnack('A role foi alterada com sucesso', true, 'success', '#228B22') else { - if(data.errors){ + if (data.errors) { HandleSnack(`${data.errors[0]}`, true, 'warning', '#FA8072') } - if (data.name) { - let errorName = ""; - data.name.map((err) => ( - errorName = errorName + err + " e " - )) - setErrorInName({ - error: true, - message: errorName - }) + else { + HandleSnack('Você precisa preencher algumas informações obrigatórias', true, 'warning', '#FFC125') + if (data.name) { + let errorName = ""; + data.name.map((err) => ( + errorName = errorName + err + " e " + )) + setErrorInName({ + error: true, + message: errorName + }) + } } } setIsLoading(false) @@ -182,7 +186,6 @@ const EditLanguage = ({ match }) => { } async function DeleteHandler() { - const id = match.params.id deleteRequest( DeleteFilter("roles", id), (data) => { @@ -206,7 +209,7 @@ const EditLanguage = ({ match }) => { useEffect(() => { getRequest( - GetAData("roles", match.params.id), + GetAData("roles", id), (data, header) => { setIsLoaded(true); setName(data.name) diff --git a/src/Admin/Components/Components/Inputs/EditUser.js b/src/Admin/Components/Components/Inputs/EditUser.js index 1dadf1b4f6367c975ea280184916d353a0cc2fbd..fe9a61c8931170c9685afa20e5a1ac118d569511 100644 --- a/src/Admin/Components/Components/Inputs/EditUser.js +++ b/src/Admin/Components/Components/Inputs/EditUser.js @@ -57,11 +57,12 @@ const useStyles = makeStyles((theme) => ({ }, })); -const EditUser = ({ match }) => { +const EditUser = () => { const classes = useStyles(); let history = useHistory(); const { state } = useContext(Store) - const id = match.params.id + const urlParams = new URLSearchParams(window.location.search); + const id = urlParams.get("id"); const [error, setError] = useState(id !== "-1" ? null : false); //Necessary to consult the API, catch errors const [isLoaded, setIsLoaded] = useState(id === "-1" ? true : false); //Necessary to consult the API, wait until complete @@ -291,10 +292,9 @@ const EditUser = ({ match }) => { deleteRequest( `/users/${userId}`, (data) => { - if(data.errors) + if (data.errors) HandleSnack("Erro!", true, "warning", "#FA8072"); - else - { + else { HandleSnack(`${name} deletado com sucesso!`, true, "success", "#228B22"); history.push("/admin/usersList") } @@ -329,7 +329,7 @@ const EditUser = ({ match }) => { if (data.id) HandleSnack(`O usuário: ${name} foi atualizado`, true, 'success', '#228B22') else { - if(data.errors){ + if (data.errors) { HandleSnack(`${data.errors[0]}`, true, 'warning', '#FA8072') } if (data.email) { @@ -381,12 +381,14 @@ const EditUser = ({ match }) => { body, (data) => { setIsLoading(false) - if (data.id) - { + if (data.id) { HandleSnack(`O usuário: ${name} foi criado`, true, 'success', '#228B22') history.push("/admin/usersList") } else { + if (data.errors) { + HandleSnack(`${data.errors[0]}`, true, 'warning', '#FA8072') + } if (data.password) { let passError = ""; data.password.map((msg) => ( @@ -453,9 +455,9 @@ const EditUser = ({ match }) => { const currRolesList = [...rolesList]; const auxiliarRolesId = [ 1, 2, 3, 4, 5, 6, 7, 9, 10, 11 - ] - for (let i = 0; i < data.roles.length; i++) { - const rol = data.roles[i]; + ] + for (let i = 0; i < data.roles.length; i++) { + const rol = data.roles[i]; const index = auxiliarRolesId.indexOf(rol.id); currRolesList.splice(index, 1); auxiliarRolesId.splice(index, 1); diff --git a/src/Admin/Components/Components/Inputs/EmailInputs.js b/src/Admin/Components/Components/Inputs/EmailInputs.js index 0b7a55e5eb445605db721c1a44394b19e53e2172..f75e8b482316ff43cea4ddff066ef9896ef81798 100644 --- a/src/Admin/Components/Components/Inputs/EmailInputs.js +++ b/src/Admin/Components/Components/Inputs/EmailInputs.js @@ -34,8 +34,6 @@ import { postRequest } from '../../../../Components/HelperFunctions/getAxiosConf import ClassicEditor from "@ckeditor/ckeditor5-build-classic" import { CKEditor } from '@ckeditor/ckeditor5-react'; -let sendToAll = false; - const useStyles = makeStyles((theme) => ({ root: { display: 'flex', @@ -52,11 +50,13 @@ const useStyles = makeStyles((theme) => ({ const EmailInputs = (props) => { const classes = useStyles(); - const [option, setOption] = useState("Todos os usuários"); //labels of the text field 'to' - const [index, setIndex] = useState(0); //Used to display something above the text field 'to' depending on what the user clicks + const [option, setOption] = useState(props.email ? "Emails" : "All"); //labels of the text field 'to' + const [isToEmails, setIsToEmails] = useState(props.email ? true : false) + const [isToAll, setIsToAll] = useState(props.email ? false : true) + const [isToRoles, setIsToRoles] = useState(false) // Capture th text insert by the user in the fields - const [emails, setEmails] = useState(props.email === "none" ? "" : props.email); + const [emails, setEmails] = useState(props.email ? props.email : ""); const [emailsAdress, setEmailsAdress] = useState([]); const [subject, setSubject] = useState(""); const [message, setMessage] = useState(""); @@ -153,12 +153,22 @@ const EmailInputs = (props) => { const handleChange = (e) => { const value = e.target.value; - if (value === "All") { - sendToAll = true; - } else { - sendToAll = false; + if (value === 'All') { + setIsToAll(true) + setIsToEmails(false) + setIsToRoles(false) + } + if (value === 'Emails') { + setIsToEmails(true) + setIsToRoles(false) + setIsToAll(false) } - setOption(value); + if (value === 'Roles') { + setIsToRoles(true) + setIsToAll(false) + setIsToEmails(false) + } + setOption(value) }; const handleChangeCheckBox = (i) => { @@ -188,7 +198,7 @@ const EmailInputs = (props) => { const OnKeyPressHandler = (key) => { if (key === 13) { - if (!isEmpty(emails)) { + if (!itsEmpty(emails)) { if (emails.includes("@")) { const arr = [...emailsAdress]; arr.push(emails); @@ -218,10 +228,6 @@ const EmailInputs = (props) => { setEmailsAdress(copyEmail); }; - const isEmpty = (text) => { - return text.length === 0 ? true : false; - }; - // Handle snack infos const HandleSnack = (message, state, icon, color) => { setSnackInfo({ @@ -238,45 +244,100 @@ const EmailInputs = (props) => { setEmailsAdress([]); }; + const itsEmpty = (obj) => { + return obj.length === 0 + } + const submitRequest = async () => { - // setIsSending(true); + setIsSending(true); + const rolesArr = []; - for (let index = 0; index < roles.length; index++) { - const role = roles[index] - if (role.isChecked) - rolesArr.push(role.value) - } - console.log(rolesArr) - console.log(sendToAll) const api = `/email`; const body = { "email": { - "all_users": sendToAll, + "all_users": isToAll, "subject": subject, "body": message, - "emails": emailsAdress, - "roles": rolesArr, + "emails": isToEmails ? emailsAdress : [], + "roles": isToRoles ? rolesArr : [], }, }; - postRequest( - api, - body, - (data, header) => { - HandleSnack( - "O email foi enviado com sucesso", - true, - "success", - "#228B22" - ); - setIsSending(false); - CleanFields(); - }, - (error) => { - HandleSnack("Ocorreu algum erro", true, "warning", "#FA8072"); - setIsSending(false); - CleanFields(); - } - ) + + for (let index = 0; index < roles.length; index++) { + const role = roles[index] + if (role.isChecked) + rolesArr.push(role.value) + } + + if (isToRoles && !itsEmpty(rolesArr) && !itsEmpty(subject) && !itsEmpty(body)) + postRequest( + api, + body, + (data, header) => { + HandleSnack( + "O email foi enviado com sucesso", + true, + "success", + "#228B22" + ); + setIsSending(false); + CleanFields(); + }, + (error) => { + HandleSnack("Ocorreu algum erro", true, "warning", "#FA8072"); + setIsSending(false); + CleanFields(); + } + ) + else if (isToEmails && !itsEmpty(emailsAdress) && !itsEmpty(subject) && !itsEmpty(body)) + postRequest( + api, + body, + (data, header) => { + HandleSnack( + "O email foi enviado com sucesso", + true, + "success", + "#228B22" + ); + setIsSending(false); + CleanFields(); + }, + (error) => { + HandleSnack("Ocorreu algum erro", true, "warning", "#FA8072"); + setIsSending(false); + CleanFields(); + } + ) + else if (isToAll && !itsEmpty(emailsAdress) && !itsEmpty(subject) && !itsEmpty(body)) + postRequest( + api, + body, + (data, header) => { + HandleSnack( + "O email foi enviado com sucesso", + true, + "success", + "#228B22" + ); + setIsSending(false); + CleanFields(); + }, + (error) => { + HandleSnack("Ocorreu algum erro", true, "warning", "#FA8072"); + setIsSending(false); + CleanFields(); + } + ) + else { + HandleSnack( + "Você precisa preencher todos os campos!", + true, + "warning", + "#FFC125" + ); + setIsSending(false); + } }; return ( @@ -328,7 +389,6 @@ const EmailInputs = (props) => { > {options.map((option, index) => ( <MenuItem - onClick={() => setIndex(index)} key={option.value} value={option.value} > @@ -337,8 +397,8 @@ const EmailInputs = (props) => { ))} </TextField> <div style={{ height: "1em" }} /> - - {index === 0 ? null : index === 1 ? ( + { + isToRoles && <FormGroup style={{ marginBottom: "1em" }}> {roles.map((role, index) => ( <FormControlLabel @@ -355,45 +415,45 @@ const EmailInputs = (props) => { /> ))} </FormGroup> - ) : ( - <> - <div - style={{ - display: "flex", - flexDirection: "row", - flexWrap: "wrap", - justifyContent: "Space-between", - marginBottom: "1em" - }} - > - {emailsAdress.map((email, index) => ( - <li key={index} style={{ listStyleType: "none", marginBottom: "0.5em" }}> - <Chip - label={email} - onDelete={() => HandleDelete(index)} - classes={classes.chip} - /> - </li> - ))} - </div> - - <TextField - id="outlined-input" - label="Emails" - rows={1} - error={errorInEmails.error} - helperText={errorInEmails.message} - value={emails} - onKeyPress={(key) => OnKeyPressHandler(key.which)} - onChange={EmailsHandler} - // onBlur={ShowEmails} - placeholder="Digite um email por vez e pressione Enter" - variant="outlined" - style={{ marginBottom: "1em" }} - /> - </> - )} - + } + { + isToEmails && + <> + <div + style={{ + display: "flex", + flexDirection: "row", + flexWrap: "wrap", + justifyContent: "Space-between", + marginBottom: "1em" + }} + > + {emailsAdress.map((email, index) => ( + <li key={index} style={{ listStyleType: "none", marginBottom: "0.5em" }}> + <Chip + label={email} + onDelete={() => HandleDelete(index)} + classes={classes.chip} + /> + </li> + ))} + </div> + <TextField + id="outlined-input" + label="Emails" + rows={1} + error={errorInEmails.error} + helperText={errorInEmails.message} + value={emails} + onKeyPress={(key) => OnKeyPressHandler(key.which)} + onChange={EmailsHandler} + // onBlur={ShowEmails} + placeholder="Digite um email por vez e pressione Enter" + variant="outlined" + style={{ marginBottom: "1em" }} + /> + </> + } <TextField id="outlined-input" label="Assunto" @@ -404,7 +464,7 @@ const EmailInputs = (props) => { onChange={SubjectHandler} variant="outlined" /> - </form> + </form > <div style={{ height: "1em" }} /> @@ -433,10 +493,10 @@ const EmailInputs = (props) => { color="primary" startIcon={<SendRoundedIcon />} > - {isSending ? <CircularProgress /> : "Enviar"} + {isSending ? <CircularProgress size={24} /> : "Enviar"} </Button> </div> - </div> + </div > ); }; diff --git a/src/Admin/Components/Components/Inputs/IntitutionsInputs.js b/src/Admin/Components/Components/Inputs/IntitutionsInputs.js index a4098e68855cea0deacccf7705205923e740c818..148f006fd401c3e485beb476954f6a324f7d25d3 100644 --- a/src/Admin/Components/Components/Inputs/IntitutionsInputs.js +++ b/src/Admin/Components/Components/Inputs/IntitutionsInputs.js @@ -37,10 +37,10 @@ import { EditFilter, GetAData } from '../../../Filters'; //Routers import { Link } from 'react-router-dom'; -let id; - -const EditInstitution = ({ match }) => { +const EditInstitution = () => { const { state } = useContext(Store); + const urlParams = new URLSearchParams(window.location.search); + const id = urlParams.get("institution"); 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 @@ -98,7 +98,7 @@ const EditInstitution = ({ match }) => { } setCountry(e.target.value) } - + // Handle snack infos const HandleSnack = (message, state, icon, color) => { setSnackInfo({ @@ -145,18 +145,21 @@ const EditInstitution = ({ match }) => { if (data.id) HandleSnack('A instituição foi criada com sucesso!', true, 'success', '#228B22') else { - if(data.errors){ + if (data.errors) { HandleSnack(`${data.errors[0]}`, true, 'warning', '#FA8072') } - if (data.name) { - let errorName = ""; - data.name.map((err) => ( - errorName = errorName + err + " e " - )) - setErrorInName({ - error: true, - message: errorName - }) + else { + HandleSnack('Você precisa preencher algumas informações obrigatórias', true, 'warning', '#FFC125') + if (data.name) { + let errorName = ""; + data.name.map((err) => ( + errorName = errorName + err + " e " + )) + setErrorInName({ + error: true, + message: errorName + }) + } } } setIsLoading(false) @@ -209,8 +212,9 @@ const EditInstitution = ({ match }) => { ] useEffect(() => { + getRequest( - GetAData("institutions", match.params.id), + GetAData("institutions", id), (data, header) => { setIsLoaded(true); setName(data.name) @@ -218,7 +222,6 @@ const EditInstitution = ({ match }) => { setAdress(data.adress) setCity(data.city) setCountry(data.country) - id = data.id }, (error) => { setIsLoaded(true); diff --git a/src/Admin/Components/Components/Inputs/NoteVarInputs.js b/src/Admin/Components/Components/Inputs/NoteVarInputs.js index 8753d1a21b214342965e7bbc9f6cbc0427ab8f40..3c1542ec851b700c0b53755592659fd2a7f9cd21 100644 --- a/src/Admin/Components/Components/Inputs/NoteVarInputs.js +++ b/src/Admin/Components/Components/Inputs/NoteVarInputs.js @@ -37,14 +37,15 @@ import { EditFilter, GetAData } from '../../../Filters'; import { Link } from 'react-router-dom'; import Unauthorized from '../Unauthorized'; -const NoteVarInputs = ({ match }) => { +const NoteVarInputs = () => { const { state } = useContext(Store); + const urlParams = new URLSearchParams(window.location.search); + const id = urlParams.get("id"); 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 [isLoading, setIsLoading] = useState(false); - const id = match.params.id const [name, setName] = useState() const [code, setCode] = useState() const [weight, setWeight] = useState() @@ -165,28 +166,31 @@ const NoteVarInputs = ({ match }) => { if (data.id) HandleSnack('A variável de nota foi atualizada com sucesso!', true, 'success', '#228B22') else { - if(data.errors){ + if (data.errors) { HandleSnack(`${data.errors[0]}`, true, 'warning', '#FA8072') } - if (data.name) { - let errorName = ""; - data.name.map((err) => ( - errorName = errorName + err + " e " - )) - setErrorInName({ - error: true, - message: errorName - }) - } - if(data.weight){ - let weightError = ""; - data.weight.map((err) => ( - weightError = weightError + err + " e " - )) - setErrorInWeight({ - error: true, - message : weightError - }) + else { + HandleSnack('Você precisa preencher algumas informações obrigatórias', true, 'warning', '#FFC125') + if (data.name) { + let errorName = ""; + data.name.map((err) => ( + errorName = errorName + err + " e " + )) + setErrorInName({ + error: true, + message: errorName + }) + } + if (data.weight) { + let weightError = ""; + data.weight.map((err) => ( + weightError = weightError + err + " e " + )) + setErrorInWeight({ + error: true, + message: weightError + }) + } } } setIsLoading(false) @@ -217,7 +221,7 @@ const NoteVarInputs = ({ match }) => { useEffect(() => { getRequest( - GetAData("scores", match.params.id), + GetAData("scores", id), (data, header) => { setIsLoaded(true); setName(data.name) diff --git a/src/Admin/Components/Components/MobileComponents/MobilePageHeader.js b/src/Admin/Components/Components/MobileComponents/MobilePageHeader.js index 99405165da5b74310a7c9f4fb7c794ce4fea3106..f3520c9f12319310eba1544dd60d551aa001a29e 100644 --- a/src/Admin/Components/Components/MobileComponents/MobilePageHeader.js +++ b/src/Admin/Components/Components/MobileComponents/MobilePageHeader.js @@ -16,7 +16,7 @@ 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 } from "react"; +import React from "react"; import Paper from "@material-ui/core/Paper" import Grid from "@material-ui/core/Grid" import Button from "@material-ui/core/Button" diff --git a/src/Admin/Components/Components/Table.js b/src/Admin/Components/Components/Table.js index 5e74b53f158fc26f834a67b9aa2658721ef6e448..ddb7a377b4fea041f52c881835700312b7f8e6c8 100644 --- a/src/Admin/Components/Components/Table.js +++ b/src/Admin/Components/Components/Table.js @@ -23,23 +23,7 @@ const StyledTableCell = withStyles((theme) => ({ const useStyles = makeStyles({ table: { minWidth: 700, - width : "100%" - }, - root: { - minWidth: 275, - boxShadow: '2px 2px 1px #A9A9A9' - }, - bullet: { - display: 'inline-block', - margin: '0 2px', - transform: 'scale(0.8)', - }, - title: { - fontSize: 28, - fontWeight: "500" - }, - pos: { - marginBottom: 12, + width: "100%" }, }); @@ -53,12 +37,13 @@ const TableData = (props) => { <TableRow> { props.top.map((top, index) => ( - index === 0 ? + top === "ID" ? <StyledTableCell key={index}> <div style={{ display: 'flex', flexDirection: 'row', alignItems: 'center' }}> {top} { - props.onIconPressed === undefined ? <div></div> : <IconButton onClick={props.onIconPressed} color='primary'> + props.onIconPressed && + <IconButton onClick={props.onIconPressed} color='primary'> <FilterListRoundedIcon style={{ color: 'white' }} /> </IconButton> } diff --git a/src/Admin/Pages/AdminLabelTabs/LabelTabs.js b/src/Admin/Pages/AdminLabelTabs/LabelTabs.js index eddb77be77677a6c655745ba407cff0219c8b02a..54b2a0fdf2dfd40bbef4f5d36ee15c9d6b95f486 100644 --- a/src/Admin/Pages/AdminLabelTabs/LabelTabs.js +++ b/src/Admin/Pages/AdminLabelTabs/LabelTabs.js @@ -18,70 +18,109 @@ along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/> //This file has the labels of the left menu navigation from admin page +import React from "react"; +import HomeIcon from "@material-ui/icons/Home"; +import PeopleRoundedIcon from "@material-ui/icons/PeopleRounded"; +import ContactSupportRoundedIcon from "@material-ui/icons/ContactSupportRounded"; +import LanguageRoundedIcon from "@material-ui/icons/LanguageRounded"; +import AccountBalanceRoundedIcon from "@material-ui/icons/AccountBalanceRounded"; +import MenuBookRoundedIcon from "@material-ui/icons/MenuBookRounded"; +import StarRoundedIcon from "@material-ui/icons/StarRounded"; +import AccountCircleRoundedIcon from "@material-ui/icons/AccountCircleRounded"; +import TrendingUpRoundedIcon from "@material-ui/icons/TrendingUpRounded"; +import HelpRoundedIcon from "@material-ui/icons/HelpRounded"; +import CheckRoundedIcon from "@material-ui/icons/CheckRounded"; +import PersonRoundedIcon from "@material-ui/icons/PersonRounded"; +import BlockRoundedIcon from "@material-ui/icons/BlockRounded"; +import AnnouncementRoundedIcon from "@material-ui/icons/AnnouncementRounded"; +import EmailRoundedIcon from "@material-ui/icons/EmailRounded"; +import AllOutIcon from "@material-ui/icons/AllOut"; + +const orange = "#ff7f00"; +const pink = "#e81f4f"; +const purple = "#673ab7"; +const blue = "#00bcd4"; + const TabsItens = [ { - label: "Home", - href: '/admin/home' + label: "Home", + href: '/admin/home', + icon: <HomeIcon style={{ fill: orange }} />, }, { label: 'Coleções', href: '/admin/Collections', + icon: <PeopleRoundedIcon style={{ fill: pink }} /> }, { label: "Atividades", href: '/admin/activities', + icon: <AllOutIcon style={{ fill: purple }} />, }, { label: "Dúvidas da comunidade", - href: '/admin/CommunityQuestions' + href: '/admin/CommunityQuestions', + icon: <ContactSupportRoundedIcon style={{ fill: blue }} />, }, { label: "Instituições", - href: '/admin/intitutions' + href: '/admin/intitutions', + icon: <AccountBalanceRoundedIcon style={{ fill: orange }} />, }, { label: "Linguagens", href: '/admin/languages', + icon: <LanguageRoundedIcon style={{ fill: pink }} />, }, { label: "Objetos educacionais", href: "/admin/learningObjects", + icon: <MenuBookRoundedIcon style={{ fill: purple }} />, }, { label: "Rating", - href : '/admin/Ratings' + href: '/admin/Ratings', + icon: <StarRoundedIcon style={{ fill: blue }} />, }, { label: "Permissões do usuário", href: "/admin/permissions", + icon: <AccountCircleRoundedIcon style={{ fill: orange }} />, }, { - label: "Variáveis de nota", - href:'/admin/noteVars' + label: "Variáveis de nota", + href: '/admin/noteVars', + icon: <TrendingUpRoundedIcon style={{ fill: pink }} />, }, { label: "Perguntas curadoria", - href: "/admin/Questions" + href: "/admin/Questions", + icon: <HelpRoundedIcon style={{ fill: purple }} />, }, { label: "Aprovação de professores", - href: "/admin/users/teacher_requests" + href: "/admin/users/teacher_requests", + icon: <CheckRoundedIcon style={{ fill: blue }} />, }, { label: "Usuários", - href : "/admin/usersList" + href: "/admin/usersList", + icon: <PersonRoundedIcon style={{ fill: orange }} />, }, { label: "Usuários bloqueados", - href : "/admin/BlockedUsers" + href: "/admin/BlockedUsers", + icon: <BlockRoundedIcon style={{ fill: pink }} />, }, { label: "Denúncias", href: "/admin/complaints", + icon: <AnnouncementRoundedIcon style={{ fill: purple }} />, }, { label: "Enviar email", - href:'/admin/sendEmail/none' + href: '/admin/sendEmail', + icon: <EmailRoundedIcon style={{ fill: blue }} />, }, ]; diff --git a/src/Admin/Pages/Pages/SubPages/Activity.js b/src/Admin/Pages/Pages/SubPages/Activity.js index 25d622a09195fd25f1d3a2cbe65583b15f6c0e57..c87c1b25fd2b7ce07aac8c36adf11909a794cd9a 100644 --- a/src/Admin/Pages/Pages/SubPages/Activity.js +++ b/src/Admin/Pages/Pages/SubPages/Activity.js @@ -16,491 +16,414 @@ 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 } from "react"; -import moment from 'moment'; +import React, { useEffect, useState } 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 { getRequest } from '../../../../Components/HelperFunctions/getAxiosConfig'; -import LoadingSpinner from '../../../../Components/LoadingSpinner'; +import TableData from "../../../Components/Components/Table" +import SnackBar from "../../../../Components/SnackbarComponent" +import { Url } from "../../../Filters" +import { getRequest } from '../../../../Components/HelperFunctions/getAxiosConfig' +import LoadingSpinner from '../../../../Components/LoadingSpinner' +import MobilePageHeader from '../../../Components/Components/MobileComponents/MobilePageHeader' +import PageHeader from '../../../Components/Components/PageHeader' //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 AllOutIcon from "@material-ui/icons/AllOut"; +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, Paper } 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 AllOutIcon from "@material-ui/icons/AllOut" //routers -import { Link } from 'react-router-dom'; +import { Link } from 'react-router-dom' import MobileList from "../../../Components/Components/MobileComponents/SimpleList" import styled from "styled-components" -import PageHeader from "../../../Components/Components/PageHeader" - -let currPage = 0; const StyledTableCell = withStyles((theme) => ({ - head: { - backgroundColor: theme.palette.common.black, - color: theme.palette.common.white, - }, - body: { - fontSize: 14, - }, + 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, - }, + root: { + "&:nth-of-type(odd)": { + backgroundColor: theme.palette.action.hover, }, + }, }))(TableRow); const Activity = () => { - const ADD_ONE_LENGHT = [""]; - const TOP_LABELS = [ - "CRIADO EM", - "DONO(A)", - "ATIVIDADE", - "PRIVACIDADE", - "VISUALIZAR", - ]; //Labels from Table - const WINDOW_WIDTH = window.innerWidth - - 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("Todos os usuários"); //labels of the text field 'to' - - const [snackInfo, setSnackInfo] = useState({ - message: "", - icon: "", - open: false, - color: "", + const ADD_ONE_LENGHT = [""]; + const TOP_LABELS = [ + "CRIADO EM", + "DONO(A)", + "ATIVIDADE", + "PRIVACIDADE", + "VISUALIZAR", + ]; //Labels from Table + const WINDOW_WIDTH = window.innerWidth + + 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 [showFilter, setShowFilter] = useState(false); + const [option, setOption] = useState(); //labels of the text field 'to' + const [currPage, setCurrPage] = useState(0) + + const [snackInfo, setSnackInfo] = useState({ + message: "", + icon: "", + open: false, + color: "", + }); + + const options = [ + { + name: "private", + value: "Privado", + }, + { + name: "public", + value: "Público", + }, + ]; + + //handle snack info + const HandleSnack = (message, state, icon, color) => { + setSnackInfo({ + message: message, + icon: icon, + open: state, + color: color, }); - - const options = [ - { - value: "private", - label: "Privado", - }, - { - value: "public", - label: "Público", - }, - ]; - - //handle snack info - const HandleSnack = (message, state, icon, color) => { - setSnackInfo({ - message: message, - icon: icon, - open: state, - color: color, - }); - }; - - //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) => { - setIsLoaded(false) - const value = e.target.value; - currPage = 0; - setOption(value); - - getRequest(Url("activities", `"privacy" : "${value}"`, `${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 DisplayDate = (date) => { - const convertedData = moment.utc(date); - return moment(convertedData) - .format("LLL") - .toString(); - }; - - //getting data from server - useEffect(() => { - getRequest( - Url("activities", "", `${currPage}`, "DESC"), - (data, header) => { - const arrData = [...data]; - setItems(arrData.concat(ADD_ONE_LENGHT)); - setIsLoaded(true); - setError(false); + }; + + const handleChange = (e) => { + setOption(e.target.value); + }; + + const DisplayDate = (date) => { + const convertedData = moment.utc(date); + return moment(convertedData) + .format("LLL") + .toString(); + }; + + const buildUrl = (privacyOpt) => { + if (privacyOpt) + return Url("activities", `"privacy" : "${privacyOpt}"`, currPage, "DESC") + + return Url("activities", "", currPage, "DESC") + } + + useEffect(() => { + if (currPage === 0) + setIsLoaded(false) + else + setIsLoadingMoreItems(true) + getRequest( + buildUrl(option), + (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] + if (currPage === 0) { + setItems(arrData.concat(ADD_ONE_LENGHT)) + } + else { + 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)) + } + } + setIsLoaded(true) + setIsLoadingMoreItems(false) + }, + (error) => { + HandleSnack('Erro ao carregar os dados', true, 'warning', '#FA8072') + setIsLoadingMoreItems(false) + setIsLoaded(true) + setError(true) + } + ) + }, [currPage, option]) + + useEffect(() => { + setOption() + setCurrPage(0) + }, [showFilter]) + + if (error) { + return <div>Error: {error.message}</div>; + } else if (!isLoaded) { + return <LoadingSpinner text="Carregando..." /> + } else { + + if (WINDOW_WIDTH <= 820) { + return <> + <SnackBar + severity={snackInfo.icon} + text={snackInfo.message} + snackbarOpen={snackInfo.open} + color={snackInfo.color} + handleClose={() => + setSnackInfo({ + message: "", + icon: "", + open: false, + color: "", + }) + } + /> + + <MobilePageHeader + title="Atividades" + actions={[ + { + name: "Atualizar", + isLoading: false, + func: () => { + setCurrPage(0) + }, + icon: <UpdateRoundedIcon /> }, - (error) => { - HandleSnack("Erro ao carregar os dados", true, "warning", "#FA8072"); - setIsLoaded(true); - setError(true); + { + name: "Filtrar", + isLoading: false, + func: () => { + setShowFilter(!showFilter); + }, + icon: <FilterListRoundedIcon /> } - ) - }, []); - - if (error) { - return <div>Error: {error.message}</div>; - } else if (!isLoaded) { - return <LoadingSpinner text="Carregando..." /> - } else { - - if (WINDOW_WIDTH <= 758) { - 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={12}> - <Typography variant="h4">Atividades</Typography> - </Grid> - <Grid - item - xs={12} - > - <Grid container justify="flex-start" spacing={3}> - <Grid item> - <Button - variant="contained" - color="secondary" - disabled={isUpdating} - onClick={() => { - currPage = 0; - UpdateHandler( - Url("activities", "", `${currPage}`, "DESC") - ); - }} - startIcon={<UpdateRoundedIcon />} - > - {isUpdating ? <CircularProgress size={24} /> : "Atualizar"} - </Button> - </Grid> - <Grid item> - <Button - variant="contained" - color="secondary" - onClick={() => { - setShowFilter(!showFilter); - }} - startIcon={<FilterListRoundedIcon />} - > - Filtrar - </Button> - </Grid> - </Grid> - </Grid> - </Grid> - - {showFilter ? ( - <> - <div style={{ height: "1em" }}></div> - - <div style={{ alignSelf: "flex-end" }}> - <TextField - select={true} - label="Filtro" - value={option ? option : ""} - onChange={handleChange} - helperText="Por favor, selecione uma das opções" - > - {options.map((option, index) => ( - <MenuItem - key={option.value} - value={option.value} - > - {option.label} - </MenuItem> - ))} - </TextField> - </div> - </> - ) : null} - </Paper> - - <div style={{ height: "2em" }}></div> - - {items.map((row, index) => - index === items.length - 1 ? ( - <StyledDivButton> - <Button - key={index} - color="primary" - variant="text" - // disabled={isLoadingMoreItems} - startIcon={<AddRoundedIcon />} - disabled={isLoadingMoreItems} - onClick={() => { - currPage++; - if (showFilter) { - LoadMoreItens( - Url("activities", `"privacy" : "${option}"`, `${currPage}`, "DESC") - ); - } else { - LoadMoreItens( - Url("activities", "", `${currPage}`, "DESC") - ); - } - }} - > - {isLoadingMoreItems ? ( - <CircularProgress size={24} /> - ) : ( - "Carregar mais itens" - )} - </Button> - </StyledDivButton> - ) : ( - <> - <MobileList - key={index} - title={row.id} - subtitle={row.privacy} - backColor={"#673ab7"} - avatar={<AllOutIcon />} - href={`/admin/activity/${row.id}`} - reset={() => { - currPage = 0; - }} - data={ - [ - { - title: "Dono(a)", - subtitle: row.owner ? row.owner.name : "Sem dados" - - }, - { - title: "Criado em", - subtitle: DisplayDate(row.created_at) - }, - { - title: "Atividade", - subtitle: row.activity - } - ] - } - /> - <div style={{ height: "0.5em" }} /> - </> - ) - )} + ]} + > + {showFilter ? ( + <> + <div style={{ height: "1em" }}></div> + + <div style={{ alignSelf: "flex-end" }}> + <TextField + select + label="Filtro" + value={option ? option : ""} + onChange={handleChange} + helperText="Por favor, selecione uma das opções" + > + {options.map((option, index) => ( + <MenuItem + key={option.value} + value={option.name} + name={option.value} + > + {option.value} + </MenuItem> + ))} + </TextField> + </div> </> - } - else { - return <> - <SnackBar - severity={snackInfo.icon} - text={snackInfo.message} - snackbarOpen={snackInfo.open} - color={snackInfo.color} - handleClose={() => - setSnackInfo({ - message: "", - icon: "", - open: false, - color: "", - }) - } + ) : null} + </MobilePageHeader> + + <div style={{ height: "2em" }}></div> + + {items.map((row, index) => + index === items.length - 1 ? ( + <StyledDivButton + key={new Date().toISOString() + row.created_at} + > + <Button + key={new Date().toISOString() + row.created_at} + color="primary" + variant="text" + // disabled={isLoadingMoreItems} + startIcon={<AddRoundedIcon />} + disabled={isLoadingMoreItems} + onClick={() => { + setCurrPage(currPage + 1) + }} + > + {isLoadingMoreItems ? ( + <CircularProgress size={24} /> + ) : ( + "Carregar mais itens" + )} + </Button> + </StyledDivButton> + ) : ( + <> + <MobileList + key={new Date().toISOString() + row.created_at} + title={row.id} + subtitle={row.privacy} + backColor={"#673ab7"} + avatar={<AllOutIcon />} + href={`/admin/activity?activity=${row.id}`} + reset={() => { + + }} + data={ + [ + { + title: "Dono(a)", + subtitle: row.owner ? row.owner.name : "Sem dados" + + }, + { + title: "Criado em", + subtitle: DisplayDate(row.created_at) + }, + { + title: "Atividade", + subtitle: row.activity + } + ] + } /> - <PageHeader - title="Atividades" - actions={[ - { - name: "Atualizar", - isLoading: isUpdating, - func: () => { - currPage = 0; - UpdateHandler( - Url("activities", "", `${currPage}`, "DESC") - ); - }, - icon: <UpdateRoundedIcon /> - }, - { - name: "Filtrar", - isLoading: false, - func: () => { - setShowFilter(!showFilter); - }, - icon: <FilterListRoundedIcon /> - } - ]} + <div style={{ height: "0.5em" }} /> + </> + ) + )} + </> + } + else { + return <> + <SnackBar + severity={snackInfo.icon} + text={snackInfo.message} + snackbarOpen={snackInfo.open} + color={snackInfo.color} + handleClose={() => + setSnackInfo({ + message: "", + icon: "", + open: false, + color: "", + }) + } + /> + <PageHeader + title="Atividades" + actions={[ + { + name: "Atualizar", + isLoading: false, + func: () => { + setCurrPage(0) + }, + icon: <UpdateRoundedIcon /> + }, + { + name: "Filtrar", + isLoading: false, + func: () => { + setShowFilter(!showFilter); + }, + icon: <FilterListRoundedIcon /> + } + ]} + > + {showFilter ? ( + <> + <div style={{ height: "1em" }}></div> + + <div style={{ alignSelf: "flex-end" }}> + <TextField + select + label="Filtro" + value={option ? option : ""} + onChange={handleChange} + helperText="Por favor, selecione uma das opções" > - {showFilter ? ( - <> - <div style={{ height: "1em" }}></div> - - <div style={{ alignSelf: "flex-end" }}> - <TextField - select - label="Filtro" - value={option ? option : ""} - onChange={handleChange} - helperText="Por favor, selecione uma das opções" - > - {options.map((option, index) => ( - <MenuItem - key={option.value} - value={option.value} - > - {option.label} - </MenuItem> - ))} - </TextField> - </div> - </> - ) : null} - </PageHeader> - - <div style={{ height: "2em" }}></div> - - <TableData top={TOP_LABELS}> - <TableBody> - {items.map((row, index) => - index === items.length - 1 ? ( - <StyledTableRow key={index} style={{ padding: "1em" }}> - {/* Button to load more data */} - <StyledTableCell> - <Button - color="primary" - variant="text" - // disabled={isLoadingMoreItems} - startIcon={<AddRoundedIcon />} - disabled={isLoadingMoreItems} - onClick={() => { - currPage++; - if (showFilter) { - LoadMoreItens( - Url("activities", `"privacy" : "${option}"`, `${currPage}`, "DESC") - ); - } else { - LoadMoreItens( - Url("activities", "", `${currPage}`, "DESC") - ); - } - }} - > - {isLoadingMoreItems ? ( - <CircularProgress size={24} /> - ) : ( - "Carregar mais itens" - )} - </Button> - </StyledTableCell> - </StyledTableRow> - ) : ( - <StyledTableRow key={index}> - <StyledTableCell component="th" scope="row"> - {DisplayDate(row.created_at)} - </StyledTableCell> - <StyledTableCell align="right"> - { - row.owner ? row.owner.name : "" - } - </StyledTableCell> - <StyledTableCell align="right"> - {row.activity} - </StyledTableCell> - <StyledTableCell align="right">{row.privacy}</StyledTableCell> - <StyledTableCell align="right"> - <Link to={`/admin/activity/${row.id}`}> - <IconButton onClick={() => { currPage = 0 }}> - <VisibilityIcon style={{ fill: "#00bcd4" }} /> - </IconButton> - </Link> - </StyledTableCell> - </StyledTableRow> - ) - )} - </TableBody> - </TableData> + {options.map((option, index) => ( + <MenuItem + key={option.value} + value={option.name} + name={option.value} + > + {option.value} + </MenuItem> + ))} + </TextField> + </div> </> - } + ) : null} + </PageHeader> + + <div style={{ height: "2em" }}></div> + + <TableData top={TOP_LABELS}> + <TableBody> + {items.map((row, index) => + index === items.length - 1 ? ( + <StyledTableRow key={new Date().toISOString() + row.created_at} style={{ padding: "1em" }}> + {/* Button to load more data */} + <StyledTableCell> + <Button + color="primary" + variant="text" + // disabled={isLoadingMoreItems} + startIcon={<AddRoundedIcon />} + disabled={isLoadingMoreItems} + onClick={() => { + setCurrPage(currPage + 1) + }} + > + {isLoadingMoreItems ? ( + <CircularProgress size={24} /> + ) : ( + "Carregar mais itens" + )} + </Button> + </StyledTableCell> + </StyledTableRow> + ) : ( + <StyledTableRow key={new Date().toISOString() + index}> + <StyledTableCell component="th" scope="row"> + {DisplayDate(row.created_at)} + </StyledTableCell> + <StyledTableCell align="right"> + { + row.owner ? row.owner.name : "" + } + </StyledTableCell> + <StyledTableCell align="right"> + {row.activity} + </StyledTableCell> + <StyledTableCell align="right">{row.privacy}</StyledTableCell> + <StyledTableCell align="right"> + <Link to={`/admin/activity?activity=${row.id}`}> + <IconButton> + <VisibilityIcon style={{ fill: "#00bcd4" }} /> + </IconButton> + </Link> + </StyledTableCell> + </StyledTableRow> + ) + )} + </TableBody> + </TableData> + </> } + } }; + + export default Activity; const StyledDivButton = styled(Paper)` diff --git a/src/Admin/Pages/Pages/SubPages/AproveTeacher.js b/src/Admin/Pages/Pages/SubPages/AproveTeacher.js index df9cbfff609dadd19a830e7ac6f23fca0901a1aa..b8f7203ab10a3c0dfbb9ee471b47b77acd2ffe35 100644 --- a/src/Admin/Pages/Pages/SubPages/AproveTeacher.js +++ b/src/Admin/Pages/Pages/SubPages/AproveTeacher.js @@ -16,18 +16,23 @@ 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 React, { useEffect, useState } from "react"; import moment from "moment"; +import styled from "styled-components"; //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, + getRequest, + postRequest, } from "../../../../Components/HelperFunctions/getAxiosConfig"; +import MobileList from "../../../Components/Components/MobileComponents/SimpleList"; +import MobilePageHeader from "../../../Components/Components/MobileComponents/MobilePageHeader"; +import PageHeader from "../../../Components/Components/PageHeader"; +import { apiDomain } from '../../../../env'; +import noAvatar from "../../../../img/default_profile.png" //imports from material ui import { withStyles } from "@material-ui/core/styles"; import TableBody from "@material-ui/core/TableBody"; @@ -36,7 +41,7 @@ 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 { Button, 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"; @@ -44,862 +49,716 @@ 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"; +import EmailRoundedIcon from '@material-ui/icons/EmailRounded'; //routers import { Link } from "react-router-dom"; -import Unauthorized from "../../../Components/Components/Unauthorized"; -import styled from "styled-components"; -import MobileList from "../../../Components/Components/MobileComponents/SimpleList"; -import { apiDomain } from '../../../../env'; -import noAvatar from "../../../../img/default_profile.png"; -import EmailRoundedIcon from '@material-ui/icons/EmailRounded'; -let currPage = 0; -let currStateFilter = "requested"; -let currNameFilter = ""; -let currEmailFilter = ""; const StyledTableCell = withStyles((theme) => ({ - head: { - backgroundColor: theme.palette.common.black, - color: theme.palette.common.white, - }, - body: { - fontSize: 14, - }, + 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, - }, + root: { + "&:nth-of-type(odd)": { + backgroundColor: theme.palette.action.hover, }, + }, }))(TableRow); const AproveTeacher = () => { - const { state } = useContext(Store); - const WINDOW_WIDTH = window.innerWidth; - - 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("requested"); - const [name, setName] = useState(""); - const [email, setEmail] = useState(""); - - const [snackInfo, setSnackInfo] = useState({ - message: "", - icon: "", - open: false, - color: "", + const WINDOW_WIDTH = window.innerWidth + 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 [invertList, setInvertList] = useState(false) + 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 [currPage, setCurrPage] = useState(0) + const [showFilter, setShowFilter] = useState(false); + + const [option, setOption] = useState("requested"); + const [name, setName] = useState(""); + const [nameValue, setNameValue] = useState("") + const [email, setEmail] = useState(""); + const [emailValue, setEmailValue] = useState("") + + const [snackInfo, setSnackInfo] = useState({ + message: "", + icon: "", + open: false, + color: "", + }); + + const StateOptions = [ + { name: "requested", value: "Pendente" }, + { name: "accepted", value: "Aceito" }, + { name: "rejected", value: "Rejeitado" }, + ]; + + //handle snack info + const HandleSnack = (message, state, icon, color) => { + setSnackInfo({ + message: message, + icon: icon, + open: state, + color: 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); - } + }; + + const handleChange = (e, type) => { + const value = e.target.value; + setOption(value); + }; + + const NameHandler = (e) => { + setNameValue(e.target.value) + }; + + const EmailHandler = (e) => { + setEmailValue(e.target.value) + }; + + const removeItemFromList = (itemId) => { + let index = -1; + for (let i = 0; i < items.length; i++) { + const element = items[i]; + if (element.id === itemId) { + index = i + break + } + } + if (index !== -1) { + const cpyItems = [...items] + cpyItems.splice(index, 1) + setItems(cpyItems) + } + } + + const ComplaintStatus = (status) => { + switch (status) { + case "accepted": + return ( + <Paper + style={{ + textAlign: "center", + padding: "0.5em", + backgroundColor: "#228B22", + fontWeight: "500", + color: "#FFFAFA", + }} + > + ACEITO + </Paper> ); - }; - - // 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); - } + case "requested": + return ( + <Paper + style={{ + textAlign: "center", + padding: "0.5em", + backgroundColor: "#FF8C00", + fontWeight: "500", + color: "#FFFAFA", + }} + > + PENDENTE + </Paper> ); - }; - - const handleChange = (e, type) => { - const value = e.target.value; - setOption(value); - }; - - const ApplyFilter = (id, type) => { - currStateFilter = id; - currPage = 0; - getRequest( - Url( - "users", - `"submitter_request":"${currStateFilter}","name":"${currNameFilter}","email":"${email}"`, - `${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); - } + case "rejected": + return ( + <Paper + style={{ + textAlign: "center", + padding: "0.5em", + backgroundColor: "#FA8072", + fontWeight: "500", + color: "#FFFAFA", + }} + > + Rejeitado + </Paper> ); - }; - - const NameHandler = (e) => { - currPage = 0; - currNameFilter = e.target.value; - setName(currNameFilter); - getRequest( - Url( - "users", - `"submitter_request":"${currStateFilter}","name":"${currNameFilter}","email":"${email}"`, - `${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); - } + 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, }; - - const EmailHandler = (e) => { - currPage = 0; - currEmailFilter = e.target.value; - setEmail(currEmailFilter); - getRequest( - Url( - "users", - `"submitter_request":"${currStateFilter}","name":"${currNameFilter}","email":"${currEmailFilter}"`, - `${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> - ); + postRequest( + url, + body, + (data) => { + if (data.errors) HandleSnack("Erro!", true, "warning", "#FA8072"); + else { + HandleSnack( + `${userName} aceito como professor!`, + true, + "success", + "#228B22" + ); + setCurrPage(0) + removeItemFromList(userId) } + }, + (error) => { + HandleSnack("Erro!", true, "warning", "#FA8072"); + } + ); + }; + + const handleReject = (userId, userName) => { + const url = `/users/${userId}/add_teacher`; + const body = { + approves: false, }; - - 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) => { - if (data.errors) HandleSnack("Erro!", true, "warning", "#FA8072"); - else { - HandleSnack( - `${userName} aceito como professor!`, - true, - "success", - "#228B22" - ); - currPage = 0; - UpdateHandler( - Url( - "users", - `"submitter_request":"${currStateFilter}","name":"${currNameFilter}","email":"${currEmailFilter}"`, - `${currPage}`, - "DESC" - ) - ); - } - }, - (error) => { - HandleSnack("Erro!", true, "warning", "#FA8072"); - } - ); - }; - - const handleReject = (userId, userName) => { - const url = `/users/${userId}/add_teacher`; - const body = { - approves: false, - }; - postRequest( - url, - body, - (data) => { - if (data.errors) HandleSnack("Erro!", true, "warning", "#FA8072"); - else { - HandleSnack( - `${userName} rejeitado como professor!`, - true, - "success", - "#228B22" - ); - currPage = 0; - UpdateHandler( - Url( - "users", - `"submitter_request":"${currStateFilter}","name":"${currNameFilter}","email":"${currEmailFilter}"`, - `${currPage}`, - "DESC" - ) - ); - } - }, - (error) => { - HandleSnack("Erro!", true, "warning", "#FA8072"); - } - ); - }; - - //getting data from server - useEffect(() => { - getRequest( - Url( - "users", - `"submitter_request":"${currStateFilter}","name":"${currNameFilter}","email":"${currEmailFilter}"`, - `${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); + postRequest( + url, + body, + (data) => { + if (data.errors) HandleSnack("Erro!", true, "warning", "#FA8072"); + else { + HandleSnack( + `${userName} rejeitado como professor!`, + true, + "success", + "#228B22" + ); + setCurrPage(0) + removeItemFromList(userId) + } + }, + (error) => { + HandleSnack("Erro!", true, "warning", "#FA8072"); + } + ); + }; + + const cleanArrayAndInvert = () => { + setInvertList(!invertList) + setCurrPage(0) + setItems([]) + } + + const buildUrl = (email, submitter_request, name, direction) => { + if (email && submitter_request && name) + return Url("users", `"submitter_request" : "${submitter_request}", "email" : "${email}", "name" : "${name}"`, currPage, direction) + + else if (email && name) + return Url("users", `"email" : "${email}", "name" : "${name}"`, currPage, direction) + else if (email && submitter_request) + return Url("users", `"email" : "${email}", "submitter_request" : "${submitter_request}"`, currPage, direction) + else if (name && submitter_request) + return Url("users", `"name" : "${name}", "submitter_request" : "${submitter_request}"`, currPage, direction) + + else if (email) + return Url("users", `"email" : "${email}"`, currPage, direction) + else if (submitter_request) + return Url("users", `"submitter_request" : "${submitter_request}"`, currPage, direction) + else if (name) + return Url("users", `"name" : ${name}`, currPage, direction) + else + return Url("users", "", currPage, direction) + } + + useEffect(() => { + if (currPage === 0) + setIsLoaded(false) + else + setIsLoadingMoreItems(true) + getRequest( + buildUrl(email, option, name, invertList ? "ASC" : "DESC"), + (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] + if (currPage === 0) { + setItems(arrData.concat(ADD_ONE_LENGHT)) + } + else { + 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)) + } + } + setIsLoaded(true) + setIsLoadingMoreItems(false) + }, + (error) => { + HandleSnack('Erro ao carregar os dados', true, 'warning', '#FA8072') + setIsLoadingMoreItems(false) + setIsLoaded(true) + setError(true) + } + ) + }, [currPage, option, email, name, invertList]) + + useEffect(() => { + setOption("requested") + setName("") + setNameValue("") + setEmail("") + setEmailValue("") + }, [showFilter]) + + if (error) { + return <div>Error: {error.message}</div>; + } else if (!isLoaded) { + return <LoadingSpinner text="Carregando..." />; + } else { + if (WINDOW_WIDTH <= 1130) { + return ( + <> + <SnackBar + severity={snackInfo.icon} + text={snackInfo.message} + snackbarOpen={snackInfo.open} + color={snackInfo.color} + handleClose={() => + setSnackInfo({ + message: "", + icon: "", + open: false, + color: "", + }) } - ); - }, []); - - if (error) { - return <div>Error: {error.message}</div>; - } else if (!isLoaded) { - return <LoadingSpinner text="Carregando..." />; - } else if (CheckUserPermission()) { - if (WINDOW_WIDTH <= 1075) { - return ( + /> + <MobilePageHeader + title="Aprovação de professores" + actions={[ + { + name: "Atualizar", + isLoading: false, + func: () => { + setCurrPage(0) + }, + icon: <UpdateRoundedIcon /> + }, + { + name: "Filtrar", + isLoading: false, + func: () => { + setShowFilter(!showFilter); + }, + icon: <FilterListRoundedIcon /> + }, + { + name: "Inverter lista", + isLoading: false, + func: () => { + cleanArrayAndInvert() + }, + } + ]} + > + {showFilter ? ( + <> + <div style={{ height: "1em" }}></div> + {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.value} + value={option.name} + name={option.value} + > + {option.value} + </MenuItem> + ))} + </TextField> + </Grid> + <Grid item> + <TextField + label="Nome" + onChange={NameHandler} + value={nameValue} + onBlur={(event) => { setName(event.target.value) }} + helperText="Retire o foco do campo de texto ao terminar de digitar" + /> + </Grid> + <Grid item> + <TextField + label="Email" + onChange={EmailHandler} + value={emailValue} + onBlur={(event) => { setEmail(event.target.value) }} + helperText="Retire o foco do campo de texto ao terminar de digitar" + /> + </Grid> + </Grid> + ) : null} + </> + ) : null} + </MobilePageHeader> + + <div style={{ height: "2em" }}></div> + + {items.map((row, index) => + index === items.length - 1 ? ( + <StyledDivButton> + <Button + key={new Date().toISOString() + row.created_at} + color="primary" + variant="text" + // disabled={isLoadingMoreItems} + startIcon={<AddRoundedIcon />} + disabled={isLoadingMoreItems} + onClick={() => { + setCurrPage(currPage + 1) + }} + > + {isLoadingMoreItems ? ( + <CircularProgress size={24} /> + ) : ( + "Carregar mais itens" + )} + </Button> + </StyledDivButton> + ) : ( <> - <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={12}> - <Typography variant="h4"> - Lista de pedidos para professores - </Typography> - </Grid> - - <Grid item xs={12}> - <Grid container justify="flex-start" spacing={3}> - <Grid item> - <Button - variant="contained" - color="secondary" - disabled={isUpdating} - onClick={() => { - currPage = 0; - UpdateHandler( - Url( - "users", - `"submitter_request":"${currStateFilter}","name":"${currNameFilter}","email":"${currEmailFilter}"`, - `${currPage}`, - "DESC" - ) - ); - }} - startIcon={<UpdateRoundedIcon />} - > - {isUpdating ? ( - <CircularProgress size={24} /> - ) : ( - "Atualizar" - )} - </Button> - </Grid> - <Grid item> - <Button - variant="contained" - color="secondary" - onClick={() => { - 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} + <MobileList + key={new Date().toISOString() + row.created_at} + title={row.name} + subtitle={row.id} + backColor={"#00bcd4"} + avatar={ + <img + src={row.avatar ? apiDomain + row.avatar : noAvatar} + alt="user avatar" + style={{ + height: "100%", + width: "100%", + borderRadius: "50%", + }} + /> + } + href={`/admin/user?id=${row.id}`} + reset={() => { + + }} + data={[ + { + title: "Email", + subtitle: row.email ? + <Link to={`/admin/sendEmail?email=${row.email}`} style={{ textDecoration: 'none' }}> + <Button + variant='text' + color='primary' + startIcon={<EmailRoundedIcon />} > - <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" onChange={NameHandler} value={name} /> - </Grid> - <Grid item> - <TextField - label="Email" - onChange={EmailHandler} - value={email} - /> - </Grid> - </Grid> - ) : null} - </Paper> - - <div style={{ height: "2em" }}></div> - - {items.map((row, index) => - index === items.length - 1 ? ( - <StyledDivButton> - <Button - key={index} - color="primary" - variant="text" - // disabled={isLoadingMoreItems} - startIcon={<AddRoundedIcon />} - disabled={isLoadingMoreItems} - onClick={() => { - currPage++; - LoadMoreItens( - Url( - "users", - `"submitter_request":"${currStateFilter}","name":"${currNameFilter}","email":"${currEmailFilter}"`, - `${currPage}`, - "DESC" - ) - ); - }} - > - {isLoadingMoreItems ? ( - <CircularProgress size={24} /> - ) : ( - "Carregar mais itens" - )} - </Button> - </StyledDivButton> - ) : ( - <> - <MobileList - key={index} - title={row.name} - subtitle={row.id} - backColor={"#00bcd4"} - avatar={ - <img - src={row.avatar ? apiDomain + row.avatar : noAvatar} - alt="user avatar" - style={{ - height: "100%", - width: "100%", - borderRadius: "50%", - }} - /> - } - href={`/admin/user/${row.id}`} - reset={() => { - currPage = 0; - currNameFilter = ""; - currEmailFilter = ""; - }} - data={[ - { - title: "Email", - subtitle: row.email ? - <Link to={`/admin/sendEmail/${row.email}`} style={{ textDecoration: 'none' }}> - <Button - variant='text' - color='primary' - startIcon={<EmailRoundedIcon />} - > - {row.email} - </Button> - </Link> : null - - }, - { - title: "Pedido em", - subtitle: DisplayDate(row.created_at), - }, - { - title: "Situação do pedido", - subtitle: ComplaintStatus(row.submitter_request), - }, - { - title: "Ações rápidas", - subtitle: <> - <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 + {row.email} + </Button> + </Link> : null + + }, + { + title: "Pedido em", + subtitle: DisplayDate(row.created_at), + }, + { + title: "Situação do pedido", + subtitle: ComplaintStatus(row.submitter_request), + }, + { + title: "Ações rápidas", + subtitle: <> + <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 + <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> - </> - } - ]} - /> - <div style={{ height: "0.5em" }} /> - </> - ) - )} + </> + } + ]} + /> + <div style={{ height: "0.5em" }} /> </> - ); - } else { - 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":"${currStateFilter}","name":"${currNameFilter}","email":"${currEmailFilter}"`, - `${currPage}`, - "DESC" - ) - ); - }} - startIcon={<UpdateRoundedIcon />} - > - {isUpdating ? ( - <CircularProgress size={24} /> - ) : ( - "Atualizar" - )} - </Button> - </Grid> - <Grid item> - <Button - variant="contained" - color="secondary" - onClick={() => { - 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" onChange={NameHandler} value={name} /> - </Grid> - <Grid item> - <TextField - label="Email" - onChange={EmailHandler} - value={email} - /> - </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":"${currStateFilter}","name":"${currNameFilter}","email":"${currEmailFilter}"`, - `${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; - currNameFilter = ""; - currEmailFilter = ""; - }} - > - <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 + ) + )} + </> + ); + } else { + return ( + <> + <SnackBar + severity={snackInfo.icon} + text={snackInfo.message} + snackbarOpen={snackInfo.open} + color={snackInfo.color} + handleClose={() => + setSnackInfo({ + message: "", + icon: "", + open: false, + color: "", + }) + } + /> + + <PageHeader + title="Aprovação de professores" + actions={[ + { + name: "Atualizar", + isLoading: false, + func: () => { + setCurrPage(0) + }, + icon: <UpdateRoundedIcon /> + }, + { + name: "Filtrar", + isLoading: false, + func: () => { + setShowFilter(!showFilter); + }, + icon: <FilterListRoundedIcon /> + } + ]} + > + {showFilter ? ( + <> + <div style={{ height: "1em" }}></div> + {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.value} + value={option.name} + name={option.value} + > + {option.value} + </MenuItem> + ))} + </TextField> + </Grid> + <Grid item> + <TextField + label="Nome" + onChange={NameHandler} + value={nameValue} + onBlur={(event) => { setName(event.target.value) }} + helperText="Retire o foco do campo de texto ao terminar de digitar" + /> + </Grid> + <Grid item> + <TextField + label="Email" + onChange={EmailHandler} + value={emailValue} + onBlur={(event) => { setEmail(event.target.value) }} + helperText="Retire o foco do campo de texto ao terminar de digitar" + /> + </Grid> + </Grid> + ) : null} + </> + ) : null} + </PageHeader> + + <div style={{ height: "2em" }}></div> + + <Grid xs={12} container> + <TableData + top={TOP_LABELS} + onIconPressed={cleanArrayAndInvert} + > + <TableBody> + {items.map((row, index) => + index === items.length - 1 ? ( + <StyledTableRow key={new Date().toISOString() + row.created_at}> + {/* Button to load more data */} + <StyledTableCell> + <Button + color="primary" + variant="text" + // disabled={isLoadingMoreItems} + startIcon={<AddRoundedIcon />} + disabled={isLoadingMoreItems} + onClick={() => { + setCurrPage(currPage + 1) + }} + > + {isLoadingMoreItems ? ( + <CircularProgress size={24} /> + ) : ( + "Carregar mais itens" + )} + </Button> + </StyledTableCell> + </StyledTableRow> + ) : ( + <StyledTableRow + key={new Date().toISOString() + 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?id=${row.id}`}> + <IconButton> + <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 + <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 />; + </StyledTableCell> + </StyledTableRow> + ) + )} + </TableBody> + </TableData> + </Grid> + </> + ); + } + } }; export default AproveTeacher; diff --git a/src/Admin/Pages/Pages/SubPages/BlockedUsers.js b/src/Admin/Pages/Pages/SubPages/BlockedUsers.js index c89b08bdbc5642225bb3bd45a0eb595db831964b..84a4419b44d2cbb0a7c3d485b9c0b840fabd2014 100644 --- a/src/Admin/Pages/Pages/SubPages/BlockedUsers.js +++ b/src/Admin/Pages/Pages/SubPages/BlockedUsers.js @@ -17,6 +17,7 @@ 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 } from 'react'; import moment from "moment"; +import styled from "styled-components" //Material ui componets import { withStyles } from '@material-ui/core/styles'; import TableBody from '@material-ui/core/TableBody'; @@ -28,7 +29,7 @@ import TextField from "@material-ui/core/TextField"; import TableCell from '@material-ui/core/TableCell'; import RemoveCircleOutlineRoundedIcon from '@material-ui/icons/RemoveCircleOutlineRounded'; import VisibilityIcon from '@material-ui/icons/Visibility'; -import { Button, Typography } from '@material-ui/core'; +import { Button } 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' @@ -37,616 +38,479 @@ import EmailRoundedIcon from '@material-ui/icons/EmailRounded'; import TableData from '../../../Components/Components/Table'; import SnackBar from '../../../../Components/SnackbarComponent'; import LoadingSpinner from '../../../../Components/LoadingSpinner'; +import MobileList from "../../../Components/Components/MobileComponents/SimpleList" +import { apiDomain } from '../../../../env'; +import noAvatar from "../../../../img/default_profile.png"; +import MobilePageHeader from "../../../Components/Components/MobileComponents/MobilePageHeader" +import PageHeader from "../../../Components/Components/PageHeader" //Services import { getRequest, putRequest } from '../../../../Components/HelperFunctions/getAxiosConfig' import { Url } from '../../../Filters'; //routers import { Link } from 'react-router-dom'; -import MobileList from "../../../Components/Components/MobileComponents/SimpleList" -import styled from "styled-components" -import { apiDomain } from '../../../../env'; -import noAvatar from "../../../../img/default_profile.png"; - -let currPage = 0; //var that controlls the current page that we are -let currContentFilter = 1; -let transformListToAsc = false; const StyledTableCell = withStyles((theme) => ({ - head: { - backgroundColor: theme.palette.common.black, - color: theme.palette.common.white, - }, - body: { - fontSize: 14, - }, + 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, - }, + root: { + '&:nth-of-type(odd)': { + backgroundColor: theme.palette.action.hover, }, + }, }))(TableRow); const BlockedUsers = () => { - const AddOneLenght = ['']; - const WINDOW_WIDTH = window.innerWidth - 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) - const [isUpdating, setIsUpdating] = useState(false) - - const [snackInfo, setSnackInfo] = useState({ - message: '', - icon: '', - open: false, - color: '', - }) - - const StateOptions = [ - { - id: 1, - name: "Semanal" - }, - { - id: 2, - name: "Permanente" - } - ]; - - // Handle snack infos - const HandleSnack = (message, state, icon, color) => { - setSnackInfo({ - message: message, - icon: icon, - open: state, - color: color - }) + const ADD_ONE_LENGHT = ['']; + const WINDOW_WIDTH = window.innerWidth + + const [invertList, setInvertList] = useState(false) + 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) + const [stateOpt, setStateOpt] = useState(1) + const [currPage, setCurrPage] = useState(0) + + const [snackInfo, setSnackInfo] = useState({ + message: '', + icon: '', + open: false, + color: '', + }) + + const StateOptions = [ + { + name: 1, + value: "Semanal" + }, + { + name: 2, + value: "Permanente" } - - 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(AddOneLenght)) - } - setIsLoadingMoreItems(false) - }, - (error) => { - HandleSnack('Erro ao carregar os dados', true, 'warning', '#FA8072') - setIsLoadingMoreItems(false) - } - ) + ]; + + // Handle snack infos + const HandleSnack = (message, state, icon, color) => { + setSnackInfo({ + message: message, + icon: icon, + open: state, + color: color + }) + } + + const handleChange = (event) => { + const type = event.target.value + setStateOpt(type) + } + + const BlockStatus = (status) => { + switch (status) { + case "blocked": + return ( + <Paper + style={{ + textAlign: "center", + padding: "0.5em", + backgroundColor: "#FF8C00", + fontWeight: "500", + color: "#FFFAFA", + }} + > + SEMANAL + </Paper> + ); + case "banished": + return ( + <Paper + style={{ + textAlign: "center", + padding: "0.5em", + backgroundColor: "red", + fontWeight: "500", + color: "#FFFAFA", + }} + > + PERMANENTE + </Paper> + ); + default: + return ( + <Paper + style={{ + textAlign: "center", + padding: "0.5em", + backgroundColor: "#797D7F", + fontWeight: "500", + color: "#FFFAFA", + }} + > + Não avaliado + </Paper> + ); } - - const handleChange = (event) => { - const type = event.target.value - switch (type) { - case "Semanal": - currPage = 0; - currContentFilter = 1; - getRequest( - Url('users', `"state" : "${currContentFilter}"`, `${currPage}`, 'ASC'), - (data, header) => { - HandleSnack("Filtro aplicado com sucesso!", true, 'success', '#228B22') - const arrData = [...data] - setItems(arrData.concat(AddOneLenght)) - setIsUpdating(false) - }, - (error) => { - HandleSnack('Erro ao carregar os dados', true, 'warning', '#FA8072') - setIsUpdating(false) - } - ) - break; - case "Permanente": - currPage = 0; - currContentFilter = 2; - getRequest( - Url('users', `"state" : "${currContentFilter}"`, `${currPage}`, 'ASC'), - (data, header) => { - HandleSnack("Filtro aplicado com sucesso!", true, 'success', '#228B22') - const arrData = [...data] - setItems(arrData.concat(AddOneLenght)) - setIsUpdating(false) - }, - (error) => { - HandleSnack('Erro ao carregar os dados', true, 'warning', '#FA8072') - setIsUpdating(false) - } - ) - break; - default: - currPage = 0; - currContentFilter = 1; - getRequest( - Url('users', `"state" : "${currContentFilter}"`, `${currPage}`, 'ASC'), - (data, header) => { - HandleSnack("Filtro aplicado com sucesso!", true, 'success', '#228B22') - const arrData = [...data] - setItems(arrData.concat(AddOneLenght)) - setIsUpdating(false) - }, - (error) => { - HandleSnack('Erro ao carregar os dados', true, 'warning', '#FA8072') - setIsUpdating(false) - } - ) - break; + }; + + const ReactiveUser = (userId, index) => { + putRequest( + `/users/${userId}/reactivate_user`, + {}, + (data) => { + if (data.errors) + HandleSnack('Erro!', true, 'warning', '#FA8072') + else { + HandleSnack('Usuário foi reativado com sucesso!', true, 'success', '#228B22') + removeItemFromList(index) + setCurrPage(0) } - } - - const InvertList = async () => { - transformListToAsc = !transformListToAsc - currPage = 0 - if (transformListToAsc) { - getRequest( - Url('users', `"state" : "${currContentFilter}"`, `${currPage}`, 'ASC'), - (data, header) => { - const arrData = [...data] - setItems(arrData.concat(AddOneLenght)) - }, - (error) => { - HandleSnack('Erro ao carregar os dados', true, 'warning', '#FA8072') - } - ) + }, + (error) => { + HandleSnack('Erro!', true, 'warning', '#FA8072') + } + ) + } + + const removeItemFromList = (index) => { + const copyList = [...items] + copyList.splice(index, 1) + setItems(copyList) + } + + const DisplayDate = (date) => { + const convertedData = moment.utc(date); + return moment(convertedData) + .format("LLL") + .toString(); + }; + + const cleanArrayAndInvert = () => { + setInvertList(!invertList) + setCurrPage(0) + setItems([]) + } + + useEffect(() => { + if (currPage === 0) + setIsLoaded(false) + else + setIsLoadingMoreItems(true) + getRequest( + Url('users', `"state" : ${stateOpt}`, currPage, invertList ? "ASC" : 'DESC'), + + (data, header) => { + const arrData = [...data] + if (arrData.length === 0) { + HandleSnack('Não há mais dados para serem carregados', true, 'warning', '#FFC125') } else { - getRequest( - Url('users', `"state" : "${currContentFilter}"`, `${currPage}`, 'DESC'), - (data, header) => { - const arrData = [...data] - setItems(arrData.concat(AddOneLenght)) - }, - (error) => { - HandleSnack('Erro ao carregar os dados', true, 'warning', '#FA8072') - } - ) + const arrItems = [...items] + if (currPage === 0) { + setItems(arrData.concat(ADD_ONE_LENGHT)) + } + else { + 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)) + } } - } - - 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(AddOneLenght)) - setIsUpdating(false) - }, - (error) => { - HandleSnack('Erro ao carregar os dados', true, 'warning', '#FA8072') - setIsUpdating(false) - } - ) - } - - const BlockStatus = (status) => { - switch (status) { - case 1: - return ( - <Paper - style={{ - textAlign: "center", - padding: "0.5em", - backgroundColor: "#FF8C00", - fontWeight: "500", - color: "#FFFAFA", - }} - > - SEMANAL - </Paper> - ); - case 2: - return ( - <Paper - style={{ - textAlign: "center", - padding: "0.5em", - backgroundColor: "red", - fontWeight: "500", - color: "#FFFAFA", - }} - > - PERMANENTE - </Paper> - ); - default: - return ( - <Paper + setIsLoaded(true) + setIsLoadingMoreItems(false) + }, + (error) => { + HandleSnack('Erro ao carregar os dados', true, 'warning', '#FA8072') + setIsLoadingMoreItems(false) + setIsLoaded(true) + setError(true) + } + ) + }, [currPage, stateOpt, invertList]) + + if (error) { + return <div>Error: {error.message}</div>; + } else if (!isLoaded) { + return <LoadingSpinner text="Carregando..." /> + } else { + + //Words in the top part of the table + const topTable = ['ID', 'ESTADO', 'NAME', 'EMAIL', 'BLOQUEADO EM', 'AÇÕES']; + if (WINDOW_WIDTH <= 899) { + return ( + <div> + <SnackBar + severity={snackInfo.icon} + text={snackInfo.message} + snackbarOpen={snackInfo.open} + color={snackInfo.color} + handleClose={() => setSnackInfo({ + message: '', + icon: '', + open: false, + color: '' + })} + /> + <MobilePageHeader + title="Lista de usuários bloqueados" + actions={[ + { + name: "Atualizar", + isLoading: false, + func: () => { + setCurrPage(0) + }, + icon: <UpdateRoundedIcon /> + }, + { + name: "Inverter lista", + isLoading: false, + func: () => { + cleanArrayAndInvert() + }, + }, + ]} + > + <Grid item> + <TextField + select + label="Estado de bloqueio" + onChange={handleChange} + helperText="Por favor, selecione uma das opções" + > + {StateOptions.map((option, index) => ( + <MenuItem + key={option.value} + value={option.name} + name={option.value} + > + {option.value} + </MenuItem> + ))} + </TextField> + </Grid> + </MobilePageHeader> + + <div style={{ height: '2em' }}></div> + + {items.map((row, index) => + index === items.length - 1 ? ( + <StyledDivButton> + <Button + key={new Date().toISOString() + row.created_at} + color="primary" + variant="text" + // disabled={isLoadingMoreItems} + startIcon={<AddRoundedIcon />} + disabled={isLoadingMoreItems} + onClick={() => { + setCurrPage(currPage + 1) + }} + > + {isLoadingMoreItems ? ( + <CircularProgress size={24} /> + ) : ( + "Carregar mais itens" + )} + </Button> + </StyledDivButton> + ) : ( + <> + <MobileList + key={new Date().toISOString() + row.created_at} + title={row.name} + subtitle={row.id} + backColor={"#e81f4f"} + avatar={ + <img + src={row.avatar ? apiDomain + row.avatar : noAvatar} + alt="user avatar" style={{ - textAlign: "center", - padding: "0.5em", - backgroundColor: "#797D7F", - fontWeight: "500", - color: "#FFFAFA", + height: "100%", + width: "100%", + borderRadius: "50%", }} - > - Não avaliado - </Paper> - ); - } - }; - - const ReactiveUser = (userId) => { - putRequest( - `/users/${userId}/reactivate_user`, - {}, - (data) => { - if (data.errors) - HandleSnack('Erro!', true, 'warning', '#FA8072') - else { - currPage = 0 - HandleSnack('Usuário foi reativado com sucesso!', true, 'success', '#228B22') - UpdateHandler(Url('users', `"state" : "${currContentFilter}"`, `${currPage}`, 'DESC')) - } - }, - (error) => { - HandleSnack('Erro!', true, 'warning', '#FA8072') - } - ) - } - - const DisplayDate = (date) => { - const convertedData = moment.utc(date); - return moment(convertedData) - .format("LLL") - .toString(); - }; - - useEffect(() => { - getRequest( - Url('users', `"state" : "${currContentFilter}"`, '0', 'DESC'), - (data, header) => { - setIsLoaded(true); - setItems(data.concat(AddOneLenght)); - }, - (error) => { - setError(true); - } - ) - }, []); - - - if (error) { - return <div>Error: {error.message}</div>; - } else if (!isLoaded) { - return <LoadingSpinner text="Carregando..." /> - } else { - - //Words in the top part of the table - const topTable = ['ID', 'ESTADO', 'NAME', 'EMAIL', 'BLOQUEADO EM', 'AÇÕES']; - if (WINDOW_WIDTH <= 899) { - return ( - <div> - <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 direction="row" alignItems="center"> - <Grid container spacing={3} > - <Grid item xs={12}> - <Typography variant="h4"> - Lista de usuários bloqueados - </Typography> - </Grid> - <Grid - item - xs={12} - - > - <Grid container justify="flex-start" spacing={3}> - <Grid item> - <Button - variant="contained" - color="secondary" - disabled={isUpdating} - onClick={() => { - currPage = 0 - transformListToAsc = false - UpdateHandler(Url('users', `"state" : "${currContentFilter}"`, `${currPage}`, 'DESC')) - }} - startIcon={<UpdateRoundedIcon />} - > - { - isUpdating ? <CircularProgress size={24} /> : 'Atualizar' - } - </Button> - </Grid> - </Grid> - </Grid> - </Grid> - <Grid item> - <TextField - select - label="Estado de bloqueio" - onChange={handleChange} - helperText="Por favor, selecione uma das opções" - > - {StateOptions.map((option, index) => ( - <MenuItem - key={option.id} - value={option.name} - name={option.id} - > - {option.name} - </MenuItem> - ))} - </TextField> - </Grid> - - </Grid> - </Paper> - - <div style={{ height: '2em' }}></div> - - {items.map((row, index) => - index === items.length - 1 ? ( - <StyledDivButton> - <Button - key={index} - color="primary" - variant="text" - // disabled={isLoadingMoreItems} - startIcon={<AddRoundedIcon />} - disabled={isLoadingMoreItems} - onClick={() => { - currPage++ - if (transformListToAsc) { - LoadMoreItens(Url('users', `"state" : "${currContentFilter}"`, `${currPage}`, 'ASC')) - } else { - LoadMoreItens(Url('users', `"state" : "${currContentFilter}"`, `${currPage}`, 'DESC')) - } - }} - > - {isLoadingMoreItems ? ( - <CircularProgress size={24} /> - ) : ( - "Carregar mais itens" - )} - </Button> - </StyledDivButton> - ) : ( - <> - <MobileList - key={index} - title={row.name} - subtitle={row.id} - backColor={"#e81f4f"} - avatar={ - <img - src={row.avatar ? apiDomain + row.avatar : noAvatar} - alt="user avatar" - style={{ - height: "100%", - width: "100%", - borderRadius: "50%", - }} - /> - } - href={`/admin/user/${row.id}`} - reset={() => { - currPage = 0; transformListToAsc = false; currContentFilter = 1 - }} - data={ - [ - { - title: "Email", - subtitle: row.email ? - <Link to={`/admin/sendEmail/${row.email}`} style={{ textDecoration: 'none' }}> - <Button - variant='text' - color='primary' - startIcon={<EmailRoundedIcon />} - > - {row.email} - </Button> - </Link> : null - - }, - { - title: "Estado", - subtitle: BlockStatus(currContentFilter) - }, - { - title: "Ações rápidas", - subtitle: <Button - style={{ width: "100%", marginBottom: "0.5em" }} - variant="contained" - color="secondary" - startIcon={<RemoveCircleOutlineRoundedIcon />} - onClick={() => ReactiveUser(row.id)} - > - Desbloquear + /> + } + href={`/admin/user?id=${row.id}`} + reset={() => { + }} + data={ + [ + { + title: "Email", + subtitle: row.email ? + <Link to={`/admin/sendEmail?email=${row.email}`} style={{ textDecoration: 'none' }}> + <Button + variant='text' + color='primary' + startIcon={<EmailRoundedIcon />} + > + {row.email} + </Button> + </Link> : null + + }, + { + title: "Estado", + subtitle: BlockStatus(row.state) + }, + { + title: "Ações rápidas", + subtitle: <Button + style={{ width: "100%", marginBottom: "0.5em" }} + variant="contained" + color="secondary" + startIcon={<RemoveCircleOutlineRoundedIcon />} + onClick={() => ReactiveUser(row.id, index)} + > + Desbloquear </Button> - } - ] - } - /> - <div style={{ height: "0.5em" }} /> - </> - ) - )} - </div> - ) - } - else { - return ( - <div> - <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 direction="row" alignItems="center"> - <Grid container spacing={3} > - <Grid item xs={6}> - <Typography variant="h4"> - Lista de usuários bloqueados - </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 - transformListToAsc = false - UpdateHandler(Url('users', `"state" : "${currContentFilter}"`, `${currPage}`, 'DESC')) - }} - startIcon={<UpdateRoundedIcon />} - > - { - isUpdating ? <CircularProgress size={24} /> : 'Atualizar' - } - </Button> - </Grid> - </Grid> - </Grid> - </Grid> - <Grid item> - <TextField - select - label="Estado de bloqueio" - onChange={handleChange} - helperText="Por favor, selecione uma das opções" - > - {StateOptions.map((option, index) => ( - <MenuItem - key={option.id} - value={option.name} - name={option.id} - > - {option.name} - </MenuItem> - ))} - </TextField> - </Grid> - - </Grid> - </Paper> - - <div style={{ height: '2em' }}></div> - - <TableData - top={topTable} - onIconPressed={InvertList} - > - <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 />} - onClick={() => { - currPage++ - if (transformListToAsc) { - LoadMoreItens(Url('users', `"state" : "${currContentFilter}"`, `${currPage}`, 'ASC')) - } else { - LoadMoreItens(Url('users', `"state" : "${currContentFilter}"`, `${currPage}`, 'DESC')) - } - }} - > - { - isLoadingMoreItems ? <CircularProgress size={24} /> : 'Carregar mais itens' - } - </Button> - </StyledTableCell> - </StyledTableRow> - - : - - <StyledTableRow key={index}> - <StyledTableCell component="th" scope="row">{row.id}</StyledTableCell> - <StyledTableCell align="right"> - {BlockStatus(currContentFilter)} - </StyledTableCell> - <StyledTableCell align="right">{row.name}</StyledTableCell> - <StyledTableCell align="right"> - { - row.email ? - <Link to={`/admin/sendEmail/${row.email}`} style={{ textDecoration: 'none' }}> - <Button - variant='text' - color='primary' - startIcon={<EmailRoundedIcon />} - > - {row.email} - </Button> - </Link> : null - } - </StyledTableCell> - <StyledTableCell align="right"> - {DisplayDate(row.suspended_at)} - </StyledTableCell> - <StyledTableCell align="right"> - <Button - style={{ width: "100%", marginBottom: "0.5em" }} - variant="contained" - color="secondary" - startIcon={<RemoveCircleOutlineRoundedIcon />} - onClick={() => ReactiveUser(row.id)} - > - Desbloquear + } + ] + } + /> + <div style={{ height: "0.5em" }} /> + </> + ) + )} + </div> + ) + } + else { + return ( + <div> + <SnackBar + severity={snackInfo.icon} + text={snackInfo.message} + snackbarOpen={snackInfo.open} + color={snackInfo.color} + handleClose={() => setSnackInfo({ + message: '', + icon: '', + open: false, + color: '' + })} + /> + <PageHeader + title="Lista de usuários bloqueados" + actions={[ + { + name: "Atualizar", + isLoading: false, + func: () => { + setCurrPage(0) + }, + icon: <UpdateRoundedIcon /> + }, + ]} + > + <Grid item> + <TextField + select + label="Estado de bloqueio" + onChange={handleChange} + helperText="Por favor, selecione uma das opções" + > + {StateOptions.map((option, index) => ( + <MenuItem + key={option.value} + value={option.name} + name={option.value} + > + {option.value} + </MenuItem> + ))} + </TextField> + </Grid> + </PageHeader> + + <div style={{ height: '2em' }}></div> + + <TableData + top={topTable} + onIconPressed={cleanArrayAndInvert} + > + <TableBody> + {items.map((row, index) => ( + index === items.length - 1 ? + <StyledTableRow key={new Date().toISOString() + row.created_at}> + {/* Button to load more data */} + <StyledTableCell> + <Button + color='primary' + variant='text' + disabled={isLoadingMoreItems} + startIcon={<AddRoundedIcon />} + onClick={() => { + setCurrPage(currPage + 1) + }} + > + { + isLoadingMoreItems ? <CircularProgress size={24} /> : 'Carregar mais itens' + } + </Button> + </StyledTableCell> + </StyledTableRow> + + : + + <StyledTableRow key={new Date().toISOString() + index}> + <StyledTableCell component="th" scope="row">{row.id}</StyledTableCell> + <StyledTableCell align="right"> + {BlockStatus(row.state)} + </StyledTableCell> + <StyledTableCell align="right">{row.name}</StyledTableCell> + <StyledTableCell align="right"> + { + row.email ? + <Link to={`/admin/sendEmail?email=${row.email}`} style={{ textDecoration: 'none' }}> + <Button + variant='text' + color='primary' + startIcon={<EmailRoundedIcon />} + > + {row.email} + </Button> + </Link> : null + } + </StyledTableCell> + <StyledTableCell align="right"> + {DisplayDate(row.suspended_at)} + </StyledTableCell> + <StyledTableCell align="right"> + <Button + style={{ width: "100%", marginBottom: "0.5em" }} + variant="contained" + color="secondary" + startIcon={<RemoveCircleOutlineRoundedIcon />} + onClick={() => ReactiveUser(row.id, index)} + > + Desbloquear </Button> - <Link to={`/admin/user/${row.id}`}> - <Button - onClick={() => { currPage = 0; transformListToAsc = false; currContentFilter = 1 }} - style={{ width: "100%" }} - variant="contained" - color="primary" - startIcon={<VisibilityIcon />} - > - Visualizar + <Link to={`/admin/user?id=${row.id}`}> + <Button + style={{ width: "100%" }} + variant="contained" + color="primary" + startIcon={<VisibilityIcon />} + > + Visualizar </Button> - </Link> - </StyledTableCell> - </StyledTableRow> - ))} - </TableBody> - </TableData> - </div> - ) - } + </Link> + </StyledTableCell> + </StyledTableRow> + ))} + </TableBody> + </TableData> + </div> + ) } + } } diff --git a/src/Admin/Pages/Pages/SubPages/Collections.js b/src/Admin/Pages/Pages/SubPages/Collections.js index 763aa71ea6aaf28df4411103b5fd0ad77c850c15..dd15cbaefc69bf3b14657d8c13393f05b9c0edf0 100644 --- a/src/Admin/Pages/Pages/SubPages/Collections.js +++ b/src/Admin/Pages/Pages/SubPages/Collections.js @@ -24,6 +24,9 @@ import SnackBar from "../../../../Components/SnackbarComponent"; import { Url, DeleteFilter } from "../../../Filters"; import AlertDialog from "../../../Components/Components/AlertDialog"; import LoadingSpinner from "../../../../Components/LoadingSpinner"; +import MobileList from "../../../Components/Components/MobileComponents/SimpleList" +import MobilePageHeader from "../../../Components/Components/MobileComponents/MobilePageHeader" +import PageHeader from "../../../Components/Components/PageHeader" //imports from material ui import { withStyles } from "@material-ui/core/styles"; import TableBody from "@material-ui/core/TableBody"; @@ -33,7 +36,7 @@ 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 { Button, 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"; @@ -41,654 +44,560 @@ import FilterListRoundedIcon from "@material-ui/icons/FilterListRounded"; import VisibilityIcon from "@material-ui/icons/Visibility"; import DeleteIcon from "@material-ui/icons/Delete"; import { - deleteRequest, - getRequest, + deleteRequest, + getRequest, } from "../../../../Components/HelperFunctions/getAxiosConfig"; //routers import { Link } from "react-router-dom"; -import MobileList from "../../../Components/Components/MobileComponents/SimpleList" import styled from 'styled-components' -let currPage = 0; -let currPrivacyFilter = ""; -let currNameFilter = ""; - const StyledTableCell = withStyles((theme) => ({ - head: { - backgroundColor: theme.palette.common.black, - color: theme.palette.common.white, - }, - body: { - fontSize: 14, - }, + 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, - }, + root: { + "&:nth-of-type(odd)": { + backgroundColor: theme.palette.action.hover, }, + }, }))(TableRow); const Collections = () => { - const ADD_ONE_LENGHT = [""]; - const TOP_LABELS = [ - "NOME", - "DESCRIÇÃO", - "DONO(A)", - "CRIAÇÃO", - "ATUALIZAÇÃO", - "PRIVACIDADE", - "VISUALIZAR", - "DELETAR", - ]; //Labels from Table - - const WINDOW_WIDTH = window.innerWidth; - - 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 [search, setSearch] = useState(""); - - const [openAlertDialog, setOpenAlertDialog] = useState(false); - const [deleteItem, setDeleteItem] = useState({}); //Delete Item - const [isLoadingToDelete, setIsLoadingToDelete] = useState(null); - - const [option, setOption] = useState("Todos os usuários"); //labels of the text field 'to' - - const [snackInfo, setSnackInfo] = useState({ - message: "", - icon: "", - open: false, - color: "", + const ADD_ONE_LENGHT = [""]; + const TOP_LABELS = [ + "NOME", + "DESCRIÇÃO", + "DONO(A)", + "CRIAÇÃO", + "ATUALIZAÇÃO", + "PRIVACIDADE", + "VISUALIZAR", + "DELETAR", + ]; //Labels from Table + + const WINDOW_WIDTH = window.innerWidth; + + 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 [showFilter, setShowFilter] = useState(false); + const [valueOfSearch, setValueOfSearch] = useState("") + const [search, setSearch] = useState(""); + const [currPage, setCurrPage] = useState(0) + + const [openAlertDialog, setOpenAlertDialog] = useState(false); + const [deleteItem, setDeleteItem] = useState({}); //Delete Item + const [isLoadingToDelete, setIsLoadingToDelete] = useState(null); + const [option, setOption] = useState(); //labels of the text field 'to' + + const [snackInfo, setSnackInfo] = useState({ + message: "", + icon: "", + open: false, + color: "", + }); + + const privacyOptions = [ + { name: "private", value: "Privado" }, + { name: "public", value: "Público" } + ]; + + + //handle snack info + const HandleSnack = (message, state, icon, color) => { + setSnackInfo({ + message: message, + icon: icon, + open: state, + color: color, }); - - const options = [ - { - value: "private", - label: "Privado", - }, - { - value: "public", - label: "Público", - }, - ]; - - //handle snack info - const HandleSnack = (message, state, icon, color) => { - setSnackInfo({ - message: message, - icon: icon, - open: state, - color: color, - }); - }; - - //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); - } - ); - }; - - //Defines which row must show the circular progress - const HandleStateCircularProgress = (i) => { - setIsLoadingToDelete(i); - }; - - // 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); - } - ); - }; - - //Called when user want to delete one institution - async function DeleteHandler() { - const id = deleteItem.id; - HandleStateAlertDialog(null); - deleteRequest( - DeleteFilter("collections", id), - (data) => { - if (data.errors) - HandleSnack("Ocorreu algum erro", true, "warning", "#FA8072"); - else { - HandleSnack( - "A Coleção foi deletada com sucesso", - true, - "success", - "#228B22" - ); - currPage = 0; - HandleStateCircularProgress(null); - UpdateHandler(Url("collections", "", `${currPage}`, "DESC")); - } - }, - (error) => { - HandleSnack("Ocorreu algum erro", true, "warning", "#FA8072"); - HandleStateCircularProgress(null); - } - ); + }; + + //Defines which row must show the circular progress + const HandleStateCircularProgress = (i) => { + setIsLoadingToDelete(i); + }; + + //Called when user want to delete one institution + async function DeleteHandler() { + const id = deleteItem.id; + HandleStateAlertDialog(null); + deleteRequest( + DeleteFilter("collections", id), + (data) => { + if (data.errors) + HandleSnack("Ocorreu algum erro", true, "warning", "#FA8072"); + else { + HandleSnack( + "A Coleção foi deletada com sucesso", + true, + "success", + "#228B22" + ); + setCurrPage(0) + HandleStateCircularProgress(null); + removeItemFromList(id); + } + }, + (error) => { + HandleSnack("Ocorreu algum erro", true, "warning", "#FA8072"); + HandleStateCircularProgress(null); + } + ); + } + + //Controlls the state of the Alert Dialog + const HandleStateAlertDialog = (i) => { + const obj = { ...items[i] }; + setDeleteItem(obj); + setOpenAlertDialog(!openAlertDialog); + }; + + // handle change of privacy + const handleChange = (e) => { + setOption(e.target.value); + }; + + const HandleSearch = (e) => { + setValueOfSearch(e.target.value) + } + + const DisplayDate = (date) => { + const convertedData = moment.utc(date); + return moment(convertedData) + .format("LLL") + .toString(); + }; + + const buildUrl = (privacyOpt, name) => { + if (privacyOpt && name) + return Url("collections", `"privacy" : "${privacyOpt}", "name" : "${name}"`, currPage, "DESC") + else if (privacyOpt) + return Url("collections", `"privacy" : "${privacyOpt}"`, currPage, "DESC") + else if (name) + return Url("collections", `"name" : "${name}"`, currPage, "DESC") + else + return Url("collections", "", currPage, "DESC") + } + + const removeItemFromList = (itemId) => { + let index = -1; + for (let i = 0; i < items.length; i++) { + const element = items[i]; + if (element.id === itemId) { + index = i + break + } } - - //Controlls the state of the Alert Dialog - const HandleStateAlertDialog = (i) => { - const obj = { ...items[i] }; - setDeleteItem(obj); - setOpenAlertDialog(!openAlertDialog); - }; - - const ApplyFilter = (value) => { - currPrivacyFilter = value - currPage = 0; - setIsLoaded(false); - getRequest( - Url( - "collections", - `"privacy" : "${currPrivacyFilter}" , "name" : "${currNameFilter}"`, - `${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); - } - ); + if (index !== -1) { + const cpyItems = [...items] + cpyItems.splice(index, 1) + setItems(cpyItems) } - - // handle change of privacy - const handleChange = (e) => { - setOption(e.target.value); - }; - - //Handle the search filter - const HandleSearch = (event) => { - currNameFilter = event.target.value - setSearch(currNameFilter); - getRequest( - Url( - "collections", - `"privacy" : "${currPrivacyFilter}" , "name" : "${currNameFilter}"`, - `${currPage}`, - "DESC" - ), - (data, header) => { - const arrData = [...data]; - setItems(arrData.concat(ADD_ONE_LENGHT)); - setIsLoaded(true); - }, - (error) => { - HandleSnack("Erro ao carregar os dados", true, "warning", "#FA8072"); - setIsLoaded(true); - } - ); - }; - - const DisplayDate = (date) => { - const convertedData = moment.utc(date); - return moment(convertedData) - .format("LLL") - .toString(); - }; - - //getting data from server - useEffect(() => { - getRequest( - Url( - "collections", - `"privacy" : "${currPrivacyFilter}" , "name" : "${currNameFilter}"`, - `${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(false); - setError(true); + } + + useEffect(() => { + if (currPage === 0) + setIsLoaded(false) + else + setIsLoadingMoreItems(true) + getRequest( + buildUrl(option, search), + (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] + if (currPage === 0) { + setItems(arrData.concat(ADD_ONE_LENGHT)) + } + else { + 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)) + } + } + setIsLoaded(true) + setIsLoadingMoreItems(false) + }, + (error) => { + HandleSnack('Erro ao carregar os dados', true, 'warning', '#FA8072') + setIsLoadingMoreItems(false) + setIsLoaded(true) + setError(true) + } + ) + }, [currPage, search, option]) + + useEffect(() => { + setCurrPage(0) + setOption() + setSearch("") + setValueOfSearch("") + }, [showFilter]) + + if (error) { + return <div>Error: {error.message}</div>; + } else if (!isLoaded) { + return <LoadingSpinner text="Carregando..." />; + } else { + if (WINDOW_WIDTH <= 1024) { + return ( + <> + <SnackBar + severity={snackInfo.icon} + text={snackInfo.message} + snackbarOpen={snackInfo.open} + color={snackInfo.color} + handleClose={() => + setSnackInfo({ + message: "", + icon: "", + open: false, + color: "", + }) } - ); - }, []); - - if (error) { - return <div>Error: {error.message}</div>; - } else if (!isLoaded) { - return <LoadingSpinner text="Carregando..." />; - } else { - if (WINDOW_WIDTH <= 954) { - 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={12}> - <Typography variant="h4">Coleções</Typography> - </Grid> - <Grid item xs={12}> - <Grid container justify="flex-start" spacing={3}> - <Grid item> - <Button - variant="contained" - color="secondary" - disabled={isUpdating} - onClick={() => { - currPage = 0; - UpdateHandler( - Url( - "collections", - `"privacy" : "${currPrivacyFilter}" , "name" : "${currNameFilter}"`, - `${currPage}`, - "DESC" - ) - ); - }} - startIcon={<UpdateRoundedIcon />} - > - {isUpdating ? <CircularProgress size={24} /> : "Atualizar"} - </Button> - </Grid> - <Grid item> - <Button - variant="contained" - color="secondary" - onClick={() => { - setShowFilter(!showFilter); - }} - startIcon={<FilterListRoundedIcon />} - > - Filtrar - </Button> - </Grid> - </Grid> - </Grid> - </Grid> - - {showFilter ? ( - <> - <div style={{ height: "1em" }}></div> - - <Grid - container - alignItems="center" - alignContent="center" - xs={12} - direction="row" - justify="space-between" - > - <Grid item> - <TextField - select - label="Filtro" - value={option ? option : ""} - onChange={handleChange} - helperText="Por favor, selecione uma das opções" - > - {options.map((option, index) => ( - <MenuItem key={index} value={option.value} onClick={() => { ApplyFilter(option.value) }}> - {option.label} - </MenuItem> - ))} - </TextField> - </Grid> - - <Grid item> - <TextField - label="Pesquisa" - value={search} - onChange={(event) => HandleSearch(event)} - ></TextField> - </Grid> - </Grid> - </> - ) : null} - </Paper> - - <div style={{ height: "2em" }}></div> - - {items.map((row, index) => - index === items.length - 1 ? ( - <StyledDivButton> - <Button - key={index} - color="primary" - variant="text" - // disabled={isLoadingMoreItems} - startIcon={<AddRoundedIcon />} - disabled={isLoadingMoreItems} - onClick={() => { - currPage++; - LoadMoreItens( - Url( - "collections", - `"privacy" : "${currPrivacyFilter}" , "name" : "${currNameFilter}"`, - `${currPage}`, - "DESC" - ) - ); - }} - > - {isLoadingMoreItems ? ( - <CircularProgress size={24} /> - ) : ( - "Carregar mais itens" - )} - </Button> - </StyledDivButton> - ) : ( - <> - <MobileList - key={index} - title={row.name} - subtitle={row.privacy} - backColor={"#e81f4f"} - avatar={<PeopleRoundedIcon />} - href={`/admin/Collection/${row.id}`} - reset={() => { - currPage = 0; - currPrivacyFilter = ""; - currNameFilter = ""; - }} - data={ - [ - { - title: "ID", - subtitle: row.id - - }, - { - title: "Dono(a)", - subtitle: row.owner ? row.owner.name : "Sem dados" - - }, - { - title: "Criado em", - subtitle: DisplayDate(row.created_at) - }, - { - title: "Atualizado em", - subtitle: DisplayDate(row.updated_at) - } - ] - } - /> - <div style={{ height: "0.5em" }} /> - </> - ) + /> + <AlertDialog + open={openAlertDialog} + OnDelete={DeleteHandler} + deleteItem={deleteItem} + HandleClose={() => { + setOpenAlertDialog(false); + HandleStateCircularProgress(null); + }} + /> + <MobilePageHeader + title="Coleções" + actions={[ + { + name: "Atualizar", + isLoading: false, + func: () => { + setCurrPage(0) + }, + icon: <UpdateRoundedIcon /> + }, + { + name: "Filtrar", + isLoading: false, + func: () => { + setShowFilter(!showFilter); + }, + icon: <FilterListRoundedIcon /> + } + ]} + > + {showFilter ? ( + <> + <div style={{ height: "1em" }}></div> + + <Grid + container + alignItems="center" + alignContent="center" + xs={12} + direction="row" + justify="space-between" + > + <Grid item> + <TextField + select + label="Filtro" + value={option} + onChange={handleChange} + helperText="Por favor, selecione uma das opções" + > + {privacyOptions.map((option, index) => ( + <MenuItem + key={option.value} + value={option.name} + name={option.value} + > + {option.value} + </MenuItem> + ))} + </TextField> + </Grid> + + <Grid item> + <TextField + label="Pesquisa" + value={valueOfSearch} + helperText="Ao digitar, tire o foco do campo de texto" + onChange={(event) => HandleSearch(event)} + onBlur={(event) => setSearch(event.target.value)} + ></TextField> + </Grid> + </Grid> + </> + ) : null} + </MobilePageHeader> + + <div style={{ height: "2em" }}></div> + + {items.map((row, index) => + index === items.length - 1 ? ( + <StyledDivButton + key={new Date().toISOString() + row.created_at} + > + <Button + color="primary" + variant="text" + // disabled={isLoadingMoreItems} + startIcon={<AddRoundedIcon />} + disabled={isLoadingMoreItems} + onClick={() => { + setCurrPage(currPage + 1) + }} + > + {isLoadingMoreItems ? ( + <CircularProgress size={24} /> + ) : ( + "Carregar mais itens" )} - </> - ); - } - else { - return ( + </Button> + </StyledDivButton> + ) : ( <> - <SnackBar - severity={snackInfo.icon} - text={snackInfo.message} - snackbarOpen={snackInfo.open} - color={snackInfo.color} - handleClose={() => - setSnackInfo({ - message: "", - icon: "", - open: false, - color: "", - }) + <MobileList + key={new Date().toISOString() + row.created_at} + title={row.name} + subtitle={row.privacy} + backColor={"#e81f4f"} + avatar={<PeopleRoundedIcon />} + href={`/admin/Collection?collection=${row.id}`} + reset={() => { + + }} + data={ + [ + { + title: "ID", + subtitle: row.id + + }, + { + title: "Dono(a)", + subtitle: row.owner ? row.owner.name : "Sem dados" + + }, + { + title: "Criado em", + subtitle: DisplayDate(row.created_at) + }, + { + title: "Atualizado em", + subtitle: DisplayDate(row.updated_at) + }, + { + title: "Deletar", + subtitle: + <Button + variant="contained" + color="secondary" + onClick={() => { + HandleStateAlertDialog(index); + HandleStateCircularProgress(index); + }} + startIcon={<DeleteIcon />} + > + Deletar + </Button> } - /> - - <Paper style={{ padding: "1em" }}> - <Grid container spacing={3} direction="row" alignItems="center"> - <Grid item xs={6}> - <Typography variant="h4">Coleções</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( - "collections", - `"privacy" : "${currPrivacyFilter}" , "name" : "${currNameFilter}"`, - `${currPage}`, - "DESC" - ) - ); - }} - startIcon={<UpdateRoundedIcon />} - > - {isUpdating ? <CircularProgress size={24} /> : "Atualizar"} - </Button> - </Grid> - <Grid item> - <Button - variant="contained" - color="secondary" - onClick={() => { - setShowFilter(!showFilter); - }} - startIcon={<FilterListRoundedIcon />} - > - Filtrar - </Button> - </Grid> - </Grid> - </Grid> - </Grid> - - {showFilter ? ( - <> - <div style={{ height: "1em" }}></div> - - <Grid - container - alignItems="center" - alignContent="center" - xs={12} - direction="row" - justify="space-between" - > - <Grid item> - <TextField - select - label="Filtro" - value={option ? option : ""} - onChange={handleChange} - helperText="Por favor, selecione uma das opções" - > - {options.map((option, index) => ( - <MenuItem key={index} value={option.value} onClick={() => { ApplyFilter(option.value) }}> - {option.label} - </MenuItem> - ))} - </TextField> - </Grid> - - <Grid item> - <TextField - label="Pesquisa" - value={search} - onChange={(event) => HandleSearch(event)} - ></TextField> - </Grid> - </Grid> - </> - ) : null} - </Paper> - - <div style={{ height: "2em" }}></div> - - <TableData top={TOP_LABELS}> - <TableBody> - {items.map((row, index) => - index === items.length - 1 ? ( - <StyledTableRow key={index}> - <StyledTableCell> - <Button - key={index} - color="primary" - variant="text" - // disabled={isLoadingMoreItems} - startIcon={<AddRoundedIcon />} - disabled={isLoadingMoreItems} - onClick={() => { - currPage++; - LoadMoreItens( - Url( - "collections", - `"privacy" : "${currPrivacyFilter}" , "name" : "${currNameFilter}"`, - `${currPage}`, - "DESC" - ) - ); - }} - > - {isLoadingMoreItems ? ( - <CircularProgress size={24} /> - ) : ( - "Carregar mais itens" - )} - </Button> - </StyledTableCell> - </StyledTableRow> - ) : ( - <StyledTableRow key={index}> - <StyledTableCell component="th" scope="row"> - {row.name} - </StyledTableCell> - <StyledTableCell align="right"> - <div - dangerouslySetInnerHTML={{ __html: row.description }} - ></div> - </StyledTableCell> - <StyledTableCell align="right"> - {row.owner ? row.owner.name : "Sem dados"} - </StyledTableCell> - <StyledTableCell align="right"> - {DisplayDate(row.created_at)} - </StyledTableCell> - <StyledTableCell align="right"> - {DisplayDate(row.updated_at)} - </StyledTableCell> - <StyledTableCell align="right">{row.privacy}</StyledTableCell> - <StyledTableCell align="right"> - <Link to={`/admin/Collection/${row.id}`}> - <IconButton - onClick={() => { - currPage = 0; - currPrivacyFilter = ""; - currNameFilter = ""; - }} - > - <VisibilityIcon style={{ fill: "#00bcd4" }} /> - </IconButton> - </Link> - </StyledTableCell> - <StyledTableCell align="right"> - {isLoadingToDelete === index ? ( - <CircularProgress size={24} color="primary" /> - ) : ( - <IconButton - onClick={() => { - HandleStateAlertDialog(index); - HandleStateCircularProgress(index); - }} - > - <DeleteIcon style={{ fill: "#FF0000" }} /> - </IconButton> - )} - </StyledTableCell> - </StyledTableRow> - ) - )} - </TableBody> - </TableData> - - {/* This alert will be displayed if the user click to delete an institution */} - <AlertDialog - open={openAlertDialog} - OnDelete={DeleteHandler} - deleteItem={deleteItem} - HandleClose={() => { - setOpenAlertDialog(false); - HandleStateCircularProgress(null); - }} - /> + ] + } + /> + <div style={{ height: "0.5em" }} /> </> - ); - } + ) + )} + </> + ); + } + else { + return ( + <> + <SnackBar + severity={snackInfo.icon} + text={snackInfo.message} + snackbarOpen={snackInfo.open} + color={snackInfo.color} + handleClose={() => + setSnackInfo({ + message: "", + icon: "", + open: false, + color: "", + }) + } + /> + + <PageHeader + title="Coleções" + actions={[ + { + name: "Atualizar", + isLoading: false, + func: () => { + setCurrPage(0) + }, + icon: <UpdateRoundedIcon /> + }, + { + name: "Filtrar", + isLoading: false, + func: () => { + setShowFilter(!showFilter); + }, + icon: <FilterListRoundedIcon /> + } + ]} + > + {showFilter ? ( + <> + <div style={{ height: "1em" }}></div> + + <Grid + container + alignItems="center" + alignContent="center" + xs={12} + direction="row" + justify="space-between" + > + <Grid item> + <TextField + select + label="Filtro" + value={option} + onChange={handleChange} + helperText="Por favor, selecione uma das opções" + > + {privacyOptions.map((option, index) => ( + <MenuItem + key={option.value} + value={option.name} + name={option.value} + > + {option.value} + </MenuItem> + ))} + </TextField> + </Grid> + + <Grid item> + <TextField + label="Pesquisa" + value={valueOfSearch} + helperText="Ao digitar, tire o foco do campo de texto" + onChange={(event) => HandleSearch(event)} + onBlur={(event) => setSearch(event.target.value)} + ></TextField> + </Grid> + </Grid> + </> + ) : null} + </PageHeader> + + <div style={{ height: "2em" }}></div> + + <TableData top={TOP_LABELS}> + <TableBody> + {items.map((row, index) => + index === items.length - 1 ? ( + <StyledTableRow key={new Date().toISOString() + row.created_at}> + <StyledTableCell> + <Button + color="primary" + variant="text" + // disabled={isLoadingMoreItems} + startIcon={<AddRoundedIcon />} + disabled={isLoadingMoreItems} + onClick={() => { + setCurrPage(currPage + 1) + }} + > + {isLoadingMoreItems ? ( + <CircularProgress size={24} /> + ) : ( + "Carregar mais itens" + )} + </Button> + </StyledTableCell> + </StyledTableRow> + ) : ( + <StyledTableRow key={new Date().toISOString() + index}> + <StyledTableCell component="th" scope="row"> + {row.name} + </StyledTableCell> + <StyledTableCell align="right"> + <div + dangerouslySetInnerHTML={{ __html: row.description }} + ></div> + </StyledTableCell> + <StyledTableCell align="right"> + {row.owner ? row.owner.name : "Sem dados"} + </StyledTableCell> + <StyledTableCell align="right"> + {DisplayDate(row.created_at)} + </StyledTableCell> + <StyledTableCell align="right"> + {DisplayDate(row.updated_at)} + </StyledTableCell> + <StyledTableCell align="right">{row.privacy}</StyledTableCell> + <StyledTableCell align="right"> + <Link to={`/admin/Collection?collection=${row.id}`}> + <IconButton> + <VisibilityIcon style={{ fill: "#00bcd4" }} /> + </IconButton> + </Link> + </StyledTableCell> + <StyledTableCell align="right"> + {isLoadingToDelete === index ? ( + <CircularProgress size={24} color="primary" /> + ) : ( + <IconButton + onClick={() => { + HandleStateAlertDialog(index); + HandleStateCircularProgress(index); + }} + > + <DeleteIcon style={{ fill: "#FF0000" }} /> + </IconButton> + )} + </StyledTableCell> + </StyledTableRow> + ) + )} + </TableBody> + </TableData> + + {/* This alert will be displayed if the user click to delete an institution */} + <AlertDialog + open={openAlertDialog} + OnDelete={DeleteHandler} + deleteItem={deleteItem} + HandleClose={() => { + setOpenAlertDialog(false); + HandleStateCircularProgress(null); + }} + /> + </> + ); } + } }; export default Collections; diff --git a/src/Admin/Pages/Pages/SubPages/CommunityQuestions.js b/src/Admin/Pages/Pages/SubPages/CommunityQuestions.js index 8941b8c8d298f11c0ad42917738d09a58473c236..4c93b941127ab8009536a7ada106ca0791ffec23 100644 --- a/src/Admin/Pages/Pages/SubPages/CommunityQuestions.js +++ b/src/Admin/Pages/Pages/SubPages/CommunityQuestions.js @@ -16,763 +16,510 @@ 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 React, { useEffect, useState } from "react"; import moment from 'moment'; //imports from local files import TableData from "../../../Components/Components/Table"; import SnackBar from "../../../../Components/SnackbarComponent"; -import Unauthorized from '../../../Components/Components/Unauthorized'; import { Url } from "../../../Filters"; -import { Store } from '../../../../Store'; import LoadingSpinner from '../../../../Components/LoadingSpinner'; import { getRequest } from '../../../../Components/HelperFunctions/getAxiosConfig'; +import MobilePageHeader from "../../../Components/Components/MobileComponents/MobilePageHeader" +import MobileList from "../../../Components/Components/MobileComponents/SimpleList" +import PageHeader from "../../../Components/Components/PageHeader" //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 TableRow from "@material-ui/core/TableRow"; import TextField from "@material-ui/core/TextField"; -import Popover from "@material-ui/core/Popover"; import IconButton from "@material-ui/core/IconButton"; -import { Button, Typography, Paper, Grid } from "@material-ui/core"; +import { Button, 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 CancelRoundedIcon from '@material-ui/icons/CancelRounded'; import FilterListRoundedIcon from "@material-ui/icons/FilterListRounded"; import VisibilityIcon from "@material-ui/icons/Visibility"; import EmailRoundedIcon from '@material-ui/icons/EmailRounded'; import ContactSupportRoundedIcon from "@material-ui/icons/ContactSupportRounded"; //routers import { Link } from 'react-router-dom'; -import MobileList from "../../../Components/Components/MobileComponents/SimpleList" import styled from "styled-components" -let currPage = 0; - const StyledTableCell = withStyles((theme) => ({ - head: { - backgroundColor: theme.palette.common.black, - color: theme.palette.common.white, - }, - body: { - fontSize: 14, - }, + 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, - }, + root: { + "&:nth-of-type(odd)": { + backgroundColor: theme.palette.action.hover, }, + }, }))(TableRow); const CommunityQuestion = () => { - const { state } = useContext(Store); - - const ADD_ONE_LENGHT = [""]; - const TOP_LABELS = [ - "ID", - "DATA DE CONTATO", - "NOME", - "EMAIL", - "MENSAGEM", - "VISUALIZAR" - ]; //Labels from Table - const WINDOW_WIDTH = window.innerWidth - - const [anchorEl, setAnchorEl] = React.useState(null); - - 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 - - //Works with the filter - const [showMessageFilter, setShowMessageFilter] = useState(false); - const [showEmailFilter, setShowEmailFilter] = useState(false); - const [showNameFilter, setShowNameFilter] = useState(false); - const [message, setMessage] = useState(""); - const [email, setEmail] = useState(""); - const [name, setName] = useState(""); - - const [snackInfo, setSnackInfo] = useState({ - message: "", - icon: "", - open: false, - color: "", - }); - //handle with the message filter - const MessageFilterHandler = (e) => { - setMessage(e.target.value) - getRequest( - Url("contacts", `"message" : "${message}", "email" : "${email}", "name" : "${name}"`, currPage, 'DESC'), - (data, header) => { - const arrData = [...data]; - setItems(arrData.concat(ADD_ONE_LENGHT)); - }, - (error) => { - HandleSnack("Não achamos nada na nossa base de dados!", true, "warning", "#FA8072"); - } - ) - } - - //handle with the email filter - const EmailFilterHandler = (e) => { - setEmail(e.target.value) - getRequest( - Url("contacts", `"message" : "${message}", "email" : "${email}", "name" : "${name}"`, currPage, 'DESC'), - (data, header) => { - const arrData = [...data]; - setItems(arrData.concat(ADD_ONE_LENGHT)); - }, - (error) => { - HandleSnack("Não achamos nada na nossa base de dados!", true, "warning", "#FA8072"); - } - ) - } - - //handle with the name filter - const NameFilterHandler = (e) => { - setName(e.target.value) - getRequest( - Url("contacts", `"message" : "${message}", "email" : "${email}", "name" : "${name}"`, currPage, 'DESC'), - (data, header) => { - const arrData = [...data]; - setItems(arrData.concat(ADD_ONE_LENGHT)); - }, - (error) => { - HandleSnack("Não achamos nada na nossa base de dados!", true, "warning", "#FA8072"); - } - ) - } - - //handle snack info - const HandleSnack = (message, state, icon, color) => { - setSnackInfo({ - message: message, - icon: icon, - open: state, - color: color, - }); - }; - - const handleClick = (event) => { - setAnchorEl(event.currentTarget); - }; - - const handleClose = () => { - setAnchorEl(null); - }; - - const open = Boolean(anchorEl); - const id = open ? 'simple-popover' : undefined; - - //handle load more items - const LoadMoreItens = (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 = (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 DisplayDate = (date) => { - const convertedData = moment.utc(date); - return moment(convertedData) - .format("LLL") - .toString(); - }; - - 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; + const ADD_ONE_LENGHT = [""]; + const TOP_LABELS = [ + "ID", + "DATA DE CONTATO", + "NOME", + "EMAIL", + "MENSAGEM", + "VISUALIZAR" + ]; //Labels from Table + const WINDOW_WIDTH = window.innerWidth + + 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 [currPage, setCurrPage] = useState(0) + + //Works with the filter + const [invertList, setInvertList] = useState(false) + const [showFilter, setShowFilter] = useState(false) + const [valueOfMessageField, setValueOfMessageField] = useState("") + const [message, setMessage] = useState(""); + const [valueOfEmailField, setValueOfEmailField] = useState("") + const [email, setEmail] = useState(""); + const [valueOfNameField, setValueOfNameField] = useState("") + const [name, setName] = useState(""); + + const [snackInfo, setSnackInfo] = useState({ + message: "", + icon: "", + open: false, + color: "", + }); + + //handle with the message filter + const valueOfMessageHandler = (e) => { + setValueOfMessageField(e.target.value) + } + + //handle with the email filter + const valueOfEmailHandler = (e) => { + setValueOfEmailField(e.target.value) + } + + //handle with the name filter + const valueOfNameHandler = (e) => { + setValueOfNameField(e.target.value) + } + + //handle snack info + const HandleSnack = (message, state, icon, color) => { + setSnackInfo({ + message: message, + icon: icon, + open: state, + color: color, + }); + }; + + const DisplayDate = (date) => { + const convertedData = moment.utc(date); + return moment(convertedData) + .format("LLL") + .toString(); + }; + + const cleanArrayAndInvert = () => { + setInvertList(!invertList) + setCurrPage(0) + setItems([]) + } + + const buildUrl = (message, email, name, direction) => { + if (message && email && name) + return Url("contacts", `"message" : "${message}", "email" : "${email}", "name" : "${name}"`, currPage, direction) + + else if (message && name) + return Url("contacts", `"message" : "${message}", "name" : "${name}"`, currPage, direction) + else if (message && email) + return Url("contacts", `"message" : "${message}", "email" : "${email}"`, currPage, direction) + else if (name && email) + return Url("contacts", `"name" : "${name}", "email" : "${email}"`, currPage, direction) + + else if (message) + return Url("contacts", `"message" : "${message}"`, currPage, direction) + else if (email) + return Url("contacts", `"email" : "${email}"`, currPage, direction) + else if (name) + return Url("contacts", `"name" : "${name}"`, currPage, direction) + else + return Url("contacts", "", currPage, direction) + } + + useEffect(() => { + if (currPage === 0) + setIsLoaded(false) + else + setIsLoadingMoreItems(true) + getRequest( + buildUrl(message, email, name, invertList ? "ASC" : "DESC"), + (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] + if (currPage === 0) { + setItems(arrData.concat(ADD_ONE_LENGHT)) + } + else { + 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)) + } } - - return canUserEdit; - } - - //getting data from server - useEffect(() => { - getRequest( - Url("contacts", `"message" : "${message}", "email" : "${email}", "name" : "${name}"`, `${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); + setIsLoaded(true) + setIsLoadingMoreItems(false) + }, + (error) => { + HandleSnack('Erro ao carregar os dados', true, 'warning', '#FA8072') + setIsLoadingMoreItems(false) + setIsLoaded(true) + setError(true) + } + ) + }, [currPage, message, email, name, invertList]) + + useEffect(() => { + setCurrPage(0) + setName("") + setValueOfNameField("") + setEmail("") + setValueOfEmailField("") + setMessage("") + setValueOfMessageField("") + }, [showFilter]) + + if (error) { + return <div>Error: {error.message}</div>; + } else if (!isLoaded) { + return <LoadingSpinner text="Carregando..." /> + } else { + if (WINDOW_WIDTH <= 1200) { + return ( + <> + <SnackBar + severity={snackInfo.icon} + text={snackInfo.message} + snackbarOpen={snackInfo.open} + color={snackInfo.color} + handleClose={() => + setSnackInfo({ + message: "", + icon: "", + open: false, + color: "", + }) } - ) - }, []); - - if (error) { - return <div>Error: {error.message}</div>; - } else if (!isLoaded) { - return <LoadingSpinner text="Carregando..." /> - } else if (CheckUserPermission()) { - if (WINDOW_WIDTH <= 1200) { - return ( + /> + <MobilePageHeader + title="Dúvidas da comunidade" + actions={[ + { + name: "Atualizar", + isLoading: false, + func: () => { + setCurrPage(0) + }, + icon: <UpdateRoundedIcon /> + }, + { + name: "Filtrar", + isLoading: false, + func: () => { + setShowFilter(!showFilter); + }, + icon: <FilterListRoundedIcon /> + }, + { + name: "Inverter lista de dados", + isLoading: false, + func: () => { + cleanArrayAndInvert() + }, + } + ]} + > + {showFilter ? ( + <Grid + container + direction="row" + justify="space-between" + alignItems="center" + alignContent="flex-end" + spacing={3} + xs={12} + > + <Grid item> + <TextField + label="Email" + value={valueOfEmailField} + onChange={valueOfEmailHandler} + onBlur={(e) => { setEmail(e.target.value) }} + helperText="Por favor, ao digitar o email que você quer filtar, retire o foco do campo de texto" + > + </TextField> + </Grid> + <Grid item> + <TextField + label="Mensagem" + value={valueOfMessageField} + onChange={valueOfMessageHandler} + onBlur={(e) => { setMessage(e.target.value) }} + helperText="Por favor, ao digitar a mensagem que você quer filtar, retire o foco do campo de texto" + > + </TextField> + </Grid> + <Grid item> + <TextField + label="Nome" + value={valueOfNameField} + onChange={valueOfNameHandler} + onBlur={(e) => { setName(e.target.value) }} + helperText="Por favor, ao digitar o nome que você quer filtar, retire o foco do campo de texto" + > + </TextField> + </Grid> + </Grid> + ) : null} + </MobilePageHeader> + + <div style={{ height: "2em" }}></div> + + {items.map((row, index) => + index === items.length - 1 ? ( + <StyledDivButton + key="Load more" + > + <Button + color="primary" + variant="text" + // disabled={isLoadingMoreItems} + startIcon={<AddRoundedIcon />} + disabled={isLoadingMoreItems} + onClick={() => { + setCurrPage(currPage + 1) + }} + > + {isLoadingMoreItems ? ( + <CircularProgress size={24} /> + ) : ( + "Carregar mais itens" + )} + </Button> + </StyledDivButton> + ) : ( <> - <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={12}> - <Typography variant="h4">Dúvidas da comunidade</Typography> - </Grid> - <Grid - item - xs={12} - > - <Grid container justify="flex-start" spacing={3}> - <Grid item> - <Button - variant="contained" - color="secondary" - disabled={isUpdating} - onClick={() => { - currPage = 0; - UpdateHandler( - Url("contacts", `"message" : "${message}", "email" : "${email}", "name" : "${name}"`, `${currPage}`, "DESC") - ); - }} - startIcon={<UpdateRoundedIcon />} - > - {isUpdating ? <CircularProgress size={24} /> : "Atualizar"} - </Button> - </Grid> - <Grid item> - <Button - variant="contained" - color="secondary" - onClick={(e) => { - handleClick(e); - }} - startIcon={<FilterListRoundedIcon />} - > - Filtrar - </Button> - <Popover - id={id} - open={open} - anchorEl={anchorEl} - onClose={handleClose} - anchorOrigin={{ - vertical: 'bottom', - horizontal: 'center', - }} - transformOrigin={{ - vertical: 'top', - horizontal: 'center', - }} - > - <Button - onClick={() => setShowEmailFilter(!showEmailFilter)} - color={showEmailFilter ? 'primary' : 'default'} - variant='text' - > - EMAIL - </Button> - - <Button - onClick={() => setShowMessageFilter(!showMessageFilter)} - color={showMessageFilter ? 'primary' : 'default'} - variant='text' - > - MENSAGEM - </Button> - - <Button - onClick={() => setShowNameFilter(!showNameFilter)} - color={showNameFilter ? 'primary' : 'default'} - variant='text' - > - NOME - </Button> - </Popover> - </Grid> - </Grid> - </Grid> - </Grid> - - <div style={{ height: '1.5em' }}></div> - - <Grid item xs={12}> - <Grid container justify="space-between" spacing={3}> - { - showMessageFilter ? - <Grid item > - <TextField - label='Mensagem' - type="search" - onChange={(e) => MessageFilterHandler(e)} - /> - <IconButton - size="small" - color="primary" - onClick={() => { - currPage = 0; - setMessage("") - UpdateHandler( - Url("contacts", `"message" : "", "email" : "${email}", "name" : "${name}"`, `${currPage}`, "DESC") - ); - setShowMessageFilter(false) - }} - > - <CancelRoundedIcon /> - </IconButton> - </Grid> : null - } - { - showEmailFilter ? - <Grid item> - <TextField - label='Email' - type="search" - onChange={(e) => EmailFilterHandler(e)} - /> - <IconButton - size="small" - color="primary" - onClick={() => { - currPage = 0; - setEmail("") - UpdateHandler( - Url("contacts", `"message" : "${message}", "email" : "", "name" : "${name}"`, `${currPage}`, "DESC") - ); - setShowEmailFilter(false) - }} - > - <CancelRoundedIcon /> - </IconButton> - </Grid> : null - } - { - showNameFilter ? - <Grid item> - <TextField - label='Nome' - type="search" - onChange={(e) => NameFilterHandler(e)} - /> - <IconButton - size="small" - color="primary" - onClick={() => { - currPage = 0; - setName("") - UpdateHandler( - Url("contacts", `"message" : "${message}", "email" : "${email}", "name" : ""`, `${currPage}`, "DESC") - ); - setShowNameFilter(false) - }} - > - <CancelRoundedIcon /> - </IconButton> - </Grid> : null - } - </Grid> - </Grid> - </Paper> - - <div style={{ height: "2em" }}></div> - - {items.map((row, index) => - index === items.length - 1 ? ( - <StyledDivButton> + <MobileList + key={index} + title={row.name} + subtitle={row.id} + backColor={"#00bcd4"} + avatar={<ContactSupportRoundedIcon />} + href={`/admin/CommunityQuestion?question=${row.id}`} + reset={() => { + }} + data={ + [ + { + title: "Email", + subtitle: + row.email ? + <Link to={`/admin/sendEmail?email=${row.email}`} style={{ textDecoration: 'none' }}> <Button - key={index} - color="primary" - variant="text" - // disabled={isLoadingMoreItems} - startIcon={<AddRoundedIcon />} - disabled={isLoadingMoreItems} - onClick={() => { - currPage++; - LoadMoreItens( - Url("contacts", `"message" : "${message}", "email" : "${email}", "name" : "${name}"`, `${currPage}`, "DESC") - ); - }} + variant='text' + color='primary' + startIcon={<EmailRoundedIcon />} > - {isLoadingMoreItems ? ( - <CircularProgress size={24} /> - ) : ( - "Carregar mais itens" - )} + {row.email} </Button> - </StyledDivButton> - ) : ( - <> - <MobileList - key={index} - title={row.name} - subtitle={row.id} - backColor={"#00bcd4"} - avatar={<ContactSupportRoundedIcon />} - href={`/admin/CommunityQuestion/${row.id}`} - reset={() => { - currPage = 0; - - }} - data={ - [ - { - title: "Email", - subtitle: - row.email ? - <Link to={`/admin/sendEmail/${row.email}`} style={{ textDecoration: 'none' }}> - <Button - variant='text' - color='primary' - startIcon={<EmailRoundedIcon />} - > - {row.email} - </Button> - </Link> : null - - }, - { - title: "Mensagem", - subtitle: row.message - - }, - { - title: "Criado em", - subtitle: DisplayDate(row.created_at) - }, - ] - } - /> - <div style={{ height: "0.5em" }} /> - </> - ) - )} - </> - ) - } - else { - return <> - <SnackBar - severity={snackInfo.icon} - text={snackInfo.message} - snackbarOpen={snackInfo.open} - color={snackInfo.color} - handleClose={() => - setSnackInfo({ - message: "", - icon: "", - open: false, - color: "", - }) + </Link> : null + + }, + { + title: "Mensagem", + subtitle: row.message + + }, + { + title: "Criado em", + subtitle: DisplayDate(row.created_at) + }, + ] } - /> - - <Paper style={{ padding: "1em" }}> - <Grid container spacing={3} direction="row" alignItems="center"> - <Grid item xs={6}> - <Typography variant="h4">Dúvidas da comunidade</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("contacts", `"message" : "${message}", "email" : "${email}", "name" : "${name}"`, `${currPage}`, "DESC") - ); - }} - startIcon={<UpdateRoundedIcon />} - > - {isUpdating ? <CircularProgress size={24} /> : "Atualizar"} - </Button> - </Grid> - <Grid item> - <Button - variant="contained" - color="secondary" - onClick={(e) => { - handleClick(e); - }} - startIcon={<FilterListRoundedIcon />} - > - Filtrar - </Button> - <Popover - id={id} - open={open} - anchorEl={anchorEl} - onClose={handleClose} - anchorOrigin={{ - vertical: 'bottom', - horizontal: 'center', - }} - transformOrigin={{ - vertical: 'top', - horizontal: 'center', - }} - > - <Button - onClick={() => setShowEmailFilter(!showEmailFilter)} - color={showEmailFilter ? 'primary' : 'default'} - variant='text' - > - EMAIL - </Button> - - <Button - onClick={() => setShowMessageFilter(!showMessageFilter)} - color={showMessageFilter ? 'primary' : 'default'} - variant='text' - > - MENSAGEM - </Button> - - <Button - onClick={() => setShowNameFilter(!showNameFilter)} - color={showNameFilter ? 'primary' : 'default'} - variant='text' - > - NOME - </Button> - </Popover> - </Grid> - </Grid> - </Grid> - </Grid> - - <div style={{ height: '1.5em' }}></div> - - <Grid item xs={12}> - <Grid container justify="space-between" spacing={3}> - { - showMessageFilter ? - <Grid item > - <TextField - label='Mensagem' - type="search" - onChange={(e) => MessageFilterHandler(e)} - /> - <IconButton - size="small" - color="primary" - onClick={() => { - currPage = 0; - setMessage("") - UpdateHandler( - Url("contacts", `"message" : "", "email" : "${email}", "name" : "${name}"`, `${currPage}`, "DESC") - ); - setShowMessageFilter(false) - }} - > - <CancelRoundedIcon /> - </IconButton> - </Grid> : null - } - { - showEmailFilter ? - <Grid item> - <TextField - label='Email' - type="search" - onChange={(e) => EmailFilterHandler(e)} - /> - <IconButton - size="small" - color="primary" - onClick={() => { - currPage = 0; - setEmail("") - UpdateHandler( - Url("contacts", `"message" : "${message}", "email" : "", "name" : "${name}"`, `${currPage}`, "DESC") - ); - setShowEmailFilter(false) - }} - > - <CancelRoundedIcon /> - </IconButton> - </Grid> : null - } - { - showNameFilter ? - <Grid item> - <TextField - label='Nome' - type="search" - onChange={(e) => NameFilterHandler(e)} - /> - <IconButton - size="small" - color="primary" - onClick={() => { - currPage = 0; - setName("") - UpdateHandler( - Url("contacts", `"message" : "${message}", "email" : "${email}", "name" : ""`, `${currPage}`, "DESC") - ); - setShowNameFilter(false) - }} - > - <CancelRoundedIcon /> - </IconButton> - </Grid> : null - } - </Grid> - </Grid> - </Paper> - - <div style={{ height: "2em" }}></div> - - <TableData top={TOP_LABELS}> - <TableBody> - {items.map((row, index) => - index === items.length - 1 ? ( - <StyledTableRow key={index} style={{ padding: "1em" }}> - {/* Button to load more data */} - <StyledTableCell> - <Button - color="primary" - variant="text" - startIcon={<AddRoundedIcon />} - disabled={isLoadingMoreItems} - onClick={() => { - currPage++; - LoadMoreItens( - Url("contacts", `"message" : "${message}", "email" : "${email}", "name" : "${name}"`, `${currPage}`, "DESC") - ); - }} - > - {isLoadingMoreItems ? ( - <CircularProgress size={24} /> - ) : ( - "Carregar mais itens" - )} - </Button> - </StyledTableCell> - </StyledTableRow> - ) : ( - <StyledTableRow key={index}> - <StyledTableCell component="th" scope="row"> - {row.id} - </StyledTableCell> - <StyledTableCell align="right"> - {DisplayDate(row.created_at)} - </StyledTableCell> - <StyledTableCell align="right"> - {row.name} - </StyledTableCell> - <StyledTableCell align="right"> - { - row.email ? - <Link to={`/admin/sendEmail/${row.email}`} style={{ textDecoration: 'none' }}> - <Button - variant='text' - color='primary' - startIcon={<EmailRoundedIcon />} - > - {row.email} - </Button> - </Link> : null - } - </StyledTableCell> - <StyledTableCell align="right"> - {row.message} - </StyledTableCell> - <StyledTableCell align="right"> - <Link to={`/admin/CommunityQuestion/${row.id}`}> - <IconButton onClick={() => { currPage = 0 }}> - <VisibilityIcon style={{ fill: "#00bcd4" }} /> - </IconButton> - </Link> - </StyledTableCell> - </StyledTableRow> - ) + /> + <div style={{ height: "0.5em" }} /> + </> + ) + )} + </> + ) + } + else { + return <> + <SnackBar + severity={snackInfo.icon} + text={snackInfo.message} + snackbarOpen={snackInfo.open} + color={snackInfo.color} + handleClose={() => + setSnackInfo({ + message: "", + icon: "", + open: false, + color: "", + }) + } + /> + + <PageHeader + title="Dúvidas da comunidade" + actions={[ + { + name: "Atualizar", + isLoading: false, + func: () => { + setCurrPage(0) + }, + icon: <UpdateRoundedIcon /> + }, + { + name: "Filtrar", + isLoading: false, + func: () => { + setShowFilter(!showFilter); + }, + icon: <FilterListRoundedIcon /> + } + ]} + > + {showFilter ? ( + <Grid + container + direction="row" + justify="space-between" + alignItems="center" + alignContent="flex-end" + spacing={3} + xs={12} + > + <Grid item> + <TextField + label="Email" + value={valueOfEmailField} + onChange={valueOfEmailHandler} + onBlur={(e) => { setEmail(e.target.value) }} + helperText="Por favor, ao digitar o email que você quer filtar, retire o foco do campo de texto" + > + </TextField> + </Grid> + <Grid item> + <TextField + label="Mensagem" + value={valueOfMessageField} + onChange={valueOfMessageHandler} + onBlur={(e) => { setMessage(e.target.value) }} + helperText="Por favor, ao digitar a mensagem que você quer filtar, retire o foco do campo de texto" + > + </TextField> + </Grid> + <Grid item> + <TextField + label="Nome" + value={valueOfNameField} + onChange={valueOfNameHandler} + onBlur={(e) => { setName(e.target.value) }} + helperText="Por favor, ao digitar o nome que você quer filtar, retire o foco do campo de texto" + > + </TextField> + </Grid> + </Grid> + ) : null} + </PageHeader> + + <div style={{ height: "2em" }}></div> + + <TableData top={TOP_LABELS} onIconPressed={cleanArrayAndInvert}> + <TableBody> + {items.map((row, index) => + index === items.length - 1 ? ( + <StyledTableRow key={row.created_at} style={{ padding: "1em" }}> + {/* Button to load more data */} + <StyledTableCell> + <Button + color="primary" + variant="text" + startIcon={<AddRoundedIcon />} + disabled={isLoadingMoreItems} + onClick={() => { + setCurrPage(currPage + 1) + }} + > + {isLoadingMoreItems ? ( + <CircularProgress size={24} /> + ) : ( + "Carregar mais itens" )} - </TableBody> - </TableData> - </> - } - - } else return <Unauthorized /> + </Button> + </StyledTableCell> + </StyledTableRow> + ) : ( + <StyledTableRow key={new Date().toISOString() + index}> + <StyledTableCell component="th" scope="row"> + {row.id} + </StyledTableCell> + <StyledTableCell align="right"> + {DisplayDate(row.created_at)} + </StyledTableCell> + <StyledTableCell align="right"> + {row.name} + </StyledTableCell> + <StyledTableCell align="right"> + { + row.email ? + <Link to={`/admin/sendEmail?email=${row.email}`} style={{ textDecoration: 'none' }}> + <Button + variant='text' + color='primary' + startIcon={<EmailRoundedIcon />} + > + {row.email} + </Button> + </Link> : null + } + </StyledTableCell> + <StyledTableCell align="right"> + {row.message} + </StyledTableCell> + <StyledTableCell align="right"> + <Link to={`/admin/CommunityQuestion?question=${row.id}`}> + <IconButton> + <VisibilityIcon style={{ fill: "#00bcd4" }} /> + </IconButton> + </Link> + </StyledTableCell> + </StyledTableRow> + ) + )} + </TableBody> + </TableData> + </> + } + } } export default CommunityQuestion; diff --git a/src/Admin/Pages/Pages/SubPages/Complaints.js b/src/Admin/Pages/Pages/SubPages/Complaints.js index 452aaf767e40435fc33ffac975610bbb2e82016c..d03514dc91f170cd84c4807e42c5f4d643de036e 100644 --- a/src/Admin/Pages/Pages/SubPages/Complaints.js +++ b/src/Admin/Pages/Pages/SubPages/Complaints.js @@ -16,15 +16,17 @@ 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 React, { useEffect, useState } 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 } from '../../../../Components/HelperFunctions/getAxiosConfig' +import MobileList from "../../../Components/Components/MobileComponents/SimpleList" +import MobilePageHeader from "../../../Components/Components/MobileComponents/MobilePageHeader" +import PageHeader from "../../../Components/Components/PageHeader" //imports from material ui import { withStyles } from "@material-ui/core/styles"; import TableBody from "@material-ui/core/TableBody"; @@ -33,7 +35,7 @@ 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 { Button, 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"; @@ -42,841 +44,602 @@ import VisibilityIcon from "@material-ui/icons/Visibility"; import LaunchRoundedIcon from "@material-ui/icons/LaunchRounded"; //routers import { Link } from "react-router-dom"; -import Unauthorized from "../../../Components/Components/Unauthorized"; import styled from "styled-components" -import MobileList from "../../../Components/Components/MobileComponents/SimpleList" import AnnouncementRoundedIcon from "@material-ui/icons/AnnouncementRounded"; -let currPage = 0; -let currStateFilter = "0" -let currComplainReasonId; -let currDescriptionFilter = ""; - const StyledTableCell = withStyles((theme) => ({ - head: { - backgroundColor: theme.palette.common.black, - color: theme.palette.common.white, - }, - body: { - fontSize: 14, - }, + 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, - }, + root: { + "&:nth-of-type(odd)": { + backgroundColor: theme.palette.action.hover, }, + }, }))(TableRow); const Complaints = () => { - const { state } = useContext(Store); - const WINDOW_WIDTH = window.innerWidth - - const PORTAL_MEC = "https://plataformaintegrada.mec.gov.br/"; - - const ADD_ONE_LENGHT = [""]; - const TOP_LABELS = [ - "ESTADO DO RECURSO", - "ID", - "DESCRIÇÃO", - "ID OBJETO", - "TIPO", - "DATA(MM/DD/YYYY)", - "VISUALIZAR", - "VISITAR", - ]; //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 [stateOption, setStateOption] = useState("Pendente"); - const [complainOption, setComplainOption] = useState(""); - const [description, setDescription] = useState(""); - - const [snackInfo, setSnackInfo] = useState({ - message: "", - icon: "", - open: false, - color: "", + const WINDOW_WIDTH = window.innerWidth + const ADD_ONE_LENGHT = [""]; + const PORTAL_MEC = "https://plataformaintegrada.mec.gov.br/"; + const TOP_LABELS = [ + "ESTADO DO RECURSO", + "ID", + "DESCRIÇÃO", + "ID OBJETO", + "TIPO", + "DATA(MM/DD/YYYY)", + "VISUALIZAR", + "VISITAR", + ]; //Labels from Table + + const [invertList, setInvertList] = useState(false) + 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 [showFilter, setShowFilter] = useState(false); + + const [stateOption, setStateOption] = useState(0); + const [complainOption, setComplainOption] = useState(""); + const [description, setDescription] = useState(""); + const [valueOfDescField, setValueOfDescField] = useState("") + const [currPage, setCurrPage] = useState(0) + + const [snackInfo, setSnackInfo] = useState({ + message: "", + icon: "", + open: false, + color: "", + }); + + const stateOptions = [ + { name: 0, value: "Pendente" }, + { name: 1, value: "Ativo" }, + { name: 2, value: "Removido" }, + ]; + + const ComplaintReasons = [ + { name: 1, value: "Viola direitos autorais" }, + { name: 2, value: "Conteúdo ofensivo/abusivo" }, + { name: 3, value: "Conta falsa" }, + { name: 4, value: "Spam" }, + { name: 5, value: "Descrição diverge do conteúdo" }, + ]; + + //handle snack info + const HandleSnack = (message, state, icon, color) => { + setSnackInfo({ + message: message, + icon: icon, + open: state, + color: color, }); - - const StateOptions = [ - { id: 0, name: "Pendente" }, - { id: 1, name: "Ativo" }, - { id: 2, name: "Bloqueado / Removido" }, - ]; - - const ComplaintReasons = [ - { id: 1, name: "Viola direitos autorais" }, - { id: 2, name: "Conteúdo ofensivo/abusivo" }, - { id: 3, name: "Conta falsa" }, - { id: 4, name: "Spam" }, - { id: 5, name: "Descrição diverge do conteúdo" }, - ]; - - //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; + }; + + const handleChangeState = (e, type) => { + const value = e.target.value; + setStateOption(value); + }; + + const handleChangeComplain = (e, type) => { + const value = e.target.value; + setComplainOption(value); + }; + + const DescriptionHandler = (e) => { + setValueOfDescField(e.target.value) + } + + const convertToLink = (type, id) => { + switch (type) { + case "LearningObject": + return `recurso?id=${id}/`; + case "User": + return `usuario-publico/${id}/`; + default: + return ""; } - - //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 ComplaintStatus = (status, type) => { + switch (status) { + case "accepted": + return ( + <Paper + style={{ + textAlign: "center", + padding: "0.5em", + backgroundColor: "#FA8072", + fontWeight: "500", + color: "#FFFAFA", + }} + > + { + type === "User" ? "BLOQUEADO" : "REMOVIDO" } - ) - }; - - const handleChangeState = (e, type) => { - const value = e.target.value; - setStateOption(value); - }; - - const handleChangeComplain = (e, type) => { - const value = e.target.value; - setComplainOption(value); - }; - - const ApplyFilterState = (id, type) => { - currPage = 0; - currStateFilter = id; - let url; - if (currComplainReasonId) { - url = Url("complaints", - `"state" : "${currStateFilter}", "complaint_reason_id" : "${currComplainReasonId}", "description" : "${currDescriptionFilter}"`, - `${currPage}`, - "DESC" - ) - } - else { - url = Url("complaints", - `"state" : "${currStateFilter}", "description" : "${currDescriptionFilter}"`, - `${currPage}`, - "DESC" - ) - } - getRequest( - url, - (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 ApplyFilterComplainReason = (id, type) => { - currPage = 0; - currComplainReasonId = id; - let url; - if (currComplainReasonId) { - url = Url("complaints", - `"state" : "${currStateFilter}", "complaint_reason_id" : "${currComplainReasonId}", "description" : "${currDescriptionFilter}"`, - `${currPage}`, - "DESC" - ) - } - else { - url = Url("complaints", - `"state" : "${currStateFilter}", "description" : "${currDescriptionFilter}"`, - `${currPage}`, - "DESC" - ) - } - getRequest( - url, - (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 DescriptionHandler = (e) => { - currPage = 0; - currDescriptionFilter = e.target.value; - setDescription(currDescriptionFilter) - let url; - if (currComplainReasonId) { - url = Url("complaints", - `"state" : "${currStateFilter}", "complaint_reason_id" : "${currComplainReasonId}", "description" : "${currDescriptionFilter}"`, - `${currPage}`, - "DESC" - ) - } - else { - url = Url("complaints", - `"state" : "${currStateFilter}", "description" : "${currDescriptionFilter}"`, - `${currPage}`, - "DESC" - ) - } - getRequest( - url, - (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); - } - ) + </Paper> + ); + case "complained": + 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: "#228B22", + fontWeight: "500", + color: "#FFFAFA", + }} + > + REJEITADO + </Paper> + ); + default: + return "NOTHING"; } - - const convertToLink = (type, id) => { - switch (type) { - case "LearningObject": - return `recurso?id=${id}/`; - case "User": - return `usuario-publico/${id}/`; - default: - return ""; - } - }; - - const ComplaintStatus = (status, type) => { - switch (status) { - case "accepted": - return ( - <Paper - style={{ - textAlign: "center", - padding: "0.5em", - backgroundColor: "#FA8072", - fontWeight: "500", - color: "#FFFAFA", - }} - > - { - type === "User" ? "BLOQUEADO" : "REMOVIDO" - } - </Paper> - ); - case "complained": - 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: "#228B22", - fontWeight: "500", - color: "#FFFAFA", - }} - > - REJEITADO - </Paper> - ); - default: - return "NOTHING"; + }; + + const DisplayDate = (date) => { + const convertedData = moment.utc(date); + return moment(convertedData) + .format("LLL") + .toString(); + }; + + const cleanArrayAndInvert = () => { + setInvertList(!invertList) + setCurrPage(0) + setItems([]) + } + + const buildUrl = (complainOpt, state, description, direction) => { + if (complainOpt && (state >= 0 && state <= 2) && description) + return Url("complaints", `"state" : ${state}, "complaint_reason_id" : ${complainOpt}, "description" : "${description}"`, currPage, direction) + + else if (complainOpt && description) + return Url("complaints", `"complaint_reason_id" : ${complainOpt}, "description" : "${description}"`, currPage, direction) + else if (complainOpt && (state >= 0 && state <= 2)) + return Url("complaints", `"complaint_reason_id" : ${complainOpt}, "state" : ${state}`, currPage, direction) + else if (description && (state >= 0 && state <= 2)) + return Url("complaints", `"description" : "${description}", "state" : ${state}`, currPage, direction) + + else if (complainOpt) + return Url("complaints", `"complaint_reason_id" : ${complainOpt}`, currPage, direction) + else if (state >= 0 && state <= 2) + return Url("complaints", `"state" : ${state}`, currPage, direction) + else if (description) + return Url("complaints", `"description" : ${description}`, currPage, direction) + else + return Url("complaints", "", currPage, direction) + } + + useEffect(() => { + if (currPage === 0) + setIsLoaded(false) + else + setIsLoadingMoreItems(true) + getRequest( + buildUrl(complainOption, stateOption, description, invertList ? "ASC" : "DESC"), + (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] + if (currPage === 0) { + setItems(arrData.concat(ADD_ONE_LENGHT)) + } + else { + 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)) + } } - }; - - const DisplayDate = (date) => { - const convertedData = moment.utc(date); - return moment(convertedData) - .format("LLL") - .toString(); - }; - - //getting data from server - useEffect(() => { - getRequest( - Url("complaints", `"state" : "${currStateFilter}"`, `${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); + setIsLoaded(true) + setIsLoadingMoreItems(false) + }, + (error) => { + HandleSnack('Erro ao carregar os dados', true, 'warning', '#FA8072') + setIsLoadingMoreItems(false) + setIsLoaded(true) + setError(true) + } + ) + }, [currPage, complainOption, stateOption, description, invertList]) + + useEffect(() => { + setComplainOption() + setDescription("") + setValueOfDescField("") + setStateOption(0) + setCurrPage(0) + }, [showFilter]) + + if (error) { + return <div>Error: {error.message}</div>; + } else if (!isLoaded) { + return <LoadingSpinner text="Carregando..." /> + } else { + if (WINDOW_WIDTH <= 994) { + return ( + <> + <SnackBar + severity={snackInfo.icon} + text={snackInfo.message} + snackbarOpen={snackInfo.open} + color={snackInfo.color} + handleClose={() => + setSnackInfo({ + message: "", + icon: "", + open: false, + color: "", + }) } - ) - }, []); - - if (error) { - return <div>Error: {error.message}</div>; - } else if (!isLoaded) { - return <LoadingSpinner text="Carregando..." /> - } else if (CheckUserPermission()) { - if (WINDOW_WIDTH <= 994) { - 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={12}> - <Typography variant="h4">Denúncias</Typography> - </Grid> - - <Grid - item - xs={12} - > - <Grid container justify="flex-start" spacing={3}> - <Grid item> - <Button - variant="contained" - color="secondary" - disabled={isUpdating} - onClick={() => { - currPage = 0; - if (currComplainReasonId) { - UpdateHandler( - Url("complaints", - `"state" : "${currStateFilter}", "complaint_reason_id" : "${currComplainReasonId}", "description" : "${currDescriptionFilter}"`, - `${currPage}`, - "DESC" - ) - ); - } - else { - UpdateHandler( - Url("complaints", - `"state" : "${currStateFilter}", "description" : "${currDescriptionFilter}"`, - `${currPage}`, - "DESC" - ) - ); - } - }} - startIcon={<UpdateRoundedIcon />} - > - {isUpdating ? <CircularProgress size={24} /> : "Atualizar"} - </Button> - </Grid> - <Grid item> - <Button - variant="contained" - color="secondary" - onClick={() => { - 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="Motivo" - value={complainOption} - onChange={handleChangeComplain} - helperText="Por favor, selecione uma das opções" - > - {ComplaintReasons.map((option, index) => ( - <MenuItem - key={option.id} - value={option.name} - name={option.id} - onClick={() => - ApplyFilterComplainReason(option.id, "complaint_reason_id") - } - > - {option.name} - </MenuItem> - ))} - </TextField> - </Grid> - <Grid item> - <TextField - select - label="Estado" - value={stateOption} - onChange={handleChangeState} - helperText="Por favor, selecione uma das opções" - > - {StateOptions.map((option, index) => ( - <MenuItem - key={option.id} - value={option.name} - name={option.id} - onClick={() => ApplyFilterState(option.id, "state")} - > - {option.name} - </MenuItem> - ))} - </TextField> - </Grid> - <Grid item> - <TextField label="Descrição" onChange={DescriptionHandler} value={description} /> - </Grid> - </Grid> - ) : null} - </Paper> - - <div style={{ height: "2em" }}></div> - - {items.map((row, index) => - index === items.length - 1 ? ( - <StyledDivButton> - <Button - key={index} - color="primary" - variant="text" - // disabled={isLoadingMoreItems} - startIcon={<AddRoundedIcon />} - disabled={isLoadingMoreItems} - onClick={() => { - currPage++; - if (currComplainReasonId) { - LoadMoreItens( - Url("complaints", - `"state" : "${currStateFilter}", "complaint_reason_id" : "${currComplainReasonId}", "description" : "${currDescriptionFilter}"`, - `${currPage}`, - "DESC" - ) - ); - } - else { - LoadMoreItens( - Url("complaints", - `"state" : "${currStateFilter}", "description" : "${currDescriptionFilter}"`, - `${currPage}`, - "DESC" - ) - ); - } - }} - > - {isLoadingMoreItems ? ( - <CircularProgress size={24} /> - ) : ( - "Carregar mais itens" - )} - </Button> - </StyledDivButton> - ) : ( - <> - <MobileList - key={index} - title={row.complainable_type} - subtitle={row.id} - backColor={"#673ab7"} - avatar={<AnnouncementRoundedIcon />} - href={`/admin/complaint/${row.id}`} - reset={() => { - currPage = 0 - currStateFilter = "0" - currDescriptionFilter = "" - currComplainReasonId = null; - }} - data={ - [ - { - title: "ID do objeto", - subtitle: row.complainable_id - - }, - { - title: "Criado em", - subtitle: DisplayDate(row.created_at) - }, - { - title: "Descrição", - subtitle: row.description - }, - { - title: "Estado", - subtitle: ComplaintStatus(row.state, row.complainable_type) - } - ] - } - /> - <div style={{ height: "0.5em" }} /> - </> - ) + /> + <MobilePageHeader + title="Denúncias" + actions={[ + { + name: "Atualizar", + isLoading: false, + func: () => { + setCurrPage(0) + }, + icon: <UpdateRoundedIcon /> + }, + { + name: "Filtrar", + isLoading: false, + func: () => { + setShowFilter(!showFilter); + }, + icon: <FilterListRoundedIcon /> + }, + { + name: "Inverter lista", + isLoading: false, + func: () => { + cleanArrayAndInvert() + }, + } + ]} + > + {showFilter ? ( + <Grid + container + direction="row" + justify="space-between" + alignItems="center" + alignContent="flex-end" + spacing={3} + xs={12} + > + <Grid item> + <TextField + select + label="Motivo" + value={complainOption} + onChange={handleChangeComplain} + helperText="Por favor, selecione uma das opções" + > + {ComplaintReasons.map((option, index) => ( + <MenuItem + key={option.value} + value={option.name} + name={option.value} + > + {option.value} + </MenuItem> + ))} + </TextField> + </Grid> + <Grid item> + <TextField + select + label="Estado" + value={stateOption} + onChange={handleChangeState} + helperText="Por favor, selecione uma das opções" + > + {stateOptions.map((option, index) => ( + <MenuItem + key={option.value} + value={option.name} + name={option.value} + > + {option.value} + </MenuItem> + ))} + </TextField> + </Grid> + <Grid item> + <TextField label="Descrição" helperText="Ao digitar a descrição, retire o foco do campo de texto" onChange={DescriptionHandler} value={valueOfDescField} onBlur={e => setDescription(e.target.value)} /> + </Grid> + </Grid> + ) : null} + </MobilePageHeader> + + <div style={{ height: "2em" }}></div> + + {items.map((row, index) => + index === items.length - 1 ? ( + <StyledDivButton + key={new Date().toISOString() + row.created_at} + > + <Button + color="primary" + variant="text" + // disabled={isLoadingMoreItems} + startIcon={<AddRoundedIcon />} + disabled={isLoadingMoreItems} + onClick={() => { + setCurrPage(currPage + 1) + }} + > + {isLoadingMoreItems ? ( + <CircularProgress size={24} /> + ) : ( + "Carregar mais itens" )} - </> - ); - } - else { - return ( + </Button> + </StyledDivButton> + ) : ( <> - <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">Denúncias</Typography> - </Grid> + <MobileList + key={new Date().toISOString() + row.created_at} + title={row.complainable_type} + subtitle={row.id} + backColor={"#673ab7"} + avatar={<AnnouncementRoundedIcon />} + href={`/admin/complaint?id=${row.id}`} + reset={() => { + + }} + data={ + [ + { + title: "ID do objeto", + subtitle: row.complainable_id - <Grid - item - xs={6} + }, + { + title: "Criado em", + subtitle: DisplayDate(row.created_at) + }, + { + title: "Descrição", + subtitle: row.description + }, + { + title: "Estado", + subtitle: ComplaintStatus(row.state, row.complainable_type) + } + ] + } + /> + <div style={{ height: "0.5em" }} /> + </> + ) + )} + </> + ); + } + else { + return ( + <> + <SnackBar + severity={snackInfo.icon} + text={snackInfo.message} + snackbarOpen={snackInfo.open} + color={snackInfo.color} + handleClose={() => + setSnackInfo({ + message: "", + icon: "", + open: false, + color: "", + }) + } + /> + + <PageHeader + title="Denúncias" + actions={[ + { + name: "Atualizar", + isLoading: false, + func: () => { + setCurrPage(0) + }, + icon: <UpdateRoundedIcon /> + }, + { + name: "Filtrar", + isLoading: false, + func: () => { + setShowFilter(!showFilter); + }, + icon: <FilterListRoundedIcon /> + } + ]} + > + {showFilter ? ( + <Grid + container + direction="row" + justify="space-between" + alignItems="center" + alignContent="flex-end" + spacing={3} + xs={12} + > + <Grid item> + <TextField + select + label="Motivo" + value={complainOption} + onChange={handleChangeComplain} + helperText="Por favor, selecione uma das opções" + > + {ComplaintReasons.map((option, index) => ( + <MenuItem + key={option.value} + value={option.name} + name={option.value} + > + {option.value} + </MenuItem> + ))} + </TextField> + </Grid> + <Grid item> + <TextField + select + label="Estado" + value={stateOption} + onChange={handleChangeState} + helperText="Por favor, selecione uma das opções" + > + {stateOptions.map((option, index) => ( + <MenuItem + key={option.value} + value={option.name} + name={option.value} + > + {option.value} + </MenuItem> + ))} + </TextField> + </Grid> + <Grid item> + <TextField label="Descrição" helperText="Ao digitar a descrição, retire o foco do campo de texto" onChange={DescriptionHandler} value={valueOfDescField} onBlur={e => setDescription(e.target.value)} /> + </Grid> + </Grid> + ) : null} + </PageHeader> + + <div style={{ height: "2em" }}></div> + + <Grid xs={12} container> + <TableData + top={TOP_LABELS} + onIconPressed={cleanArrayAndInvert} + > + <TableBody> + {items.map((row, index) => + index === items.length - 1 ? ( + <StyledTableRow key={new Date().toISOString() + row.created_at}> + {/* Button to load more data */} + <StyledTableCell> + <Button + color="primary" + variant="text" + // disabled={isLoadingMoreItems} + startIcon={<AddRoundedIcon />} + disabled={isLoadingMoreItems} + onClick={() => { + setCurrPage(currPage + 1) + }} + > + {isLoadingMoreItems ? ( + <CircularProgress size={24} /> + ) : ( + "Carregar mais itens" + )} + </Button> + </StyledTableCell> + </StyledTableRow> + ) : ( + <StyledTableRow + key={new Date().toISOString() + index} + style={{ flex: 1, width: "100%" }} + > + <StyledTableCell component="th" scope="row"> + {ComplaintStatus(row.state, row.complainable_type)} + </StyledTableCell> + <StyledTableCell align="right">{row.id}</StyledTableCell> + <StyledTableCell align="right"> + {row.description} + </StyledTableCell> + <StyledTableCell align="right"> + {row.complainable_id} + </StyledTableCell> + <StyledTableCell align="right"> + {row.complainable_type} + </StyledTableCell> + <StyledTableCell align="right"> + {DisplayDate(row.created_at)} + </StyledTableCell> + <StyledTableCell align="right"> + <Link to={`/admin/complaint?id=${row.id}`}> + <IconButton + onClick={() => { + }} > - <Grid container justify="flex-end" spacing={3}> - <Grid item> - <Button - variant="contained" - color="secondary" - disabled={isUpdating} - onClick={() => { - currPage = 0; - if (currComplainReasonId) { - UpdateHandler( - Url("complaints", - `"state" : "${currStateFilter}", "complaint_reason_id" : "${currComplainReasonId}", "description" : "${currDescriptionFilter}"`, - `${currPage}`, - "DESC" - ) - ); - } - else { - UpdateHandler( - Url("complaints", - `"state" : "${currStateFilter}", "description" : "${currDescriptionFilter}"`, - `${currPage}`, - "DESC" - ) - ); - } - }} - startIcon={<UpdateRoundedIcon />} - > - {isUpdating ? <CircularProgress size={24} /> : "Atualizar"} - </Button> - </Grid> - <Grid item> - <Button - variant="contained" - color="secondary" - onClick={() => { - 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} + <VisibilityIcon style={{ fill: "#00bcd4" }} /> + </IconButton> + </Link> + </StyledTableCell> + <StyledTableCell align="right"> + <Button + variant="text" + secondary={true} + startIcon={ + <LaunchRoundedIcon style={{ fill: "#FA8072" }} /> + } + > + <a + style={{ + textDecoration: "none", + color: "#FA8072", + }} + target="_blank" + rel="noreferrer" + href={ + PORTAL_MEC + + convertToLink( + row.complainable_type, + row.complainable_id + ) + } > - <Grid item> - <TextField - select - label="Motivo" - value={complainOption} - onChange={handleChangeComplain} - helperText="Por favor, selecione uma das opções" - > - {ComplaintReasons.map((option, index) => ( - <MenuItem - key={option.id} - value={option.name} - name={option.id} - onClick={() => - ApplyFilterComplainReason(option.id, "complaint_reason_id") - } - > - {option.name} - </MenuItem> - ))} - </TextField> - </Grid> - <Grid item> - <TextField - select - label="Estado" - value={stateOption} - onChange={handleChangeState} - helperText="Por favor, selecione uma das opções" - > - {StateOptions.map((option, index) => ( - <MenuItem - key={option.id} - value={option.name} - name={option.id} - onClick={() => ApplyFilterState(option.id, "state")} - > - {option.name} - </MenuItem> - ))} - </TextField> - </Grid> - <Grid item> - <TextField label="Descrição" onChange={DescriptionHandler} value={description} /> - </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++; - if (currComplainReasonId) { - LoadMoreItens( - Url("complaints", - `"state" : "${currStateFilter}", "complaint_reason_id" : "${currComplainReasonId}", "description" : "${currDescriptionFilter}"`, - `${currPage}`, - "DESC" - ) - ); - } - else { - LoadMoreItens( - Url("complaints", - `"state" : "${currStateFilter}", "description" : "${currDescriptionFilter}"`, - `${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.state, row.complainable_type)} - </StyledTableCell> - <StyledTableCell align="right">{row.id}</StyledTableCell> - <StyledTableCell align="right"> - {row.description} - </StyledTableCell> - <StyledTableCell align="right"> - {row.complainable_id} - </StyledTableCell> - <StyledTableCell align="right"> - {row.complainable_type} - </StyledTableCell> - <StyledTableCell align="right"> - {DisplayDate(row.created_at)} - </StyledTableCell> - <StyledTableCell align="right"> - <Link to={`/admin/complaint/${row.id}`}> - <IconButton - onClick={() => { - currPage = 0 - currStateFilter = "0" - currDescriptionFilter = "" - currComplainReasonId = null; - }} - > - <VisibilityIcon style={{ fill: "#00bcd4" }} /> - </IconButton> - </Link> - </StyledTableCell> - <StyledTableCell align="right"> - <Button - variant="text" - secondary={true} - startIcon={ - <LaunchRoundedIcon style={{ fill: "#FA8072" }} /> - } - > - <a - style={{ - textDecoration: "none", - color: "#FA8072", - }} - target="_blank" - rel="noreferrer" - href={ - PORTAL_MEC + - convertToLink( - row.complainable_type, - row.complainable_id - ) - } - > - MEC RED + MEC RED </a> - </Button> - </StyledTableCell> - </StyledTableRow> - ) - )} - </TableBody> - </TableData> - </Grid> - </> - ); - } - } else return <Unauthorized /> + </Button> + </StyledTableCell> + </StyledTableRow> + ) + )} + </TableBody> + </TableData> + </Grid> + </> + ); + } + } }; export default Complaints; diff --git a/src/Admin/Pages/Pages/SubPages/EducationalObjects.js b/src/Admin/Pages/Pages/SubPages/EducationalObjects.js index a4219eea0efbc89a1af6c218b2d0fce6ca5b47da..69d0dfc326b54a0f970a6e98e905dddff7f0f41f 100644 --- a/src/Admin/Pages/Pages/SubPages/EducationalObjects.js +++ b/src/Admin/Pages/Pages/SubPages/EducationalObjects.js @@ -18,11 +18,14 @@ along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/> import React, { useState, useEffect } from "react"; import moment from 'moment'; -// Imports from local files +// Imports from local file import TableData from "../../../Components/Components/Table"; import SnackBar from "../../../../Components/SnackbarComponent"; import AlertDialog from "../../../Components/Components/AlertDialog"; import LoadingSpinner from '../../../../Components/LoadingSpinner'; +import MobileList from "../../../Components/Components/MobileComponents/SimpleList" +import MobilePageHeader from "../../../Components/Components/MobileComponents/MobilePageHeader" +import PageHeader from "../../../Components/Components/PageHeader" // Imports about icon import FilterListRoundedIcon from "@material-ui/icons/FilterListRounded"; import AddRoundedIcon from "@material-ui/icons/AddRounded"; @@ -31,16 +34,14 @@ import TableBody from "@material-ui/core/TableBody"; import TableCell from "@material-ui/core/TableCell"; import TableRow from "@material-ui/core/TableRow"; import IconButton from "@material-ui/core/IconButton"; -import CancelRoundedIcon from "@material-ui/icons/CancelRounded"; import VisibilityIcon from "@material-ui/icons/Visibility"; import DeleteIcon from "@material-ui/icons/Delete"; // Import from material-ui -import { withStyles, makeStyles } from "@material-ui/core/styles"; +import { withStyles } from "@material-ui/core/styles"; import Paper from "@material-ui/core/Paper"; import Button from "@material-ui/core/Button"; import Grid from "@material-ui/core/Grid"; -import { Typography, CircularProgress } from "@material-ui/core"; -import Popover from "@material-ui/core/Popover"; +import { CircularProgress } from "@material-ui/core"; import TextField from "@material-ui/core/TextField"; // services import { getRequest, deleteRequest } from '../../../../Components/HelperFunctions/getAxiosConfig' @@ -50,9 +51,6 @@ import { Url, DeleteFilter } from "../../../Filters"; import { Link } from 'react-router-dom'; import styled from 'styled-components' import MenuBookRoundedIcon from "@material-ui/icons/MenuBookRounded"; -import MobileList from "../../../Components/Components/MobileComponents/SimpleList" - -let currPage = 0; const StyledTableCell = withStyles((theme) => ({ head: { @@ -72,35 +70,18 @@ const StyledTableRow = withStyles((theme) => ({ }, }))(TableRow); -const useStyles = makeStyles((theme) => ({ - root: { - flexGrow: 1, - }, - paper: { - padding: theme.spacing(1), - textAlign: "start", - }, - button: { - margin: theme.spacing(1), - alignSelf: "flex-end", - }, -})); - const EducationalObjects = () => { - const classes = useStyles(); const WINDOW_WIDTH = window.innerWidth - - const addOndeLenght = [""]; + const ADD_ONE_LENGHT = [""]; 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 [currPage, setCurrPage] = useState(0) const [deleteItem, setDeleteItem] = useState({}); //Delete Item const [isLoadingToDelete, setIsLoadingToDelete] = useState(null); - const [isUpdating, setIsUpdating] = useState(false); const [isLoadingMoreItems, setIsLoadingMoreItems] = useState(false); - + const [showFilter, setShowFilter] = useState(false) const [openAlertDialog, setOpenAlertDialog] = useState(false); const [snackInfo, setSnackInfo] = useState({ @@ -110,88 +91,26 @@ const EducationalObjects = () => { color: "", }); - // **************** About the PopOver Menu **************** - const [anchorEl, setAnchorEl] = React.useState(null); - const [showAuthorField, setShowAuthorField] = useState(false); //show the text field of filter by Author - const [showDescriptionField, setShowDescriptionField] = useState(false); //show the text field of the filter by description - const [showStandadSearch, setShowStandarSearchField] = useState(false); const [search, setSeacrh] = useState(""); + const [valueSearch, setValueSearch] = useState("") const [author, setAuthor] = useState(""); - const [description, setDescription] = useState(null); - - const AuthorHandler = () => { - setAuthor("") - setShowAuthorField(!showAuthorField); - let url; - if (description) - url = Url("learning_objects", `"name" : "${search}", "author" : "", "description" : "${description}"`, currPage, "DESC") - else - url = Url("learning_objects", `"name" : "${search}", "author" : ""`, currPage, "DESC") - Filter(url); - }; - - const DescHandler = () => { - setDescription(null) - setShowDescriptionField(!showDescriptionField); - let url; - url = Url("learning_objects", `"name" : "${search}", "author" : "${author}"`, currPage, "DESC") - Filter(url); - }; - - const StandartHandler = () => { - setSeacrh("") - setShowStandarSearchField(!showStandadSearch); - let url; - if (description) - url = Url("learning_objects", `"name" : "", "author" : "${author}", "description" : "${description}"`, currPage, "DESC") - else - url = Url("learning_objects", `"name" : "", "author" : "${author}"`, currPage, "DESC") - Filter(url); - }; + const [valueAuthor, setValueAuthor] = useState("") + const [description, setDescription] = useState(""); + const [valueDescription, setValueDescription] = useState("") - const handleClick = (event) => { - setAnchorEl(event.currentTarget); + const AuthorHandler = (event) => { + setValueAuthor(event.target.value) }; - const handleClose = () => { - setAnchorEl(null); + const DescHandler = (event) => { + setValueDescription(event.target.value) }; - const open = Boolean(anchorEl); - const id = open ? "simple-popover" : undefined; - - const OnChangeSearchHandler = (e) => { - setSeacrh(e.target.value); - let url; - if (description) - url = Url("learning_objects", `"name" : "${search}", "author" : "${author}", "description" : "${description}"`, currPage, "DESC") - else - url = Url("learning_objects", `"name" : "${search}", "author" : "${author}"`, currPage, "DESC") - Filter(url); + const StandartHandler = (event) => { + setValueSearch(event.target.value) }; - const onChangeAuthorHandler = (e) => { - setAuthor(e.target.value); - let url; - if (description) - url = Url("learning_objects", `"name" : "${search}", "author" : "${author}", "description" : "${description}"`, currPage, "DESC") - else - url = Url("learning_objects", `"name" : "${search}", "author" : "${author}"`, currPage, "DESC") - Filter(url); - }; - - const onChangeDescriptionHandler = (e) => { - setDescription(e.target.value); - let url; - if (description) - url = Url("learning_objects", `"name" : "${search}", "author" : "${author}", "description" : "${description}"`, currPage, "DESC") - else - url = Url("learning_objects", `"name" : "${search}", "author" : "${author}"`, currPage, "DESC") - Filter(url); - }; - // **************** About the PopOverMenu **************** - //Controlls the state of the Alert Dialog const HandleStateAlertDialog = (i) => { const obj = { ...items[i] }; @@ -214,60 +133,25 @@ const EducationalObjects = () => { setIsLoadingToDelete(i); }; - //Filters the search - const Filter = (api) => { - getRequest( - api, - (data, header) => { - const arrData = [...data]; - setItems(arrData.concat(addOndeLenght)); - }, - (error) => { - setError(true); - } - ) - }; - - //This function updates List every time the content of the api changes - const UpdtateListData = (api) => { - getRequest( - api, - (data, header) => { - setItems([...data.concat(addOndeLenght)]); - HandleSnack( - "A lista de dados foi atualizada", - true, - "success", - "#228B22" - ); - setIsUpdating(false); - }, - (error) => { - HandleSnack("Ocorreu algum erro", true, "warning", "#FA8072"); - setIsUpdating(false); - } - ) - }; - //Called when user want to delete one institution async function DeleteHandler() { const id = deleteItem.id; HandleStateAlertDialog(null); deleteRequest( - DeleteFilter("institutions", id), + DeleteFilter("learning_objects", id), (data) => { if (data.errors) HandleSnack("Ocorreu algum erro", true, "warning", "#FA8072"); else { HandleSnack( - "A instituição foi deletada com sucesso", + "O objeto educacional foi deletada com sucesso", true, "success", "#228B22" ); - currPage = 0; - UpdtateListData(Url("institutions", "", `${currPage}`, "DESC")); + setCurrPage(0) HandleStateCircularProgress(null); + removeItemFromList(id) } }, (error) => { @@ -277,33 +161,21 @@ const EducationalObjects = () => { ) } - 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(addOndeLenght)); - } - setIsLoadingMoreItems(false); - }, - (error) => { - HandleSnack("Erro ao carregar os dados", true, "warning", "#FA8072"); - setIsLoadingMoreItems(false); + const removeItemFromList = (itemId) => { + let index = -1; + for (let i = 0; i < items.length; i++) { + const element = items[i]; + if (element.id === itemId) { + index = i + break } - ) - }; + } + if (index !== -1) { + const cpyItems = [...items] + cpyItems.splice(index, 1) + setItems(cpyItems) + } + } const DisplayDate = (date) => { const convertedData = moment.utc(date); @@ -312,28 +184,79 @@ const EducationalObjects = () => { .toString(); }; + const buildUrl = (author, description, name) => { + if (author && description && name) + return Url("learning_objects", `"author" : "${author}", "description" : "${description}", "name" : "${name}"`, currPage, "DESC") + + else if (author && name) + return Url("learning_objects", `"author" : "${author}", "name" : "${name}"`, currPage, "DESC") + else if (author && description) + return Url("learning_objects", `"author" : "${author}", "description" : "${description}"`, currPage, "DESC") + else if (name && description) + return Url("learning_objects", `"name" : "${name}", "description" : "${description}"`, currPage, "DESC") + + else if (author) + return Url("learning_objects", `"author" : "${author}"`, currPage, "DESC") + else if (description) + return Url("learning_objects", `"description" : "${description}"`, currPage, "DESC") + else if (name) + return Url("learning_objects", `"name" : "${name}"`, currPage, "DESC") + else + return Url("learning_objects", "", currPage, "DESC") + } + useEffect(() => { + if (currPage === 0) + setIsLoaded(false) + else + setIsLoadingMoreItems(true) getRequest( - Url("learning_objects", `"name" : "${search}", "author" : "${author}"`, `${currPage}`, "DESC"), + buildUrl(author, description, search), (data, header) => { - setIsLoaded(true); - setItems(data.concat(addOndeLenght)); + const arrData = [...data] + if (arrData.length === 0) { + HandleSnack('Não há mais dados para serem carregados', true, 'warning', '#FFC125') + } else { + const arrItems = [...items] + if (currPage === 0) { + setItems(arrData.concat(ADD_ONE_LENGHT)) + } + else { + 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)) + } + } + setIsLoaded(true) + setIsLoadingMoreItems(false) }, (error) => { - setError(true); - + HandleSnack('Erro ao carregar os dados', true, 'warning', '#FA8072') + setIsLoadingMoreItems(false) + setIsLoaded(true) + setError(true) } ) - }, []); + }, [currPage, search, description, author]) + + useEffect(() => { + setCurrPage(0) + setSeacrh("") + setValueSearch("") + setDescription("") + setValueDescription("") + setAuthor("") + setValueAuthor("") + }, [showFilter]) if (error) { return <div>Error: {error.message}</div>; } - if (!isLoaded) { + else if (!isLoaded) { return <LoadingSpinner text="Carregando..." /> } else { //Words that defines that column - const topTable = [ + const TOP_TABLE = [ "CRIADO EM", "NOME", "DESCRIÇÃO", @@ -343,46 +266,31 @@ const EducationalObjects = () => { "DELETAR", ]; - //Buttons from PopOverMenu - const flatButtonsFromPopOverMenu = [ - { - label: "Pesquisa padrão", - onClick: StandartHandler, - color: showStandadSearch ? "primary" : "default", - }, - { - label: "Autor", - onClick: AuthorHandler, - color: showAuthorField ? "primary" : "default", - }, - { - label: "Descrição", - onClick: DescHandler, - color: showDescriptionField ? "primary" : "default", - }, - ]; - //Field of the Filter const TextFieldOfTheFilter = [ { label: "Pesquisar", - show: showStandadSearch, - onChange: (event) => OnChangeSearchHandler(event), - hide: StandartHandler, + value: valueSearch, + onChange: (event) => StandartHandler(event), + onBlur: (event) => setSeacrh(event.target.value), + helperText: "Ao terminar de digitar no campo, retire o foco do campo de texto" }, { label: "Autor", - show: showAuthorField, - onChange: (event) => onChangeAuthorHandler(event), - hide: AuthorHandler, + value: valueAuthor, + onChange: (event) => AuthorHandler(event), + onBlur: (event) => setAuthor(event.target.value), + helperText: "Ao terminar de digitar no campo, retire o foco do campo de texto" }, { label: "Descrição", - show: showDescriptionField, - onChange: (event) => onChangeDescriptionHandler(event), - hide: DescHandler, + value: valueDescription, + onChange: (event) => DescHandler(event), + onBlur: (event) => setDescription(event.target.value), + helperText: "Ao terminar de digitar no campo, retire o foco do campo de texto" }, ]; + if (WINDOW_WIDTH <= 1058) { return ( <div> @@ -400,109 +308,58 @@ const EducationalObjects = () => { }) } /> + <AlertDialog + open={openAlertDialog} + OnDelete={DeleteHandler} + deleteItem={deleteItem} + HandleClose={() => { + setOpenAlertDialog(false); + HandleStateCircularProgress(null); + }} + /> {/************** Start of the header **************/} - <Paper style={{ padding: "1em" }}> - <Grid container spacing={3} direction="row" alignItems="center"> + <MobilePageHeader + title="Objetos educacionais" + actions={[ + { + name: "Atualizar", + isLoading: false, + func: () => { + setCurrPage(0) + }, + icon: <UpdateRoundedIcon /> + }, + { + name: "Filtrar", + isLoading: false, + func: () => { + setShowFilter(!showFilter); + }, + icon: <FilterListRoundedIcon /> + } + ]} + > + { + showFilter && <Grid item xs={12}> - <Typography className={classes.paper} variant="h4"> - Lista de objetos educacionais - </Typography> - </Grid> - <Grid - item - xs={12} - - > - <Grid container justify="flex-start" spacing={3}> - <Grid item> - <Button - aria-describedby={id} - variant="contained" - color="secondary" - className={classes.button} - onClick={(event) => { - handleClick(event) - }} - startIcon={ - <FilterListRoundedIcon style={{ fill: "white" }} /> - } - > - Filtrar - </Button> - <Popover - id={id} - open={open} - anchorEl={anchorEl} - onClose={handleClose} - anchorOrigin={{ - vertical: "bottom", - horizontal: "center", - }} - transformOrigin={{ - vertical: "top", - horizontal: "center", - }} - > - {flatButtonsFromPopOverMenu.map((flat, index) => ( - <Button - key={index} - onClick={flat.onClick} - color={flat.color} - > - {flat.label} - </Button> - ))} - </Popover> - </Grid> - - <Grid item> - <Button - variant="contained" - color="secondary" - className={classes.button} - startIcon={<UpdateRoundedIcon />} - disabled={isUpdating} - onClick={() => { - currPage = 0; - setIsUpdating(true); - if (description) - UpdtateListData(Url("learning_objects", `"name" : "${search}", "author" : "${author}", "description" : "${description}"`, currPage, "DESC")) - else - UpdtateListData(Url("learning_objects", `"name" : "${search}", "author" : "${author}"`, currPage, "DESC")) - }} - > - {isUpdating ? <CircularProgress size={24} /> : "Atualizar"} - </Button> - </Grid> + <Grid container justify="space-between" spacing={3}> + {TextFieldOfTheFilter.map((field, index) => ( + <Grid item key={field.label}> + <TextField + id={index} + label={field.label} + type="search" + onChange={field.onChange} + onBlur={field.onBlur} + value={field.value} + helperText={field.helperText} + /> + </Grid> + ))} </Grid> </Grid> - </Grid> - <Grid item xs={12}> - <Grid container justify="space-between" spacing={3}> - {TextFieldOfTheFilter.map((field, index) => ( - <Grid item key={index}> - {field.show ? ( - <div> - <TextField - id={index} - label={field.label} - type="search" - onChange={field.onChange} - /> - <IconButton - size="small" - color="primary" - onClick={field.hide} - > - <CancelRoundedIcon /> - </IconButton> - </div> - ) : null} - </Grid> - ))} - </Grid> - </Grid> - </Paper> + } + </MobilePageHeader> {/************** End of the header **************/} <div style={{ height: "2em" }}></div> @@ -512,18 +369,14 @@ const EducationalObjects = () => { index === items.length - 1 ? ( <StyledDivButton> <Button - key={index} + key={new Date().toISOString() + row.created_at} color="primary" variant="text" // disabled={isLoadingMoreItems} startIcon={<AddRoundedIcon />} disabled={isLoadingMoreItems} onClick={() => { - currPage++ - if (description) - LoadMoreItens(Url("learning_objects", `"name" : "${search}", "author" : "${author}", "description" : "${description}"`, currPage, "DESC")) - else - LoadMoreItens(Url("learning_objects", `"name" : "${search}", "author" : "${author}"`, currPage, "DESC")) + setCurrPage(currPage + 1) }} > {isLoadingMoreItems ? ( @@ -536,14 +389,14 @@ const EducationalObjects = () => { ) : ( <> <MobileList - key={index} + key={new Date().toISOString() + row.created_at} title={row.name} subtitle={row.id} backColor={"#673ab7"} avatar={<MenuBookRoundedIcon />} - href={`/admin/learningObject/${row.id}`} + href={`/admin/learningObject?learnObj=${row.id}`} reset={() => { - currPage = 0; + }} data={ [ @@ -563,6 +416,21 @@ const EducationalObjects = () => { title: "Score", subtitle: row.score }, + { + title: "Deletar", + subtitle: + <Button + variant="contained" + color="secondary" + onClick={() => { + HandleStateAlertDialog(index); + HandleStateCircularProgress(index); + }} + startIcon={<DeleteIcon />} + > + Deletar + </Button> + } ] } /> @@ -592,117 +460,58 @@ const EducationalObjects = () => { } /> {/************** Start of the header **************/} - <Paper style={{ padding: "1em" }}> - <Grid container spacing={3} direction="row" alignItems="center"> - <Grid item xs={6}> - <Typography className={classes.paper} variant="h4"> - Lista de objetos educacionais - </Typography> - </Grid> - <Grid - item - xs={6} - > - <Grid container justify="flex-end" spacing={3}> - <Grid item> - <Button - aria-describedby={id} - variant="contained" - color="secondary" - className={classes.button} - onClick={(event) => { - handleClick(event) - }} - startIcon={ - <FilterListRoundedIcon style={{ fill: "white" }} /> - } - > - Filtrar - </Button> - <Popover - id={id} - open={open} - anchorEl={anchorEl} - onClose={handleClose} - anchorOrigin={{ - vertical: "bottom", - horizontal: "center", - }} - transformOrigin={{ - vertical: "top", - horizontal: "center", - }} - > - {flatButtonsFromPopOverMenu.map((flat, index) => ( - <Button - key={index} - onClick={flat.onClick} - color={flat.color} - > - {flat.label} - </Button> - ))} - </Popover> - </Grid> - - <Grid item> - <Button - variant="contained" - color="secondary" - className={classes.button} - startIcon={<UpdateRoundedIcon />} - disabled={isUpdating} - onClick={() => { - currPage = 0; - setIsUpdating(true); - if (description) - UpdtateListData(Url("learning_objects", `"name" : "${search}", "author" : "${author}", "description" : "${description}"`, currPage, "DESC")) - else - UpdtateListData(Url("learning_objects", `"name" : "${search}", "author" : "${author}"`, currPage, "DESC")) - }} - > - {isUpdating ? <CircularProgress size={24} /> : "Atualizar"} - </Button> - </Grid> + <PageHeader + title="Objetos educacionais" + actions={[ + { + name: "Atualizar", + isLoading: false, + func: () => { + setCurrPage(0) + }, + icon: <UpdateRoundedIcon /> + }, + { + name: "Filtrar", + isLoading: false, + func: () => { + setShowFilter(!showFilter); + }, + icon: <FilterListRoundedIcon /> + } + ]} + > + { + showFilter && + <Grid item xs={12}> + <Grid container justify="space-between" spacing={3}> + {TextFieldOfTheFilter.map((field, index) => ( + <Grid item key={field.label}> + <TextField + id={index} + label={field.label} + type="search" + onChange={field.onChange} + onBlur={field.onBlur} + value={field.value} + helperText={field.helperText} + /> + </Grid> + ))} </Grid> </Grid> - </Grid> - <Grid item xs={12}> - <Grid container justify="space-between" spacing={3}> - {TextFieldOfTheFilter.map((field, index) => ( - <Grid item key={index}> - {field.show ? ( - <div> - <TextField - id={index} - label={field.label} - type="search" - onChange={field.onChange} - /> - <IconButton - size="small" - color="primary" - onClick={field.hide} - > - <CancelRoundedIcon /> - </IconButton> - </div> - ) : null} - </Grid> - ))} - </Grid> - </Grid> - </Paper> + } + </PageHeader> {/************** End of the header **************/} <div style={{ height: "2em" }}></div> {/************** Start of display data in table **************/} - <TableData top={topTable}> + <TableData top={TOP_TABLE}> <TableBody> {items.map((row, index) => index === items.length - 1 ? ( - <StyledTableRow key={index}> + <StyledTableRow key={new Date().toISOString() + row.created_at}> {/* Button to load more data */} <StyledTableCell> <Button @@ -713,11 +522,7 @@ const EducationalObjects = () => { isLoadingMoreItems } onClick={() => { - currPage++ - if (description) - LoadMoreItens(Url("learning_objects", `"name" : "${search}", "author" : "${author}", "description" : "${description}"`, currPage, "DESC")) - else - LoadMoreItens(Url("learning_objects", `"name" : "${search}", "author" : "${author}"`, currPage, "DESC")) + setCurrPage(currPage + 1) }} > {isLoadingMoreItems ? ( @@ -729,7 +534,7 @@ const EducationalObjects = () => { </StyledTableCell> </StyledTableRow> ) : ( - <StyledTableRow key={index}> + <StyledTableRow key={new Date().toISOString() + index}> <StyledTableCell component="th" scope="row"> {DisplayDate(row.created_at)} </StyledTableCell> @@ -746,11 +551,8 @@ const EducationalObjects = () => { {row.score} </StyledTableCell> <StyledTableCell align="right"> - <Link to={`/admin/learningObject/${row.id}`}> - <IconButton onClick={() => { - currPage = 0 - - }}> + <Link to={`/admin/learningObject?learnObj=${row.id}`}> + <IconButton> <VisibilityIcon style={{ fill: "#00bcd4" }} /> </IconButton> </Link> diff --git a/src/Admin/Pages/Pages/SubPages/Institutions.js b/src/Admin/Pages/Pages/SubPages/Institutions.js index d8f41e7dac618091750a2fd09e8bb5e0d72c6e48..7f713b9e4f42d42c906092fc0c3e1baccbdb1080 100644 --- a/src/Admin/Pages/Pages/SubPages/Institutions.js +++ b/src/Admin/Pages/Pages/SubPages/Institutions.js @@ -22,6 +22,9 @@ import TableData from "../../../Components/Components/Table"; import SnackBar from "../../../../Components/SnackbarComponent"; import AlertDialog from "../../../Components/Components/AlertDialog"; import LoadingSpinner from '../../../../Components/LoadingSpinner'; +import MobileList from "../../../Components/Components/MobileComponents/SimpleList" +import MobilePageHeader from "../../../Components/Components/MobileComponents/MobilePageHeader" +import PageHeader from "../../../Components/Components/PageHeader" // Imports about icon import FilterListRoundedIcon from "@material-ui/icons/FilterListRounded"; import AddRoundedIcon from "@material-ui/icons/AddRounded"; @@ -30,833 +33,575 @@ import TableBody from "@material-ui/core/TableBody"; import TableCell from "@material-ui/core/TableCell"; import TableRow from "@material-ui/core/TableRow"; import IconButton from "@material-ui/core/IconButton"; -import CancelRoundedIcon from "@material-ui/icons/CancelRounded"; import VisibilityIcon from "@material-ui/icons/Visibility"; import DeleteIcon from "@material-ui/icons/Delete"; // Import from material-ui -import { withStyles, makeStyles } from "@material-ui/core/styles"; +import { withStyles } from "@material-ui/core/styles"; import Paper from "@material-ui/core/Paper"; import Button from "@material-ui/core/Button"; import Grid from "@material-ui/core/Grid"; -import { Typography, CircularProgress } from "@material-ui/core"; -import Popover from "@material-ui/core/Popover"; +import { CircularProgress } from "@material-ui/core"; import TextField from "@material-ui/core/TextField"; // services import { getRequest, deleteRequest } from '../../../../Components/HelperFunctions/getAxiosConfig' //Filters -import { Url, GetOneOfAllUrl, DeleteFilter } from "../../../Filters"; +import { Url, DeleteFilter } from "../../../Filters"; //router -import { Link } from 'react-router-dom'; +import { Link, useHistory } from 'react-router-dom'; import styled from "styled-components" -import MobileList from "../../../Components/Components/MobileComponents/SimpleList" import AccountBalanceRoundedIcon from "@material-ui/icons/AccountBalanceRounded"; -let currPage = 0; -let transformListToAsc = false - const StyledTableCell = withStyles((theme) => ({ - head: { - backgroundColor: theme.palette.common.black, - color: theme.palette.common.white, - }, - body: { - fontSize: 14, - }, + 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, - }, + root: { + "&:nth-of-type(odd)": { + backgroundColor: theme.palette.action.hover, }, + }, }))(TableRow); -const useStyles = makeStyles((theme) => ({ - root: { - flexGrow: 1, - }, - paper: { - padding: theme.spacing(1), - textAlign: "start", - }, - button: { - margin: theme.spacing(1), - alignSelf: "flex-end", - }, -})); - const Institutions = () => { - const classes = useStyles(); - const WINDOW_WIDTH = window.innerWidth - - const addOndeLenght = [""]; - - 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 [deleteItem, setDeleteItem] = useState({}); //Delete Item - const [isLoadingToDelete, setIsLoadingToDelete] = useState(null); - const [isUpdating, setIsUpdating] = useState(false); - const [isLoadingMoreItems, setIsLoadingMoreItems] = useState(false); - - const [openAlertDialog, setOpenAlertDialog] = useState(false); - - const [snackInfo, setSnackInfo] = useState({ - message: "", - icon: "", - open: false, - color: "", + const WINDOW_WIDTH = window.innerWidth + const ADD_ONE_LENGHT = [""]; + + const router = useHistory() + + const [invertList, setInvertList] = useState(false) + 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 [showFilter, setShowFilter] = useState(false) + const [currPage, setCurrPage] = useState(0) + const [deleteItem, setDeleteItem] = useState({}); //Delete Item + const [isLoadingToDelete, setIsLoadingToDelete] = useState(null); + const [isLoadingMoreItems, setIsLoadingMoreItems] = useState(false); + + const [openAlertDialog, setOpenAlertDialog] = useState(false); + + const [snackInfo, setSnackInfo] = useState({ + message: "", + icon: "", + open: false, + color: "", + }); + + const [search, setSeacrh] = useState(""); + const [valueOfSearch, setValueOfSearch] = useState("") + const [city, setCity] = useState(""); + const [valueOfCity, setValueOfCity] = useState("") + const [country, setCountry] = useState(""); + const [valueOfCountry, setValueOfCountry] = useState("") + const [description, setDescription] = useState(""); + const [valueOfDescription, setValueOfDescription] = useState("") + + const OnChangeSearchHandler = (e) => { + setValueOfSearch(e.target.value); + }; + + const onChangeCityHandler = (e) => { + setValueOfCity(e.target.value); + }; + + const onChangeCountryHandler = (e) => { + setValueOfCountry(e.target.value); + }; + + const onChangeDescriptionHandler = (e) => { + setValueOfDescription(e.target.value); + }; + // **************** About the PopOverMenu **************** + + //Controlls the state of the Alert Dialog + const HandleStateAlertDialog = (i) => { + const obj = { ...items[i] }; + setDeleteItem(obj); + setOpenAlertDialog(!openAlertDialog); + }; + + //Controlls the state and the informations of the snack + const HandleSnack = (message, state, icon, color) => { + setSnackInfo({ + message: message, + icon: icon, + open: state, + color: color, }); - - // **************** About the PopOver Menu **************** - const [anchorEl, setAnchorEl] = React.useState(null); - const [showCityField, setShowCityField] = useState(false); //show the text field of filter by city - const [showContryField, setShowCountryField] = useState(false); //show the text field of the filter by country - const [showDescriptionField, setShowDescriptionField] = useState(false); //show the text field of the filter by description - const [showStandadSearch, setShowStandarSearchField] = useState(false); - - const [isFilteringByName, setisFilteringByName] = useState(false); - const [isFilteringByCity, setisFilteringByCity] = useState(false); - const [isFilteringByCounty, setisFilteringByCountry] = useState(false); - const [isFilteringByDesc, setisFilteringByDesc] = useState(false); - - const [search, setSeacrh] = useState(""); - const [city, setCity] = useState(""); - const [country, setCountry] = useState(""); - const [description, setDescription] = useState(""); - - const CityHandler = () => { - currPage = 0; - transformListToAsc = false - setShowCityField(!showCityField); - setisFilteringByCity(!isFilteringByCity); - UpdtateListData(Url("institutions", "", `${currPage}`, "DESC")); - }; - - const CountryHandler = () => { - currPage = 0; - transformListToAsc = false - setShowCountryField(!showContryField); - UpdtateListData(Url("institutions", "", `${currPage}`, "DESC")); - setisFilteringByCountry(!isFilteringByCounty); - }; - - const DescHandler = () => { - currPage = 0; - transformListToAsc = false - setShowDescriptionField(!showDescriptionField); - setisFilteringByDesc(!isFilteringByDesc); - UpdtateListData(Url("institutions", "", `${currPage}`, "DESC")); - }; - - const StandartHandler = () => { - currPage = 0; - transformListToAsc = false - setShowStandarSearchField(!showStandadSearch); - setisFilteringByName(!isFilteringByName); - UpdtateListData(Url("institutions", "", `${currPage}`, "DESC")); - }; - - const handleClick = (event) => { - setAnchorEl(event.currentTarget); - }; - - const handleClose = () => { - setAnchorEl(null); - }; - - const open = Boolean(anchorEl); - const id = open ? "simple-popover" : undefined; - - const OnChangeSearchHandler = (e) => { - setSeacrh(e.target.value); - Filter(GetOneOfAllUrl("institutions", `"name" : "${search}"`)); - }; - - const onChangeCityHandler = (e) => { - setCity(e.target.value); - Filter(GetOneOfAllUrl("institutions", `"city" : "${city}"`)); - }; - - const onChangeCountryHandler = (e) => { - setCountry(e.target.value); - Filter(GetOneOfAllUrl("institutions", `"country" : "${country}"`)); - }; - - const onChangeDescriptionHandler = (e) => { - setDescription(e.target.value); - Filter(GetOneOfAllUrl("institutions", `"description" : "${description}"`)); - }; - // **************** About the PopOverMenu **************** - - //Controlls the state of the Alert Dialog - const HandleStateAlertDialog = (i) => { - const obj = { ...items[i] }; - setDeleteItem(obj); - setOpenAlertDialog(!openAlertDialog); - }; - - //Controlls the state and the informations of the snack - const HandleSnack = (message, state, icon, color) => { - setSnackInfo({ - message: message, - icon: icon, - open: state, - color: color, - }); - }; - - //Defines which row must show the circular progress - const HandleStateCircularProgress = (i) => { - setIsLoadingToDelete(i); - }; - - //Filters the search - const Filter = (api) => { - getRequest( - api, - (data, header) => { - const arrData = [...data]; - transformListToAsc = false - setItems(arrData.concat(addOndeLenght)); - }, - (error) => { - setError(true); - } - ) - }; - - //This function updates List every time the content of the api changes - const UpdtateListData = (api) => { - getRequest( - api, - (data, header) => { - const arrData = [...data]; - setItems(arrData.concat(addOndeLenght)); - HandleSnack( - "A lista de dados foi atualizada", - true, - "success", - "#228B22" - ); - setIsUpdating(false); - }, - (error) => { - HandleSnack("Ocorreu algum erro", true, "warning", "#FA8072"); - setIsUpdating(false); - } - ) - }; - - //Called when user want to delete one institution - async function DeleteHandler() { - const id = deleteItem.id; - HandleStateAlertDialog(null); - deleteRequest( - DeleteFilter("institutions", id), - (data) => { - if (data.errors) - HandleSnack("Ocorreu algum erro!", true, "warning", "#FA8072"); - else { - HandleSnack( - "A instituição foi deletada com sucesso", - true, - "success", - "#228B22" - ); - currPage = 0; - transformListToAsc = false - UpdtateListData(Url("institutions", "", `${currPage}`, "DESC")); - HandleStateCircularProgress(null); - } - }, - (error) => { - HandleSnack("Ocorreu algum erro!", true, "warning", "#FA8072"); - HandleStateCircularProgress(null); - } - ) + }; + + //Defines which row must show the circular progress + const HandleStateCircularProgress = (i) => { + setIsLoadingToDelete(i); + }; + + //Called when user want to delete one institution + async function DeleteHandler() { + const id = deleteItem.id; + HandleStateAlertDialog(null); + deleteRequest( + DeleteFilter("institutions", id), + (data) => { + if (data.errors) + HandleSnack("Ocorreu algum erro!", true, "warning", "#FA8072"); + else { + HandleSnack( + "A instituição foi deletada com sucesso", + true, + "success", + "#228B22" + ); + setCurrPage(0) + removeItemFromList(id); + HandleStateCircularProgress(null); + } + }, + (error) => { + HandleSnack("Ocorreu algum erro!", true, "warning", "#FA8072"); + HandleStateCircularProgress(null); + } + ) + } + + const removeItemFromList = (itemId) => { + let index = -1; + for (let i = 0; i < items.length; i++) { + const element = items[i]; + if (element.id === itemId) { + index = i + break + } } - - const LoadMoreItens = async (api) => { - setIsLoadingMoreItems(true); - getRequest( - api, - (data, header) => { - const arrData = [...data]; - console.log(arrData); - 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(addOndeLenght)); - } - setIsLoadingMoreItems(false); - }, - (error) => { - HandleSnack("Erro ao carregar os dados", true, "warning", "#FA8072"); - setIsLoadingMoreItems(false); + if (index !== -1) { + const cpyItems = [...items] + cpyItems.splice(index, 1) + setItems(cpyItems) + } + } + + const cleanArrayAndInvert = () => { + setInvertList(!invertList) + setCurrPage(0) + setItems([]) + } + + const buildUrl = () => { + return Url("institutions", `"name" : "${search}", "description" : "${description}", "city" : "${city}", "country" : "${country}"`, currPage, invertList ? "ASC" : "DESC") + } + + useEffect(() => { + if (currPage === 0) + setIsLoaded(false) + else + setIsLoadingMoreItems(true) + getRequest( + buildUrl(), + (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] + if (currPage === 0) { + setItems(arrData.concat(ADD_ONE_LENGHT)) + } + else { + 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)) + } + } + setIsLoaded(true) + setIsLoadingMoreItems(false) + }, + (error) => { + HandleSnack('Erro ao carregar os dados', true, 'warning', '#FA8072') + setIsLoadingMoreItems(false) + setIsLoaded(true) + setError(true) + } + ) + }, [currPage, description, country, search, city, invertList]) + + useEffect(() => { + setSeacrh("") + setDescription("") + setCountry("") + setCity("") + setValueOfDescription("") + setValueOfSearch("") + setValueOfCountry("") + setValueOfCity("") + setCurrPage(0) + }, [showFilter]) + + if (error) { + return <div>Error: {error.message}</div>; + } + else if (!isLoaded) { + return <LoadingSpinner text="Carregando..." /> + } else { + //Words that defines that column + const topTable = [ + "ID", + "NOME", + "DESCRIÇÃO", + "CIDADE", + "PAÍS", + "VISUALIZAR", + "DELETAR", + ]; + + //Field of the Filter + const TextFieldOfTheFilter = [ + { + label: "Pesquisar", + value: valueOfSearch, + helperText: "Ao digitar, retire o foco do campo", + onChange: (event) => OnChangeSearchHandler(event), + onBlur: (event) => setSeacrh(event.target.value) + }, + { + label: "Cidade", + value: valueOfCity, + helperText: "Ao digitar, retire o foco do campo", + onChange: (event) => onChangeCityHandler(event), + onBlur: (event) => setCity(event.target.value) + }, + { + label: "País", + value: valueOfCountry, + helperText: "Ao digitar, retire o foco do campo", + onChange: (event) => onChangeCountryHandler(event), + onBlur: (event) => setCountry(event.target.value) + + }, + { + label: "Descrição", + value: valueOfDescription, + helperText: "Ao digitar, retire o foco do campo", + onChange: (event) => onChangeDescriptionHandler(event), + onBlur: (event) => setDescription(event.target.value) + }, + ]; + + if (WINDOW_WIDTH <= 977) { + return ( + <div> + <SnackBar + severity={snackInfo.icon} + text={snackInfo.message} + snackbarOpen={snackInfo.open} + color={snackInfo.color} + handleClose={() => + setSnackInfo({ + message: "", + icon: "", + open: false, + color: "", + }) } - ) - }; - - const InvertList = async () => { - transformListToAsc = !transformListToAsc - currPage = 0 - if (transformListToAsc) { - getRequest( - Url('institutions', '', `${currPage}`, 'ASC'), - (data, header) => { - const arrData = [...data] - setItems(arrData.concat(addOndeLenght)) + /> + <AlertDialog + open={openAlertDialog} + OnDelete={DeleteHandler} + deleteItem={deleteItem} + HandleClose={() => { + setOpenAlertDialog(false); + HandleStateCircularProgress(null); + }} + /> + {/************** Start of the header **************/} + <MobilePageHeader + title="Instituições" + actions={[ + { + name: "Atualizar", + isLoading: false, + func: () => { + setCurrPage(0) }, - (error) => { - HandleSnack('Erro ao carregar os dados', true, 'warning', '#FA8072') - } - ) - } else { - getRequest( - Url('institutions', '', `${currPage}`, 'DESC'), - (data, header) => { - const arrData = [...data] - setItems(arrData.concat(addOndeLenght)) + icon: <UpdateRoundedIcon /> + }, + { + name: "Filtrar", + isLoading: false, + func: () => { + setShowFilter(!showFilter); }, - (error) => { - HandleSnack('institutions ao carregar os dados', true, 'warning', '#FA8072') - } - ) - } - } - - useEffect(() => { - getRequest( - Url("institutions", "", `${currPage}`, "DESC"), - (data, header) => { - setIsLoaded(true); - setItems(data.concat(addOndeLenght)); - }, - (error) => { - setError(true); + icon: <FilterListRoundedIcon /> + }, + { + name: "Novo", + isLoading: false, + func: () => { + router.push('/admin/InstitutionCreate') + }, + icon: <AddRoundedIcon /> + } + ]} + > + { + showFilter && + <Grid item xs={12}> + <Grid container justify="space-between" spacing={3}> + {TextFieldOfTheFilter.map((field, index) => ( + <Grid item key={field.label}> + <TextField + id={index} + label={field.label} + value={field.value} + helperText={field.helperText} + onChange={field.onChange} + onBlur={field.onBlur} + /> + </Grid> + ))} + </Grid> + </Grid> } - ) - }, []); - - if (error) { - return <div>Error: {error.message}</div>; + </MobilePageHeader> + {/************** End of the header **************/} + + <div style={{ height: "2em" }}></div> + + {/************** Start of display data in table **************/} + {items.map((row, index) => + index === items.length - 1 ? ( + <StyledDivButton + key={new Date().toISOString() + row.created_at} + > + <Button + color="primary" + variant="text" + // disabled={isLoadingMoreItems} + startIcon={<AddRoundedIcon />} + disabled={isLoadingMoreItems} + onClick={() => { + setCurrPage(currPage + 1) + }} + > + {isLoadingMoreItems ? ( + <CircularProgress size={24} /> + ) : ( + "Carregar mais itens" + )} + </Button> + </StyledDivButton> + ) : ( + <> + <MobileList + key={new Date().toISOString() + row.created_at} + title={row.name} + subtitle={row.id} + backColor={"#ff7f00"} + avatar={<AccountBalanceRoundedIcon />} + href={`/admin/institution?institution=${row.id}`} + reset={() => { + + }} + data={ + [ + { + title: "Descrição", + subtitle: row.description ? row.description : "Sem dado" + + }, + { + title: "Cidade", + subtitle: row.city ? row.city : "Sem dado" + + }, + { + title: "País", + subtitle: row.country ? row.country : "Sem dado" + }, + { + title: "Deletar", + subtitle: + <Button + variant="contained" + color="secondary" + onClick={() => { + HandleStateAlertDialog(index); + HandleStateCircularProgress(index); + }} + startIcon={<DeleteIcon />} + > + Deletar + </Button> + } + ] + } + /> + <div style={{ height: "0.5em" }} /> + </> + ) + )} + {/************** End of display data in table **************/} + + {/* This alert will be displayed if the user click to delete an institution */} + </div> + ) } - if (!isLoaded) { - return <LoadingSpinner text="Carregando..." /> - } else { - //Words that defines that column - const topTable = [ - "ID", - "NOME", - "DESCRIÇÃO", - "CIDADE", - "PAÍS", - "VISUALIZAR", - "DELETAR", - ]; - - //Buttons from PopOverMenu - const flatButtonsFromPopOverMenu = [ - { - label: "Pesquisa padrão", - onClick: StandartHandler, - color: showStandadSearch ? "primary" : "default", - }, - { - label: "Cidade", - onClick: CityHandler, - color: showCityField ? "primary" : "default", - }, - { - label: "País", - onClick: CountryHandler, - color: showContryField ? "primary" : "default", - }, - { - label: "Descrição", - onClick: DescHandler, - color: showDescriptionField ? "primary" : "default", - }, - ]; - - //Field of the Filter - const TextFieldOfTheFilter = [ - { - label: "Pesquisar", - show: showStandadSearch, - onChange: (event) => OnChangeSearchHandler(event), - hide: StandartHandler, - }, - { - label: "Cidade", - show: showCityField, - onChange: (event) => onChangeCityHandler(event), - hide: CityHandler, - }, - { - label: "País", - show: showContryField, - onChange: (event) => onChangeCountryHandler(event), - hide: CountryHandler, - }, + else { + return ( + <div> + <SnackBar + severity={snackInfo.icon} + text={snackInfo.message} + snackbarOpen={snackInfo.open} + color={snackInfo.color} + handleClose={() => + setSnackInfo({ + message: "", + icon: "", + open: false, + color: "", + }) + } + /> + {/************** Start of the header **************/} + <PageHeader + title="Instituições" + actions={[ + { + name: "Atualizar", + isLoading: false, + func: () => { + setCurrPage(0) + }, + icon: <UpdateRoundedIcon /> + }, + { + name: "Filtrar", + isLoading: false, + func: () => { + setShowFilter(!showFilter); + }, + icon: <FilterListRoundedIcon /> + }, + { + name: "Novo", + isLoading: false, + func: () => { + router.push('/admin/InstitutionCreate') + }, + icon: <AddRoundedIcon /> + } + ]} + > { - label: "Descrição", - show: showDescriptionField, - onChange: (event) => onChangeDescriptionHandler(event), - hide: DescHandler, - }, - ]; - - if (WINDOW_WIDTH <= 977) { - return ( - <div> - <SnackBar - severity={snackInfo.icon} - text={snackInfo.message} - snackbarOpen={snackInfo.open} - color={snackInfo.color} - handleClose={() => - setSnackInfo({ - message: "", - icon: "", - open: false, - color: "", - }) - } - /> - {/************** Start of the header **************/} - <Paper style={{ padding: "1em" }}> - <Grid container spacing={3} direction="row" alignItems="center"> - <Grid item xs={12}> - <Typography className={classes.paper} variant="h4"> - Lista de Instituições - </Typography> - </Grid> - <Grid - item - xs={12} - > - <Grid container justify="flex-start" spacing={3}> - <Grid item> - <Button - aria-describedby={id} - variant="contained" - color="secondary" - className={classes.button} - onClick={handleClick} - startIcon={ - <FilterListRoundedIcon style={{ fill: "white" }} /> - } - > - Filtrar - </Button> - <Popover - id={id} - open={open} - anchorEl={anchorEl} - onClose={handleClose} - anchorOrigin={{ - vertical: "bottom", - horizontal: "center", - }} - transformOrigin={{ - vertical: "top", - horizontal: "center", - }} - > - {flatButtonsFromPopOverMenu.map((flat, index) => ( - <Button - key={index} - onClick={flat.onClick} - color={flat.color} - > - {flat.label} - </Button> - ))} - </Popover> - </Grid> - - <Grid item> - <Link style={{ textDecoration: 'none' }} to={'/admin/InstitutionCreate'}> - <Button - variant="contained" - color="secondary" - className={classes.button} - startIcon={<AddRoundedIcon style={{ fill: "white" }} />} - onClick={() => { - currPage = 0 - transformListToAsc = false - }} - > - Novo - </Button> - </Link> - </Grid> - - <Grid item> - <Button - variant="contained" - color="secondary" - className={classes.button} - startIcon={<UpdateRoundedIcon />} - disabled={isUpdating} - onClick={() => { - currPage = 0; - transformListToAsc = false - setIsUpdating(true); - UpdtateListData( - Url("institutions", "", `${currPage}`, "DESC") - ); - }} - > - {isUpdating ? <CircularProgress size={24} /> : "Atualizar"} - </Button> - </Grid> - </Grid> - </Grid> - </Grid> - <Grid item xs={12}> - <Grid container justify="space-between" spacing={3}> - {TextFieldOfTheFilter.map((field, index) => ( - <Grid item key={index}> - {field.show ? ( - <div> - <TextField - id={index} - label={field.label} - type="search" - onChange={field.onChange} - /> - <IconButton - size="small" - color="primary" - onClick={field.hide} - > - <CancelRoundedIcon /> - </IconButton> - </div> - ) : null} - </Grid> - ))} - </Grid> - </Grid> - </Paper> - {/************** End of the header **************/} - - <div style={{ height: "2em" }}></div> - - {/************** Start of display data in table **************/} - {items.map((row, index) => - index === items.length - 1 ? ( - <StyledDivButton> - <Button - key={index} - color="primary" - variant="text" - // disabled={isLoadingMoreItems} - startIcon={<AddRoundedIcon />} - disabled={isLoadingMoreItems} - onClick={() => { - currPage++ - if (transformListToAsc) { - LoadMoreItens(Url('institutions', '', `${currPage}`, 'ASC')) - } else { - LoadMoreItens(Url('institutions', '', `${currPage}`, 'DESC')) - } - }} - > - {isLoadingMoreItems ? ( - <CircularProgress size={24} /> - ) : ( - "Carregar mais itens" - )} - </Button> - </StyledDivButton> + showFilter && + <Grid item xs={12}> + <Grid container justify="space-between" spacing={3}> + {TextFieldOfTheFilter.map((field, index) => ( + <Grid item key={field.label}> + <TextField + id={index} + label={field.label} + value={field.value} + helperText={field.helperText} + onChange={field.onChange} + onBlur={field.onBlur} + /> + </Grid> + ))} + </Grid> + </Grid> + } + </PageHeader> + {/************** End of the header **************/} + + <div style={{ height: "2em" }}></div> + + {/************** Start of display data in table **************/} + <TableData top={topTable} onIconPressed={cleanArrayAndInvert}> + <TableBody> + {items.map((row, index) => + index === items.length - 1 ? ( + <StyledTableRow key={new Date().toISOString() + row.created_at}> + {/* Button to load more data */} + <StyledTableCell> + <Button + color="primary" + variant="text" + startIcon={<AddRoundedIcon />} + disabled={isLoadingMoreItems} + onClick={() => { + setCurrPage(currPage + 1) + }} + > + {isLoadingMoreItems ? ( + <CircularProgress size={24} /> ) : ( - <> - <MobileList - key={index} - title={row.name} - subtitle={row.id} - backColor={"#ff7f00"} - avatar={<AccountBalanceRoundedIcon />} - href={`/admin/institution/${row.id}`} - reset={() => { - currPage = 0 - transformListToAsc = false - }} - data={ - [ - { - title: "Descrição", - subtitle: row.description ? row.description : "Sem dado" - - }, - { - title: "Cidade", - subtitle: row.city ? row.city : "Sem dado" - - }, - { - title: "País", - subtitle: row.country ? row.country : "Sem dado" - }, - ] - } - /> - <div style={{ height: "0.5em" }} /> - </> - ) - )} - {/************** End of display data in table **************/} - - {/* This alert will be displayed if the user click to delete an institution */} - </div> - ) - } - else { - return ( - <div> - <SnackBar - severity={snackInfo.icon} - text={snackInfo.message} - snackbarOpen={snackInfo.open} - color={snackInfo.color} - handleClose={() => - setSnackInfo({ - message: "", - icon: "", - open: false, - color: "", - }) - } - /> - {/************** Start of the header **************/} - <Paper style={{ padding: "1em" }}> - <Grid container spacing={3} direction="row" alignItems="center"> - <Grid item xs={6}> - <Typography className={classes.paper} variant="h4"> - Lista de Instituições - </Typography> - </Grid> - <Grid - item - xs={6} + "Carregar mais itens" + )} + </Button> + </StyledTableCell> + </StyledTableRow> + ) : ( + <StyledTableRow key={new Date().toISOString() + index}> + <StyledTableCell component="th" scope="row"> + {row.id} + </StyledTableCell> + <StyledTableCell align="right">{row.name}</StyledTableCell> + <StyledTableCell align="right"> + {row.description} + </StyledTableCell> + <StyledTableCell align="right">{row.city}</StyledTableCell> + <StyledTableCell align="right"> + {row.country} + </StyledTableCell> + <StyledTableCell align="right"> + <Link to={`/admin/institution?institution=${row.id}`}> + <IconButton> + <VisibilityIcon style={{ fill: "#00bcd4" }} /> + </IconButton> + </Link> + </StyledTableCell> + <StyledTableCell align="right"> + {isLoadingToDelete === index ? ( + <CircularProgress size={24} color="primary" /> + ) : ( + <IconButton + onClick={() => { + HandleStateAlertDialog(index); + HandleStateCircularProgress(index); + }} > - <Grid container justify="flex-end" spacing={3}> - <Grid item> - <Button - aria-describedby={id} - variant="contained" - color="secondary" - className={classes.button} - onClick={handleClick} - startIcon={ - <FilterListRoundedIcon style={{ fill: "white" }} /> - } - > - Filtrar - </Button> - <Popover - id={id} - open={open} - anchorEl={anchorEl} - onClose={handleClose} - anchorOrigin={{ - vertical: "bottom", - horizontal: "center", - }} - transformOrigin={{ - vertical: "top", - horizontal: "center", - }} - > - {flatButtonsFromPopOverMenu.map((flat, index) => ( - <Button - key={index} - onClick={flat.onClick} - color={flat.color} - > - {flat.label} - </Button> - ))} - </Popover> - </Grid> - - <Grid item> - <Link style={{ textDecoration: 'none' }} to={'/admin/InstitutionCreate'}> - <Button - variant="contained" - color="secondary" - className={classes.button} - startIcon={<AddRoundedIcon style={{ fill: "white" }} />} - onClick={() => { - currPage = 0 - transformListToAsc = false - }} - > - Novo - </Button> - </Link> - </Grid> - - <Grid item> - <Button - variant="contained" - color="secondary" - className={classes.button} - startIcon={<UpdateRoundedIcon />} - disabled={isUpdating} - onClick={() => { - currPage = 0; - transformListToAsc = false - setIsUpdating(true); - UpdtateListData( - Url("institutions", "", `${currPage}`, "DESC") - ); - }} - > - {isUpdating ? <CircularProgress size={24} /> : "Atualizar"} - </Button> - </Grid> - </Grid> - </Grid> - </Grid> - <Grid item xs={12}> - <Grid container justify="space-between" spacing={3}> - {TextFieldOfTheFilter.map((field, index) => ( - <Grid item key={index}> - {field.show ? ( - <div> - <TextField - id={index} - label={field.label} - type="search" - onChange={field.onChange} - /> - <IconButton - size="small" - color="primary" - onClick={field.hide} - > - <CancelRoundedIcon /> - </IconButton> - </div> - ) : null} - </Grid> - ))} - </Grid> - </Grid> - </Paper> - {/************** End of the header **************/} - - <div style={{ height: "2em" }}></div> - - {/************** Start of display data in table **************/} - <TableData top={topTable} onIconPressed={InvertList}> - <TableBody> - {items.map((row, index) => - index === items.length - 1 ? ( - <StyledTableRow key={index}> - {/* Button to load more data */} - <StyledTableCell> - <Button - color="primary" - variant="text" - startIcon={<AddRoundedIcon />} - disabled={ - isLoadingMoreItems || - isFilteringByCity || - isFilteringByCounty || - isFilteringByDesc || - isFilteringByName - } - onClick={() => { - currPage++ - if (transformListToAsc) { - LoadMoreItens(Url('institutions', '', `${currPage}`, 'ASC')) - } else { - LoadMoreItens(Url('institutions', '', `${currPage}`, 'DESC')) - } - }} - > - {isLoadingMoreItems ? ( - <CircularProgress size={24} /> - ) : ( - "Carregar mais itens" - )} - </Button> - </StyledTableCell> - </StyledTableRow> - ) : ( - <StyledTableRow key={index}> - <StyledTableCell component="th" scope="row"> - {row.id} - </StyledTableCell> - <StyledTableCell align="right">{row.name}</StyledTableCell> - <StyledTableCell align="right"> - {row.description} - </StyledTableCell> - <StyledTableCell align="right">{row.city}</StyledTableCell> - <StyledTableCell align="right"> - {row.country} - </StyledTableCell> - <StyledTableCell align="right"> - <Link to={`/admin/institution/${row.id}`}> - <IconButton onClick={() => { - currPage = 0 - transformListToAsc = false - }}> - <VisibilityIcon style={{ fill: "#00bcd4" }} /> - </IconButton> - </Link> - </StyledTableCell> - <StyledTableCell align="right"> - {isLoadingToDelete === index ? ( - <CircularProgress size={24} color="primary" /> - ) : ( - <IconButton - onClick={() => { - HandleStateAlertDialog(index); - HandleStateCircularProgress(index); - }} - > - <DeleteIcon style={{ fill: "#FF0000" }} /> - </IconButton> - )} - </StyledTableCell> - </StyledTableRow> - ) - )} - </TableBody> - </TableData> - {/************** End of display data in table **************/} - - {/* This alert will be displayed if the user click to delete an institution */} - <AlertDialog - open={openAlertDialog} - OnDelete={DeleteHandler} - deleteItem={deleteItem} - HandleClose={() => { - setOpenAlertDialog(false); - HandleStateCircularProgress(null); - }} - /> - </div> - ) - } + <DeleteIcon style={{ fill: "#FF0000" }} /> + </IconButton> + )} + </StyledTableCell> + </StyledTableRow> + ) + )} + </TableBody> + </TableData> + {/************** End of display data in table **************/} + + {/* This alert will be displayed if the user click to delete an institution */} + <AlertDialog + open={openAlertDialog} + OnDelete={DeleteHandler} + deleteItem={deleteItem} + HandleClose={() => { + setOpenAlertDialog(false); + HandleStateCircularProgress(null); + }} + /> + </div> + ) } + } }; export default Institutions; diff --git a/src/Admin/Pages/Pages/SubPages/Languages.js b/src/Admin/Pages/Pages/SubPages/Languages.js index 00693f02998a332451f42f0bc8aa744e8d4e28d9..c38ac1e1015d1ad352f23e597ee85240c4e28a2c 100644 --- a/src/Admin/Pages/Pages/SubPages/Languages.js +++ b/src/Admin/Pages/Pages/SubPages/Languages.js @@ -25,469 +25,406 @@ import { Url } from '../../../Filters'; import LoadingSpinner from '../../../../Components/LoadingSpinner'; import { DeleteFilter } from '../../../Filters'; import { getRequest, deleteRequest } from '../../../../Components/HelperFunctions/getAxiosConfig' +import MobileList from "../../../Components/Components/MobileComponents/SimpleList" +import MobilePageHeader from "../../../Components/Components/MobileComponents/MobilePageHeader" +import PageHeader from "../../../Components/Components/PageHeader" //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 TableRow from '@material-ui/core/TableRow'; import IconButton from '@material-ui/core/IconButton'; -import { Button, Typography, Paper, Grid } from '@material-ui/core'; +import { Button, Paper } 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 EditRoundedIcon from '@material-ui/icons/EditRounded'; import DeleteRoundedIcon from '@material-ui/icons/DeleteRounded'; //router -import { Link } from 'react-router-dom'; +import { Link, useHistory } from 'react-router-dom'; import styled from "styled-components" import LanguageRoundedIcon from "@material-ui/icons/LanguageRounded"; -import MobileList from "../../../Components/Components/MobileComponents/SimpleList" - -let currPage = 0; -let transformListToAsc = false; const StyledTableCell = withStyles((theme) => ({ - head: { - backgroundColor: theme.palette.common.black, - color: theme.palette.common.white, - }, - body: { - fontSize: 14, - }, + 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, - }, + root: { + '&:nth-of-type(odd)': { + backgroundColor: theme.palette.action.hover, }, + }, }))(TableRow); const Languages = () => { - const ADD_ONE_LENGHT = [""]; - const TOP_LABELS = ['ID', 'NOME', 'CODE', 'EDITAR', 'DELETAR'] //Labels from Table - const WINDOW_WIDTH = window.innerWidth - - 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 [openAlertDialog, setOpenAlertDialog] = useState(false); //controlls the state od alert dialog - - const [deleteItem, setDeleteItem] = useState({}); //Delete Item - const [isLoadingToDelete, setIsLoadingToDelete] = useState(null); - - const [snackInfo, setSnackInfo] = useState({ - message: '', - icon: '', - open: false, - color: '', + const ADD_ONE_LENGHT = [""]; + const TOP_LABELS = ['ID', 'NOME', 'CODE', 'EDITAR', 'DELETAR'] //Labels from Table + const WINDOW_WIDTH = window.innerWidth + const router = useHistory() + + const [invertList, setInvertList] = useState(false) + 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 [openAlertDialog, setOpenAlertDialog] = useState(false); //controlls the state od alert dialog + const [currPage, setCurrPage] = useState(0) + + const [deleteItem, setDeleteItem] = useState({}); //Delete Item + const [isLoadingToDelete, setIsLoadingToDelete] = useState(null); + + const [snackInfo, setSnackInfo] = useState({ + message: '', + icon: '', + open: false, + color: '', + }) + + //handle snack info + const HandleSnack = (message, state, icon, color) => { + setSnackInfo({ + message: message, + icon: icon, + open: state, + color: color }) - - //handle snack info - const HandleSnack = (message, state, icon, color) => { - setSnackInfo({ - message: message, - icon: icon, - open: state, - color: color - }) - } - - //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) - } - ) + } + + //handle Delete + async function DeleteHandler() { + const id = deleteItem.id; + HandleStateAlertDialog(null); + deleteRequest( + DeleteFilter("languages", id), + (data) => { + if (data.errors) + HandleSnack("Ocorreu algum erro", true, "warning", "#FA8072"); + else { + HandleSnack( + "A língua foi deletada com sucesso", + true, + "success", + "#228B22" + ); + setCurrPage(0) + HandleStateCircularProgress(null); + removeItemFromList(id) + } + }, + (error) => { + HandleSnack("Ocorreu algum erro", true, "warning", "#FA8072"); + HandleStateCircularProgress(null); + } + ) + } + + const HandleStateCircularProgress = (i) => { + setIsLoadingToDelete(i); + }; + + const HandleStateAlertDialog = (i) => { + const obj = { ...items[i] }; + setDeleteItem(obj); + setOpenAlertDialog(!openAlertDialog); + }; + + const removeItemFromList = (itemId) => { + let index = -1; + for (let i = 0; i < items.length; i++) { + const element = items[i]; + if (element.id === itemId) { + index = i + break + } } - - //handle Delete - async function DeleteHandler() { - const id = deleteItem.id; - HandleStateAlertDialog(null); - deleteRequest( - DeleteFilter("languages", id), - (data) => { - if (data.errors) - HandleSnack("Ocorreu algum erro", true, "warning", "#FA8072"); - else { - HandleSnack( - "A língua foi deletada com sucesso", - true, - "success", - "#228B22" - ); - currPage = 0; - transformListToAsc = false - UpdateHandler(Url("languages", "", `${currPage}`, "DESC")); - HandleStateCircularProgress(null); - } - }, - (error) => { - HandleSnack("Ocorreu algum erro", true, "warning", "#FA8072"); - HandleStateCircularProgress(null); - } - ) + if (index !== -1) { + const cpyItems = [...items] + cpyItems.splice(index, 1) + setItems(cpyItems) } - - const HandleStateCircularProgress = (i) => { - setIsLoadingToDelete(i); - }; - - const HandleStateAlertDialog = (i) => { - const obj = { ...items[i] }; - setDeleteItem(obj); - setOpenAlertDialog(!openAlertDialog); - }; - - const InvertList = async () => { - transformListToAsc = !transformListToAsc - currPage = 0 - if (transformListToAsc) { - getRequest( - Url('languages', '', `${currPage}`, 'ASC'), - (data, header) => { - const arrData = [...data] - setItems(arrData.concat(ADD_ONE_LENGHT)) - }, - (error) => { - HandleSnack('Erro ao carregar os dados', true, 'warning', '#FA8072') - } - ) + } + + const cleanArrayAndInvert = () => { + setInvertList(!invertList) + setCurrPage(0) + setItems([]) + } + + //getting data from server + useEffect(() => { + if (currPage === 0) + setIsLoaded(false) + else + setIsLoadingMoreItems(true) + + getRequest( + Url("languages", "", currPage, invertList ? "ASC" : "DESC"), + (data, header) => { + const arrData = [...data] + if (arrData.length === 0) { + HandleSnack('Não há mais dados para serem carregados', true, 'warning', '#FFC125') } else { - getRequest( - Url('languages', '', `${currPage}`, 'DESC'), - (data, header) => { - const arrData = [...data] - setItems(arrData.concat(ADD_ONE_LENGHT)) - }, - (error) => { - HandleSnack('Erro ao carregar os dados', true, 'warning', '#FA8072') - } - ) + const arrItems = [...items] + if (currPage === 0) { + setItems(arrData.concat(ADD_ONE_LENGHT)) + } + else { + 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)) + } } - } - - //getting data from server - useEffect(() => { - getRequest( - Url('languages', '', `${currPage}`, 'DESC'), - (data, header) => { - setIsLoaded(true); - setItems(data.concat(ADD_ONE_LENGHT)); - }, - (error) => { - setError(true); - } - ) - }, []); - - - if (error) { - return <div>Error: {error.message}</div>; - } else if (!isLoaded) { - return <LoadingSpinner text="Carregando..." /> - } else { - if (WINDOW_WIDTH <= 755) { - 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={12}> - <Typography variant="h4"> - Linguagens - </Typography> - </Grid> - <Grid - item - xs={12} - > - <Grid container justify="flex-start" spacing={3}> - <Grid item> - <Button - variant="contained" - color="secondary" - disabled={isUpdating} - onClick={() => { - currPage = 0 - transformListToAsc = false - UpdateHandler(Url('languages', '', `${currPage}`, 'DESC')) - }} - startIcon={<UpdateRoundedIcon />} - > - { - isUpdating ? <CircularProgress size={24} /> : 'Atualizar' - } - </Button> - </Grid> - <Grid item> - - <Link style={{ textDecoration: 'none' }} to={'/admin/languageCreate'}> - <Button - variant="contained" - color="secondary" - startIcon={<AddRoundedIcon />} - > - Novo - </Button> - </Link> - </Grid> - </Grid> - </Grid> - </Grid> - </Paper> - - <div style={{ height: '2em' }}></div> - - {items.map((row, index) => - index === items.length - 1 ? ( - <StyledDivButton> - <Button - key={index} - color="primary" - variant="text" - // disabled={isLoadingMoreItems} - startIcon={<AddRoundedIcon />} - disabled={isLoadingMoreItems} - onClick={() => { - currPage++ - if (transformListToAsc) { - LoadMoreItens(Url('languages', '', `${currPage}`, 'ASC')) - } else { - LoadMoreItens(Url('languages', '', `${currPage}`, 'DESC')) - } - }} - > - {isLoadingMoreItems ? ( - <CircularProgress size={24} /> - ) : ( - "Carregar mais itens" - )} - </Button> - </StyledDivButton> - ) : ( - <> - <MobileList - key={index} - title={row.name} - subtitle={row.id} - backColor={"#e81f4f"} - avatar={<LanguageRoundedIcon />} - href={`/admin/languageEdit/${row.id}`} - reset={() => { - currPage = 0; - transformListToAsc = false - }} - data={ - [ - { - title: "Code", - subtitle: row.code - - }, - ] - } - /> - <div style={{ height: "0.5em" }} /> - </> - ) + setIsLoaded(true) + setIsLoadingMoreItems(false) + }, + (error) => { + HandleSnack('Erro ao carregar os dados', true, 'warning', '#FA8072') + setIsLoadingMoreItems(false) + setIsLoaded(true) + setError(true) + } + ) + }, [currPage, invertList]) + + if (error) { + return <div>Error: {error.message}</div>; + } else if (!isLoaded) { + return <LoadingSpinner text="Carregando..." /> + } else { + if (WINDOW_WIDTH <= 800) { + return ( + <> + <SnackBar + severity={snackInfo.icon} + text={snackInfo.message} + snackbarOpen={snackInfo.open} + color={snackInfo.color} + handleClose={() => setSnackInfo({ + message: '', + icon: '', + open: false, + color: '' + })} + /> + <AlertDialog + open={openAlertDialog} + OnDelete={DeleteHandler} + deleteItem={deleteItem} + HandleClose={() => { + setOpenAlertDialog(false); + HandleStateCircularProgress(null); + }} + /> + <MobilePageHeader + title="Linguagens" + actions={[ + { + name: "Atualizar", + isLoading: false, + func: () => { + setCurrPage(0) + }, + icon: <UpdateRoundedIcon /> + }, + { + name: "Novo", + isLoading: false, + func: () => { + router.push('/admin/languageCreate') + }, + icon: <AddRoundedIcon /> + } + ]} + > + </MobilePageHeader> + + <div style={{ height: '2em' }}></div> + + {items.map((row, index) => + index === items.length - 1 ? ( + <StyledDivButton key={new Date().toISOString() + row.created_at}> + <Button + color="primary" + variant="text" + // disabled={isLoadingMoreItems} + startIcon={<AddRoundedIcon />} + disabled={isLoadingMoreItems} + onClick={() => { + setCurrPage(currPage + 1) + }} + > + {isLoadingMoreItems ? ( + <CircularProgress size={24} /> + ) : ( + "Carregar mais itens" )} - </> - ); - } - else { - return ( + </Button> + </StyledDivButton> + ) : ( <> - <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"> - Linguagens - </Typography> - </Grid> - <Grid - item - xs={6} + <MobileList + key={new Date().toISOString() + row.created_at} + title={row.name} + subtitle={row.id} + backColor={"#e81f4f"} + avatar={<LanguageRoundedIcon />} + href={`/admin/languageEdit?language=${row.id}`} + reset={() => { + + }} + data={ + [ + { + title: "Code", + subtitle: row.code + }, + { + title: "Deletar", + subtitle: + <Button + variant="contained" + color="secondary" + onClick={() => { + HandleStateAlertDialog(index); + HandleStateCircularProgress(index); + }} + startIcon={<DeleteRoundedIcon />} > - <Grid container justify="flex-end" spacing={3}> - <Grid item> - <Button - variant="contained" - color="secondary" - disabled={isUpdating} - onClick={() => { - currPage = 0 - transformListToAsc = false - UpdateHandler(Url('languages', '', `${currPage}`, 'DESC')) - }} - startIcon={<UpdateRoundedIcon />} - > - { - isUpdating ? <CircularProgress size={24} /> : 'Atualizar' - } - </Button> - </Grid> - <Grid item> - - <Link style={{ textDecoration: 'none' }} to={'/admin/languageCreate'}> - <Button - variant="contained" - color="secondary" - startIcon={<AddRoundedIcon />} - > - Novo - </Button> - </Link> - </Grid> - </Grid> - </Grid> - </Grid> - </Paper> - - <div style={{ height: '2em' }}></div> - - <TableData - top={TOP_LABELS} - onIconPressed={InvertList} - > - <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++ - if (transformListToAsc) { - LoadMoreItens(Url('languages', '', `${currPage}`, 'ASC')) - } else { - LoadMoreItens(Url('languages', '', `${currPage}`, 'DESC')) - } - }} - > - { - isLoadingMoreItems ? <CircularProgress size={24} /> : 'Carregar mais itens' - } - </Button> - </StyledTableCell> - </StyledTableRow> - - : - - <StyledTableRow key={index}> - <StyledTableCell component="th" scope="row">{row.id}</StyledTableCell> - <StyledTableCell align="right">{row.name}</StyledTableCell> - <StyledTableCell align="right">{row.code}</StyledTableCell> - <StyledTableCell align="right"> - <Link to={`/admin/languageEdit/${row.id}`}> - <IconButton onClick={() => { currPage = 0; transformListToAsc = false }}> - <EditRoundedIcon style={{ fill: '#00bcd4' }} /> - </IconButton> - </Link> - </StyledTableCell> - <StyledTableCell align="right"> - {isLoadingToDelete === index ? ( - <CircularProgress size={24} color="primary" /> - ) : ( - <IconButton - onClick={() => { - HandleStateAlertDialog(index); - HandleStateCircularProgress(index); - }} - > - <DeleteRoundedIcon style={{ fill: "#FF0000" }} /> - </IconButton> - )} - </StyledTableCell> - </StyledTableRow> - ))} - </TableBody> - </TableData> - - {/* This alert will be displayed if the user click to delete an institution */} - <AlertDialog - open={openAlertDialog} - OnDelete={DeleteHandler} - deleteItem={deleteItem} - HandleClose={() => { - setOpenAlertDialog(false); - HandleStateCircularProgress(null); - }} - /> + Deletar + </Button> + } + ] + } + /> + <div style={{ height: "0.5em" }} /> </> - ); - } + ) + )} + </> + ); + } + else { + return ( + <> + <SnackBar + severity={snackInfo.icon} + text={snackInfo.message} + snackbarOpen={snackInfo.open} + color={snackInfo.color} + handleClose={() => setSnackInfo({ + message: '', + icon: '', + open: false, + color: '' + })} + /> + + <PageHeader + title="Linguagens" + actions={[ + { + name: "Atualizar", + isLoading: false, + func: () => { + setCurrPage(0) + }, + icon: <UpdateRoundedIcon /> + }, + { + name: "Novo", + isLoading: false, + func: () => { + router.push('/admin/languageCreate') + }, + icon: <AddRoundedIcon /> + } + ]} + > + </PageHeader> + + <div style={{ height: '2em' }}></div> + + <TableData + top={TOP_LABELS} + onIconPressed={cleanArrayAndInvert} + > + <TableBody> + {items.map((row, index) => ( + index === items.length - 1 ? + <StyledTableRow key={new Date().toISOString() + row.created_at}> + {/* Button to load more data */} + <StyledTableCell> + <Button + color='primary' + variant='text' + // disabled={isLoadingMoreItems} + startIcon={<AddRoundedIcon />} + disabled={isLoadingMoreItems} + onClick={() => { + setCurrPage(currPage + 1) + }} + > + { + isLoadingMoreItems ? <CircularProgress size={24} /> : 'Carregar mais itens' + } + </Button> + </StyledTableCell> + </StyledTableRow> + + : + + <StyledTableRow key={new Date().toISOString() + index}> + <StyledTableCell component="th" scope="row">{row.id}</StyledTableCell> + <StyledTableCell align="right">{row.name}</StyledTableCell> + <StyledTableCell align="right">{row.code}</StyledTableCell> + <StyledTableCell align="right"> + <Link to={`/admin/languageEdit?language=${row.id}`}> + <IconButton> + <EditRoundedIcon style={{ fill: '#00bcd4' }} /> + </IconButton> + </Link> + </StyledTableCell> + <StyledTableCell align="right"> + {isLoadingToDelete === index ? ( + <CircularProgress size={24} color="primary" /> + ) : ( + <IconButton + onClick={() => { + HandleStateAlertDialog(index); + HandleStateCircularProgress(index); + }} + > + <DeleteRoundedIcon style={{ fill: "#FF0000" }} /> + </IconButton> + )} + </StyledTableCell> + </StyledTableRow> + ))} + </TableBody> + </TableData> + + {/* This alert will be displayed if the user click to delete an institution */} + <AlertDialog + open={openAlertDialog} + OnDelete={DeleteHandler} + deleteItem={deleteItem} + HandleClose={() => { + setOpenAlertDialog(false); + HandleStateCircularProgress(null); + }} + /> + </> + ); } + } } export default Languages; diff --git a/src/Admin/Pages/Pages/SubPages/NoteVariables.js b/src/Admin/Pages/Pages/SubPages/NoteVariables.js index 16c39487c44ed81523beab4d0351ef1e07a5c093..1ad35f99a8c2a8c5a7e8340acfbd1d9551ec5473 100644 --- a/src/Admin/Pages/Pages/SubPages/NoteVariables.js +++ b/src/Admin/Pages/Pages/SubPages/NoteVariables.js @@ -19,7 +19,6 @@ import React, { useEffect, useState } from 'react'; //Material ui componets import { withStyles } from '@material-ui/core/styles'; import TableBody from '@material-ui/core/TableBody'; -import Grid from "@material-ui/core/Grid"; import Paper from "@material-ui/core/Paper"; import TableCell from '@material-ui/core/TableCell'; import TableRow from '@material-ui/core/TableRow'; @@ -35,386 +34,303 @@ import UpdateRoundedIcon from '@material-ui/icons/UpdateRounded' import TableData from '../../../Components/Components/Table'; import SnackBar from '../../../../Components/SnackbarComponent'; import LoadingSpinner from '../../../../Components/LoadingSpinner'; +import MobileList from "../../../Components/Components/MobileComponents/SimpleList" +import MobilePageHeader from "../../../Components/Components/MobileComponents/MobilePageHeader" +import PageHeader from "../../../Components/Components/PageHeader" + //Services import { getRequest } from '../../../../Components/HelperFunctions/getAxiosConfig' import { Url } from '../../../Filters'; //routers import { Link } from 'react-router-dom'; import styled from "styled-components" -import MobileList from "../../../Components/Components/MobileComponents/SimpleList" import TrendingUpRoundedIcon from "@material-ui/icons/TrendingUpRounded"; -let currPage = 0; //var that controlls the current page that we are -let transformListToAsc = false; - const StyledTableCell = withStyles((theme) => ({ - head: { - backgroundColor: theme.palette.common.black, - color: theme.palette.common.white, - }, - body: { - fontSize: 14, - }, + 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, - }, + root: { + '&:nth-of-type(odd)': { + backgroundColor: theme.palette.action.hover, }, + }, }))(TableRow); const NoteVariables = () => { - const WINDOW_WIDTH = window.innerWidth - const AddOneLenght = ['']; - 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) - const [isUpdating, setIsUpdating] = useState(false) + const WINDOW_WIDTH = window.innerWidth + const ADD_ONE_LENGHT = [""]; - const [snackInfo, setSnackInfo] = useState({ - message: '', - icon: '', - open: false, - color: '', - }) + const [invertList, setInvertList] = useState(false) + 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 [currPage, setCurrPage] = useState(0) + const [items, setItems] = useState([]); //Necessary to consult the API, data + const [isLoadingMoreItems, setIsLoadingMoreItems] = useState(false) - // Handle snack infos - const HandleSnack = (message, state, icon, color) => { - setSnackInfo({ - message: message, - icon: icon, - open: state, - color: color - }) - } + const [snackInfo, setSnackInfo] = useState({ + message: '', + icon: '', + open: false, + color: '', + }) - 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(AddOneLenght)) - } - setIsLoadingMoreItems(false) - }, - (error) => { - HandleSnack('Erro ao carregar os dados', true, 'warning', '#FA8072') - setIsLoadingMoreItems(false) - } - ) - } + // Handle snack infos + const HandleSnack = (message, state, icon, color) => { + setSnackInfo({ + message: message, + icon: icon, + open: state, + color: color + }) + } - const InvertList = async () => { - transformListToAsc = !transformListToAsc - currPage = 0 - if (transformListToAsc) { - getRequest( - Url('scores', '', `${currPage}`, 'ASC'), - (data, header) => { - const arrData = [...data] - setItems(arrData.concat(AddOneLenght)) - }, - (error) => { - HandleSnack('Erro ao carregar os dados', true, 'warning', '#FA8072') - } - ) + const cleanArrayAndInvert = () => { + setInvertList(!invertList) + setCurrPage(0) + setItems([]) + } + + useEffect(() => { + if (currPage === 0) + setIsLoaded(false) + else + setIsLoadingMoreItems(true) + getRequest( + Url("scores", "", currPage, invertList ? "ASC" : "DESC"), + (data, header) => { + const arrData = [...data] + if (arrData.length === 0) { + HandleSnack('Não há mais dados para serem carregados', true, 'warning', '#FFC125') } else { - getRequest( - Url('scores', '', `${currPage}`, 'DESC'), - (data, header) => { - const arrData = [...data] - setItems(arrData.concat(AddOneLenght)) - }, - (error) => { - HandleSnack('Erro ao carregar os dados', true, 'warning', '#FA8072') - } - ) + const arrItems = [...items] + if (currPage === 0) { + setItems(arrData.concat(ADD_ONE_LENGHT)) + } + else { + 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)) + } } - } - - 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(AddOneLenght)) - setIsUpdating(false) - }, - (error) => { - HandleSnack('Erro ao carregar os dados', true, 'warning', '#FA8072') - setIsUpdating(false) - } - ) - } - - useEffect(() => { - getRequest( - Url('scores', '', '0', 'DESC'), - (data, header) => { - setIsLoaded(true); - setItems(data.concat(AddOneLenght)); - }, - (error) => { - setError(true); - } - ) - }, []); + setIsLoaded(true) + setIsLoadingMoreItems(false) + }, + (error) => { + HandleSnack('Erro ao carregar os dados', true, 'warning', '#FA8072') + setIsLoadingMoreItems(false) + setIsLoaded(true) + setError(true) + } + ) + }, [currPage, invertList]) + if (error) { + return <div>Error: {error.message}</div>; + } else if (!isLoaded) { + return <LoadingSpinner text="Carregando..." /> + } else { - if (error) { - return <div>Error: {error.message}</div>; - } else if (!isLoaded) { - return <LoadingSpinner text="Carregando..." /> - } else { + //Words in the top part of the table + const topTable = ['ID', 'NOME', 'CÓDIGO', 'PESO', 'ATIVO', 'SCORE TYPE', 'VISUALIZAR']; - //Words in the top part of the table - const topTable = ['ID', 'NOME', 'CÓDIGO', 'PESO', 'ATIVO', 'SCORE TYPE', 'VISUALIZAR']; - - if (WINDOW_WIDTH <= 961) { - return ( - <div> - <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={12}> - <Typography variant="h4"> - Variáveis de nota - </Typography> - </Grid> - <Grid - item - xs={12} - > - <Grid container justify="flex-start" spacing={3}> - <Grid item> - <Button - variant="contained" - color="secondary" - disabled={isUpdating} - onClick={() => { - currPage = 0 - transformListToAsc = false - UpdateHandler(Url('scores', '', `${currPage}`, 'DESC')) - }} - startIcon={<UpdateRoundedIcon />} - > - { - isUpdating ? <CircularProgress size={24} /> : 'Atualizar' - } - </Button> - </Grid> - </Grid> - </Grid> - </Grid> - </Paper> + if (WINDOW_WIDTH <= 1000) { + return ( + <div> + <SnackBar + severity={snackInfo.icon} + text={snackInfo.message} + snackbarOpen={snackInfo.open} + color={snackInfo.color} + handleClose={() => setSnackInfo({ + message: '', + icon: '', + open: false, + color: '' + })} + /> + <MobilePageHeader + title="Variáveis de nota" + actions={[ + { + name: "Atualizar", + isLoading: false, + func: () => { + setCurrPage(0) + }, + icon: <UpdateRoundedIcon /> + }, + { + name: "Inverter lista", + isLoading: false, + func: () => { + cleanArrayAndInvert() + }, + }, + ]} + > + </MobilePageHeader> - <div style={{ height: '2em' }}></div> + <div style={{ height: '2em' }}></div> - {items.map((row, index) => - index === items.length - 1 ? ( - <StyledDivButton> - <Button - key={index} - color="primary" - variant="text" - // disabled={isLoadingMoreItems} - startIcon={<AddRoundedIcon />} - disabled={isLoadingMoreItems} - onClick={() => { - currPage++ - if (transformListToAsc) { - LoadMoreItens(Url('scores', '', `${currPage}`, 'ASC')) - } else { - LoadMoreItens(Url('scores', '', `${currPage}`, 'DESC')) - } - }} - > - {isLoadingMoreItems ? ( - <CircularProgress size={24} /> - ) : ( - "Carregar mais itens" - )} - </Button> - </StyledDivButton> - ) : ( - <> - <MobileList - key={index} - title={row.name} - subtitle={row.id} - backColor={"#e81f4f"} - avatar={<TrendingUpRoundedIcon />} - href={`/admin/noteVar/${row.id}`} - reset={() => { - currPage = 0; - }} - data={ - [ - { - title: "Código", - subtitle: row.code + {items.map((row, index) => + index === items.length - 1 ? ( + <StyledDivButton key={new Date().toISOString() + row.created_at}> + <Button + color="primary" + variant="text" + // disabled={isLoadingMoreItems} + startIcon={<AddRoundedIcon />} + disabled={isLoadingMoreItems} + onClick={() => { + setCurrPage(currPage + 1) + }} + > + {isLoadingMoreItems ? ( + <CircularProgress size={24} /> + ) : ( + "Carregar mais itens" + )} + </Button> + </StyledDivButton> + ) : ( + <> + <MobileList + key={new Date().toISOString() + row.created_at} + title={row.name} + subtitle={row.id} + backColor={"#e81f4f"} + avatar={<TrendingUpRoundedIcon />} + href={`/admin/noteVar?id=${row.id}`} + reset={() => { + }} + data={ + [ + { + title: "Código", + subtitle: row.code - }, - { - title: "Score Type", - subtitle: row.score_type + }, + { + title: "Score Type", + subtitle: row.score_type - }, - { - title: "Ativo", - subtitle: row.active ? <CheckRoundedIcon style={{ fill: '#3CB371' }} /> : <BlockRoundedIcon style={{ fill: '#FA8072' }} /> - }, - ] - } - /> - <div style={{ height: "0.5em" }} /> - </> - ) - )} - </div> - ) - } - else { - return ( - <div> - <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"> - Variáveis de nota - </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 - transformListToAsc = false - UpdateHandler(Url('scores', '', `${currPage}`, 'DESC')) - }} - startIcon={<UpdateRoundedIcon />} - > - { - isUpdating ? <CircularProgress size={24}/> : 'Atualizar' - } - </Button> - </Grid> - </Grid> - </Grid> - </Grid> - </Paper> + }, + { + title: "Ativo", + subtitle: row.active ? <CheckRoundedIcon style={{ fill: '#3CB371' }} /> : <BlockRoundedIcon style={{ fill: '#FA8072' }} /> + }, + ] + } + /> + <div style={{ height: "0.5em" }} /> + </> + ) + )} + </div> + ) + } + else { + return ( + <div> + <SnackBar + severity={snackInfo.icon} + text={snackInfo.message} + snackbarOpen={snackInfo.open} + color={snackInfo.color} + handleClose={() => setSnackInfo({ + message: '', + icon: '', + open: false, + color: '' + })} + /> + <PageHeader + title="Variáveis de nota" + actions={[ + { + name: "Atualizar", + isLoading: false, + func: () => { + setCurrPage(0) + }, + icon: <UpdateRoundedIcon /> + }, + ]} + > + </PageHeader> - <div style={{ height: '2em' }}></div> + <div style={{ height: '2em' }}></div> - <TableData - top={topTable} - onIconPressed={InvertList} - > - <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 />} - onClick={() => { - currPage++ - if (transformListToAsc) { - LoadMoreItens(Url('scores', '', `${currPage}`, 'ASC')) - } else { - LoadMoreItens(Url('scores', '', `${currPage}`, 'DESC')) - } - }} - > - { - isLoadingMoreItems ? <CircularProgress /> : 'Carregar mais itens' - } - </Button> - </StyledTableCell> - </StyledTableRow> + <TableData + top={topTable} + onIconPressed={cleanArrayAndInvert} + > + <TableBody> + {items.map((row, index) => ( + index === items.length - 1 ? + <StyledTableRow key={new Date().toISOString() + row.created_at}> + {/* Button to load more data */} + <StyledTableCell> + <Button + color='primary' + variant='text' + disabled={isLoadingMoreItems} + startIcon={<AddRoundedIcon />} + onClick={() => { + setCurrPage(currPage + 1) + }} + > + { + isLoadingMoreItems ? <CircularProgress /> : 'Carregar mais itens' + } + </Button> + </StyledTableCell> + </StyledTableRow> - : + : - <StyledTableRow key={index}> - <StyledTableCell component="th" scope="row">{row.id}</StyledTableCell> - <StyledTableCell align="right">{row.name}</StyledTableCell> - <StyledTableCell align="right">{row.code}</StyledTableCell> - <StyledTableCell align="right">{row.weight}</StyledTableCell> - <StyledTableCell align="right"> - { - row.active ? <CheckRoundedIcon style={{ fill: '#3CB371' }} /> : <BlockRoundedIcon style={{ fill: '#FA8072' }} /> - } - </StyledTableCell> - <StyledTableCell align="right"> - { - row['score_type'].map((item) => ( - <Typography key={item} style={{ fontSize: 14 }}> - {item} - </Typography> - )) - } - </StyledTableCell> - <StyledTableCell align="right"> - <Link to={`/admin/noteVar/${row.id}`}> - <IconButton onClick={() => { currPage = 0; transformListToAsc = false }}> - <VisibilityIcon style={{ fill: '#00bcd4' }} /> - </IconButton> - </Link> - </StyledTableCell> - </StyledTableRow> - ))} - </TableBody> - </TableData> - </div> - ) - } + <StyledTableRow key={new Date().toISOString() + index}> + <StyledTableCell component="th" scope="row">{row.id}</StyledTableCell> + <StyledTableCell align="right">{row.name}</StyledTableCell> + <StyledTableCell align="right">{row.code}</StyledTableCell> + <StyledTableCell align="right">{row.weight}</StyledTableCell> + <StyledTableCell align="right"> + { + row.active ? <CheckRoundedIcon style={{ fill: '#3CB371' }} /> : <BlockRoundedIcon style={{ fill: '#FA8072' }} /> + } + </StyledTableCell> + <StyledTableCell align="right"> + { + row['score_type'].map((item) => ( + <Typography key={item} style={{ fontSize: 14 }}> + {item} + </Typography> + )) + } + </StyledTableCell> + <StyledTableCell align="right"> + <Link to={`/admin/noteVar?id=${row.id}`}> + <IconButton> + <VisibilityIcon style={{ fill: '#00bcd4' }} /> + </IconButton> + </Link> + </StyledTableCell> + </StyledTableRow> + ))} + </TableBody> + </TableData> + </div> + ) } + } } diff --git a/src/Admin/Pages/Pages/SubPages/Permissions.js b/src/Admin/Pages/Pages/SubPages/Permissions.js index a630739ddad8d375b8255faff563043b878694bf..787ac0de2893aeaa4107d7c57d3ef43935fe78dd 100644 --- a/src/Admin/Pages/Pages/SubPages/Permissions.js +++ b/src/Admin/Pages/Pages/SubPages/Permissions.js @@ -25,479 +25,418 @@ import { Url } from '../../../Filters'; import LoadingSpinner from '../../../../Components/LoadingSpinner'; import { DeleteFilter } from '../../../Filters'; import { getRequest, deleteRequest } from '../../../../Components/HelperFunctions/getAxiosConfig' +import MobileList from "../../../Components/Components/MobileComponents/SimpleList" +import MobilePageHeader from "../../../Components/Components/MobileComponents/MobilePageHeader" +import PageHeader from "../../../Components/Components/PageHeader" //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 TableRow from '@material-ui/core/TableRow'; -import { Button, Typography, Paper, Grid } from '@material-ui/core'; +import { Button, Paper } 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 EditRoundedIcon from '@material-ui/icons/EditRounded'; import DeleteRoundedIcon from '@material-ui/icons/DeleteRounded'; //router -import { Link } from 'react-router-dom'; +import { Link, useHistory } from 'react-router-dom'; import styled from "styled-components" import AccountCircleRoundedIcon from "@material-ui/icons/AccountCircleRounded" -import MobileList from "../../../Components/Components/MobileComponents/SimpleList" - -let currPage = 0; -let transformListToAsc = false; const StyledTableCell = withStyles((theme) => ({ - head: { - backgroundColor: theme.palette.common.black, - color: theme.palette.common.white, - }, - body: { - fontSize: 14, - }, + 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, - }, + root: { + '&:nth-of-type(odd)': { + backgroundColor: theme.palette.action.hover, }, + }, }))(TableRow); const UserPermissions = () => { - const ADD_ONE_LENGHT = [""]; - const TOP_LABELS = ['ID', 'NOME', 'DESCRIÇÃO', 'AÇÕES'] //Labels from Table - const WINDOW_WIDTH = window.innerWidth - - 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 [openAlertDialog, setOpenAlertDialog] = useState(false); //controlls the state od alert dialog - - const [deleteItem, setDeleteItem] = useState({}); //Delete Item - const [isLoadingToDelete, setIsLoadingToDelete] = useState(null); - - const [snackInfo, setSnackInfo] = useState({ - message: '', - icon: '', - open: false, - color: '', + const ADD_ONE_LENGHT = [""]; + const TOP_LABELS = ['ID', 'NOME', 'DESCRIÇÃO', 'AÇÕES'] //Labels from Table + const WINDOW_WIDTH = window.innerWidth + + const router = useHistory() + + const [invertList, setInvertList] = useState(false) + 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 [currPage, setCurrPage] = useState(0) + const [isLoadingMoreItems, setIsLoadingMoreItems] = useState(false) //controlls the state of loadind more data + const [openAlertDialog, setOpenAlertDialog] = useState(false); //controlls the state od alert dialog + + const [deleteItem, setDeleteItem] = useState({}); //Delete Item + const [isLoadingToDelete, setIsLoadingToDelete] = useState(null); + + const [snackInfo, setSnackInfo] = useState({ + message: '', + icon: '', + open: false, + color: '', + }) + + //handle snack info + const HandleSnack = (message, state, icon, color) => { + setSnackInfo({ + message: message, + icon: icon, + open: state, + color: color }) - - //handle snack info - const HandleSnack = (message, state, icon, color) => { - setSnackInfo({ - message: message, - icon: icon, - open: state, - color: color - }) - } - - //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) - } - ) + } + + //handle Delete + async function DeleteHandler() { + const id = deleteItem.id; + HandleStateAlertDialog(null); + deleteRequest( + DeleteFilter("roles", id), + (data) => { + if (data.errors) + HandleSnack("Ocorreu algum erro", true, "warning", "#FA8072"); + else { + HandleSnack( + "A língua foi deletada com sucesso", + true, + "success", + "#228B22" + ); + setCurrPage(0) + HandleStateCircularProgress(null); + removeItemFromList(id) + } + }, + (error) => { + HandleSnack("Ocorreu algum erro", true, "warning", "#FA8072"); + HandleStateCircularProgress(null); + } + ) + } + + const removeItemFromList = (itemId) => { + let index = -1; + for (let i = 0; i < items.length; i++) { + const element = items[i]; + if (element.id === itemId) { + index = i + break + } } - - //handle Delete - async function DeleteHandler() { - const id = deleteItem.id; - HandleStateAlertDialog(null); - deleteRequest( - DeleteFilter("roles", id), - (data) => { - if (data.errors) - HandleSnack("Ocorreu algum erro", true, "warning", "#FA8072"); - else { - HandleSnack( - "A língua foi deletada com sucesso", - true, - "success", - "#228B22" - ); - currPage = 0; - transformListToAsc = false - UpdateHandler(Url("roles", "", `${currPage}`, "DESC")); - HandleStateCircularProgress(null); - } - }, - (error) => { - HandleSnack("Ocorreu algum erro", true, "warning", "#FA8072"); - HandleStateCircularProgress(null); - } - ) + if (index !== -1) { + const cpyItems = [...items] + cpyItems.splice(index, 1) + setItems(cpyItems) } - - const HandleStateCircularProgress = (i) => { - setIsLoadingToDelete(i); - }; - - const HandleStateAlertDialog = (i) => { - const obj = { ...items[i] }; - setDeleteItem(obj); - setOpenAlertDialog(!openAlertDialog); - }; - - const InvertList = async () => { - transformListToAsc = !transformListToAsc - currPage = 0 - if (transformListToAsc) { - getRequest( - Url('roles', '', `${currPage}`, 'ASC'), - (data, header) => { - const arrData = [...data] - setItems(arrData.concat(ADD_ONE_LENGHT)) - }, - (error) => { - HandleSnack('Erro ao carregar os dados', true, 'warning', '#FA8072') - } - ) + } + + const HandleStateCircularProgress = (i) => { + setIsLoadingToDelete(i); + }; + + const HandleStateAlertDialog = (i) => { + const obj = { ...items[i] }; + setDeleteItem(obj); + setOpenAlertDialog(!openAlertDialog); + }; + + const cleanArrayAndInvert = () => { + setInvertList(!invertList) + setCurrPage(0) + setItems([]) + } + + useEffect(() => { + if (currPage === 0) + setIsLoaded(false) + else + setIsLoadingMoreItems(true) + getRequest( + Url("roles", "", currPage, invertList ? "ASC" : "DESC"), + (data, header) => { + const arrData = [...data] + if (arrData.length === 0) { + HandleSnack('Não há mais dados para serem carregados', true, 'warning', '#FFC125') } else { - getRequest( - Url('roles', '', `${currPage}`, 'DESC'), - (data, header) => { - const arrData = [...data] - setItems(arrData.concat(ADD_ONE_LENGHT)) - }, - (error) => { - HandleSnack('Erro ao carregar os dados', true, 'warning', '#FA8072') - } - ) + const arrItems = [...items] + if (currPage === 0) { + setItems(arrData.concat(ADD_ONE_LENGHT)) + } + else { + 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)) + } } - } - - //getting data from server - useEffect(() => { - getRequest( - Url('roles', '', `${currPage}`, 'DESC'), - (data, header) => { - setIsLoaded(true); - setItems(data.concat(ADD_ONE_LENGHT)); - }, - (error) => { - setError(true); - } - ) - }, []); - - - if (error) { - return <div>Error: {error.message}</div>; - } else if (!isLoaded) { - return <LoadingSpinner text="Carregando..." /> - } else { - if (WINDOW_WIDTH <= 760) { - 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={12}> - <Typography variant="h4"> - Lista de permissões de usuário - </Typography> - </Grid> - <Grid - item - xs={12} - > - <Grid container justify="flex-start" spacing={3}> - <Grid item> - <Button - variant="contained" - color="secondary" - disabled={isUpdating} - onClick={() => { - currPage = 0 - transformListToAsc = false - UpdateHandler(Url('roles', '', `${currPage}`, 'DESC')) - }} - startIcon={<UpdateRoundedIcon />} - > - { - isUpdating ? <CircularProgress size={24} /> : 'Atualizar' - } - </Button> - </Grid> - <Grid item> - - <Link style={{ textDecoration: 'none' }} to={'/admin/CreateRole'}> - <Button - variant="contained" - color="secondary" - startIcon={<AddRoundedIcon />} - onClick={() => { currPage = 0 }} - > - Novo - </Button> - </Link> - </Grid> - </Grid> - </Grid> - </Grid> - </Paper> - - <div style={{ height: '2em' }}></div> - - {items.map((row, index) => - index === items.length - 1 ? ( - <StyledDivButton> - <Button - key={index} - color="primary" - variant="text" - // disabled={isLoadingMoreItems} - startIcon={<AddRoundedIcon />} - disabled={isLoadingMoreItems} - onClick={() => { - currPage++ - if (transformListToAsc) { - LoadMoreItens(Url('roles', '', `${currPage}`, 'ASC')) - } else { - LoadMoreItens(Url('roles', '', `${currPage}`, 'DESC')) - } - }} - > - {isLoadingMoreItems ? ( - <CircularProgress size={24} /> - ) : ( - "Carregar mais itens" - )} - </Button> - </StyledDivButton> - ) : ( - <> - <MobileList - key={index} - title={row.name} - subtitle={row.id} - backColor={"#ff7f00"} - avatar={<AccountCircleRoundedIcon />} - href={`/admin/EditPermissions/${row.id}`} - reset={() => { - currPage = 0; - }} - data={ - [ - { - title: "Descrição", - subtitle: row.description - - }, - ] - } - /> - <div style={{ height: "0.5em" }} /> - </> - ) + setIsLoaded(true) + setIsLoadingMoreItems(false) + }, + (error) => { + HandleSnack('Erro ao carregar os dados', true, 'warning', '#FA8072') + setIsLoadingMoreItems(false) + setIsLoaded(true) + setError(true) + } + ) + }, [currPage, invertList]) + + if (error) { + return <div>Error: {error.message}</div>; + } else if (!isLoaded) { + return <LoadingSpinner text="Carregando..." /> + } else { + if (WINDOW_WIDTH <= 800) { + return ( + <> + <SnackBar + severity={snackInfo.icon} + text={snackInfo.message} + snackbarOpen={snackInfo.open} + color={snackInfo.color} + handleClose={() => setSnackInfo({ + message: '', + icon: '', + open: false, + color: '' + })} + /> + <AlertDialog + open={openAlertDialog} + OnDelete={DeleteHandler} + deleteItem={deleteItem} + HandleClose={() => { + setOpenAlertDialog(false); + HandleStateCircularProgress(null); + }} + /> + <MobilePageHeader + title="Lista de permissões de usuário" + actions={[ + { + name: "Atualizar", + isLoading: false, + func: () => { + setCurrPage(0) + }, + icon: <UpdateRoundedIcon /> + }, + { + name: "Novo", + isLoading: false, + func: () => { + router.push('/admin/CreateRole') + }, + icon: <AddRoundedIcon /> + }, + { + name: "Inverter lista", + isLoading: false, + func: () => { + cleanArrayAndInvert() + }, + } + ]} + > + </MobilePageHeader> + + <div style={{ height: '2em' }}></div> + + {items.map((row, index) => + index === items.length - 1 ? ( + <StyledDivButton key={new Date().toISOString() + row.created_at}> + <Button + color="primary" + variant="text" + // disabled={isLoadingMoreItems} + startIcon={<AddRoundedIcon />} + disabled={isLoadingMoreItems} + onClick={() => { + setCurrPage(currPage + 1) + }} + > + {isLoadingMoreItems ? ( + <CircularProgress size={24} /> + ) : ( + "Carregar mais itens" )} - </> - ); - } - else { - return ( + </Button> + </StyledDivButton> + ) : ( <> - <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 permissões de usuário - </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 - transformListToAsc = false - UpdateHandler(Url('roles', '', `${currPage}`, 'DESC')) - }} - startIcon={<UpdateRoundedIcon />} - > - { - isUpdating ? <CircularProgress size={24} /> : 'Atualizar' - } - </Button> - </Grid> - <Grid item> - - <Link style={{ textDecoration: 'none' }} to={'/admin/CreateRole'}> - <Button - variant="contained" - color="secondary" - startIcon={<AddRoundedIcon />} - onClick={() => { currPage = 0 }} - > - Novo - </Button> - </Link> - </Grid> - </Grid> - </Grid> - </Grid> - </Paper> - - <div style={{ height: '2em' }}></div> - - <TableData - top={TOP_LABELS} - onIconPressed={InvertList} - > - <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++ - if (transformListToAsc) { - LoadMoreItens(Url('roles', '', `${currPage}`, 'ASC')) - } else { - LoadMoreItens(Url('roles', '', `${currPage}`, 'DESC')) - } - }} - > - { - isLoadingMoreItems ? <CircularProgress size={24} /> : 'Carregar mais itens' - } - </Button> - </StyledTableCell> - </StyledTableRow> - - : - - <StyledTableRow key={index}> - <StyledTableCell component="th" scope="row">{row.id}</StyledTableCell> - <StyledTableCell align="right">{row.name}</StyledTableCell> - <StyledTableCell align="right">{row.description}</StyledTableCell> - <StyledTableCell align="right"> - <Link to={`/admin/EditPermissions/${row.id}`}> - <Button - style={{ width: "100%", marginBottom: "0.5em" }} - variant="contained" - color="primary" - onClick={() => { currPage = 0 }} - startIcon={<EditRoundedIcon />} - > - Editar - </Button> - </Link> - - {isLoadingToDelete === index ? ( - <CircularProgress size={24} color="primary" /> - ) : ( - <Button - style={{ width: "100%" }} - variant="contained" - color="secondary" - onClick={() => { - HandleStateAlertDialog(index) - HandleStateCircularProgress(index) - }} - startIcon={<DeleteRoundedIcon />} - > - Deletar + <MobileList + key={new Date().toISOString() + row.created_at} + title={row.name} + subtitle={row.id} + backColor={"#ff7f00"} + avatar={<AccountCircleRoundedIcon />} + href={`/admin/EditPermissions?role=${row.id}`} + reset={() => { + }} + data={ + [ + { + title: "Descrição", + subtitle: row.description + + }, + { + title: "Ações", + subtitle: <Button + variant="contained" + color="secondary" + onClick={() => { + HandleStateAlertDialog(index) + HandleStateCircularProgress(index) + }} + startIcon={<DeleteRoundedIcon />} + > + Deletar </Button> - )} - - </StyledTableCell> - </StyledTableRow> - ))} - </TableBody> - </TableData> - - {/* This alert will be displayed if the user click to delete an institution */} - <AlertDialog - open={openAlertDialog} - OnDelete={DeleteHandler} - deleteItem={deleteItem} - HandleClose={() => { - setOpenAlertDialog(false); - HandleStateCircularProgress(null); - }} - /> + }, + ] + } + /> + <div style={{ height: "0.5em" }} /> </> - ); - } + ) + )} + </> + ); + } + else { + return ( + <> + <SnackBar + severity={snackInfo.icon} + text={snackInfo.message} + snackbarOpen={snackInfo.open} + color={snackInfo.color} + handleClose={() => setSnackInfo({ + message: '', + icon: '', + open: false, + color: '' + })} + /> + + <PageHeader + title="Lista de permissões de usuário" + actions={[ + { + name: "Atualizar", + isLoading: false, + func: () => { + setCurrPage(0) + }, + icon: <UpdateRoundedIcon /> + }, + { + name: "Novo", + isLoading: false, + func: () => { + router.push('/admin/CreateRole') + }, + icon: <AddRoundedIcon /> + } + ]} + > + </PageHeader> + + <div style={{ height: '2em' }}></div> + + <TableData + top={TOP_LABELS} + onIconPressed={cleanArrayAndInvert} + > + <TableBody> + {items.map((row, index) => ( + index === items.length - 1 ? + <StyledTableRow key={new Date().toISOString() + row.created_at}> + {/* Button to load more data */} + <StyledTableCell> + <Button + color='primary' + variant='text' + // disabled={isLoadingMoreItems} + startIcon={<AddRoundedIcon />} + disabled={isLoadingMoreItems} + onClick={() => { + setCurrPage(currPage + 1) + }} + > + { + isLoadingMoreItems ? <CircularProgress size={24} /> : 'Carregar mais itens' + } + </Button> + </StyledTableCell> + </StyledTableRow> + + : + + <StyledTableRow key={new Date().toISOString() + index}> + <StyledTableCell component="th" scope="row">{row.id}</StyledTableCell> + <StyledTableCell align="right">{row.name}</StyledTableCell> + <StyledTableCell align="right">{row.description}</StyledTableCell> + <StyledTableCell align="right"> + <Link to={`/admin/EditPermissions?role=${row.id}`}> + <Button + style={{ width: "100%", marginBottom: "0.5em" }} + variant="contained" + color="primary" + startIcon={<EditRoundedIcon />} + > + Editar + </Button> + </Link> + + {isLoadingToDelete === index ? ( + <CircularProgress size={24} color="primary" /> + ) : ( + <Button + style={{ width: "100%" }} + variant="contained" + color="secondary" + onClick={() => { + HandleStateAlertDialog(index) + HandleStateCircularProgress(index) + }} + startIcon={<DeleteRoundedIcon />} + > + Deletar + </Button> + )} + + </StyledTableCell> + </StyledTableRow> + ))} + </TableBody> + </TableData> + + {/* This alert will be displayed if the user click to delete an institution */} + <AlertDialog + open={openAlertDialog} + OnDelete={DeleteHandler} + deleteItem={deleteItem} + HandleClose={() => { + setOpenAlertDialog(false); + HandleStateCircularProgress(null); + }} + /> + </> + ); } + } } export default UserPermissions; diff --git a/src/Admin/Pages/Pages/SubPages/Questions.js b/src/Admin/Pages/Pages/SubPages/Questions.js index 8118ec31d8bc7667baeffd9b349337efa591e5b3..ca32e0cd11a506134b40c2801dde53209d615cb2 100644 --- a/src/Admin/Pages/Pages/SubPages/Questions.js +++ b/src/Admin/Pages/Pages/SubPages/Questions.js @@ -16,553 +16,413 @@ 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 React, { useEffect, useState } from 'react' import moment from 'moment'; //imports from local files import TableData from '../../../Components/Components/Table'; import SnackBar from '../../../../Components/SnackbarComponent'; -import Unauthorized from '../../../Components/Components/Unauthorized'; import { Url, EditFilter } from '../../../Filters'; -import { Store } from '../../../../Store'; import LoadingSpinner from '../../../../Components/LoadingSpinner'; import { getRequest, putRequest } from '../../../../Components/HelperFunctions/getAxiosConfig' +import MobileList from "../../../Components/Components/MobileComponents/SimpleList" +import MobilePageHeader from "../../../Components/Components/MobileComponents/MobilePageHeader" +import PageHeader from "../../../Components/Components/PageHeader" //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 TableRow from '@material-ui/core/TableRow'; -import { Button, Typography, Paper, Grid } from '@material-ui/core'; +import { Button, Paper } 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 CheckCircleRoundedIcon from '@material-ui/icons/CheckCircleRounded'; -import CancelRoundedIcon from '@material-ui/icons/CancelRounded'; import Switch from '@material-ui/core/Switch'; //router -import { Link } from 'react-router-dom'; +import { useHistory } from 'react-router-dom'; import styled from "styled-components" -import MobileList from "../../../Components/Components/MobileComponents/SimpleList" import HelpRoundedIcon from "@material-ui/icons/HelpRounded"; -let currPage = 0; -let transformListToAsc = false; - const StyledTableCell = withStyles((theme) => ({ - head: { - backgroundColor: theme.palette.common.black, - color: theme.palette.common.white, - }, - body: { - fontSize: 14, - }, + 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, - }, + root: { + '&:nth-of-type(odd)': { + backgroundColor: theme.palette.action.hover, }, + }, }))(TableRow); const Questions = () => { - const { state } = useContext(Store); - - const ADD_ONE_LENGHT = [""]; - const WINDOW_WIDTH = window.innerWidth - const TOP_LABELS = ['ID', 'CRIAÇÃO EM', 'DESCRIÇÃO', 'STATUS', 'ATUALIZAÇÃO EM'] //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 [snackInfo, setSnackInfo] = useState({ - message: '', - icon: '', - open: false, - color: '', + const ADD_ONE_LENGHT = [""]; + const WINDOW_WIDTH = window.innerWidth + const TOP_LABELS = ['ID', 'CRIAÇÃO EM', 'DESCRIÇÃO', 'STATUS', 'ATUALIZAÇÃO EM'] //Labels from Table + const router = useHistory() + + const [invertList, setInvertList] = useState(false) + 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 [currPage, setCurrPage] = useState(0) + const [isLoadingMoreItems, setIsLoadingMoreItems] = useState(false) //controlls the state of loadind more data + + const [snackInfo, setSnackInfo] = useState({ + message: '', + icon: '', + open: false, + color: '', + }) + + //handle snack info + const HandleSnack = (message, state, icon, color) => { + setSnackInfo({ + message: message, + icon: icon, + open: state, + color: color }) - - //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') - canUserEdit = true; + } + + const changeStateItem = (index, currState) => { + const copyItems = [...items] + copyItems[index].status = currState + setItems(copyItems) + } + + const handleChange = async (index, status) => { + const id = items[index].id; + const description = items[index].description; + if (status === 'active') { + const body = { + "question": { + "description": description, + "status": "inactive" } - else { - canUserEdit = false; + } + putRequest( + EditFilter('questions', id), + body, + (data) => { + if (data.errors) + HandleSnack('Erro ao carregar os dados', true, 'warning', '#FA8072') + else { + HandleSnack('Question modificada com sucesso', true, 'success', '#228B22') + changeStateItem(index, "inactive") + setCurrPage(0) + } + }, + (error) => { + HandleSnack('Erro ao carregar os dados', true, 'warning', '#FA8072') } - - 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) - } - ) + ) + } else { + const body = { + "question": { + "description": description, + "status": "active" + } + } + putRequest( + EditFilter('questions', id), + body, + (data) => { + if (data.errors) + HandleSnack('Erro ao carregar os dados', true, 'warning', '#FA8072') + else { + setCurrPage(0) + HandleSnack('Question modificada com sucesso', true, 'success', '#228B22') + changeStateItem(index, "active") + } + }, + (error) => { + HandleSnack('Erro ao carregar os dados', true, 'warning', '#FA8072') + } + ) } - - const InvertList = async () => { - transformListToAsc = !transformListToAsc - currPage = 0 - if (transformListToAsc) { - getRequest( - Url('questions', '', `${currPage}`, 'ASC'), - (data, header) => { - const arrData = [...data] - setItems(arrData.concat(ADD_ONE_LENGHT)) - }, - () => { - HandleSnack('Erro ao carregar os dados', true, 'warning', '#FA8072') - } - ) + } + + const DisplayDate = (date) => { + const convertedData = moment.utc(date); + return moment(convertedData) + .format("LLL") + .toString(); + }; + + const cleanArrayAndInvert = () => { + setInvertList(!invertList) + setCurrPage(0) + setItems([]) + } + + useEffect(() => { + if (currPage === 0) + setIsLoaded(false) + else + setIsLoadingMoreItems(true) + getRequest( + Url("questions", "", currPage, invertList ? "ASC" : "DESC"), + (data, header) => { + const arrData = [...data] + if (arrData.length === 0) { + HandleSnack('Não há mais dados para serem carregados', true, 'warning', '#FFC125') } else { - getRequest( - Url('questions', '', `${currPage}`, 'DESC'), - (data, header) => { - const arrData = [...data] - setItems(arrData.concat(ADD_ONE_LENGHT)) - }, - (error) => { - HandleSnack('Erro ao carregar os dados', true, 'warning', '#FA8072') - } - ) + const arrItems = [...items] + if (currPage === 0) { + setItems(arrData.concat(ADD_ONE_LENGHT)) + } + else { + 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)) + } } - } - - const handleChange = async (index, status) => { - const id = items[index].id; - const description = items[index].description; - if (status === 'active') { - const body = { - "question": { - "description": description, - "status": "inactive" - } - } - putRequest( - EditFilter('questions', id), - body, - (data) => { - if (data.errors) - HandleSnack('Erro ao carregar os dados', true, 'warning', '#FA8072') - else { - currPage = 0 - transformListToAsc = false - UpdateHandler(Url('questions', '', `${currPage}`, 'DESC')) - } + setIsLoaded(true) + setIsLoadingMoreItems(false) + }, + (error) => { + HandleSnack('Erro ao carregar os dados', true, 'warning', '#FA8072') + setIsLoadingMoreItems(false) + setIsLoaded(true) + setError(true) + } + ) + }, [currPage, invertList]) + + + if (error) { + return <div>Error: {error.message}</div>; + } else if (!isLoaded) { + return <LoadingSpinner text="Carregando..." /> + } else { + if (WINDOW_WIDTH <= 800) { + return ( + <> + <SnackBar + severity={snackInfo.icon} + text={snackInfo.message} + snackbarOpen={snackInfo.open} + color={snackInfo.color} + handleClose={() => setSnackInfo({ + message: '', + icon: '', + open: false, + color: '' + })} + /> + + <MobilePageHeader + title="Perguntas da curadoria" + actions={[ + { + name: "Atualizar", + isLoading: false, + func: () => { + setCurrPage(0) }, - (error) => { - HandleSnack('Erro ao carregar os dados', true, 'warning', '#FA8072') - } - ) - } else { - const body = { - "question": { - "description": description, - "status": "active" - } - } - putRequest( - EditFilter('questions', id), - body, - (data) => { - if (data.errors) - HandleSnack('Erro ao carregar os dados', true, 'warning', '#FA8072') - else { - currPage = 0 - transformListToAsc = false - UpdateHandler(Url('questions', '', `${currPage}`, 'DESC')) - } + icon: <UpdateRoundedIcon /> + }, + { + name: "Novo", + isLoading: false, + func: () => { + router.push('/admin/CreateQuestion') }, - (error) => { - HandleSnack('Erro ao carregar os dados', true, 'warning', '#FA8072') - } - ) - } - } - - const DisplayDate = (date) => { - const convertedData = moment.utc(date); - return moment(convertedData) - .format("LLL") - .toString(); - }; - - //getting data from server - useEffect(() => { - getRequest( - Url('questions', '', `${currPage}`, 'DESC'), - (data, header) => { - setIsLoaded(true); - setItems(data.concat(ADD_ONE_LENGHT)); - }, - (error) => { - setError(true) - } - ) - }, []); - - - if (error) { - return <div>Error: {error.message}</div>; - } else if (!isLoaded) { - return <LoadingSpinner text="Carregando..." /> - } else if (CheckUserPermission()) { - if (WINDOW_WIDTH <= 761) { - 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={12}> - <Typography variant="h4"> - Perguntas da curadoria - </Typography> - </Grid> - <Grid - item - xs={12} - > - <Grid container justify="flex-start" spacing={3}> - <Grid item> - <Button - variant="contained" - color="secondary" - disabled={isUpdating} - onClick={() => { - currPage = 0 - transformListToAsc = false - UpdateHandler(Url('questions', '', `${currPage}`, 'DESC')) - }} - startIcon={<UpdateRoundedIcon />} - > - { - isUpdating ? <CircularProgress size={24} /> : 'Atualizar' - } - </Button> - </Grid> - <Grid item> - - <Link style={{ textDecoration: 'none' }} to={'/admin/CreateQuestion'}> - <Button - variant="contained" - color="secondary" - startIcon={<AddRoundedIcon />} - onClick={() => { currPage = 0 }} - > - Novo - </Button> - </Link> - </Grid> - </Grid> - </Grid> - </Grid> - </Paper> - - <div style={{ height: '2em' }}></div> - - {items.map((row, index) => - index === items.length - 1 ? ( - <StyledDivButton> - <Button - key={index} - color="primary" - variant="text" - // disabled={isLoadingMoreItems} - startIcon={<AddRoundedIcon />} - disabled={isLoadingMoreItems} - onClick={() => { - currPage++ - if (transformListToAsc) { - LoadMoreItens(Url('questions', '', `${currPage}`, 'ASC')) - } else { - LoadMoreItens(Url('questions', '', `${currPage}`, 'DESC')) - } - }} - > - {isLoadingMoreItems ? ( - <CircularProgress size={24} /> - ) : ( - "Carregar mais itens" - )} - </Button> - </StyledDivButton> - ) : ( - <> - <MobileList - key={index} - title={row.id} - subtitle={DisplayDate(row.created_at)} - backColor={"#673ab7"} - avatar={<HelpRoundedIcon />} - reset={() => { - currPage = 0; transformListToAsc = false - }} - data={ - [ - { - title: "Descrição", - subtitle: row.description - }, - { - title: "Status", - subtitle: - row.status === 'active' ? - <Grid container direction='row'> - <Grid item> - <CheckCircleRoundedIcon style={{ fill: '#3CB371' }} /> - - <Switch - checked={true} - onChange={() => handleChange(index, row.status)} - name="checkedB" - color="primary" - /> - </Grid> - </Grid> - - : - - <Grid container justify='flex-end' alignItems='center' direction='row'> - <Grid item> - <CancelRoundedIcon style={{ fill: '#FA8072' }} /> - </Grid> - - <Grid item> - <Switch - checked={false} - onChange={() => handleChange(index, row.status)} - name="checkedB" - color="primary" - /> - </Grid> - </Grid> - }, - { - title : "Atualizado em", - subtitle : DisplayDate(row.updated_at) - } - ] - } - /> - <div style={{ height: "0.5em" }} /> - </> - ) + icon: <AddRoundedIcon /> + }, + { + name: "Inverter lista", + isLoading: false, + func: () => { + cleanArrayAndInvert() + }, + }, + ]} + > + </MobilePageHeader> + + <div style={{ height: '2em' }}></div> + + {items.map((row, index) => + index === items.length - 1 ? ( + <StyledDivButton + key={new Date().toISOString() + row.created_at} + > + <Button + color="primary" + variant="text" + // disabled={isLoadingMoreItems} + startIcon={<AddRoundedIcon />} + disabled={isLoadingMoreItems} + onClick={() => { + setCurrPage(currPage + 1) + }} + > + {isLoadingMoreItems ? ( + <CircularProgress size={24} /> + ) : ( + "Carregar mais itens" )} - </> - ); - } - else { - return ( + </Button> + </StyledDivButton> + ) : ( <> - <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"> - Perguntas da curadoria - </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 - transformListToAsc = false - UpdateHandler(Url('questions', '', `${currPage}`, 'DESC')) - }} - startIcon={<UpdateRoundedIcon />} - > - { - isUpdating ? <CircularProgress size={24} /> : 'Atualizar' - } - </Button> - </Grid> - <Grid item> - - <Link style={{ textDecoration: 'none' }} to={'/admin/CreateQuestion'}> - <Button - variant="contained" - color="secondary" - startIcon={<AddRoundedIcon />} - onClick={() => { currPage = 0; transformListToAsc = false }} - > - Novo - </Button> - </Link> - </Grid> - </Grid> - </Grid> - </Grid> - </Paper> - - <div style={{ height: '2em' }}></div> - - <TableData - top={TOP_LABELS} - onIconPressed={InvertList} - > - <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++ - if (transformListToAsc) { - LoadMoreItens(Url('questions', '', `${currPage}`, 'ASC')) - } else { - LoadMoreItens(Url('questions', '', `${currPage}`, 'DESC')) - } - }} - > - { - isLoadingMoreItems ? <CircularProgress size={24} /> : 'Carregar mais itens' - } - </Button> - </StyledTableCell> - </StyledTableRow> - - : - - <StyledTableRow key={index}> - <StyledTableCell component="th" scope="row">{row.id}</StyledTableCell> - <StyledTableCell align="right">{DisplayDate(row.created_at)}</StyledTableCell> - <StyledTableCell align="right">{row.description}</StyledTableCell> - <StyledTableCell align="right"> - { - row.status === 'active' ? - <Grid container direction='row'> - <Grid item> - <CheckCircleRoundedIcon style={{ fill: '#3CB371' }} /> - - <Switch - checked={true} - onChange={() => handleChange(index, row.status)} - name="checkedB" - color="primary" - /> - </Grid> - </Grid> - - : - - <Grid container justify='flex-end' alignItems='center' direction='row'> - <Grid item> - <CancelRoundedIcon style={{ fill: '#FA8072' }} /> - </Grid> - - <Grid item> - <Switch - checked={false} - onChange={() => handleChange(index, row.status)} - name="checkedB" - color="primary" - /> - </Grid> - </Grid> - } - </StyledTableCell> - <StyledTableCell align="right">{DisplayDate(row.updated_at)}</StyledTableCell> - </StyledTableRow> - ))} - </TableBody> - </TableData> + <MobileList + key={new Date().toISOString() + row.created_at} + title={row.id} + subtitle={DisplayDate(row.created_at)} + backColor={"#673ab7"} + avatar={<HelpRoundedIcon />} + reset={() => { + }} + data={ + [ + { + title: "Descrição", + subtitle: row.description + }, + { + title: "Status", + subtitle: + row.status === 'active' ? + <Switch + checked={true} + onChange={() => handleChange(index, row.status)} + name="checkedB" + color="primary" + /> + : + + <Switch + checked={false} + onChange={() => handleChange(index, row.status)} + name="checkedB" + color="primary" + /> + }, + { + title: "Atualizado em", + subtitle: DisplayDate(row.updated_at) + } + ] + } + /> + <div style={{ height: "0.5em" }} /> </> - ); - } - } else return <Unauthorized /> + ) + )} + </> + ); + } + else { + return ( + <> + <SnackBar + severity={snackInfo.icon} + text={snackInfo.message} + snackbarOpen={snackInfo.open} + color={snackInfo.color} + handleClose={() => setSnackInfo({ + message: '', + icon: '', + open: false, + color: '' + })} + /> + + <PageHeader + title="Perguntas da curadoria" + actions={[ + { + name: "Atualizar", + isLoading: false, + func: () => { + setCurrPage(0) + }, + icon: <UpdateRoundedIcon /> + }, + { + name: "Novo", + isLoading: false, + func: () => { + router.push('/admin/CreateQuestion') + }, + icon: <AddRoundedIcon /> + } + ]} + > + </PageHeader> + + <div style={{ height: '2em' }}></div> + + <TableData + top={TOP_LABELS} + onIconPressed={cleanArrayAndInvert} + > + <TableBody> + {items.map((row, index) => ( + index === items.length - 1 ? + <StyledTableRow key={new Date().toISOString() + row.created_at}> + {/* Button to load more data */} + <StyledTableCell> + <Button + color='primary' + variant='text' + // disabled={isLoadingMoreItems} + startIcon={<AddRoundedIcon />} + disabled={isLoadingMoreItems} + onClick={() => { + setCurrPage(currPage + 1) + }} + > + { + isLoadingMoreItems ? <CircularProgress size={24} /> : 'Carregar mais itens' + } + </Button> + </StyledTableCell> + </StyledTableRow> + + : + + <StyledTableRow key={new Date().toISOString() + index}> + <StyledTableCell component="th" scope="row">{row.id}</StyledTableCell> + <StyledTableCell align="right">{DisplayDate(row.created_at)}</StyledTableCell> + <StyledTableCell align="right">{row.description}</StyledTableCell> + <StyledTableCell align="right"> + { + row.status === 'active' ? + <Switch + checked={true} + onChange={() => handleChange(index, row.status)} + name="checkedB" + color="primary" + /> + : + + <Switch + checked={false} + onChange={() => handleChange(index, row.status)} + name="checkedB" + color="primary" + /> + } + </StyledTableCell> + <StyledTableCell align="right">{DisplayDate(row.updated_at)}</StyledTableCell> + </StyledTableRow> + ))} + </TableBody> + </TableData> + </> + ); + } + } } export default Questions; diff --git a/src/Admin/Pages/Pages/SubPages/Rating.js b/src/Admin/Pages/Pages/SubPages/Rating.js index 547e140ddf41a9b427bc7fabe894d71bac16be5e..22d57d409dfe56f9b649f36c9ad4b67d10cd923c 100644 --- a/src/Admin/Pages/Pages/SubPages/Rating.js +++ b/src/Admin/Pages/Pages/SubPages/Rating.js @@ -20,476 +20,410 @@ import React, { useEffect, useState } from 'react'; //Material ui componets import { withStyles } from '@material-ui/core/styles'; import TableBody from '@material-ui/core/TableBody'; -import Grid from "@material-ui/core/Grid"; import Paper from "@material-ui/core/Paper"; import TableCell from '@material-ui/core/TableCell'; import TableRow from '@material-ui/core/TableRow'; import IconButton from '@material-ui/core/IconButton'; import VisibilityIcon from '@material-ui/icons/Visibility'; -import { Button, Typography } from '@material-ui/core'; +import { Button } 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 DeleteRoundedIcon from '@material-ui/icons/DeleteRounded'; -//Local files +//Local files' import TableData from '../../../Components/Components/Table'; import SnackBar from '../../../../Components/SnackbarComponent'; import LoadingSpinner from '../../../../Components/LoadingSpinner'; +import MobileList from "../../../Components/Components/MobileComponents/SimpleList" +import MobilePageHeader from "../../../Components/Components/MobileComponents/MobilePageHeader" +import PageHeader from "../../../Components/Components/PageHeader" //Services import AlertDialog from "../../../Components/Components/AlertDialog"; import { Url } from '../../../Filters'; import { DeleteFilter } from '../../../Filters'; import { getRequest, deleteRequest } from '../../../../Components/HelperFunctions/getAxiosConfig' //routers -import { Link } from 'react-router-dom'; +import { Link, useHistory } from 'react-router-dom'; import StarRoundedIcon from "@material-ui/icons/StarRounded"; import styled from "styled-components" -import MobileList from "../../../Components/Components/MobileComponents/SimpleList" - -let currPage = 0; //var that controlls the current page that we are -let transformListToAsc = false; const StyledTableCell = withStyles((theme) => ({ - head: { - backgroundColor: theme.palette.common.black, - color: theme.palette.common.white, - }, - body: { - fontSize: 14, - }, + 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, - }, + root: { + '&:nth-of-type(odd)': { + backgroundColor: theme.palette.action.hover, }, + }, }))(TableRow); const Ratings = () => { - const WINDOW_WIDTH = window.innerWidth - const AddOneLenght = ['']; - 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) - const [isUpdating, setIsUpdating] = useState(false) - - const [openAlertDialog, setOpenAlertDialog] = useState(false); //controlls the state od alert dialog - const [deleteItem, setDeleteItem] = useState({}); //Delete Item - const [isLoadingToDelete, setIsLoadingToDelete] = useState(null); - - const [snackInfo, setSnackInfo] = useState({ - message: '', - icon: '', - open: false, - color: '', + const WINDOW_WIDTH = window.innerWidth + const ADD_ONE_LENGHT = [""]; + + const router = useHistory() + + const [invertList, setInvertList] = useState(false) + 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) + const [currPage, setCurrPage] = useState(0) + const [openAlertDialog, setOpenAlertDialog] = useState(false); //controlls the state od alert dialog + const [deleteItem, setDeleteItem] = useState({}); //Delete Item + const [isLoadingToDelete, setIsLoadingToDelete] = useState(null); + + const [snackInfo, setSnackInfo] = useState({ + message: '', + icon: '', + open: false, + color: '', + }) + + // Handle snack infos + const HandleSnack = (message, state, icon, color) => { + setSnackInfo({ + message: message, + icon: icon, + open: state, + color: color }) - - // Handle snack infos - const HandleSnack = (message, state, icon, color) => { - setSnackInfo({ - message: message, - icon: icon, - open: state, - color: color - }) + } + + //handle Delete + async function DeleteHandler() { + const id = deleteItem.id; + HandleStateAlertDialog(null); + deleteRequest( + DeleteFilter("ratings", id), + (data) => { + if (data.errors) + HandleSnack("Ocorreu algum erro", true, "warning", "#FA8072"); + else { + HandleSnack( + "O rating foi deletada com sucesso", + true, + "success", + "#228B22" + ); + setCurrPage(0) + HandleStateCircularProgress(null); + removeItemFromList(id) + } + }, + (error) => { + HandleSnack("Ocorreu algum erro", true, "warning", "#FA8072"); + HandleStateCircularProgress(null); + } + ) + } + + const removeItemFromList = (itemId) => { + let index = -1; + for (let i = 0; i < items.length; i++) { + const element = items[i]; + if (element.id === itemId) { + index = i + break + } } - - 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(AddOneLenght)) - } - setIsLoadingMoreItems(false) - }, - (error) => { - HandleSnack('Erro ao carregar os dados', true, 'warning', '#FA8072') - setIsLoadingMoreItems(false) - } - ) + if (index !== -1) { + const cpyItems = [...items] + cpyItems.splice(index, 1) + setItems(cpyItems) } - - const InvertList = async () => { - transformListToAsc = !transformListToAsc - currPage = 0 - if (transformListToAsc) { - getRequest( - Url('ratings', '', `${currPage}`, 'ASC'), - (data, header) => { - const arrData = [...data] - setItems(arrData.concat(AddOneLenght)) - }, - (error) => { - HandleSnack('Erro ao carregar os dados', true, 'warning', '#FA8072') - } - ) + } + + const HandleStateCircularProgress = (i) => { + setIsLoadingToDelete(i); + }; + + const HandleStateAlertDialog = (i) => { + const obj = { ...items[i] }; + setDeleteItem(obj); + setOpenAlertDialog(!openAlertDialog); + }; + + const cleanArrayAndInvert = () => { + setInvertList(!invertList) + setCurrPage(0) + setItems([]) + } + + useEffect(() => { + if (currPage === 0) + setIsLoaded(false) + else + setIsLoadingMoreItems(true) + getRequest( + Url("ratings", "", currPage, invertList ? "ASC" : "DESC"), + (data, header) => { + const arrData = [...data] + if (arrData.length === 0) { + HandleSnack('Não há mais dados para serem carregados', true, 'warning', '#FFC125') } else { - getRequest( - Url('ratings', '', `${currPage}`, 'DESC'), - (data, header) => { - const arrData = [...data] - setItems(arrData.concat(AddOneLenght)) - }, - (error) => { - HandleSnack('Erro ao carregar os dados', true, 'warning', '#FA8072') - } - ) + const arrItems = [...items] + if (currPage === 0) { + setItems(arrData.concat(ADD_ONE_LENGHT)) + } + else { + 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)) + } } - } - - 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(AddOneLenght)) - setIsUpdating(false) - }, - (error) => { - HandleSnack('Erro ao carregar os dados', true, 'warning', '#FA8072') - setIsUpdating(false) - } - ) - } - - //handle Delete - async function DeleteHandler() { - const id = deleteItem.id; - HandleStateAlertDialog(null); - deleteRequest( - DeleteFilter("ratings", id), - (data) => { - if (data.errors) - HandleSnack("Ocorreu algum erro", true, "warning", "#FA8072"); - else { - HandleSnack( - "O rating foi deletada com sucesso", - true, - "success", - "#228B22" - ); - currPage = 0; - transformListToAsc = false - UpdateHandler(Url("ratings", "", `${currPage}`, "DESC")); - HandleStateCircularProgress(null); - } - }, - (error) => { - HandleSnack("Ocorreu algum erro", true, "warning", "#FA8072"); - HandleStateCircularProgress(null); - } - ) - } - - const HandleStateCircularProgress = (i) => { - setIsLoadingToDelete(i); - }; - - const HandleStateAlertDialog = (i) => { - const obj = { ...items[i] }; - setDeleteItem(obj); - setOpenAlertDialog(!openAlertDialog); - }; - - - useEffect(() => { - getRequest( - Url('ratings', '', currPage, 'DESC'), - (data, header) => { - setIsLoaded(true); - setItems(data.concat(AddOneLenght)); - }, - (error) => { - setError(true) - } - ) - }, []); - - - if (error) { - return <div>Error: {error.message}</div>; - } else if (!isLoaded) { - return <LoadingSpinner text="Carregando..." /> - } else { - - //Words in the top part of the table - const topTable = ['ID', 'NOME', 'DESCRIÇÃO', 'VISUALIZAR', 'DELETAR']; - if (WINDOW_WIDTH <= 760) { - return ( - <div> - <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={12}> - <Typography variant="h4"> - Lista de ratings - </Typography> - </Grid> - <Grid - item - xs={12} - > - <Grid container justify="flex-start" spacing={3}> - <Grid item> - <Button - variant="contained" - color="secondary" - disabled={isUpdating} - onClick={() => { - currPage = 0 - transformListToAsc = false - UpdateHandler(Url('ratings', '', `${currPage}`, 'DESC')) - }} - startIcon={<UpdateRoundedIcon />} - > - { - isUpdating ? <CircularProgress size={24} /> : 'Atualizar' - } - </Button> - </Grid> - <Grid item> - <Link style={{ textDecoration: 'none' }} to={'/admin/CreateRating'}> - <Button - variant="contained" - color="secondary" - startIcon={<AddRoundedIcon style={{ fill: "white" }} />} - onClick={() => { - currPage = 0 - transformListToAsc = false - }} - > - Novo - </Button> - </Link> - </Grid> - </Grid> - </Grid> - </Grid> - </Paper> - - <div style={{ height: '2em' }}></div> - - {items.map((row, index) => - index === items.length - 1 ? ( - <StyledDivButton> - <Button - key={index} - color="primary" - variant="text" - // disabled={isLoadingMoreItems} - startIcon={<AddRoundedIcon />} - disabled={isLoadingMoreItems} - onClick={() => { - currPage++ - if (transformListToAsc) { - LoadMoreItens(Url('ratings', '', `${currPage}`, 'ASC')) - } else { - LoadMoreItens(Url('ratings', '', `${currPage}`, 'DESC')) - } - }} - > - {isLoadingMoreItems ? ( - <CircularProgress size={24} /> - ) : ( - "Carregar mais itens" - )} - </Button> - </StyledDivButton> - ) : ( - <> - <MobileList - key={index} - title={row.name} - subtitle={row.id} - backColor={"#00bcd4"} - avatar={<StarRoundedIcon />} - href={`/admin/Rating/${row.id}`} - reset={() => { - currPage = 0; - }} - data={ - [ - { - title: "Descrição", - subtitle: row.description - } - ] - } - /> - <div style={{ height: "0.5em" }} /> - </> - ) + setIsLoaded(true) + setIsLoadingMoreItems(false) + }, + (error) => { + HandleSnack('Erro ao carregar os dados', true, 'warning', '#FA8072') + setIsLoadingMoreItems(false) + setIsLoaded(true) + setError(true) + } + ) + }, [currPage, invertList]) + + if (error) { + return <div>Error: {error.message}</div>; + } else if (!isLoaded) { + return <LoadingSpinner text="Carregando..." /> + } else { + + //Words in the top part of the table + const topTable = ['ID', 'NOME', 'DESCRIÇÃO', 'VISUALIZAR', 'DELETAR']; + if (WINDOW_WIDTH <= 800) { + return ( + <div> + <SnackBar + severity={snackInfo.icon} + text={snackInfo.message} + snackbarOpen={snackInfo.open} + color={snackInfo.color} + handleClose={() => setSnackInfo({ + message: '', + icon: '', + open: false, + color: '' + })} + /> + <AlertDialog + open={openAlertDialog} + OnDelete={DeleteHandler} + deleteItem={deleteItem} + HandleClose={() => { + setOpenAlertDialog(false); + HandleStateCircularProgress(null); + }} + /> + <MobilePageHeader + title="Lista de ratings" + actions={[ + { + name: "Atualizar", + isLoading: false, + func: () => { + setCurrPage(0) + }, + icon: <UpdateRoundedIcon /> + }, + { + name: "Novo", + isLoading: false, + func: () => { + router.push('/admin/CreateRating') + }, + icon: <AddRoundedIcon /> + } + ]} + > + </MobilePageHeader> + + <div style={{ height: '2em' }}></div> + + {items.map((row, index) => + index === items.length - 1 ? ( + <StyledDivButton key={new Date().toISOString() + row.created_at}> + <Button + color="primary" + variant="text" + // disabled={isLoadingMoreItems} + startIcon={<AddRoundedIcon />} + disabled={isLoadingMoreItems} + onClick={() => { + setCurrPage(currPage + 1) + }} + > + {isLoadingMoreItems ? ( + <CircularProgress size={24} /> + ) : ( + "Carregar mais itens" )} - </div> - ) - } - else { - return ( - <div> - <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 ratings - </Typography> - </Grid> - <Grid - item - xs={6} + </Button> + </StyledDivButton> + ) : ( + <> + <MobileList + key={new Date().toISOString() + row.created_at} + title={row.name} + subtitle={row.id} + backColor={"#00bcd4"} + avatar={<StarRoundedIcon />} + href={`/admin/Rating?rating=${row.id}`} + reset={() => { + + }} + data={ + [ + { + title: "Descrição", + subtitle: row.description + }, + { + title: "Deletar", + subtitle: + <Button + variant="contained" + color="secondary" + onClick={() => { + HandleStateAlertDialog(index); + HandleStateCircularProgress(index); + }} + startIcon={<DeleteRoundedIcon />} > - <Grid container justify="flex-end" spacing={3}> - <Grid item> - <Button - variant="contained" - color="secondary" - disabled={isUpdating} - onClick={() => { - currPage = 0 - transformListToAsc = false - UpdateHandler(Url('ratings', '', `${currPage}`, 'DESC')) - }} - startIcon={<UpdateRoundedIcon />} - > - { - isUpdating ? <CircularProgress size={24} /> : 'Atualizar' - } - </Button> - </Grid> - <Grid item> - <Link style={{ textDecoration: 'none' }} to={'/admin/CreateRating'}> - <Button - variant="contained" - color="secondary" - startIcon={<AddRoundedIcon style={{ fill: "white" }} />} - onClick={() => { - currPage = 0 - transformListToAsc = false - }} - > - Novo - </Button> - </Link> - </Grid> - </Grid> - </Grid> - </Grid> - </Paper> - - <div style={{ height: '2em' }}></div> - - <TableData - top={topTable} - onIconPressed={InvertList} - > - <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 />} - onClick={() => { - currPage++ - if (transformListToAsc) { - LoadMoreItens(Url('ratings', '', `${currPage}`, 'ASC')) - } else { - LoadMoreItens(Url('ratings', '', `${currPage}`, 'DESC')) - } - }} - > - { - isLoadingMoreItems ? <CircularProgress size={24} /> : 'Carregar mais itens' - } - </Button> - </StyledTableCell> - </StyledTableRow> - - : - - <StyledTableRow key={index}> - <StyledTableCell component="th" scope="row">{row.id}</StyledTableCell> - <StyledTableCell align="right">{row.name}</StyledTableCell> - <StyledTableCell align="right">{row.description}</StyledTableCell> - <StyledTableCell align="right"> - <Link to={`/admin/Rating/${row.id}`}> - <IconButton onClick={() => { currPage = 0 }}> - <VisibilityIcon style={{ fill: '#00bcd4' }} /> - </IconButton> - </Link> - </StyledTableCell> - <StyledTableCell align="right"> - {isLoadingToDelete === index ? ( - <CircularProgress size={24} color="primary" /> - ) : ( - <IconButton - onClick={() => { - HandleStateAlertDialog(index); - HandleStateCircularProgress(index); - }} - > - <DeleteRoundedIcon style={{ fill: "#FF0000" }} /> - </IconButton> - )} - </StyledTableCell> - </StyledTableRow> - ))} - </TableBody> - </TableData> - - {/* This alert will be displayed if the user click to delete an institution */} - <AlertDialog - open={openAlertDialog} - OnDelete={DeleteHandler} - deleteItem={deleteItem} - HandleClose={() => { - setOpenAlertDialog(false); - HandleStateCircularProgress(null); + Deletar + </Button> + } + ] + } + /> + <div style={{ height: "0.5em" }} /> + </> + ) + )} + </div> + ) + } + else { + return ( + <div> + <SnackBar + severity={snackInfo.icon} + text={snackInfo.message} + snackbarOpen={snackInfo.open} + color={snackInfo.color} + handleClose={() => setSnackInfo({ + message: '', + icon: '', + open: false, + color: '' + })} + /> + <PageHeader + title="Lista de ratings" + actions={[ + { + name: "Atualizar", + isLoading: false, + func: () => { + setCurrPage(0) + }, + icon: <UpdateRoundedIcon /> + }, + { + name: "Novo", + isLoading: false, + func: () => { + router.push('/admin/CreateRating') + }, + icon: <AddRoundedIcon /> + } + ]} + > + </PageHeader> + + <div style={{ height: '2em' }}></div> + + <TableData + top={topTable} + onIconPressed={cleanArrayAndInvert} + > + <TableBody> + {items.map((row, index) => ( + index === items.length - 1 ? + <StyledTableRow key={new Date().toISOString() + row.created_at}> + {/* Button to load more data */} + <StyledTableCell> + <Button + color='primary' + variant='text' + disabled={isLoadingMoreItems} + startIcon={<AddRoundedIcon />} + onClick={() => { + setCurrPage(currPage + 1) }} - /> - </div> - ) - } + > + { + isLoadingMoreItems ? <CircularProgress size={24} /> : 'Carregar mais itens' + } + </Button> + </StyledTableCell> + </StyledTableRow> + + : + + <StyledTableRow key={new Date().toISOString() + index}> + <StyledTableCell component="th" scope="row">{row.id}</StyledTableCell> + <StyledTableCell align="right">{row.name}</StyledTableCell> + <StyledTableCell align="right">{row.description}</StyledTableCell> + <StyledTableCell align="right"> + <Link to={`/admin/Rating?rating=${row.id}`}> + <IconButton> + <VisibilityIcon style={{ fill: '#00bcd4' }} /> + </IconButton> + </Link> + </StyledTableCell> + <StyledTableCell align="right"> + {isLoadingToDelete === index ? ( + <CircularProgress size={24} color="primary" /> + ) : ( + <IconButton + onClick={() => { + HandleStateAlertDialog(index); + HandleStateCircularProgress(index); + }} + > + <DeleteRoundedIcon style={{ fill: "#FF0000" }} /> + </IconButton> + )} + </StyledTableCell> + </StyledTableRow> + ))} + </TableBody> + </TableData> + + {/* This alert will be displayed if the user click to delete an institution */} + <AlertDialog + open={openAlertDialog} + OnDelete={DeleteHandler} + deleteItem={deleteItem} + HandleClose={() => { + setOpenAlertDialog(false); + HandleStateCircularProgress(null); + }} + /> + </div> + ) } + } } diff --git a/src/Admin/Pages/Pages/SubPages/SendEmail.js b/src/Admin/Pages/Pages/SubPages/SendEmail.js index 5e9b05ed713d797f2e072811cf573c323b1009de..aff09bc843ce63f5238516695dd3887398987756 100644 --- a/src/Admin/Pages/Pages/SubPages/SendEmail.js +++ b/src/Admin/Pages/Pages/SubPages/SendEmail.js @@ -18,14 +18,12 @@ 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, {useContext} from 'react'; +import React from 'react'; import Card from "@material-ui/core/Card"; import CardContent from "@material-ui/core/CardContent"; import { makeStyles } from "@material-ui/core/styles"; import { Typography } from '@material-ui/core'; import EmailInputs from '../../../Components/Components/Inputs/EmailInputs'; -import { Store } from '../../../../Store'; -import Unauthorized from '../../../Components/Components/Unauthorized'; const useStyles = makeStyles({ root: { @@ -56,42 +54,26 @@ const useStyles = makeStyles({ }, }); + const SendEmail = ({ match }) => { - const { state } = useContext(Store); const classes = useStyles(); + const urlParams = new URLSearchParams(window.location.search); + const email = urlParams.get("email"); - 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; - } - - if(CheckUserPermission()){ - return ( - <Card> - <CardContent> - <Typography - className={classes.title} - color="inherit" - gutterBottom - > - Enviar email - </Typography> - <EmailInputs email={`${match.params.email}`} /> - </CardContent> - </Card> - ); - } else return <Unauthorized/> + return ( + <Card> + <CardContent> + <Typography + className={classes.title} + color="inherit" + gutterBottom + > + Enviar email + </Typography> + <EmailInputs email={email} /> + </CardContent> + </Card> + ); } export default SendEmail; \ No newline at end of file diff --git a/src/Admin/Pages/Pages/SubPages/Users.js b/src/Admin/Pages/Pages/SubPages/Users.js index fe3524c9e120bb5586a9965bbdccfa4a541f0d91..cb31af1e213e65b7c8d13be01fb48c68a75dd190 100644 --- a/src/Admin/Pages/Pages/SubPages/Users.js +++ b/src/Admin/Pages/Pages/SubPages/Users.js @@ -25,624 +25,539 @@ import TableCell from '@material-ui/core/TableCell'; import TableRow from '@material-ui/core/TableRow'; import IconButton from '@material-ui/core/IconButton'; import VisibilityIcon from '@material-ui/icons/Visibility'; -import { Button, Typography, Chip } from '@material-ui/core'; +import { Button, Chip } from '@material-ui/core'; import CircularProgress from '@material-ui/core/CircularProgress'; import AddRoundedIcon from '@material-ui/icons/AddRounded'; import TextField from '@material-ui/core/TextField'; import UpdateRoundedIcon from '@material-ui/icons/UpdateRounded' +import FilterListRoundedIcon from "@material-ui/icons/FilterListRounded"; //Local files import TableData from '../../../Components/Components/Table'; import SnackBar from '../../../../Components/SnackbarComponent'; import LoadingSpinner from '../../../../Components/LoadingSpinner'; +import MobileList from "../../../Components/Components/MobileComponents/SimpleList" +import MobilePageHeader from "../../../Components/Components/MobileComponents/MobilePageHeader" +import PageHeader from "../../../Components/Components/PageHeader" //Services import { getRequest, putRequest } from '../../../../Components/HelperFunctions/getAxiosConfig' import { Url } from '../../../Filters'; //routers -import { Link } from 'react-router-dom'; +import { Link, useHistory } from 'react-router-dom'; import moment from 'moment'; import styled from 'styled-components' -import MobileList from "../../../Components/Components/MobileComponents/SimpleList" import EmailRoundedIcon from '@material-ui/icons/EmailRounded'; import { apiDomain } from '../../../../env'; import noAvatar from "../../../../img/default_profile.png"; -let currPage = 0; //var that controlls the current page that we are -let transformListToAsc = false; -let nameFilter = ""; -let emailFilter = ""; const StyledTableCell = withStyles((theme) => ({ - head: { - backgroundColor: theme.palette.common.black, - color: theme.palette.common.white, - }, - body: { - fontSize: 14, - }, + 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, - }, + root: { + '&:nth-of-type(odd)': { + backgroundColor: theme.palette.action.hover, }, + }, }))(TableRow); const Users = () => { - const AddOneLenght = ['']; - const WINDOW_WIDTH = window.innerWidth - 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) - const [isUpdating, setIsUpdating] = useState(false) - const [showFilter, setShowFilter] = useState(false) - - const [name, setName] = useState(""); - const [email, setEmail] = useState(""); - - const [snackInfo, setSnackInfo] = useState({ - message: '', - icon: '', - open: false, - color: '', + const ADD_ONE_LENGHT = ['']; + const WINDOW_WIDTH = window.innerWidth + + const router = useHistory() + + const [invertList, setInvertList] = useState(false) + 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) + const [showFilter, setShowFilter] = useState(false) + const [currPage, setCurrPage] = useState(0) + + const [name, setName] = useState(""); + const [nameValue, setNameValue] = useState("") + const [email, setEmail] = useState(""); + const [emailValue, setEmailValue] = useState("") + + const [snackInfo, setSnackInfo] = useState({ + message: '', + icon: '', + open: false, + color: '', + }) + + // Handle snack infos + const HandleSnack = (message, state, icon, color) => { + setSnackInfo({ + message: message, + icon: icon, + open: state, + color: color }) - - // Handle snack infos - const HandleSnack = (message, state, icon, color) => { - setSnackInfo({ - message: message, - icon: icon, - open: state, - color: color - }) + } + + const NameHandler = (event) => { + setNameValue(event.target.value) + } + + const EmailHandler = (event) => { + setEmailValue(event.target.value) + } + + const DisplayDate = (date) => { + const convertedData = moment.utc(date); + return moment(convertedData) + .format("LLL") + .toString(); + }; + + const isUserPublisher = (userRoles) => { + for (let index = 0; index < userRoles.length; index++) { + if (userRoles[index].id === 10) + return true; } - - const NameHandler = (event) => { - currPage = 0 - setName(event.target.value) - nameFilter = event.target.value - getRequest( - Url('users', `"name" : "${nameFilter}", "email" : "${emailFilter}"`, `${currPage}`, 'DESC'), - (data, header) => { - const arrData = [...data] - setItems(arrData.concat(AddOneLenght)) - HandleSnack('Filtro aplicado com sucesso', true, 'success', '#228B22') - }, - (error) => { - HandleSnack('Erro ao carregar os dados', true, 'warning', '#FA8072') - } - ) - + return false; + } + + const pushPublisherRole = (userId) => { + let index = -1; + for (let i = 0; i < items.length; i++) { + const element = items[i]; + if (element.id === userId) { + index = i + break + } } - - const EmailHandler = (event) => { - currPage = 0 - setEmail(event.target.value) - emailFilter = event.target.value - getRequest( - Url('users', `"name" : "${nameFilter}", "email" : "${emailFilter}"`, `${currPage}`, 'DESC'), - (data, header) => { - const arrData = [...data] - setItems(arrData.concat(AddOneLenght)) - HandleSnack('Filtro aplicado com sucesso', true, 'success', '#228B22') - }, - (error) => { - HandleSnack('Erro ao carregar os dados', true, 'warning', '#FA8072') - } - ) + if (index !== -1) { + const cpyItems = [...items] + cpyItems[index].roles.push({ + id: 10, + name: "publisher" + }) + setItems(cpyItems) } - - 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(AddOneLenght)) - } - setIsLoadingMoreItems(false) - }, - (error) => { - HandleSnack('Erro ao carregar os dados', true, 'warning', '#FA8072') - setIsLoadingMoreItems(false) - } - ) + } + + const turnUserPublisher = (userRoles, userId) => { + let roles_ids = []; + userRoles.map((role) => ( + roles_ids.push(role.id) + )) + roles_ids.push(10); + const body = { + "user": { + "role_ids": roles_ids + } } - - const InvertList = async () => { - transformListToAsc = !transformListToAsc - currPage = 0 - if (transformListToAsc) { - getRequest( - Url('users', `"name" : "${nameFilter}", "email" : "${emailFilter}"`, `${currPage}`, 'ASC'), - (data, header) => { - const arrData = [...data] - setItems(arrData.concat(AddOneLenght)) - }, - (error) => { - HandleSnack('Erro ao carregar os dados', true, 'warning', '#FA8072') - } - ) - } else { - getRequest( - Url('users', `"name" : "${nameFilter}", "email" : "${emailFilter}"`, `${currPage}`, 'DESC'), - (data, header) => { - const arrData = [...data] - setItems(arrData.concat(AddOneLenght)) - }, - (error) => { - HandleSnack('Erro ao carregar os dados', true, 'warning', '#FA8072') - } - ) + putRequest( + `/users/${userId}`, + body, + (data) => { + if (data.errors) { + HandleSnack('Ocorreu algum erro', true, 'warning', '#FA8072') } - } - - const DisplayDate = (date) => { - const convertedData = moment.utc(date); - return moment(convertedData) - .format("LLL") - .toString(); - }; - - 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(AddOneLenght)) - setIsUpdating(false) - }, - (error) => { - HandleSnack('Erro ao carregar os dados', true, 'warning', '#FA8072') - setIsUpdating(false) - } - ) - } - - const isUserPublisher = (userRoles) => { - for (let index = 0; index < userRoles.length; index++) { - if (userRoles[index].id === 10) - return true; + else { + HandleSnack(`O usuário ${userId}, agora é publicador`, true, 'success', '#228B22') + pushPublisherRole(userId) + setCurrPage(0) } - return false; - } - - const turnUserPublisher = (userRoles, userId) => { - let roles_ids = []; - userRoles.map((role) => ( - roles_ids.push(role.id) - )) - roles_ids.push(10); - const body = { - "user": { - "role_ids": roles_ids - } + }, + (error) => { + HandleSnack('Ocorreu algum erro', true, 'warning', '#FA8072') + } + ) + } + + const cleanArrayAndInvert = () => { + setInvertList(!invertList) + setCurrPage(0) + setItems([]) + } + + const buildUrl = (email, name, direction) => { + if (email && name) + return Url("users", `"email" : "${email}", "name" : "${name}"`, currPage, direction) + if (email) + return Url("users", `"email" : "${email}"`, currPage, direction) + if (name) + return Url("users", `"name" : "${name}"`, currPage, direction) + else + return Url("users", "", currPage, direction) + } + + useEffect(() => { + if (currPage === 0) + setIsLoaded(false) + else + setIsLoadingMoreItems(true) + getRequest( + buildUrl(email, name, invertList ? "ASC" : "DESC"), + (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] + if (currPage === 0) { + setItems(arrData.concat(ADD_ONE_LENGHT)) + } + else { + 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)) + } } - putRequest( - `/users/${userId}`, - body, - (data) => { - if (data.errors) { - HandleSnack('Ocorreu algum erro', true, 'warning', '#FA8072') - } - else { - currPage = 0; - HandleSnack(`O usuário ${userId}, agora é publicador`, true, 'success', '#228B22') - UpdateHandler(Url('users', `"name" : "${nameFilter}", "email" : "${emailFilter}"`, `${currPage}`, 'DESC')) - } - }, - (error) => { - HandleSnack('Ocorreu algum erro', true, 'warning', '#FA8072') - } - ) - } - - useEffect(() => { - getRequest( - Url('users', `"name" : "${nameFilter}", "email" : "${emailFilter}"`, '0', 'DESC'), - (data, header) => { - setIsLoaded(true); - setItems(data.concat(AddOneLenght)); - }, - (error) => { - setError(true); - } - ) - }, []); - - - if (error) { - return <div>Error: {error.message}</div>; - } else if (!isLoaded) { - return <LoadingSpinner text="Carregando..." /> - } else { - - //Words in the top part of the table - const topTable = ['ID', 'NOME', 'EMAIL', 'CRIADO EM', 'SCORE', 'PERMISSÃO', 'AÇÃO', "VISUALIZAR"]; - if (WINDOW_WIDTH <= 1150) { - return ( - <div> - <SnackBar - severity={snackInfo.icon} - text={snackInfo.message} - snackbarOpen={snackInfo.open} - color={snackInfo.color} - handleClose={() => setSnackInfo({ - message: '', - icon: '', - open: false, - color: '' - })} + setIsLoaded(true) + setIsLoadingMoreItems(false) + }, + (error) => { + HandleSnack('Erro ao carregar os dados', true, 'warning', '#FA8072') + setIsLoaded(true) + setError(true) + setIsLoadingMoreItems(false) + } + ) + }, [currPage, email, name, invertList]) + + useEffect(() => { + setNameValue("") + setName("") + setEmailValue("") + setEmail("") + }, [showFilter]) + + if (error) { + return <div>Error: {error.message}</div>; + } else if (!isLoaded) { + return <LoadingSpinner text="Carregando..." /> + } else { + + //Words in the top part of the table + const topTable = ['ID', 'NOME', 'EMAIL', 'CRIADO EM', 'SCORE', 'PERMISSÃO', 'AÇÃO', "VISUALIZAR"]; + if (WINDOW_WIDTH <= 1150) { + return ( + <div> + <SnackBar + severity={snackInfo.icon} + text={snackInfo.message} + snackbarOpen={snackInfo.open} + color={snackInfo.color} + handleClose={() => setSnackInfo({ + message: '', + icon: '', + open: false, + color: '' + })} + /> + <MobilePageHeader + title="Lista de usuários" + actions={[ + { + name: "Atualizar", + isLoading: false, + func: () => { + setCurrPage(0) + }, + icon: <UpdateRoundedIcon /> + }, + { + name: "Filtrar", + isLoading: false, + func: () => { + setShowFilter(!showFilter); + }, + icon: <FilterListRoundedIcon /> + }, + { + name: "Novo", + isLoading: false, + func: () => { + router.push('/admin/EditUser?id=-1') + }, + icon: <AddRoundedIcon /> + }, + { + name: "Inverter lista", + isLoading: false, + func: () => { + cleanArrayAndInvert() + }, + } + ]} + > + { + showFilter ? ( + <Grid container direction="row" justify="space-between" alignItems="center"> + <Grid item> + <TextField + label="Name" + value={nameValue} + onChange={(e) => { NameHandler(e) }} + onBlur={(e) => { setEmail(e.target.value) }} + helperText="Ao digitar, retire o foco do campo" + /> + </Grid> + <Grid item> + <TextField + label="Email" + value={emailValue} + onChange={(e) => { EmailHandler(e) }} + onBlur={(e) => { setEmail(e.target.value) }} + helperText="Ao digitar, retire o foco do campo" /> - <Paper style={{ padding: '1em' }}> - <Grid container spacing={3} direction="row" alignItems="center"> - <Grid item xs={12}> - <Typography variant="h4"> - Lista de usuários - </Typography> - </Grid> - <Grid - item - xs={12} + </Grid> + </Grid> + ) : null + } + </MobilePageHeader> + + <div style={{ height: '2em' }}></div> + + {items.map((row, index) => + index === items.length - 1 ? ( + <StyledDivButton key={new Date().toISOString() + row.created_at}> + <Button + color="primary" + variant="text" + // disabled={isLoadingMoreItems} + startIcon={<AddRoundedIcon />} + disabled={isLoadingMoreItems} + onClick={() => { + setCurrPage(currPage + 1) + }} + > + {isLoadingMoreItems ? ( + <CircularProgress size={24} /> + ) : ( + "Carregar mais itens" + )} + </Button> + </StyledDivButton> + ) : ( + <> + <MobileList + key={new Date().toISOString() + row.created_at} + title={row.name} + subtitle={row.id} + backColor={"#00bcd4"} + avatar={ + <img + src={row.avatar ? apiDomain + row.avatar : noAvatar} + alt="user avatar" + style={{ + height: "100%", + width: "100%", + borderRadius: "50%", + }} + /> + } + href={`/admin/user?id=${row.id}`} + reset={() => { + }} + data={[ + { + title: "Email", + subtitle: row.email ? + <Link to={`/admin/sendEmail?email=${row.email}`} style={{ textDecoration: 'none' }}> + <Button + variant='text' + color='primary' + startIcon={<EmailRoundedIcon />} > - <Grid container justify="flex-start" spacing={3}> - <Grid item> - <Button - variant="contained" - color="secondary" - disabled={isUpdating} - onClick={() => { - currPage = 0 - transformListToAsc = false - UpdateHandler(Url('users', `"name" : "${nameFilter}", "email" : "${emailFilter}"`, `${currPage}`, 'DESC')) - }} - startIcon={<UpdateRoundedIcon />} - > - { - isUpdating ? <CircularProgress size={24} /> : 'Atualizar' - } - </Button> - </Grid> - <Grid item> - <Button - variant="contained" - color="secondary" - onClick={() => { - setShowFilter(!showFilter) - }} - startIcon={<UpdateRoundedIcon />} - > - filtrar - </Button> - </Grid> - <Grid item> - <Link to="/admin/EditUser/-1"> - <Button - variant="contained" - color="secondary" - startIcon={<AddRoundedIcon />} - > - Novo - </Button> - </Link> - </Grid> - </Grid> - </Grid> - </Grid> - { - showFilter ? ( - <Grid container direction="row" justify="space-between" alignItems="center"> - <Grid item> - <TextField - label="Name" - value={name} - onChange={(e) => { NameHandler(e) }} - /> - </Grid> - <Grid item> - <TextField - label="Email" - value={email} - onChange={(e) => { EmailHandler(e) }} - /> - </Grid> - </Grid> - ) : null - } - </Paper> - - <div style={{ height: '2em' }}></div> - - {items.map((row, index) => - index === items.length - 1 ? ( - <StyledDivButton> - <Button - key={index} - color="primary" - variant="text" - // disabled={isLoadingMoreItems} - startIcon={<AddRoundedIcon />} - disabled={isLoadingMoreItems} - onClick={() => { - currPage++ - if (transformListToAsc) { - LoadMoreItens(Url('users', `"name" : "${nameFilter}", "email" : "${emailFilter}"`, `${currPage}`, 'ASC')) - } else { - LoadMoreItens(Url('users', `"name" : "${nameFilter}", "email" : "${emailFilter}"`, `${currPage}`, 'DESC')) - } - }} - > - {isLoadingMoreItems ? ( - <CircularProgress size={24} /> - ) : ( - "Carregar mais itens" - )} - </Button> - </StyledDivButton> - ) : ( - <> - <MobileList - key={index} - title={row.name} - subtitle={row.id} - backColor={"#00bcd4"} - avatar={ - <img - src={row.avatar ? apiDomain + row.avatar : noAvatar} - alt="user avatar" - style={{ - height: "100%", - width: "100%", - borderRadius: "50%", - }} - /> - } - href={`/admin/user/${row.id}`} - reset={() => { - currPage = 0; - transformListToAsc = false - nameFilter = "" - emailFilter = "" - }} - data={[ - { - title: "Email", - subtitle: row.email ? - <Link to={`/admin/sendEmail/${row.email}`} style={{ textDecoration: 'none' }}> - <Button - variant='text' - color='primary' - startIcon={<EmailRoundedIcon />} - > - {row.email} - </Button> - </Link> : null - }, - { - title: "Criado em", - subtitle: DisplayDate(row.created_at) - }, - { - title: "Score", - subtitle: row.score - }, - { - title: "Permissão", - subtitle: row.roles.map((chip) => ( - <ChipDiv> - <Chip label={chip.name} key={chip.id} /> - </ChipDiv> - )) - }, - { - title: "Score", - subtitle: row.score - }, - { - title: "Ações rápidas", - subtitle: <Button - variant="contained" - color="primary" - disabled={isUserPublisher(row.roles)} - onClick={() => { turnUserPublisher(row.roles, row.id) }} - > - Tornar publicador + {row.email} + </Button> + </Link> : null + }, + { + title: "Criado em", + subtitle: DisplayDate(row.created_at) + }, + { + title: "Score", + subtitle: row.score + }, + { + title: "Permissão", + subtitle: row.roles.map((chip) => ( + <ChipDiv> + <Chip label={chip.name} key={chip.id} /> + </ChipDiv> + )) + }, + { + title: "Score", + subtitle: row.score + }, + { + title: "Ações rápidas", + subtitle: <Button + variant="contained" + color="primary" + disabled={isUserPublisher(row.roles)} + onClick={() => { turnUserPublisher(row.roles, row.id) }} + > + Tornar publicador </Button> - } - - ]} - /> - <div style={{ height: "0.5em" }} /> - </> - ) - )} - </div> - ) - } - else { - return ( - <div> - <SnackBar - severity={snackInfo.icon} - text={snackInfo.message} - snackbarOpen={snackInfo.open} - color={snackInfo.color} - handleClose={() => setSnackInfo({ - message: '', - icon: '', - open: false, - color: '' - })} + } + + ]} + /> + <div style={{ height: "0.5em" }} /> + </> + ) + )} + </div> + ) + } + else { + return ( + <div> + <SnackBar + severity={snackInfo.icon} + text={snackInfo.message} + snackbarOpen={snackInfo.open} + color={snackInfo.color} + handleClose={() => setSnackInfo({ + message: '', + icon: '', + open: false, + color: '' + })} + /> + <PageHeader + title="Lista de usuários" + actions={[ + { + name: "Atualizar", + isLoading: false, + func: () => { + setCurrPage(0) + }, + icon: <UpdateRoundedIcon /> + }, + { + name: "Filtrar", + isLoading: false, + func: () => { + setShowFilter(!showFilter); + }, + icon: <FilterListRoundedIcon /> + }, + { + name: "Novo", + isLoading: false, + func: () => { + router.push('/admin/EditUser?id=-1') + }, + icon: <AddRoundedIcon /> + } + ]} + > + { + showFilter ? ( + <Grid container direction="row" justify="space-between" alignItems="center"> + <Grid item> + <TextField + label="Name" + value={nameValue} + onChange={(e) => { NameHandler(e) }} + onBlur={(e) => { setEmail(e.target.value) }} + helperText="Ao digitar, retire o foco do campo" /> - <Paper style={{ padding: '1em' }}> - <Grid container spacing={3} direction="row" alignItems="center"> - <Grid item xs={6}> - <Typography variant="h4"> - Lista de usuários - </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 - transformListToAsc = false - UpdateHandler(Url('users', `"name" : "${nameFilter}", "email" : "${emailFilter}"`, `${currPage}`, 'DESC')) - }} - startIcon={<UpdateRoundedIcon />} - > - { - isUpdating ? <CircularProgress size={24} /> : 'Atualizar' - } - </Button> - </Grid> - <Grid item> - <Button - variant="contained" - color="secondary" - onClick={() => { - setShowFilter(!showFilter) - }} - startIcon={<UpdateRoundedIcon />} - > - filtrar - </Button> - </Grid> - <Grid item> - <Link to="/admin/EditUser/-1"> - <Button - variant="contained" - color="secondary" - startIcon={<AddRoundedIcon />} - > - Novo - </Button> - </Link> - </Grid> - </Grid> - </Grid> - </Grid> + </Grid> + <Grid item> + <TextField + label="Email" + value={emailValue} + onChange={(e) => { EmailHandler(e) }} + onBlur={(e) => { setEmail(e.target.value) }} + helperText="Ao digitar, retire o foco do campo" + /> + </Grid> + </Grid> + ) : null + } + </PageHeader> + + <div style={{ height: '2em' }}></div> + + <TableData + top={topTable} + onIconPressed={cleanArrayAndInvert} + > + <TableBody> + {items.map((row, index) => ( + index === items.length - 1 ? + <StyledTableRow key={new Date().toISOString() + row.created_at}> + {/* Button to load more data */} + <StyledTableCell> + <Button + color='primary' + variant='text' + disabled={isLoadingMoreItems} + startIcon={<AddRoundedIcon />} + onClick={() => { + setCurrPage(currPage + 1) + }} + > { - showFilter ? ( - <Grid container direction="row" justify="space-between" alignItems="center"> - <Grid item> - <TextField - label="Name" - value={name} - onChange={(e) => { NameHandler(e) }} - /> - </Grid> - <Grid item> - <TextField - label="Email" - value={email} - onChange={(e) => { EmailHandler(e) }} - /> - </Grid> - </Grid> - ) : null + isLoadingMoreItems ? <CircularProgress size={24} /> : 'Carregar mais itens' } - </Paper> - - <div style={{ height: '2em' }}></div> - - <TableData - top={topTable} - onIconPressed={InvertList} - > - <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 />} - onClick={() => { - currPage++ - if (transformListToAsc) { - LoadMoreItens(Url('users', `"name" : "${nameFilter}", "email" : "${emailFilter}"`, `${currPage}`, 'ASC')) - } else { - LoadMoreItens(Url('users', `"name" : "${nameFilter}", "email" : "${emailFilter}"`, `${currPage}`, 'DESC')) - } - }} - > - { - isLoadingMoreItems ? <CircularProgress size={24} /> : 'Carregar mais itens' - } - </Button> - </StyledTableCell> - </StyledTableRow> - - : - - <StyledTableRow key={index}> - <StyledTableCell component="th" scope="row">{row.id}</StyledTableCell> - <StyledTableCell align="right">{row.name}</StyledTableCell> - <StyledTableCell align="right">{row.email ? row.email : ""}</StyledTableCell> - <StyledTableCell align="right"> - {DisplayDate(row.created_at)} - </StyledTableCell> - <StyledTableCell align="right">{row.score}</StyledTableCell> - <StyledTableCell align="right"> - { - row.roles.map((chip) => ( - <ChipDiv> - <Chip label={chip.name} key={chip.id} /> - </ChipDiv> - )) - } - </StyledTableCell> - <StyledTableCell align="right"> - <Button - variant="contained" - color="primary" - disabled={isUserPublisher(row.roles)} - onClick={() => { turnUserPublisher(row.roles, row.id) }} - > - Tornar publicador + </Button> + </StyledTableCell> + </StyledTableRow> + + : + + <StyledTableRow key={new Date().toISOString() + index}> + <StyledTableCell component="th" scope="row">{row.id}</StyledTableCell> + <StyledTableCell align="right">{row.name}</StyledTableCell> + <StyledTableCell align="right">{row.email ? row.email : ""}</StyledTableCell> + <StyledTableCell align="right"> + {DisplayDate(row.created_at)} + </StyledTableCell> + <StyledTableCell align="right">{row.score}</StyledTableCell> + <StyledTableCell align="right"> + { + row.roles.map((chip) => ( + <ChipDiv> + <Chip label={chip.name} key={chip.id} /> + </ChipDiv> + )) + } + </StyledTableCell> + <StyledTableCell align="right"> + <Button + variant="contained" + color="primary" + disabled={isUserPublisher(row.roles)} + onClick={() => { turnUserPublisher(row.roles, row.id) }} + > + Tornar publicador </Button> - </StyledTableCell> - <StyledTableCell align="right"> - <Link to={`/admin/user/${row.id}`}> - <IconButton onClick={() => { - currPage = 0; - transformListToAsc = false - nameFilter = "" - emailFilter = "" - } - }> - <VisibilityIcon style={{ fill: '#00bcd4' }} /> - </IconButton> - </Link> - </StyledTableCell> - </StyledTableRow> - ))} - </TableBody> - </TableData> - </div> - ) - } + </StyledTableCell> + <StyledTableCell align="right"> + <Link to={`/admin/user?id=${row.id}`}> + <IconButton> + <VisibilityIcon style={{ fill: '#00bcd4' }} /> + </IconButton> + </Link> + </StyledTableCell> + </StyledTableRow> + ))} + </TableBody> + </TableData> + </div> + ) } + } } export default Users; diff --git a/src/App.js b/src/App.js index 1400c7a2cb90a656777c7f1b8608f48298cd20b5..c97423244a92cc6662c82335e42e3dd8794d1c49 100644 --- a/src/App.js +++ b/src/App.js @@ -17,6 +17,8 @@ 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, { useContext, useEffect, useState } from "react"; +import { Store } from './Store' +import Unauthorized from './Admin/Components/Components/Unauthorized' import Home from "./Pages/HomeFunction"; import Search from "./Pages/Search"; import Header from "./Components/Header"; @@ -35,8 +37,7 @@ import TabManageAc from "./Pages/TabsHelp/TabManageAc"; import PasswordRecoveryPage from "./Pages/PasswordRecoveryPage.js"; import PageProfessor from "./Pages/PageProfessor.js"; import ResourcePage from "./Pages/ResourcePage"; -import { BrowserRouter, Switch, Route, Link } from "react-router-dom"; -import { Store } from "./Store"; +import { BrowserRouter, Switch, Route } from "react-router-dom"; import TermsPage from "./Pages/TermsPage.js"; import PublicationPermissionsPage from "./Pages/PublicationPermissionsPage.js"; import TabPlataformaMEC from "./Pages/TabsHelp/TabPlataformaMEC"; @@ -51,13 +52,8 @@ import CollectionPage from "./Pages/CollectionPage.js"; import FormationMaterialPage from "./Pages/FormationMaterialPage.js"; import FormationMaterialIframe from "./Pages/FormationMaterialIframe.js"; import MaterialPage from "./Pages/MaterialPage"; +import Maintence from './Components/maintenance' -//material ui -import { Tab, Tabs } from "@material-ui/core"; - -//admin -import { makeStyles } from "@material-ui/core/styles"; -import DisplayIcon from "./Admin/Components/Components/DisplayIcon"; import NoteVariables from "./Admin/Pages/Pages/SubPages/NoteVariables"; import Institution from "./Admin/Pages/Pages/SubPages/Institutions"; import SendEmail from "./Admin/Pages/Pages/SubPages/SendEmail"; @@ -96,64 +92,30 @@ import UserPermissions from "./Admin/Pages/Pages/SubPages/Permissions"; import EditRole from "./Admin/Components/Components/Inputs/EditRoles"; import CreateRole from "./Admin/Components/Components/Inputs/CreateRole"; import BlockedUser from "./Admin/Pages/Pages/SubPages/BlockedUsers"; -import PropTypes from "prop-types"; -import Typography from "@material-ui/core/Typography"; -import Box from "@material-ui/core/Box"; -import AppBar from "@material-ui/core/AppBar"; - -function TabPanel(props) { - const { children, value, index, ...other } = props; - - return ( - <div - role="tabpanel" - hidden={value !== index} - id={`nav-tabpanel-${index}`} - aria-labelledby={`nav-tab-${index}`} - {...other} - > - {value === index && ( - <Box p={3}> - <Typography>{children}</Typography> - </Box> - )} - </div> - ); -} - -TabPanel.propTypes = { - children: PropTypes.node, - index: PropTypes.any.isRequired, - value: PropTypes.any.isRequired, -}; - -function a11yProps(index) { - return { - id: `nav-tab-${index}`, - "aria-controls": `nav-tabpanel-${index}`, - }; -} - -const useStyles = makeStyles({ - list: { - width: 250, - }, - fullList: { - width: "auto", - }, -}); +import AppBarAdmin from './Admin/Components/Components/AppBar' +import Maintenance from "./Components/maintenance"; export default function App() { // eslint-disable-next-line - const classes = useStyles(); - const { dispatch } = useContext(Store); + const { state, dispatch } = useContext(Store); const [hideFooter, setHideFooter] = useState(false); - const [value, setValue] = React.useState(0); - const handleChange = (event, newValue) => { - setValue(newValue); - }; + 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; + } useEffect(() => { setHideFooter(String(window.location.href).includes("iframe-colecao")); @@ -187,6 +149,7 @@ export default function App() { return ( <BrowserRouter basename="/react"> + <Maintenance /> <Header /> <div style={{ @@ -235,194 +198,259 @@ export default function App() { <Route path="/iframe-colecao" component={FormationMaterialIframe} /> <Route path="/material-formacao" component={MaterialPage} /> <div style={{ backgroundColor: " #D3D3D3" }}> - <AppBar position="static" color="default"> - <Tabs - variant="scrollable" - scrollButtons="on" - value={value} - onChange={handleChange} - aria-label="nav tabs example" - > - <Tab - label="Home" - to="/admin/home" - icon={<DisplayIcon i={0} />} - component={Link} - {...a11yProps(0)} - /> - <Tab - label="Coleções" - to="/admin/Collections" - icon={<DisplayIcon i={1} />} - component={Link} - {...a11yProps(1)} - /> - <Tab - label="Atividades" - to="/admin/activities" - icon={<DisplayIcon i={2} />} - component={Link} - {...a11yProps(2)} - /> - <Tab - label="Dúvidas da comunidade" - to="/admin/CommunityQuestions" - icon={<DisplayIcon i={3} />} - component={Link} - {...a11yProps(3)} - /> - <Tab - label="Instituição" - to="/admin/intitutions" - icon={<DisplayIcon i={4} />} - component={Link} - {...a11yProps(4)} - /> - <Tab - label="Linguagens" - to="/admin/languages" - icon={<DisplayIcon i={5} />} - component={Link} - {...a11yProps(5)} - /> - <Tab - label="Objetos educacionais" - to="/admin/learningObjects" - icon={<DisplayIcon i={6} />} - component={Link} - {...a11yProps(6)} - /> - <Tab - label="Rating" - to="/admin/Ratings" - icon={<DisplayIcon i={7} />} - component={Link} - {...a11yProps(7)} - /> - <Tab - label="Permissões do usuário" - to="/admin/permissions" - icon={<DisplayIcon i={8} />} - component={Link} - {...a11yProps(8)} - /> - <Tab - label="Variáveis de nota" - to="/admin/noteVars" - icon={<DisplayIcon i={9} />} - component={Link} - {...a11yProps(9)} - /> - <Tab - label="Perguntas da curadoria" - to="/admin/Questions" - icon={<DisplayIcon i={10} />} - component={Link} - {...a11yProps(10)} - /> - <Tab - label="Aprovação de professores" - to="/admin/users/teacher_requests" - icon={<DisplayIcon i={11} />} - component={Link} - {...a11yProps(11)} - /> - <Tab - label="Usuários" - to="/admin/usersList" - icon={<DisplayIcon i={12} />} - component={Link} - {...a11yProps(12)} - /> - <Tab - label="Usuários bloqueados" - to="/admin/BlockedUsers" - icon={<DisplayIcon i={13} />} - component={Link} - {...a11yProps(13)} - /> - <Tab - label="Denúncias" - to="/admin/complaints" - icon={<DisplayIcon i={14} />} - component={Link} - {...a11yProps(14)} - /> - <Tab - label="Enviar email" - to="/admin/sendEmail/:email" - icon={<DisplayIcon i={15} />} - component={Link} - {...a11yProps(15)} - /> - </Tabs> - </AppBar> + <AppBarAdmin /> <div style={{ padding: "2em" }}> - <Route path="/admin/home" exact={true} component={Inframe} /> - <Route path="/admin/intitutions" component={Institution} /> - <Route path="/admin/institution/:id" component={InstitutionCard} /> + <Route path="/admin/home" exact={true} render={() => { + if (CheckUserPermission()) + return <Inframe /> + else + return <Unauthorized /> + }} /> + <Route path="/admin/intitutions" render={() => { + if (CheckUserPermission()) + return <Institution /> + else + return <Unauthorized /> + }} /> + <Route path="/admin/institution" render={() => { + if (CheckUserPermission()) + return <InstitutionCard /> + else + return <Unauthorized /> + }} /> <Route - path="/admin/institutionEdit/:id" - component={InstitutionsInput} + path="/admin/institutionEdit" + render={() => { + if (CheckUserPermission()) + return <InstitutionsInput /> + else + return <Unauthorized /> + }} /> <Route path="/admin/InstitutionCreate" - component={CreateInstitution} + render={() => { + if (CheckUserPermission()) + return <CreateInstitution /> + else + return <Unauthorized /> + }} /> - <Route path="/admin/noteVars" component={NoteVariables} /> - <Route path="/admin/noteVar/:id" component={NoteVarCard} /> - <Route path="/admin/noteVarEdit/:id" component={NoteVarInputs} /> - <Route path="/admin/languages" component={Languages} /> - <Route path="/admin/languageEdit/:id" component={EditLanguage} /> - <Route path="/admin/languageCreate" component={CreateLanguage} /> + <Route path="/admin/noteVars" render={() => { + if (CheckUserPermission()) + return <NoteVariables /> + else + return <Unauthorized /> + }} /> + <Route path="/admin/noteVar" render={() => { + if (CheckUserPermission()) + return <NoteVarCard /> + else + return <Unauthorized /> + }} /> + <Route path="/admin/noteVarEdit" render={() => { + if (CheckUserPermission()) + return <NoteVarInputs /> + else + return <Unauthorized /> + }} /> + <Route path="/admin/languages" render={() => { + if (CheckUserPermission()) + return <Languages /> + else + return <Unauthorized /> + }} /> + <Route path="/admin/languageEdit" render={() => { + if (CheckUserPermission()) + return <EditLanguage /> + else + return <Unauthorized /> + }} /> + <Route path="/admin/languageCreate" render={() => { + if (CheckUserPermission()) + return <CreateLanguage /> + else + return <Unauthorized /> + }} /> <Route path="/admin/CommunityQuestions" - component={CommunityQuestions} + render={() => { + if (CheckUserPermission()) + return <CommunityQuestions /> + else + return <Unauthorized /> + }} /> <Route - path="/admin/CommunityQuestion/:id" - component={CommunityCard} + path="/admin/CommunityQuestion" + render={() => { + if (CheckUserPermission()) + return <CommunityCard /> + else + return <Unauthorized /> + }} /> - <Route path="/admin/Collections" component={Collections} /> - <Route path="/admin/Collection/:id" component={CollectionCard} /> + <Route path="/admin/Collections" render={() => { + if (CheckUserPermission()) + return <Collections /> + else + return <Unauthorized /> + }} /> + <Route path="/admin/Collection" render={() => { + if (CheckUserPermission()) + return <CollectionCard /> + else + return <Unauthorized /> + }} /> <Route - path="/admin/EditCollection/:id" - component={EditCollection} + path="/admin/EditCollection" + render={() => { + if (CheckUserPermission()) + return <EditCollection /> + else + return <Unauthorized /> + }} /> - <Route path="/admin/Ratings" component={Ratings} /> - <Route path="/admin/Rating/:id" component={RatingCard} /> - <Route path="/admin/EditRating/:id" component={EditRating} /> - <Route path="/admin/CreateRating" component={CreateRating} /> - <Route path="/admin/Questions" component={Questions} /> - <Route path="/admin/CreateQuestion" component={CreateQuestions} /> - <Route path="/admin/activities" component={Activity} /> - <Route path="/admin/activity/:id" component={ActivityCard} /> + <Route path="/admin/Ratings" render={() => { + if (CheckUserPermission()) + return <Ratings /> + else + return <Unauthorized /> + }} /> + <Route path="/admin/Rating" render={() => { + if (CheckUserPermission()) + return <RatingCard /> + else + return <Unauthorized /> + }} /> + <Route path="/admin/EditRating" render={() => { + if (CheckUserPermission()) + return <EditRating /> + else + return <Unauthorized /> + }} /> + <Route path="/admin/CreateRating" render={() => { + if (CheckUserPermission()) + return <CreateRating /> + else + return <Unauthorized /> + }} /> + <Route path="/admin/Questions" render={() => { + if (CheckUserPermission()) + return <Questions /> + else + return <Unauthorized /> + }} /> + <Route path="/admin/CreateQuestion" render={() => { + if (CheckUserPermission()) + return <CreateQuestions /> + else + return <Unauthorized /> + }} /> + <Route path="/admin/activities" render={() => { + if (CheckUserPermission()) + return <Activity /> + else + return <Unauthorized /> + }} /> + <Route path="/admin/activity" render={() => { + if (CheckUserPermission()) + return <ActivityCard /> + else + return <Unauthorized /> + }} /> <Route path="/admin/learningObjects" - component={EducationalObject} - /> + render={() => { + if (CheckUserPermission()) + return <EducationalObject /> + else + return <Unauthorized /> + }} /> <Route - path="/admin/learningObject/:id" - component={EducationalObjectCard} - /> + path="/admin/learningObject" + render={() => { + if (CheckUserPermission()) + return <EducationalObjectCard /> + else + return <Unauthorized /> + }} /> <Route - path="/admin/learningObjectEdit/:id" - component={EducationalObjectEdit} - /> - <Route path="/admin/complaints" component={Complaints} /> - <Route path="/admin/complaint/:id" component={ComplaintCard} /> + path="/admin/learningObjectEdit" + render={() => { + if (CheckUserPermission()) + return <EducationalObjectEdit /> + else + return <Unauthorized /> + }} /> + <Route path="/admin/complaints" render={() => { + if (CheckUserPermission()) + return <Complaints /> + else + return <Unauthorized /> + }} /> + <Route path="/admin/complaint" render={() => { + if (CheckUserPermission()) + return <ComplaintCard /> + else + return <Unauthorized /> + }} /> <Route path="/admin/users/teacher_requests" - component={AproveTeacher} - /> - <Route path="/admin/usersList" component={UserList} /> - <Route path="/admin/user/:id" component={UserCard} /> - <Route path="/admin/EditUser/:id" component={EditUser} /> - <Route path="/admin/permissions" component={UserPermissions} /> - <Route path="/admin/EditPermissions/:id" component={EditRole} /> - <Route path="/admin/CreateRole" component={CreateRole} /> - <Route path="/admin/BlockedUsers" component={BlockedUser} /> - <Route path="/admin/sendEmail/:email" component={SendEmail} /> + render={() => { + if (CheckUserPermission()) + return <AproveTeacher /> + else + return <Unauthorized /> + }} /> + <Route path="/admin/usersList" render={() => { + if (CheckUserPermission()) + return <UserList /> + else + return <Unauthorized /> + }} /> + <Route path="/admin/user" render={() => { + if (CheckUserPermission()) + return <UserCard /> + else + return <Unauthorized /> + }} /> + <Route path="/admin/EditUser" render={() => { + if (CheckUserPermission()) + return <EditUser /> + else + return <Unauthorized /> + }} /> + <Route path="/admin/permissions" render={() => { + if (CheckUserPermission()) + return <UserPermissions /> + else + return <Unauthorized /> + }} /> + <Route path="/admin/EditPermissions" render={() => { + if (CheckUserPermission()) + return <EditRole /> + else + return <Unauthorized /> + }} /> + <Route path="/admin/CreateRole" render={() => { + if (CheckUserPermission()) + return <CreateRole /> + else + return <Unauthorized /> + }} /> + <Route path="/admin/BlockedUsers" render={() => { + if (CheckUserPermission()) + return <BlockedUser /> + else + return <Unauthorized /> + }} /> + <Route path="/admin/sendEmail" render={() => { + if (CheckUserPermission()) + return <SendEmail /> + else + return <Unauthorized /> + }} /> </div> </div> </Switch> diff --git a/src/Components/MenuBar.js b/src/Components/MenuBar.js index 67f91119de51c36b8912101dff158f5f9328e2d2..7cf1153b7bdf834d4694b1d7367df27fbc9319ca 100644 --- a/src/Components/MenuBar.js +++ b/src/Components/MenuBar.js @@ -107,7 +107,7 @@ export default function MenuBar(props) { { name: "Favoritos", href: "/perfil", value: '2' }, { name: "Coleções", href: "/perfil", value: '3' }, { name: "Rede", href: "/perfil", value: '4' }, - { name: "Configurações", href: "/editarperfil", value: '5'}, + { name: "Configurações", href: "/editarperfil", value: '5' }, ] if (state.currentUser.roles) { @@ -116,15 +116,15 @@ export default function MenuBar(props) { const userRoles = [...state.currentUser.roles] while (!canUserAdmin && index < userRoles.length) { - if(userRoles[index].id === 3 || userRoles[index].id === 7) + if (userRoles[index].id === 3 || userRoles[index].id === 7) canUserAdmin = true index++ } - - if(canUserAdmin) + + if (canUserAdmin) minhaArea.push({ - name: "Administrador", - href: "/admin/home", + name: "Administrador", + href: "/admin/home", value: '6', }) } @@ -186,7 +186,7 @@ export default function MenuBar(props) { </div> <MenuList items={minhaArea} /> - + </> ) : ( diff --git a/src/Components/maintenance.js b/src/Components/maintenance.js new file mode 100644 index 0000000000000000000000000000000000000000..f39358e42ef75e8ee1a1b4afbfb14abd44365340 --- /dev/null +++ b/src/Components/maintenance.js @@ -0,0 +1,19 @@ +import React from 'react' +import styled from 'styled-components' + +export default function Maintenance() { + return ( + <MaintenanceDiv> + Estamos em manuntenção. Em breve voltaremos! + </MaintenanceDiv> + ) +} + +const MaintenanceDiv = styled.div` + z-index: 1000; + position: fixed; + color:white; + background-color: red; + text-align: center; + width: 100%; +` \ No newline at end of file