From 26eb849c61c62fca32577fafc90680821d686cd3 Mon Sep 17 00:00:00 2001 From: Luis Felipe Risch <lfr20@inf.ufpr.br> Date: Fri, 14 May 2021 09:14:26 -0300 Subject: [PATCH] get the most recent admin --- src/Admin/Components/Components/AppBar.js | 73 + .../Components/Components/DisplayIcon.js | 79 - .../Components/Components/Inputs/EditUser.js | 19 +- .../Components/Inputs/EmailInputs.js | 3 +- .../MobileComponents/MobilePageHeader.js | 2 +- src/Admin/Pages/AdminLabelTabs/LabelTabs.js | 63 +- src/Admin/Pages/Pages/SubPages/Activity.js | 803 ++++----- .../Pages/Pages/SubPages/AproveTeacher.js | 1523 ++++++++--------- .../Pages/Pages/SubPages/BlockedUsers.js | 1020 +++++------ src/Admin/Pages/Pages/SubPages/Collections.js | 1164 ++++++------- .../Pages/SubPages/CommunityQuestions.js | 1170 +++++-------- src/Admin/Pages/Pages/SubPages/Complaints.js | 1387 +++++++-------- .../Pages/SubPages/EducationalObjects.js | 620 +++---- .../Pages/Pages/SubPages/Institutions.js | 1325 ++++++-------- src/Admin/Pages/Pages/SubPages/Languages.js | 790 ++++----- .../Pages/Pages/SubPages/NoteVariables.js | 596 +++---- src/Admin/Pages/Pages/SubPages/Permissions.js | 806 ++++----- src/Admin/Pages/Pages/SubPages/Questions.js | 866 ++++------ src/Admin/Pages/Pages/SubPages/Rating.js | 790 ++++----- src/Admin/Pages/Pages/SubPages/Users.js | 1050 +++++------- src/App.js | 184 +- src/env.js | 2 +- 22 files changed, 6116 insertions(+), 8219 deletions(-) create mode 100644 src/Admin/Components/Components/AppBar.js delete mode 100644 src/Admin/Components/Components/DisplayIcon.js diff --git a/src/Admin/Components/Components/AppBar.js b/src/Admin/Components/Components/AppBar.js new file mode 100644 index 00000000..b596c35f --- /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/DisplayIcon.js b/src/Admin/Components/Components/DisplayIcon.js deleted file mode 100644 index 5336574d..00000000 --- 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/EditUser.js b/src/Admin/Components/Components/Inputs/EditUser.js index 1dadf1b4..73a42e96 100644 --- a/src/Admin/Components/Components/Inputs/EditUser.js +++ b/src/Admin/Components/Components/Inputs/EditUser.js @@ -291,10 +291,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 +328,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 +380,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 +454,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 0b7a55e5..438b27cb 100644 --- a/src/Admin/Components/Components/Inputs/EmailInputs.js +++ b/src/Admin/Components/Components/Inputs/EmailInputs.js @@ -246,8 +246,7 @@ const EmailInputs = (props) => { if (role.isChecked) rolesArr.push(role.value) } - console.log(rolesArr) - console.log(sendToAll) + const api = `/email`; const body = { "email": { diff --git a/src/Admin/Components/Components/MobileComponents/MobilePageHeader.js b/src/Admin/Components/Components/MobileComponents/MobilePageHeader.js index 99405165..f3520c9f 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/Pages/AdminLabelTabs/LabelTabs.js b/src/Admin/Pages/AdminLabelTabs/LabelTabs.js index eddb77be..1c7e9ac5 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/none', + icon: <EmailRoundedIcon style={{ fill: blue }} />, }, ]; diff --git a/src/Admin/Pages/Pages/SubPages/Activity.js b/src/Admin/Pages/Pages/SubPages/Activity.js index 25d622a0..bd43798c 100644 --- a/src/Admin/Pages/Pages/SubPages/Activity.js +++ b/src/Admin/Pages/Pages/SubPages/Activity.js @@ -24,6 +24,8 @@ 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"; @@ -32,7 +34,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 } 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"; @@ -43,463 +45,382 @@ import AllOutIcon from "@material-ui/icons/AllOut"; 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="Load more" + > + <Button + key={index} + 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={index} + title={row.id} + subtitle={row.privacy} + backColor={"#673ab7"} + avatar={<AllOutIcon />} + href={`/admin/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={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={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> + <VisibilityIcon style={{ fill: "#00bcd4" }} /> + </IconButton> + </Link> + </StyledTableCell> + </StyledTableRow> + ) + )} + </TableBody> + </TableData> + </> } + } }; export default Activity; diff --git a/src/Admin/Pages/Pages/SubPages/AproveTeacher.js b/src/Admin/Pages/Pages/SubPages/AproveTeacher.js index df9cbfff..b6cbc697 100644 --- a/src/Admin/Pages/Pages/SubPages/AproveTeacher.js +++ b/src/Admin/Pages/Pages/SubPages/AproveTeacher.js @@ -18,6 +18,7 @@ along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/> import React, { useEffect, useState, useContext } 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"; @@ -25,9 +26,15 @@ import { Url } from "../../../Filters"; import { Store } from "../../../../Store"; import LoadingSpinner from "../../../../Components/LoadingSpinner"; import { - getRequest, - postRequest, + getRequest, + postRequest, } from "../../../../Components/HelperFunctions/getAxiosConfig"; +import Unauthorized from "../../../Components/Components/Unauthorized"; +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 +43,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 +51,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 { 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 [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 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 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 buildUrl = (email, submitter_request, name) => { + if (email && submitter_request && name) + return Url("users", `"submitter_request" : "${submitter_request}", "email" : "${email}", "name" : "${name}"`, currPage, "DESC") + + else if (email && name) + return Url("users", `"email" : "${email}", "name" : "${name}"`, currPage, "DESC") + else if (email && submitter_request) + return Url("users", `"email" : "${email}", "submitter_request" : "${submitter_request}"`, currPage, "DESC") + else if (name && submitter_request) + return Url("users", `"name" : "${name}", "submitter_request" : "${submitter_request}"`, currPage, "DESC") + + else if (email) + return Url("users", `"email" : "${email}"`, currPage, "DESC") + else if (submitter_request) + return Url("users", `"submitter_request" : "${submitter_request}"`, currPage, "DESC") + else if (name) + return Url("users", `"name" : ${name}`, currPage, "DESC") + else + return Url("users", "", currPage, "DESC") + } + + useEffect(() => { + if (currPage === 0) + setIsLoaded(false) + else + setIsLoadingMoreItems(true) + getRequest( + buildUrl(email, option, name), + (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]) + + 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 (CheckUserPermission()) { + 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 /> + } + ]} + > + {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={index} + 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={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={() => { + + }} + data={[ + { + title: "Email", + subtitle: row.email ? + <Link to={`/admin/sendEmail/${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}> + <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={() => { + setCurrPage(currPage + 1) + }} + > + {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> + <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> + </> + ); + } + } else return <Unauthorized />; }; export default AproveTeacher; diff --git a/src/Admin/Pages/Pages/SubPages/BlockedUsers.js b/src/Admin/Pages/Pages/SubPages/BlockedUsers.js index c89b08bd..0e2dc4da 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,463 @@ 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 [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(); + }; + + useEffect(() => { + if (currPage === 0) + setIsLoaded(false) + else + setIsLoadingMoreItems(true) + getRequest( + Url('users', `"state" : ${stateOpt}`, currPage, '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]) + + 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 /> + }, + ]} + > + <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={index} + 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={index} + 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/${row.id}`} + reset={() => { + }} + 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(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} + > + <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={() => { + setCurrPage(currPage + 1) + }} + > + { + 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(row.state)} + </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, 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/${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 763aa71e..493d50a2 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,561 @@ 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="Load more" + > + <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={index} + title={row.name} + subtitle={row.privacy} + backColor={"#e81f4f"} + avatar={<PeopleRoundedIcon />} + href={`/admin/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={row.created_at}> + <StyledTableCell> + <Button + key={index} + 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={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> + <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 8941b8c8..c3a78462 100644 --- a/src/Admin/Pages/Pages/SubPages/CommunityQuestions.js +++ b/src/Admin/Pages/Pages/SubPages/CommunityQuestions.js @@ -26,753 +26,507 @@ 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: "", + 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 [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 [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, }); - - //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"); - } - ) + }; + + 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; } - - //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"); - } - ) + else { + canUserEdit = false; } - //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; + return canUserEdit; + } + + const buildUrl = (message, email, name) => { + if (message && email && name) + return Url("contacts", `"message" : "${message}", "email" : "${email}", "name" : "${name}"`, currPage, "DESC") + + else if (message && name) + return Url("contacts", `"message" : "${message}", "name" : "${name}"`, currPage, "DESC") + else if (message && email) + return Url("contacts", `"message" : "${message}", "email" : "${email}"`, currPage, "DESC") + else if (name && email) + return Url("contacts", `"name" : "${name}", "email" : "${email}"`, currPage, "DESC") + + else if (message) + return Url("contacts", `"message" : "${message}"`, currPage, "DESC") + else if (email) + return Url("contacts", `"email" : "${email}"`, currPage, "DESC") + else if (name) + return Url("contacts", `"name" : "${name}"`, currPage, "DESC") + else + return Url("contacts", "", currPage, "DESC") + } + + useEffect(() => { + if (currPage === 0) + setIsLoaded(false) + else + setIsLoadingMoreItems(true) + getRequest( + buildUrl(message, email, name), + (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)) + } } - else { - canUserEdit = false; - } - - 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]) + + 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 (CheckUserPermission()) { + 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 /> + } + ]} + > + {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/${row.id}`} + reset={() => { + }} + data={ + [ + { + title: "Email", + subtitle: + row.email ? + <Link to={`/admin/sendEmail/${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}> + <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> - </> - } + </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> + <VisibilityIcon style={{ fill: "#00bcd4" }} /> + </IconButton> + </Link> + </StyledTableCell> + </StyledTableRow> + ) + )} + </TableBody> + </TableData> + </> + } - } else return <Unauthorized /> + } else return <Unauthorized /> } export default CommunityQuestion; diff --git a/src/Admin/Pages/Pages/SubPages/Complaints.js b/src/Admin/Pages/Pages/SubPages/Complaints.js index 452aaf76..0b1cc0a0 100644 --- a/src/Admin/Pages/Pages/SubPages/Complaints.js +++ b/src/Admin/Pages/Pages/SubPages/Complaints.js @@ -25,6 +25,10 @@ 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" +import Unauthorized from "../../../Components/Components/Unauthorized"; //imports from material ui import { withStyles } from "@material-ui/core/styles"; import TableBody from "@material-ui/core/TableBody"; @@ -33,7 +37,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 +46,604 @@ 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 { 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 [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; - } + const CheckUserPermission = () => { + let canUserEdit = false; - return canUserEdit; + 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; } - //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 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); + 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 ""; + } + }; + + 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 convertToLink = (type, id) => { - switch (type) { - case "LearningObject": - return `recurso?id=${id}/`; - case "User": - return `usuario-publico/${id}/`; - default: - return ""; + }; + + const DisplayDate = (date) => { + const convertedData = moment.utc(date); + return moment(convertedData) + .format("LLL") + .toString(); + }; + + const buildUrl = (complainOpt, state, description) => { + if (complainOpt && (state >= 0 && state <= 2) && description) + return Url("complaints", `"state" : ${state}, "complaint_reason_id" : ${complainOpt}, "description" : "${description}"`, currPage, "DESC") + + else if (complainOpt && description) + return Url("complaints", `"complaint_reason_id" : ${complainOpt}, "description" : "${description}"`, currPage, "DESC") + else if (complainOpt && (state >= 0 && state <= 2)) + return Url("complaints", `"complaint_reason_id" : ${complainOpt}, "state" : ${state}`, currPage, "DESC") + else if (description && (state >= 0 && state <= 2)) + return Url("complaints", `"description" : "${description}", "state" : ${state}`, currPage, "DESC") + + else if (complainOpt) + return Url("complaints", `"complaint_reason_id" : ${complainOpt}`, currPage, "DESC") + else if (state >= 0 && state <= 2) + return Url("complaints", `"state" : ${state}`, currPage, "DESC") + else if (description) + return Url("complaints", `"description" : ${description}`, currPage, "DESC") + else + return Url("complaints", "", currPage, "DESC") + } + + useEffect(() => { + if (currPage === 0) + setIsLoaded(false) + else + setIsLoadingMoreItems(true) + getRequest( + buildUrl(complainOption, stateOption, description), + (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 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(); - }; - - //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]) + + 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 (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: "", + }) } - ) - }, []); - - 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 /> + } + ]} + > + {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="Load more items" + > + <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={row.created_at} + title={row.complainable_type} + subtitle={row.id} + backColor={"#673ab7"} + avatar={<AnnouncementRoundedIcon />} + href={`/admin/complaint/${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}> + <TableBody> + {items.map((row, index) => + index === items.length - 1 ? ( + <StyledTableRow key={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={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={() => { + }} > - <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> + </> + ); + } + } else return <Unauthorized /> }; export default Complaints; diff --git a/src/Admin/Pages/Pages/SubPages/EducationalObjects.js b/src/Admin/Pages/Pages/SubPages/EducationalObjects.js index a4219eea..a5df3138 100644 --- a/src/Admin/Pages/Pages/SubPages/EducationalObjects.js +++ b/src/Admin/Pages/Pages/SubPages/EducationalObjects.js @@ -23,6 +23,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"; @@ -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,19 @@ 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,87 +92,25 @@ 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 [valueAuthor, setValueAuthor] = useState("") + const [description, setDescription] = useState(""); + const [valueDescription, setValueDescription] = useState("") - const DescHandler = () => { - setDescription(null) - setShowDescriptionField(!showDescriptionField); - let url; - url = Url("learning_objects", `"name" : "${search}", "author" : "${author}"`, currPage, "DESC") - Filter(url); + const AuthorHandler = (event) => { + setValueAuthor(event.target.value) }; - 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 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); - 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 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 DescHandler = (event) => { + setValueDescription(event.target.value) }; - 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); + const StandartHandler = (event) => { + setValueSearch(event.target.value) }; - // **************** About the PopOverMenu **************** //Controlls the state of the Alert Dialog const HandleStateAlertDialog = (i) => { @@ -214,47 +134,12 @@ 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"); @@ -265,9 +150,9 @@ const EducationalObjects = () => { "success", "#228B22" ); - currPage = 0; - UpdtateListData(Url("institutions", "", `${currPage}`, "DESC")); + setCurrPage(0) HandleStateCircularProgress(null); + removeItemFromList(id) } }, (error) => { @@ -277,33 +162,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,19 +185,70 @@ 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>; @@ -343,44 +267,28 @@ 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) { @@ -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> @@ -519,11 +376,7 @@ const EducationalObjects = () => { 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 ? ( @@ -543,7 +396,7 @@ const EducationalObjects = () => { avatar={<MenuBookRoundedIcon />} href={`/admin/learningObject/${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,107 +460,48 @@ 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> @@ -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 ? ( @@ -747,10 +552,7 @@ const EducationalObjects = () => { </StyledTableCell> <StyledTableCell align="right"> <Link to={`/admin/learningObject/${row.id}`}> - <IconButton onClick={() => { - currPage = 0 - - }}> + <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 d8f41e7d..cf77c1e4 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,567 @@ 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 router = useHistory() + 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 [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 buildUrl = () => { + return Url("institutions", `"name" : "${search}", "description" : "${description}", "city" : "${city}", "country" : "${country}"`, currPage, "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]) + + useEffect(() => { + setSeacrh("") + setDescription("") + setCountry("") + setCity("") + setValueOfDescription("") + setValueOfSearch("") + setValueOfCountry("") + setValueOfCity("") + setCurrPage(0) + }, [showFilter]) + + if (error) { + return <div>Error: {error.message}</div>; + } + 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="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> + ) : ( + <> + <MobileList + key={index} + title={row.name} + subtitle={row.id} + backColor={"#ff7f00"} + avatar={<AccountBalanceRoundedIcon />} + href={`/admin/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}> + <TableBody> + {items.map((row, index) => + index === items.length - 1 ? ( + <StyledTableRow key={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={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> + <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 00693f02..deb622b6 100644 --- a/src/Admin/Pages/Pages/SubPages/Languages.js +++ b/src/Admin/Pages/Pages/SubPages/Languages.js @@ -25,469 +25,399 @@ 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 [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') - } - ) + } + + //getting data from server + useEffect(() => { + if (currPage === 0) + setIsLoaded(false) + else + setIsLoadingMoreItems(true) + getRequest( + Url("languages", "", currPage, "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]) + + + 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="Load"> + <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={row.created_at} + title={row.name} + subtitle={row.id} + backColor={"#e81f4f"} + avatar={<LanguageRoundedIcon />} + href={`/admin/languageEdit/${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} + > + <TableBody> + {items.map((row, index) => ( + index === items.length - 1 ? + <StyledTableRow key="Load more"> + {/* 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={row.created_at}> + <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> + <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 16c39487..e3b15ae4 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,287 @@ 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 [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) - const [snackInfo, setSnackInfo] = useState({ - message: '', - icon: '', - open: false, - color: '', - }) + 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 - }) - } - - 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') - } - ) + useEffect(() => { + if (currPage === 0) + setIsLoaded(false) + else + setIsLoadingMoreItems(true) + getRequest( + Url("scores", "", currPage, "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) - } - ) - } + setIsLoaded(true) + setIsLoadingMoreItems(false) + }, + (error) => { + HandleSnack('Erro ao carregar os dados', true, 'warning', '#FA8072') + setIsLoadingMoreItems(false) + setIsLoaded(true) + setError(true) + } + ) + }, [currPage]) - useEffect(() => { - getRequest( - Url('scores', '', '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', 'CÓDIGO', 'PESO', 'ATIVO', 'SCORE TYPE', 'VISUALIZAR']; - 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']; - - 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 /> + }, + ]} + > + </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="Load"> + <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={row.created_at} + title={row.name} + subtitle={row.id} + backColor={"#e81f4f"} + avatar={<TrendingUpRoundedIcon />} + href={`/admin/noteVar/${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="Linguagens" + 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} + > + <TableBody> + {items.map((row, index) => ( + index === items.length - 1 ? + <StyledTableRow key="Load more"> + {/* 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={row.created_at}> + <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> + <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 a630739d..c4aba3f8 100644 --- a/src/Admin/Pages/Pages/SubPages/Permissions.js +++ b/src/Admin/Pages/Pages/SubPages/Permissions.js @@ -25,479 +25,403 @@ 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 [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); + }; + + useEffect(() => { + if (currPage === 0) + setIsLoaded(false) + else + setIsLoadingMoreItems(true) + getRequest( + Url("roles", "", currPage, "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]) + + + 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 /> + } + ]} + > + </MobilePageHeader> + + <div style={{ height: '2em' }}></div> + + {items.map((row, index) => + index === items.length - 1 ? ( + <StyledDivButton key="Load"> + <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={row.created_at} + title={row.name} + subtitle={row.id} + backColor={"#ff7f00"} + avatar={<AccountCircleRoundedIcon />} + href={`/admin/EditPermissions/${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} + > + <TableBody> + {items.map((row, index) => ( + index === items.length - 1 ? + <StyledTableRow key="Load more"> + {/* 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={row.created_at}> + <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" + 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 8118ec31..58b80d4b 100644 --- a/src/Admin/Pages/Pages/SubPages/Questions.js +++ b/src/Admin/Pages/Pages/SubPages/Questions.js @@ -26,543 +26,405 @@ 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 { 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 router = useHistory() + + 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; - 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; - } - else { - canUserEdit = false; - } - - return canUserEdit; + if (state.userIsLoggedIn) { + const roles = [...state.currentUser.roles]; + for (let i = 0; i < roles.length; i++) + if (roles[i].name === 'admin') + canUserEdit = true; } - - //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) - } - ) + else { + canUserEdit = 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) - } - ) + return canUserEdit; + } + + 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" + } + } + 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') + } + ) + } 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(); + }; + + useEffect(() => { + if (currPage === 0) + setIsLoaded(false) + else + setIsLoadingMoreItems(true) + getRequest( + Url("questions", "", currPage, "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]) + + + if (error) { + return <div>Error: {error.message}</div>; + } else if (!isLoaded) { + return <LoadingSpinner text="Carregando..." /> + } else if (CheckUserPermission()) { + 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" }} /> - </> - ) + } + ]} + > + </MobilePageHeader> + + <div style={{ height: '2em' }}></div> + + {items.map((row, index) => + index === items.length - 1 ? ( + <StyledDivButton + key="Load" + > + <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={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') + }, + } + ]} + > + </PageHeader> + + <div style={{ height: '2em' }}></div> + + <TableData + top={TOP_LABELS} + > + <TableBody> + {items.map((row, index) => ( + index === items.length - 1 ? + <StyledTableRow key="Load more"> + {/* 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={row.created_at}> + <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> + </> + ); + } + } else return <Unauthorized /> } export default Questions; diff --git a/src/Admin/Pages/Pages/SubPages/Rating.js b/src/Admin/Pages/Pages/SubPages/Rating.js index 547e140d..b6ecfe7e 100644 --- a/src/Admin/Pages/Pages/SubPages/Rating.js +++ b/src/Admin/Pages/Pages/SubPages/Rating.js @@ -20,13 +20,12 @@ 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'; @@ -35,461 +34,390 @@ import DeleteRoundedIcon from '@material-ui/icons/DeleteRounded'; 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 [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); + }; + + + useEffect(() => { + if (currPage === 0) + setIsLoaded(false) + else + setIsLoadingMoreItems(true) + getRequest( + Url("ratings", "", currPage, "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]) + + + 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="Load"> + <Button + key={index} + 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={row.created_at} + title={row.name} + subtitle={row.id} + backColor={"#00bcd4"} + avatar={<StarRoundedIcon />} + href={`/admin/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} + > + <TableBody> + {items.map((row, index) => ( + index === items.length - 1 ? + <StyledTableRow key={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={row.created_at}> + <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> + <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/Users.js b/src/Admin/Pages/Pages/SubPages/Users.js index fe3524c9..49f091d3 100644 --- a/src/Admin/Pages/Pages/SubPages/Users.js +++ b/src/Admin/Pages/Pages/SubPages/Users.js @@ -25,624 +25,522 @@ 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 router = useHistory() + 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 [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 buildUrl = (email, name) => { + if (email && name) + return Url("users", `"email" : "${email}", "name" : "${name}"`, currPage, "DESC") + if (email) + return Url("users", `"email" : "${email}"`, currPage, "DESC") + if (name) + return Url("users", `"name" : "${name}"`, currPage, "DESC") + else + return Url("users", "", currPage, "DESC") + } + + useEffect(() => { + if (currPage === 0) + setIsLoaded(false) + else + setIsLoadingMoreItems(true) + getRequest( + buildUrl(email, name), + (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]) + + 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/-1') + }, + } + ]} + > + { + 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={12}> - <Typography variant="h4"> - Lista de usuários - </Typography> - </Grid> - <Grid - item - xs={12} + </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 + } + </MobilePageHeader> + + <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={() => { + setCurrPage(currPage + 1) + }} + > + {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={() => { + }} + data={[ + { + title: "Email", + subtitle: row.email ? + <Link to={`/admin/sendEmail/${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/-1') + }, + } + ]} + > + { + 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} + > + <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={() => { + 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={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/${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 1400c7a2..7c06612f 100644 --- a/src/App.js +++ b/src/App.js @@ -35,7 +35,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 { BrowserRouter, Switch, Route } from "react-router-dom"; import { Store } from "./Store"; import TermsPage from "./Pages/TermsPage.js"; import PublicationPermissionsPage from "./Pages/PublicationPermissionsPage.js"; @@ -52,12 +52,6 @@ import FormationMaterialPage from "./Pages/FormationMaterialPage.js"; import FormationMaterialIframe from "./Pages/FormationMaterialIframe.js"; import MaterialPage from "./Pages/MaterialPage"; -//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 +90,13 @@ 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' export default function App() { // eslint-disable-next-line - const classes = useStyles(); const { dispatch } = useContext(Store); const [hideFooter, setHideFooter] = useState(false); - const [value, setValue] = React.useState(0); - - const handleChange = (event, newValue) => { - setValue(newValue); - }; useEffect(() => { setHideFooter(String(window.location.href).includes("iframe-colecao")); @@ -235,128 +178,7 @@ 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} /> diff --git a/src/env.js b/src/env.js index 82bf229b..b7359157 100644 --- a/src/env.js +++ b/src/env.js @@ -17,7 +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/>.*/ -var apiDomain = 'https://api.portalmectest.c3sl.ufpr.br', +var apiDomain = 'https://api.portalmec.c3sl.ufpr.br', apiVersion = 'v1', apiUrl = apiDomain + '/' + apiVersion; -- GitLab