From 6616b2aac9713f28bb7d72a7480bd7f29f4da7c2 Mon Sep 17 00:00:00 2001 From: Vinicius Gabriel Machado <vgm18@inf.ufpr.br> Date: Wed, 12 May 2021 14:30:08 -0300 Subject: [PATCH 01/12] fixing minnor bugs --- .../HelperFunctions/getAxiosConfig.js | 16 --------------- src/Components/MenuList.js | 3 +++ src/Components/MobileDrawerMenu.js | 4 +++- .../TabPanels/PublicUserPageTabs/TabRede.js | 18 ++++++++++++++--- src/Components/TabPanels/StyledComponents.js | 2 +- .../UserPageTabs/PanelEditarPerfil.js | 20 +++++++++---------- src/Components/UserPageComponents/Avatar.js | 2 +- src/Pages/PublicUserPage.js | 2 +- src/Pages/UserPage.js | 6 +++--- 9 files changed, 37 insertions(+), 36 deletions(-) diff --git a/src/Components/HelperFunctions/getAxiosConfig.js b/src/Components/HelperFunctions/getAxiosConfig.js index aa645cc9..6d1608bc 100644 --- a/src/Components/HelperFunctions/getAxiosConfig.js +++ b/src/Components/HelperFunctions/getAxiosConfig.js @@ -100,17 +100,9 @@ export async function getRequest (url, onSuccess, onError) { headers : fetchHeaders() }) if (response.ok) { - /*if (response.headers.has('access-token')) { - updateHeaders(response.headers) - }*/ if (response.headers.has('access-token')) { updateAccessToken(response.headers.get('access-token')) } - /*if (response.headers.has('client')) { - let auth_headers = JSON.parse(sessionStorage.getItem('@portalmec/auth_headers')) - auth_headers['client'] = response.headers.get('client') - sessionStorage.setItem('@portalmec/auth_headers', JSON.stringify(auth_headers)) - }*/ let json = await response.json() onSuccess(json, response.headers) } @@ -224,17 +216,9 @@ export async function fetchAllRequest (urls, onSuccess, onError) { var headers = [] for (let res of responses) { - /*if (checkPreviousTokens(res.headers.get('access-token'))) { - updateHeaders(res.headers) - }*/ if (res.headers.has('access-token') && res.status !== 304) { updateAccessToken(res.headers.get('access-token')) } - /*if (res.headers.has('client')) { - let auth_headers = JSON.parse(sessionStorage.getItem('@portalmec/auth_headers')) - auth_headers['client'] = res.headers.get('client') - sessionStorage.setItem('@portalmec/auth_headers', JSON.stringify(auth_headers)) - }*/ let json = await res.json().catch(err => { return {}; }) diff --git a/src/Components/MenuList.js b/src/Components/MenuList.js index 65ab3c6b..bed81e11 100644 --- a/src/Components/MenuList.js +++ b/src/Components/MenuList.js @@ -28,6 +28,7 @@ import Profile from '../img/default_profile0.png' import styled from 'styled-components' import {apiDomain} from '../env.js' import {deleteRequest} from './HelperFunctions/getAxiosConfig' +import { useHistory } from 'react-router-dom' const OverrideButton = styled(Button)` @@ -52,9 +53,11 @@ export default function MenuList(props) { userLoggedOut: !state.userIsLoggedIn, }) } + let history = useHistory() const handleLogout = () => { const url = `/auth/sign_out` deleteRequest(url, handleSuccessSignOut, (error) => {console.log(error)}) + history.push("/") } return ( diff --git a/src/Components/MobileDrawerMenu.js b/src/Components/MobileDrawerMenu.js index 469fa378..12fec2ad 100644 --- a/src/Components/MobileDrawerMenu.js +++ b/src/Components/MobileDrawerMenu.js @@ -20,7 +20,7 @@ import React, { useContext } from 'react' import { Store } from '../Store'; import Drawer from '@material-ui/core/Drawer'; import styled from 'styled-components' -import { Link } from 'react-router-dom' +import { Link, useHistory } from 'react-router-dom' import HomeIcon from '@material-ui/icons/Home'; import InfoIcon from '@material-ui/icons/Info'; import MailOutlineIcon from '@material-ui/icons/MailOutline'; @@ -102,9 +102,11 @@ export default function MobileDrawerMenu(props) { userLoggedOut: !state.userIsLoggedIn, }) } + let history = useHistory() const handleLogout = () => { const url = `/auth/sign_out` deleteRequest(url, handleSuccessSignOut, (error) => { console.log(error) }) + history.push("/") } return ( diff --git a/src/Components/TabPanels/PublicUserPageTabs/TabRede.js b/src/Components/TabPanels/PublicUserPageTabs/TabRede.js index c173dc19..a9350fd3 100644 --- a/src/Components/TabPanels/PublicUserPageTabs/TabRede.js +++ b/src/Components/TabPanels/PublicUserPageTabs/TabRede.js @@ -24,6 +24,9 @@ export default function TabRede (props) { const [followers, setFollowers] = useState([]) const [followersSlice, setFollowersSlice] = useState([]) + const [endOfFollowing, setEndOfFollowing] = useState(false) + const [endOfFollowers, setEndOfFollowers] = useState(false) + const showMoreFollowers = () => { let varSlice = followersSlice.length setFollowersSlice(followers.slice(0, varSlice + 4)) @@ -32,18 +35,25 @@ export default function TabRede (props) { const [following, setFollowing] = useState([]) const [followingSlice, setFollowingSlice] = useState([]) - const showMoreFollowing = () => { + const showMoreFollowing = (num) => { let varSlice = followingSlice.length - setFollowingSlice(following.slice(0, varSlice + 4)) + setFollowingSlice(following.slice(0, varSlice + num)) } const showAllFollowing = () => {setFollowingSlice(following)} - function handleSuccess (responseArr) { + function handleSuccess (responseArr, headersArr) { setFollowers(responseArr[0]) setFollowersSlice(responseArr[0].slice(0,4)) setFollowing(responseArr[1]) setFollowingSlice(responseArr[1].slice(0,4)) + + if (headersArr[1].has('X-Total-Count')) { + setEndOfFollowing(headersArr[1].get('X-Total-Count')); + } + if (headersArr[0].has('X-Total-Count')) { + setEndOfFollowers(headersArr[0].get('X-Total-Count')); + } } useEffect( () => { @@ -62,6 +72,7 @@ export default function TabRede (props) { showMore={showMoreFollowers} showAll={showAllFollowers} follower={true} + end={endOfFollowers} noContentText={props.username + ' não possui nenhum seguidor'} /> @@ -72,6 +83,7 @@ export default function TabRede (props) { showMore={showMoreFollowing} showAll={showAllFollowing} follower={false} + end={endOfFollowing} noContentText={props.username + ' não segue nenhum usuário'} /> </React.Fragment> diff --git a/src/Components/TabPanels/StyledComponents.js b/src/Components/TabPanels/StyledComponents.js index c8e75d5d..182fd013 100644 --- a/src/Components/TabPanels/StyledComponents.js +++ b/src/Components/TabPanels/StyledComponents.js @@ -173,7 +173,7 @@ export const UserProfileContainer = styled.div` export const CoverContainer = styled.div` height : 230px; position : relative; - @media screen and (max-width: 501px) { + @media screen and (max-width: 600px) { height : 128px } ` diff --git a/src/Components/TabPanels/UserPageTabs/PanelEditarPerfil.js b/src/Components/TabPanels/UserPageTabs/PanelEditarPerfil.js index e8d25332..ce5a319e 100644 --- a/src/Components/TabPanels/UserPageTabs/PanelEditarPerfil.js +++ b/src/Components/TabPanels/UserPageTabs/PanelEditarPerfil.js @@ -37,13 +37,13 @@ export default function TabPanelEditarPerfil(props) { const [hoverAlterarFoto, handleAlterarFoto] = React.useState(false) const [formNome, setNome] = useState({ - key: false, - value: "" + key: state.currentUser.name ? false : true, + value: state.currentUser.name ? state.currentUser.name : "" }) const [formAboutMe, setAboutMe] = useState({ - key: false, - value: "", + key: state.currentUser.description ? false : true, + value: state.currentUser.description ? state.currentUser.description : "" }) const handleHoverAlterarFoto = () => { @@ -86,14 +86,14 @@ export default function TabPanelEditarPerfil(props) { const limpaCamposForm = () => { setNome({ ...formNome, - key: false, - value: '' + key: state.currentUser.name ? false : true, + value: state.currentUser.name ? state.currentUser.name : "" }) setAboutMe({ ...formAboutMe, - key: false, - value: '' + key: state.currentUser.description ? false : true, + value: state.currentUser.description ? state.currentUser.description : "" }) } @@ -102,7 +102,7 @@ export default function TabPanelEditarPerfil(props) { const handleSubmit = (e) => { e.preventDefault() - const info = { user: { name: formNome.value, description: formAboutMe.value, email: sessionStorage.getItem('@portalmec/uid') } } + const info = { user: { name: formNome.value, description: formAboutMe.value, email: state.currentUser.email } } const flagNome = formNome.key const flagAboutMe = formAboutMe.key @@ -172,7 +172,7 @@ export default function TabPanelEditarPerfil(props) { rows="3" rowsMax="3" error={formAboutMe.key} - placeholder={"Sobre Mim"} + placeholder={"Sobre mim (visÃvel no seu perfil público)"} handleChange={e => handleChange(e, 'aboutMe')} required={false} help={formAboutMe.value.length + '/160'} diff --git a/src/Components/UserPageComponents/Avatar.js b/src/Components/UserPageComponents/Avatar.js index 368b54b6..8c381f19 100644 --- a/src/Components/UserPageComponents/Avatar.js +++ b/src/Components/UserPageComponents/Avatar.js @@ -68,7 +68,7 @@ const ProfileAvatarDiv = styled.div` outline : 0; cursor : pointer; background-color : #a5a5a5; - @media screen and (max-width: 501px) { + @media screen and (max-width: 600px) { height : 73px; width : 73px; position:absolute; diff --git a/src/Pages/PublicUserPage.js b/src/Pages/PublicUserPage.js index 0f2a14d5..2571305e 100644 --- a/src/Pages/PublicUserPage.js +++ b/src/Pages/PublicUserPage.js @@ -226,7 +226,7 @@ export default function PublicUserPage(props) { { tabs.map((tab) => <Tab label={tab} key={tab} - disabled={(tab === "Recursos" && learningObjArr.length === 0) || (tab === "Coleções" && collectionsArr.length === 0)} + disabled={(tab === "Recursos" && learningObjArr.length === 0) || (tab === "Coleções" && collectionsArr.length === 0) || (tab === "Rede" && state.currentUser.id === '')} /> ) } diff --git a/src/Pages/UserPage.js b/src/Pages/UserPage.js index 259522a0..2688500e 100644 --- a/src/Pages/UserPage.js +++ b/src/Pages/UserPage.js @@ -144,10 +144,10 @@ export default function UserPage(props) { <HeaderContainer> <Cover id={id} /> <ProfileAvatar id={id} /> - {WIDTH <= 501 ? null : <UserInfo />} + {WIDTH <= 600 ? null : <UserInfo />} <EditProfileButton /> </HeaderContainer> - {WIDTH <= 501 ? ( + {WIDTH <= 600 ? ( <Grid style={{ marginTop: "4em" }} container @@ -210,7 +210,7 @@ export default function UserPage(props) { indicatorColor="primary" textColor="primary" variant="scrollable" - scrollButtons="auto" + scrollButtons="on" TabIndicatorProps={{ style: { background: "#00bcd4" }, }} -- GitLab From 28459f13fb423e93ac1554b2a14b43e07ba34b9b Mon Sep 17 00:00:00 2001 From: Luis Felipe Risch <lfr20@inf.ufpr.br> Date: Thu, 13 May 2021 10:25:45 -0300 Subject: [PATCH 02/12] fixed anchor bug and added a logic to scroll to the top when user enters in some tab of the help or about --- src/Components/EcFooter.js | 64 +++++---- src/Components/HomeScreenSearchBar.js | 180 +++++++++++++------------- src/Pages/AboutPage.js | 105 ++++++++------- src/Pages/Contact.js | 7 +- src/Pages/HelpCenter.js | 94 +++++++------- src/Pages/TabsHelp/TabManageAc.js | 52 ++++---- src/Pages/TabsHelp/TabNetPart.js | 72 +++++------ src/Pages/TabsHelp/TabResourseFind.js | 71 +++++----- src/Pages/TabsHelp/TabResoursePub.js | 76 +++++------ src/Pages/UserTerms.js | 175 +++++++++++++------------ src/env.js | 2 +- 11 files changed, 456 insertions(+), 442 deletions(-) diff --git a/src/Components/EcFooter.js b/src/Components/EcFooter.js index 2bdf8a2f..eca582f2 100644 --- a/src/Components/EcFooter.js +++ b/src/Components/EcFooter.js @@ -16,11 +16,11 @@ 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, {Component} from 'react'; -import {Row, Col, Container} from 'react-grid-system'; +import React, { Component } from 'react'; +import { Row, Col, Container } from 'react-grid-system'; import eduConectada from '../img/educa-conectada.png'; import styled from 'styled-components'; -import {Link} from 'react-router-dom' +import { HashLink as Link } from 'react-router-hash-link'; const BlueFooter = styled.div` background-color : #00bcd4; @@ -30,12 +30,10 @@ const BlueFooter = styled.div` @media screen and (min-width : 502px) { padding-bottom : 2em; } - - vertical-align: bottom; ` -const listStyle={ +const listStyle = { listStyleType: "none", fontSize: "80%", padding: "0", @@ -46,35 +44,35 @@ const WhiteLink = styled(Link)` color: white; ` -class EcFooter extends Component{ - render(){ - return( +class EcFooter extends Component { + render() { + return ( <BlueFooter> <Container> - <Row> - <Col md={4} sm={6} xs={6} style={window.innerWidth < 502 && {textAlign : "center"} }> - <h4>Sobre</h4> - <ul style={listStyle}> - <li> <WhiteLink to="/sobre">Sobre a Plataforma</WhiteLink> </li> - <li> <WhiteLink to="/sobre#portaisparceiros">Portais Parceiros</WhiteLink> </li> - <li> <WhiteLink to="/termos">Termos de Uso</WhiteLink> </li> - <li> <WhiteLink to="/contato">Contato</WhiteLink> </li> - </ul> - </Col> - <Col md={4} sm={6} xs={6} style={window.innerWidth < 502 && {textAlign : "center"} }> - <h4>Ajuda</h4> - <ul style={listStyle}> - <li> <WhiteLink to="/ajuda">Central de Ajuda</WhiteLink> </li> - <li> <WhiteLink to="/publicando-recurso">Publicando Recursos</WhiteLink> </li> - <li> <WhiteLink to="/encontrando-recurso">Encontrando Recursos</WhiteLink> </li> - <li> <WhiteLink to="/participando-da-rede">Participando da Rede</WhiteLink> </li> - <li> <WhiteLink to="/gerenciando-conta">Gerenciando a Conta</WhiteLink> </li> - </ul> - </Col> - <Col md={4} sm={12} xs={12} style={window.innerWidth < 502 && {textAlign : "center"} }> - <img src={eduConectada} height="50%" alt="logo educação conectada"/> - </Col> - </Row> + <Row> + <Col md={4} sm={6} xs={6} style={window.innerWidth < 502 && { textAlign: "center" }}> + <h4>Sobre</h4> + <ul style={listStyle}> + <li> <WhiteLink to="/sobre">Sobre a Plataforma</WhiteLink> </li> + <li> <WhiteLink to="/sobre#portaisparceiros">Portais Parceiros</WhiteLink> </li> + <li> <WhiteLink to="/termos">Termos de Uso</WhiteLink> </li> + <li> <WhiteLink to="/contato">Contato</WhiteLink> </li> + </ul> + </Col> + <Col md={4} sm={6} xs={6} style={window.innerWidth < 502 && { textAlign: "center" }}> + <h4>Ajuda</h4> + <ul style={listStyle}> + <li> <WhiteLink to="/ajuda">Central de Ajuda</WhiteLink> </li> + <li> <WhiteLink to="/publicando-recurso">Publicando Recursos</WhiteLink> </li> + <li> <WhiteLink to="/encontrando-recurso">Encontrando Recursos</WhiteLink> </li> + <li> <WhiteLink to="/participando-da-rede">Participando da Rede</WhiteLink> </li> + <li> <WhiteLink to="/gerenciando-conta">Gerenciando a Conta</WhiteLink> </li> + </ul> + </Col> + <Col md={4} sm={12} xs={12} style={window.innerWidth < 502 && { textAlign: "center" }}> + <img src={eduConectada} height="50%" alt="logo educação conectada" /> + </Col> + </Row> </Container> </BlueFooter> ) diff --git a/src/Components/HomeScreenSearchBar.js b/src/Components/HomeScreenSearchBar.js index 4427eb29..ef12b7cc 100644 --- a/src/Components/HomeScreenSearchBar.js +++ b/src/Components/HomeScreenSearchBar.js @@ -27,55 +27,55 @@ import ArrowDropDownIcon from '@material-ui/icons/ArrowDropDown'; import SearchIcon from '@material-ui/icons/Search'; /*import {Link} from 'react-router-dom'*/ -export default function HomeScreenSearchBar (props) { - const [ query, setQuery ] = useState("") - const [ searchClass, setSearchClass ] = useState('LearningObject') +export default function HomeScreenSearchBar(props) { + const [query, setQuery] = useState("") + const [searchClass, setSearchClass] = useState('LearningObject') const { state, dispatch } = useContext(Store) - const [ goSearch, setGoSearch ] = useState(false) - - useEffect(()=>{ - if(window.location.pathname.includes('busca')){ - const urlParams = new URLSearchParams(window.location.search) - const urlQuery = urlParams.get('query') - const urlSearchClass = urlParams.get('search_class') - if( searchClass !== urlSearchClass || query !== urlQuery){ - setQuery(urlQuery) - setSearchClass(urlSearchClass) - } + const [goSearch, setGoSearch] = useState(false) + + useEffect(() => { + if (window.location.pathname.includes('busca')) { + const urlParams = new URLSearchParams(window.location.search) + const urlQuery = urlParams.get('query') + const urlSearchClass = urlParams.get('search_class') + if (searchClass !== urlSearchClass || query !== urlQuery) { + setQuery(urlQuery) + setSearchClass(urlSearchClass) + } } - },[]) + }, []) - useEffect(()=>setGoSearch(false),[goSearch]) + useEffect(() => setGoSearch(false), [goSearch]) - const handleChange = ( event ) => { - setQuery(event.target.value) + const handleChange = (event) => { + setQuery(event.target.value) } const handleKeyDown = (event) => { - if(event.key === 'Enter' || event.type === 'click'){ - dispatch({ - type: 'SAVE_SEARCH', - newSearch: { - query: query !== '' ? query: '*', - class: searchClass - } - }) - setGoSearch(true) - } + if (event.key === 'Enter' || event.type === 'click') { + dispatch({ + type: 'SAVE_SEARCH', + newSearch: { + query: query !== '' ? query : '*', + class: searchClass + } + }) + setGoSearch(true) + } } const options = [ - {text : "Recursos", value : "LearningObject", color : "#ff7f00"}, - {text : "Coleções", value : "Collection", color : "#673ab7"}, - {text : "Usuários", value : "User", color : "#00bcd4"}, + { text: "Recursos", value: "LearningObject", color: "#ff7f00" }, + { text: "Coleções", value: "Collection", color: "#673ab7" }, + { text: "Usuários", value: "User", color: "#00bcd4" }, ] const [anchorEl, setAnchorEl] = React.useState(null); const [selectedIndex, setSelectedIndex] = React.useState(0); const handleClickListItem = (event) => { - setAnchorEl(event.currentTarget); + setAnchorEl(event.currentTarget); }; const handleMenuItemClick = (event, index, value) => { @@ -93,69 +93,69 @@ export default function HomeScreenSearchBar (props) { return ( - <StyledGrid container> - {goSearch && <Redirect to={`/busca?query=${state.search.query}&search_class=${state.search.class}`} />} - <Grid item md={7} xs={12} className="first white"> - <StyledTextField - id="standard-search" - placeholder="O que está buscando?" - type="search" - margin="normal" - value={query} - onChange={handleChange} - onKeyPress={handleKeyDown} - fullwidth + <StyledGrid container> + {goSearch && <Redirect to={`/busca?query=${state.search.query}&search_class=${state.search.class}`} />} + <Grid item md={7} xs={12} className="first white"> + <StyledTextField + id="standard-search" + placeholder="O que está buscando?" + type="search" + margin="normal" + value={query} + onChange={handleChange} + onKeyPress={handleKeyDown} + fullwidth + /> + </Grid> + <Grid item md={3} xs={12} className="second white"> + <List component="nav" aria-label="Recurso"> + <ListItem + button + aria-haspopup="true" + aria-controls="lock-menu" + aria-label="Recurso" + onClick={handleClickListItem} + > + <ListItemText + style={{ color: options[selectedIndex].color }} + primary={options[selectedIndex].text} /> - </Grid> - <Grid item md={3} xs={12} className="second white"> - <List component="nav" aria-label="Recurso"> - <ListItem - button - aria-haspopup="true" - aria-controls="lock-menu" - aria-label="Recurso" - onClick={handleClickListItem} - > - <ListItemText - style={{color : options[selectedIndex].color}} - primary={options[selectedIndex].text} - /> - <ListItemIcon> - <ArrowDropDownIcon/> - </ListItemIcon> - </ListItem> - </List> - <Menu - id="simple-menu" - anchorEl={anchorEl} - keepMounted - open={Boolean(anchorEl)} - onClose={handleClose} - > - {options.map((option, index) => ( - <MenuItem + <ListItemIcon> + <ArrowDropDownIcon /> + </ListItemIcon> + </ListItem> + </List> + <Menu + id="simple-menu" + anchorEl={anchorEl} + keepMounted + open={Boolean(anchorEl)} + onClose={handleClose} + > + {options.map((option, index) => ( + <MenuItem key={option.value} selected={index === selectedIndex} onClick={(event) => handleMenuItemClick(event, index, option.value)} - style={{color : option.color}} - > + style={{ color: option.color }} + > {option.text} - </MenuItem> - ))} - </Menu> - </Grid> - <Grid item md={2} xs={12}> - <div style={{height : "100%"}}> - <Button onClick={handleKeyDown} className="custom-button" style={{backgroundColor : options[selectedIndex].color, color : "#fff"}}> - { - WIDTH < 503 && - <span>Buscar</span> - } - <SearchIcon fontSize="large"/> - </Button> - </div> - </Grid> - </StyledGrid> + </MenuItem> + ))} + </Menu> + </Grid> + <Grid item md={2} xs={12}> + <div style={{ height: "100%" }}> + <Button onClick={handleKeyDown} className="custom-button" style={{ backgroundColor: options[selectedIndex].color, color: "#fff" }}> + { + WIDTH < 503 && + <span>Buscar</span> + } + <SearchIcon fontSize="large" /> + </Button> + </div> + </Grid> + </StyledGrid> ) } diff --git a/src/Pages/AboutPage.js b/src/Pages/AboutPage.js index 56b84041..98fdfd05 100644 --- a/src/Pages/AboutPage.js +++ b/src/Pages/AboutPage.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 from 'react'; +import React, { useEffect } from 'react'; import Grid from '@material-ui/core/Grid'; import styled from 'styled-components'; import Modal from '../Components/ModalAbout'; @@ -551,26 +551,31 @@ const Secao8 = styled.div` export default function AboutPage(props) { var pageWidth = window.innerWidth - const calculateMargin = ((pageWidth)=>{ - if (pageWidth > 700 && pageWidth <= 850){ + const calculateMargin = ((pageWidth) => { + if (pageWidth > 700 && pageWidth <= 850) { return "40%" } - if (pageWidth > 850 && pageWidth <= 900){ + if (pageWidth > 850 && pageWidth <= 900) { return "25%" } - if (pageWidth > 900 && pageWidth < 1100){ + if (pageWidth > 900 && pageWidth < 1100) { return "13%" } - else{ + else { return "0%" } }) var marginSet = calculateMargin(pageWidth) - const styleIMGSec3 = {float:"right", width:"80%", maxWidth:475, marginRight:30, marginTop: marginSet} + const styleIMGSec3 = { float: "right", width: "80%", maxWidth: 475, marginRight: 30, marginTop: marginSet } + + useEffect(() => { + window.scrollTo(0, 0) + }, []) + return ( <> - <link href="https://fonts.googleapis.com/css?family=Pompiere|Roboto:300,400&display=swap" rel="stylesheet"/> + <link href="https://fonts.googleapis.com/css?family=Pompiere|Roboto:300,400&display=swap" rel="stylesheet" /> <Secao1> <iframe title="VÃdeo página sobre" src="https://player.vimeo.com/video/231609051" width="100%" height="100%" frameBorder="0" allow="autoplay; fullscreen" allowFullScreen></iframe> @@ -582,7 +587,7 @@ export default function AboutPage(props) { <div className="container-secao"> <div className="conteudo-secao"> <h2>Um Pouco da História</h2> - <p style={{marginLeft:20, marginRight:20, marginBottom:40}}> + <p style={{ marginLeft: 20, marginRight: 20, marginBottom: 40 }}> A partir de uma iniciativa do Ministério da Educação, surge em outubro de 2015 a proposta de reunir e disponibilizar, em um único lugar, os Recursos Educacionais Digitais dos principais @@ -592,13 +597,13 @@ export default function AboutPage(props) { da Educação Básica de todo o Brasil. Assim, a Plataforma MEC pretende se tornar uma referência em Recursos Educacionais Digitais, como um ambiente de busca, interação e colaboração - entre professoras(es)!<br/><br/>Faça parte deste espaço de + entre professoras(es)!<br /><br />Faça parte deste espaço de colaborativo você também! </p> <img src={Agpl} alt="agpl" /> <p> Este programa é software livre, sob os termos da - <a href="https://www.gnu.org/licenses/agpl-3.0.en.html" rel="noreferrer" target="_blank"> licença GNU/AGPL</a><br/> + <a href="https://www.gnu.org/licenses/agpl-3.0.en.html" rel="noreferrer" target="_blank"> licença GNU/AGPL</a><br /> Seu código fonte está disponÃvel no <a href="https://gitlab.c3sl.ufpr.br/portalmec/portalmec" rel="noreferrer" target="_blank">GitLab</a> </p> @@ -613,7 +618,7 @@ export default function AboutPage(props) { <div className="container-secao"> <div className="conteudo-secao"> <Grid container spacing={0}> - <Grid item xs style={{paddingRight:20}}> + <Grid item xs style={{ paddingRight: 20 }}> <h2>O que nos faz diferentes?</h2> <h3>Espaço construÃdo por e para professores</h3> <p> @@ -630,19 +635,19 @@ export default function AboutPage(props) { </p> <h3>Todos os recursos em um só lugar</h3> <p> - Aqui você consegue otimizar o seu tempo! A plataforma integra - os Recursos Educacionais Digitais dos principais portais abertos. + Aqui você consegue otimizar o seu tempo! A plataforma integra + os Recursos Educacionais Digitais dos principais portais abertos. </p> </Grid> { - pageWidth >= 751? - <Grid item xs={6} style={{position:"relative"}}> - <img src={Notebook} alt="Imagem Notebook" style={styleIMGSec3}/> - </Grid> - : - <div/> + pageWidth >= 751 ? + <Grid item xs={6} style={{ position: "relative" }}> + <img src={Notebook} alt="Imagem Notebook" style={styleIMGSec3} /> + </Grid> + : + <div /> } - + </Grid> @@ -651,10 +656,10 @@ export default function AboutPage(props) { </div> </Secao3> - - + + <Secao4> - <div className="container"> + <div className="container"> <div className="container-secao" id="portaisparceiros"> <div className="conteudo-secao" > <div> @@ -662,18 +667,18 @@ export default function AboutPage(props) { <p>Aqui na Plataforma você encontra os Recursos Digitais dos principais portais do MEC e de vários outros parceiros.</p> </div> - <AboutCarouselPartner/> - + <AboutCarouselPartner /> + <div> <h3>Você busca Recursos Educacionais Digitais em outros sites?</h3> <p> - Você gostaria que a plataforma tivesse os recursos do site que - você acessa?<br/>Deixe a sua sugestão pra que juntos possamos + Você gostaria que a plataforma tivesse os recursos do site que + você acessa?<br />Deixe a sua sugestão pra que juntos possamos avançar na integração dos mais variados recursos. </p> </div> - <div style={{marginTop:"30px"}}> - <Modal/> + <div style={{ marginTop: "30px" }}> + <Modal /> </div> </div> @@ -686,7 +691,7 @@ export default function AboutPage(props) { <div className="container-secao"> <div className="conteudo-secao"> <h2>AQUI VOCÊ É PROTAGONISTA</h2> - <br/> + <br /> <p> Construa conosco a plataforma e amplie sua rede de conhecimento interagindo com pessoas envolvidas com experiências que ocorrem em todo o Brasil! @@ -697,20 +702,20 @@ export default function AboutPage(props) { </Secao5> <Secao6> - <div className="container"> - <div className="container-secao"> - <div className="conteudo-secao"> - <div> - <h2>Aqui você pode:</h2> + <div className="container"> + <div className="container-secao"> + <div className="conteudo-secao"> + <div> + <h2>Aqui você pode:</h2> - </div> - <div> - <AboutCarousel/> - </div> + </div> + <div> + <AboutCarousel /> + </div> + </div> </div> </div> - </div> </Secao6> <Secao7> @@ -720,7 +725,7 @@ export default function AboutPage(props) { <div className="cabecalho"> <h2>A quem se destina?</h2> <p>A plataforma é aberta e destina-se a todos e todas que se - interessam<br/>pela relação entre a escola e a Cultura Digital:</p> + interessam<br />pela relação entre a escola e a Cultura Digital:</p> </div> <div> <Grid container spacing={3}> @@ -776,18 +781,18 @@ export default function AboutPage(props) { </Secao7> <Secao8> - <div className="container"> - <div className="container-secao"> - <div className="conteudo-secao"> + <div className="container"> + <div className="container-secao"> + <div className="conteudo-secao"> - <h2>Ficou alguma dúvida? Gostaria de fazer alguma sugestão ou crÃtica? Construa conosco.</h2> - <div> - <button><a href="contato">ENTRAR EM CONTATO</a></button> - </div> + <h2>Ficou alguma dúvida? Gostaria de fazer alguma sugestão ou crÃtica? Construa conosco.</h2> + <div> + <button><a href="contato">ENTRAR EM CONTATO</a></button> + </div> + </div> </div> </div> - </div> </Secao8> </> ); diff --git a/src/Pages/Contact.js b/src/Pages/Contact.js index cf2b6458..181e16d4 100644 --- a/src/Pages/Contact.js +++ b/src/Pages/Contact.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 from "react"; +import React, { useEffect } from "react"; import styled from "styled-components"; import Banner1 from "../img/banner-sobre.jpg"; import InputFormulario from "../Components/ContactForm.js"; @@ -137,6 +137,11 @@ const Formulario = styled.div` `; function Contact(props) { + + useEffect(() => { + window.scrollTo(0, 0) + }) + return ( <> <link diff --git a/src/Pages/HelpCenter.js b/src/Pages/HelpCenter.js index f70481b0..8b5ae509 100644 --- a/src/Pages/HelpCenter.js +++ b/src/Pages/HelpCenter.js @@ -16,10 +16,10 @@ 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 React, { useEffect } from 'react'; import styled from 'styled-components'; import Grid from '@material-ui/core/Grid'; -import { Link } from 'react-router-dom'; +import { Link } from 'react-router-dom'; @@ -36,20 +36,22 @@ import CardGerenciando from '../Components/HelpCenter/Cards/CardGerenciando'; function HelpCenter(props) { let windowWidth = window.innerWidth - return( - <div style={{backgroundColor: "#f4f4f4"}}> - <link href="https://fonts.googleapis.com/css?family=Pompiere|Roboto:300,400&display=swap" rel="stylesheet"/> + useEffect(() => { window.scrollTo(0, 0) }, []) + + return ( + <div style={{ backgroundColor: "#f4f4f4" }}> + <link href="https://fonts.googleapis.com/css?family=Pompiere|Roboto:300,400&display=swap" rel="stylesheet" /> <Secao1> - <div className= "container"> + <div className="container"> { - windowWidth > 420? - <img src={Banner3} alt="banner3"/> - : - <div/> + windowWidth > 420 ? + <img src={Banner3} alt="banner3" /> + : + <div /> } - <div className= "conteudo"> - <div className= "title"> + <div className="conteudo"> + <div className="title"> <h2>OLÃ! COMO PODEMOS AJUDAR?</h2> </div> </div> @@ -64,18 +66,18 @@ function HelpCenter(props) { <h2>Tópicos de Ajuda</h2> </div> <div> - <Grid container justify="center" style={{margin:-8}}> - <Grid item xs={12} md={5} style={{padding:8}}> - <CardPublicando/> + <Grid container justify="center" style={{ margin: -8 }}> + <Grid item xs={12} md={5} style={{ padding: 8 }}> + <CardPublicando /> </Grid> - <Grid item xs={12} md={5} style={{padding:8}}> - <CardEncontrando/> + <Grid item xs={12} md={5} style={{ padding: 8 }}> + <CardEncontrando /> </Grid> - <Grid item xs={12} md={5} style={{padding:8}}> - <CardParticipando/> + <Grid item xs={12} md={5} style={{ padding: 8 }}> + <CardParticipando /> </Grid> - <Grid item xs={12} md={5} style={{padding:8}}> - <CardGerenciando/> + <Grid item xs={12} md={5} style={{ padding: 8 }}> + <CardGerenciando /> </Grid> </Grid> </div> @@ -84,10 +86,10 @@ function HelpCenter(props) { </div> </Secao2> - <div style={{width:"100%"}}> - <Secao3> - <Grid style={{height:"100%"}} container justify="center"> - <Grid style={{backgroundColor: "#333",paddingInline:"0" }} item xs={12} md={6}> + <div style={{ width: "100%" }}> + <Secao3> + <Grid style={{ height: "100%" }} container justify="center"> + <Grid style={{ backgroundColor: "#333", paddingInline: "0" }} item xs={12} md={6}> <iframe title="VÃdeo página ajuda" src="https://player.vimeo.com/video/231609051" width="100%" height="100%" frameborder="0" allow="autoplay; fullscreen" allowfullscreen></iframe> </Grid> <Grid item xs={12} md={6}> @@ -102,39 +104,39 @@ function HelpCenter(props) { <Grid container> <Grid item xs={12} md={6}> <p className="links"> - <br/> + <br /> <Link to={{ - pathname : 'plataforma-mec', - state : {value : '0'} + pathname: 'plataforma-mec', + state: { value: '0' } }}>O que é a Plataforma MEC</Link> - <br/> + <br /> <Link to={{ - pathname : 'plataforma-mec', - state : {value : '1'} - }}>Como foi construida a Plataforma<br/>MEC?</Link> - <br/> + pathname: 'plataforma-mec', + state: { value: '1' } + }}>Como foi construida a Plataforma<br />MEC?</Link> + <br /> <Link to={{ - pathname : 'plataforma-mec', - state : {value : '3'} + pathname: 'plataforma-mec', + state: { value: '3' } }}>Quais são os Portais Parceiros?</Link> </p> </Grid> <Grid item xs={12} md={6}> <p className="links"> - <br/> + <br /> <Link to={{ - pathname : 'plataforma-mec', - state : {value : '2'} + pathname: 'plataforma-mec', + state: { value: '2' } }}>Entendendo as 3 áreas</Link> - <br/> + <br /> <Link to={{ - pathname : 'plataforma-mec', - state : {value : '4'} + pathname: 'plataforma-mec', + state: { value: '4' } }}>Tipos de recursos</Link> - <br/> + <br /> <Link to={{ - pathname : 'plataforma-mec', - state : {value : '5'} + pathname: 'plataforma-mec', + state: { value: '5' } }}>Softwares especÃficos</Link> </p> </Grid> @@ -150,8 +152,8 @@ function HelpCenter(props) { <div className="conteudo"> <h2>Não encontrou o que você precisa?</h2> <span>Entre em contato com a nossa Central de Ajuda</span> - <br/> - <button style={{marginBottom:50, marginTop:20}}><a href="contato">ENTRAR EM CONTATO</a></button> + <br /> + <button style={{ marginBottom: 50, marginTop: 20 }}><a href="contato">ENTRAR EM CONTATO</a></button> </div> </div> diff --git a/src/Pages/TabsHelp/TabManageAc.js b/src/Pages/TabsHelp/TabManageAc.js index 9aa293b3..a8280274 100644 --- a/src/Pages/TabsHelp/TabManageAc.js +++ b/src/Pages/TabsHelp/TabManageAc.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, { useState } from "react"; +import React, { useState, useEffect } from "react"; import styled from "styled-components"; import Tabs from "@material-ui/core/Tabs"; import Tab from "@material-ui/core/Tab"; @@ -49,6 +49,8 @@ export default function TabManageAc(props) { setTabValue(newValue); }; + useEffect(() => { window.scrollTo(0, 0) }, []) + return ( <div style={{ backgroundColor: "#f4f4f4" }}> <link @@ -73,19 +75,19 @@ export default function TabManageAc(props) { <img src={GerenciandoConta} alt="Gerenciando a conta" /> <span>{tabs[5]}</span> </div> - <TabsStyled orientation = "vertical" - variant = "scrollable" - value = {tabValue} - onChange = {handleChangeTab} - TabIndicatorProps = {{style:{display: "none"}}} + <TabsStyled orientation="vertical" + variant="scrollable" + value={tabValue} + onChange={handleChangeTab} + TabIndicatorProps={{ style: { display: "none" } }} > - <TabStyled label={tabs[0]}></TabStyled> - <TabStyled label={tabs[1]}></TabStyled> - <TabStyled label={tabs[2]}></TabStyled> - <TabStyled label={tabs[3]}></TabStyled> - <TabStyled label={tabs[4]}></TabStyled> + <TabStyled label={tabs[0]}></TabStyled> + <TabStyled label={tabs[1]}></TabStyled> + <TabStyled label={tabs[2]}></TabStyled> + <TabStyled label={tabs[3]}></TabStyled> + <TabStyled label={tabs[4]}></TabStyled> </TabsStyled> - <br/> + <br /> <div className="voltarInicio"> <a href="ajuda">VOLTAR AO ÃNICIO</a> </div> @@ -104,21 +106,21 @@ export default function TabManageAc(props) { </div> </Principal> - </Grid> - </Grid> + </Grid> + </Grid> + - <Grid style={{ marginBottom: "50px" }} container justify={"center"}> - <Grid item xs={12} md={3} style={{margin:5}}> - <CardPublicando /> - </Grid> - <Grid item xs={12} md={3} style={{margin:5}}> - <CardEncontrando /> - </Grid> - <Grid item xs={12} md={3} style={{margin:5}}> - <CardParticipando /> - </Grid> - </Grid> + <Grid item xs={12} md={3} style={{ margin: 5 }}> + <CardPublicando /> + </Grid> + <Grid item xs={12} md={3} style={{ margin: 5 }}> + <CardEncontrando /> + </Grid> + <Grid item xs={12} md={3} style={{ margin: 5 }}> + <CardParticipando /> + </Grid> + </Grid> </Secao> </div> ); diff --git a/src/Pages/TabsHelp/TabNetPart.js b/src/Pages/TabsHelp/TabNetPart.js index 107a998b..c08e3ea1 100644 --- a/src/Pages/TabsHelp/TabNetPart.js +++ b/src/Pages/TabsHelp/TabNetPart.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, { useState } from 'react'; +import React, { useState, useEffect } from 'react'; import styled from 'styled-components'; import Tabs from '@material-ui/core/Tabs' import Tab from '@material-ui/core/Tab'; @@ -28,7 +28,7 @@ import What from '../../Components/HelpCenter/TabsNetPart/What' import CardEncontrando from '../../Components/HelpCenter/Cards/CardEncontrando'; import CardPublicando from '../../Components/HelpCenter/Cards/CardPublicando'; import CardGerenciando from '../../Components/HelpCenter/Cards/CardGerenciando'; -import { Link } from 'react-router-dom'; +import { Link } from 'react-router-dom'; @@ -36,25 +36,25 @@ import { Link } from 'react-router-dom'; -export default function TabNetPart (props) { - const tabs= [ +export default function TabNetPart(props) { + const tabs = [ 'Como comentar ou avaliar um recurso?', 'Que tipo de comentário posso fazer sobre o recurso?', 'Participando da Rede' ] - + const [tabValue, setTabValue] = useState(props.location.state === "undefined" ? 0 : props.location.state); const handleChangeTab = (e, newValue) => { setTabValue(newValue) -} + } + useEffect(() => { window.scrollTo(0, 0) }, []) + return ( + <div style={{ backgroundColor: "#f4f4f4" }}> + <link href="https://fonts.googleapis.com/css?family=Pompiere|Roboto:500,400&display=swap" rel="stylesheet" /> - return( - <div style={{backgroundColor:"#f4f4f4"}}> - <link href="https://fonts.googleapis.com/css?family=Pompiere|Roboto:500,400&display=swap" rel="stylesheet"/> - <Secao> <BreadCrumbsDiv> <StyledBreadCrumbs> @@ -64,7 +64,7 @@ export default function TabNetPart (props) { <Link to="ajuda" > Ajuda </Link> - + <span> {tabs[2]} </span> @@ -78,26 +78,26 @@ export default function TabNetPart (props) { <Principal> <Menu> <div className="fixo"> - <img src={ParticipandoRede} alt="Participando da Rede"/> + <img src={ParticipandoRede} alt="Participando da Rede" /> <span>{tabs[2]}</span> </div> - <TabsStyled orientation = "vertical" - variant = "scrollable" - value = {tabValue} - onChange = {handleChangeTab} - TabIndicatorProps = {{style:{display: "none"}}} + <TabsStyled orientation="vertical" + variant="scrollable" + value={tabValue} + onChange={handleChangeTab} + TabIndicatorProps={{ style: { display: "none" } }} > - <TabStyled label={tabs[0]}></TabStyled> - <TabStyled label={tabs[1]}></TabStyled> + <TabStyled label={tabs[0]}></TabStyled> + <TabStyled label={tabs[1]}></TabStyled> </TabsStyled> - <br/> + <br /> <div className="voltarInicio"> <a href="ajuda">VOLTAR AO ÃNICIO</a> </div> </Menu> - {tabValue === 0 && <How title={tabs[0]}/>} - {tabValue === 1 && <What title={tabs[1]}/>} + {tabValue === 0 && <How title={tabs[0]} />} + {tabValue === 1 && <What title={tabs[1]} />} <div className="resultadosProcura"> <span>Não era bem o que você procurava?</span> <div className="subtitulo"> @@ -106,21 +106,21 @@ export default function TabNetPart (props) { </div> </Principal> - </Grid> + </Grid> + </Grid> + + + <Grid style={{ paddingBottom: "50px" }} container justify={"center"}> + <Grid item xs={12} md={3} style={{ margin: 5 }}> + <CardPublicando /> + </Grid> + <Grid item xs={12} md={3} style={{ margin: 5 }}> + <CardEncontrando /> + </Grid> + <Grid item xs={12} md={3} style={{ margin: 5 }}> + <CardGerenciando /> + </Grid> </Grid> - - - <Grid style={{paddingBottom:"50px"}} container justify={"center"}> - <Grid item xs={12} md={3} style={{margin:5}}> - <CardPublicando/> - </Grid> - <Grid item xs={12} md={3} style={{margin:5}}> - <CardEncontrando/> - </Grid> - <Grid item xs={12} md={3} style={{margin:5}}> - <CardGerenciando/> - </Grid> - </Grid> </Secao> diff --git a/src/Pages/TabsHelp/TabResourseFind.js b/src/Pages/TabsHelp/TabResourseFind.js index 8691d282..3ea89256 100644 --- a/src/Pages/TabsHelp/TabResourseFind.js +++ b/src/Pages/TabsHelp/TabResourseFind.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, { useState } from 'react'; +import React, { useState, useEffect } from 'react'; import styled from 'styled-components'; import Tabs from '@material-ui/core/Tabs' import Tab from '@material-ui/core/Tab'; @@ -29,7 +29,7 @@ import HowToFilter from '../../Components/HelpCenter/TabsResourseFind/HowToFilte import CardPublicando from '../../Components/HelpCenter/Cards/CardPublicando'; import CardParticipando from '../../Components/HelpCenter/Cards/CardParticipando'; import CardGerenciando from '../../Components/HelpCenter/Cards/CardGerenciando'; -import { Link } from 'react-router-dom'; +import { Link } from 'react-router-dom'; @@ -37,25 +37,26 @@ import { Link } from 'react-router-dom'; -export default function TabResourseFind (props) { - const tabs= [ +export default function TabResourseFind(props) { + const tabs = [ 'Como fazer uma busca?', 'Como filtrar os resultados?', 'Como os recursos são ranqueados?', 'Encontrando Recursos' ] - + const [tabValue, setTabValue] = useState(props.location.state === "undefined" ? 0 : props.location.state); const handleChangeTab = (e, newValue) => { setTabValue(newValue) -} + } + useEffect(() => { window.scrollTo(0, 0) }, []) + + return ( + <div style={{ backgroundColor: "#f4f4f4" }}> + <link href="https://fonts.googleapis.com/css?family=Pompiere|Roboto:500,400&display=swap" rel="stylesheet" /> - return( - <div style={{backgroundColor:"#f4f4f4"}}> - <link href="https://fonts.googleapis.com/css?family=Pompiere|Roboto:500,400&display=swap" rel="stylesheet"/> - <Secao> <BreadCrumbsDiv> <StyledBreadCrumbs> @@ -65,7 +66,7 @@ export default function TabResourseFind (props) { <Link to="ajuda" > Ajuda </Link> - + <span> {tabs[3]} </span> @@ -78,51 +79,51 @@ export default function TabResourseFind (props) { <Principal> <Menu> <div className="fixo"> - <img src={EncontrandoRecurso} alt="Encontrando Recursos"/> + <img src={EncontrandoRecurso} alt="Encontrando Recursos" /> <span>{tabs[3]}</span> </div> - <TabsStyled orientation = "vertical" - variant = "scrollable" - value = {tabValue} - onChange = {handleChangeTab} - TabIndicatorProps = {{style:{display: "none"}}} + <TabsStyled orientation="vertical" + variant="scrollable" + value={tabValue} + onChange={handleChangeTab} + TabIndicatorProps={{ style: { display: "none" } }} > - <TabStyled label={tabs[0]}></TabStyled> - <TabStyled label={tabs[1]}></TabStyled> - <TabStyled label={tabs[2]}></TabStyled> + <TabStyled label={tabs[0]}></TabStyled> + <TabStyled label={tabs[1]}></TabStyled> + <TabStyled label={tabs[2]}></TabStyled> </TabsStyled> - <br/> + <br /> <div className="voltarInicio"> <a href="ajuda">VOLTAR AO ÃNICIO</a> </div> </Menu> - {tabValue === 0 && <HowToDo title={tabs[0]}/>} - {tabValue === 1 && <HowToFilter title={tabs[1]}/>} - {tabValue === 2 && <HowToRank title={tabs[2]}/>} + {tabValue === 0 && <HowToDo title={tabs[0]} />} + {tabValue === 1 && <HowToFilter title={tabs[1]} />} + {tabValue === 2 && <HowToRank title={tabs[2]} />} <div className="resultadosProcura"> <span>Não era bem o que você procurava?</span> <div className="subtitulo"> <span>Você pode navegar pelos tópicos de ajuda ou entrar em <a href="contato">Contato</a>.</span> </div> </div> - + </Principal> - </Grid> - </Grid> - <Grid style={{paddingBottom:"50px"}} container justify={"center"}> - <Grid item xs={12} md={3} style={{margin:5}}> - <CardPublicando/> </Grid> - <Grid item xs={12} md={3} style={{margin:5}}> - <CardParticipando/> + </Grid> + <Grid style={{ paddingBottom: "50px" }} container justify={"center"}> + <Grid item xs={12} md={3} style={{ margin: 5 }}> + <CardPublicando /> </Grid> - <Grid item xs={12} md={3} style={{margin:5}}> - <CardGerenciando/> + <Grid item xs={12} md={3} style={{ margin: 5 }}> + <CardParticipando /> + </Grid> + <Grid item xs={12} md={3} style={{ margin: 5 }}> + <CardGerenciando /> </Grid> </Grid> - + </Secao> </div> diff --git a/src/Pages/TabsHelp/TabResoursePub.js b/src/Pages/TabsHelp/TabResoursePub.js index 75dead02..514362aa 100644 --- a/src/Pages/TabsHelp/TabResoursePub.js +++ b/src/Pages/TabsHelp/TabResoursePub.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, { useState } from 'react'; +import React, { useState, useEffect } from 'react'; import styled from 'styled-components'; import Tabs from '@material-ui/core/Tabs' import Tab from '@material-ui/core/Tab'; @@ -29,40 +29,42 @@ import Which from '../../Components/HelpCenter/TabsResoursePub/Which' import CardEncontrando from '../../Components/HelpCenter/Cards/CardEncontrando'; import CardParticipando from '../../Components/HelpCenter/Cards/CardParticipando'; import CardGerenciando from '../../Components/HelpCenter/Cards/CardGerenciando'; -import { Link } from 'react-router-dom'; +import { Link } from 'react-router-dom'; -export default function TabResoursePub (props) { +export default function TabResoursePub(props) { console.log(props) - - const tabs= [ + + const tabs = [ 'Por que enviar um recurso?', 'Como publicar um recurso?', 'Quais tipos de recursos e formatos de arquivo a plataforma aceita?', 'Publicando Recursos' ] - + const [tabValue, setTabValue] = useState(props.location.state === "undefined" ? 0 : props.location.state); const handleChangeTab = (e, newValue) => { setTabValue(newValue) -} + } + + useEffect(() => { window.scrollTo(0, 0) }, []) + + return ( + <div style={{ backgroundColor: "#f4f4f4" }}> + <link href="https://fonts.googleapis.com/css?family=Pompiere|Roboto:500,400&display=swap" rel="stylesheet" /> - return( - <div style={{backgroundColor:"#f4f4f4"}}> - <link href="https://fonts.googleapis.com/css?family=Pompiere|Roboto:500,400&display=swap" rel="stylesheet"/> - <Secao> <BreadCrumbsDiv> <StyledBreadCrumbs> <Link to="/" > - Página Inicial + Página Inicial </Link> <Link to="ajuda" > Ajuda - </Link> + </Link> <span> - {tabs[3]} + {tabs[3]} </span> </StyledBreadCrumbs> @@ -72,28 +74,28 @@ export default function TabResoursePub (props) { <Principal> <Menu> <div className="fixo"> - <img src={PublicandoRecursos} alt="Publicando Recursos"/> + <img src={PublicandoRecursos} alt="Publicando Recursos" /> <span>{tabs[3]}</span> </div> - <TabsStyled orientation = "vertical" - variant = "scrollable" - value = {tabValue} - onChange = {handleChangeTab} - TabIndicatorProps = {{style:{display: "none"}}} + <TabsStyled orientation="vertical" + variant="scrollable" + value={tabValue} + onChange={handleChangeTab} + TabIndicatorProps={{ style: { display: "none" } }} > - <TabStyled label={tabs[0]}></TabStyled> - <TabStyled label={tabs[1]}></TabStyled> - <TabStyled label={tabs[2]}></TabStyled> + <TabStyled label={tabs[0]}></TabStyled> + <TabStyled label={tabs[1]}></TabStyled> + <TabStyled label={tabs[2]}></TabStyled> </TabsStyled> - <br/> + <br /> <div className="voltarInicio"> <a href="ajuda">VOLTAR AO ÃNICIO</a> </div> </Menu> - {tabValue === 0 && <Why title={tabs[0]}/>} - {tabValue === 1 && <How title={tabs[1]}/>} - {tabValue === 2 && <Which title={tabs[2]}/>} + {tabValue === 0 && <Why title={tabs[0]} />} + {tabValue === 1 && <How title={tabs[1]} />} + {tabValue === 2 && <Which title={tabs[2]} />} <div className="resultadosProcura"> <span>Não era bem o que você procurava?</span> <div className="subtitulo"> @@ -102,20 +104,20 @@ export default function TabResoursePub (props) { </div> </Principal> - </Grid> - </Grid> - <Grid style={{paddingBottom:"50px"}} container justify={"center"}> - <Grid item xs={12} md={3} style={{margin:5}}> - <CardEncontrando/> </Grid> - <Grid item xs={12} md={3} style={{margin:5}}> - <CardParticipando/> + </Grid> + <Grid style={{ paddingBottom: "50px" }} container justify={"center"}> + <Grid item xs={12} md={3} style={{ margin: 5 }}> + <CardEncontrando /> + </Grid> + <Grid item xs={12} md={3} style={{ margin: 5 }}> + <CardParticipando /> </Grid> - <Grid item xs={12} md={3} style={{margin:5}}> - <CardGerenciando/> + <Grid item xs={12} md={3} style={{ margin: 5 }}> + <CardGerenciando /> </Grid> - </Grid> + </Grid> </Secao> diff --git a/src/Pages/UserTerms.js b/src/Pages/UserTerms.js index d7722bef..e6c2e7cb 100644 --- a/src/Pages/UserTerms.js +++ b/src/Pages/UserTerms.js @@ -15,7 +15,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, {Component} from 'react'; +import React, { useEffect } from 'react'; import SimpleExpansionPanels from '../Components/ExpansionPanels' import Grid from '@material-ui/core/Grid'; import Modal from '../Components/Modal' @@ -32,7 +32,7 @@ import Linha from "../img/termos/linha.svg"; -const BannerStyle=styled.div` +const BannerStyle = styled.div` width: 100%; background-image: url(${Banner1}); background-size: cover; @@ -186,99 +186,98 @@ const Secao4 = styled.div` ` -class UserTerms extends Component { - render() { +export default function UserTerms() { + useEffect(() => { + window.scrollTo(0, 0) + }, []) + return ( + <div style={{ color: "rgba(0,0,0,0.87" }} > - return ( - <div style={{color:"rgba(0,0,0,0.87"}} > + <BannerStyle> + <h2 style={{ width: "100%", textAlign: "center", marginTop: "0px", paddingTop: "6rem", marginBottom: "16px", fontSize: "52px", fontFamily: "'Pompiere', cursive", color: "#fff", fontWeight: "500" }}>TERMOS DE USO</h2> + <Modal /> + </BannerStyle> - <BannerStyle> - <h2 style={{width: "100%",textAlign: "center",marginTop:"0px", paddingTop:"6rem",marginBottom:"16px",fontSize:"52px",fontFamily: "'Pompiere', cursive",color:"#fff",fontWeight:"500"}}>TERMOS DE USO</h2> - <Modal/> - </BannerStyle> + <ImagemSeçao2> + <Grid container > + <Grid item xs={12} md={1}></Grid> + <Grid item xs={12} md={10}> + <div> + <h3><strong style={{ fontWeight: "700" }}>Plataforma Integrada de Recursos Educacionais Digitais,</strong><br />uma iniciativa do Ministério da Educação!</h3> - <ImagemSeçao2> - <Grid container > - <Grid item xs={12} md={1}></Grid> - <Grid item xs={12} md={10}> - <div> - <h3><strong style={{fontWeight:"700"}}>Plataforma Integrada de Recursos Educacionais Digitais,</strong><br/>uma iniciativa do Ministério da Educação!</h3> - - <p>A <strong>Plataforma Integrada de RED do MEC</strong> é parte do processo de implementação do Compromisso 6 do <AColorido href="http://www.governoaberto.cgu.gov.br/noticias/2017/3o-plano-de-acao-nacional-na-parceria-para-governo-aberto" target="_blank">3º Plano de Ação da Parceria Governo Aberto</AColorido> (OGP-Brasil), que tem por objetivo “incorporar na polÃtica educacional o potencial da cultura digital, de modo a fomentar a autonomia para uso, reuso e adaptação de recursos educacionais digitais, valorizando a pluralidade e a diversidade da educação brasileiraâ€. + <p>A <strong>Plataforma Integrada de RED do MEC</strong> é parte do processo de implementação do Compromisso 6 do <AColorido href="http://www.governoaberto.cgu.gov.br/noticias/2017/3o-plano-de-acao-nacional-na-parceria-para-governo-aberto" target="_blank">3º Plano de Ação da Parceria Governo Aberto</AColorido> (OGP-Brasil), que tem por objetivo “incorporar na polÃtica educacional o potencial da cultura digital, de modo a fomentar a autonomia para uso, reuso e adaptação de recursos educacionais digitais, valorizando a pluralidade e a diversidade da educação brasileiraâ€. </p> - <p>Seguindo o compromisso, a <strong>Plataforma Integrada de RED do MEC</strong> visa fortalecer a distribuição de recursos educacionais digitais para o ensino básico brasileiro. Há preferência pela disponibilização de Recursos Educacionais Abertos (REA), ou seja, recursos que “se situem no domiÌnio puÌblico ou que tenham sido divulgados sob licença aberta que permita acesso, uso, adaptação e redistribuição gratuita por terceiros, mediante nenhuma restrição ou poucas restrições.†<AColorido href="http://www.unesco.org/new/fileadmin/MULTIMEDIA/HQ/CI/CI/pdf/Events/Portuguese_Paris_OER_Declaration.pdf" target="_blank">(Declaração REA de Paris, 2012)</AColorido>. + <p>Seguindo o compromisso, a <strong>Plataforma Integrada de RED do MEC</strong> visa fortalecer a distribuição de recursos educacionais digitais para o ensino básico brasileiro. Há preferência pela disponibilização de Recursos Educacionais Abertos (REA), ou seja, recursos que “se situem no domiÌnio puÌblico ou que tenham sido divulgados sob licença aberta que permita acesso, uso, adaptação e redistribuição gratuita por terceiros, mediante nenhuma restrição ou poucas restrições.†<AColorido href="http://www.unesco.org/new/fileadmin/MULTIMEDIA/HQ/CI/CI/pdf/Events/Portuguese_Paris_OER_Declaration.pdf" target="_blank">(Declaração REA de Paris, 2012)</AColorido>. </p> - </div> - </Grid> - <Grid item xs={12} md={1}></Grid> - </Grid> - </ImagemSeçao2> - - <Secao3 > - <Grid container > - <h3>Para melhor compreensão, podemos dividir os recursos em dois tipos:</h3> - <Grid item xs={12} md={1} ></Grid> - <Grid item xs={12} md={5} > - <div class="caixa aberto"> - <div class ="texto"> - <span>Abertos</span> - <p>De acordo com a Declaração de Paris, são recursos que, no mÃnimo, têm uma licença de uso mais flexÃvel, que garante livre redistribuição. Adicionalmente, um recurso aberto deve utilizar um formato aberto, um formato de arquivo que permite a fácil edição por terceiros. Nenhum controle sobre o acesso (como cadastro e senha) deve existir para acesso a recursos abertos. Em sua maioria, são recursos gratuitos.</p> - </div> - </div> - </Grid> - - <Grid item xs={12} md={5}> - <div class="caixa fechado"> - <div class ="texto"> - <span>Fechados</span> - <p>São recursos que criam restrições no seu acesso, uso ou reuso. Como exemplo, podemos mencionar recursos que só são acessÃveis mediante cadastro ou que têm licenças restritivas (como “todos os direitos reservadosâ€, o sÃmbolo ©). Podem ser gratuitos ou pagos.</p> - </div> - </div> - </Grid> - <Grid item xs={12} md={1} ></Grid> - </Grid> - </Secao3> - - - - - <Grid container > - <Grid item xs={12} md={1}></Grid> - <Grid item xs={12} md={10}> - <Secao4> - <div class="texto" style={{paddingTop:"70px"}}> - <p>O <a href="http://www.planalto.gov.br/ccivil_03/_ato2011-2014/2014/lei/l13005.htm" rel="noreferrer" target="_blank">Plano Nacional de Educação</a> (2014-2024) enfatiza nas metas 5 e 7 a importância dos recursos educacionais abertos para fomentar a qualidade da educação baÌsica. A <a href="http://portal.mec.gov.br/index.php?option=com_docman&view=download&alias=35541-res-cne-ces-001-14032016-pdf&category_slug=marco-2016-pdf&Itemid=30192" rel="noreferrer" target="_blank">Resolução CNE/CES nº 1</a>, de 11 de março de 2016, também destaca a importância dos recursos educacionais abertos para as instituições de educação superior e para as atividades de educação a distância.</p> - </div> - <div class="titulo"> - <h3>TERMOS DE USO</h3> - <p>InÃcio da vigência: agosto de 2017</p> - </div> - <div class="texto" style={{paddingBottom:"40px"}}> - <p>Aqui estão os “Termos de Uso†da <strong>Plataforma Integrada de RED do MEC</strong>, isto é, as regras de funcionamento da Plataforma e seus serviços, e o que se espera de seus usuários. Por “usuárioâ€, entende-se qualquer pessoa que acesse o domÃnio portal.mec.gov.br, tanto para pesquisa (acesso) como para a inclusão de dados e informações (participação) mediante cadastro.</p> - <p>Fazem parte dos Termos de Uso as polÃticas de responsabilidade, de privacidade e confidencialidade, a licença de uso do conteúdo e as informações sobre como reportar violações.</p> - <p>Ao utilizar a <strong>Plataforma Integrada de RED do MEC</strong>, o usuário aceita todas as condições aqui estabelecidas. O uso da <strong>Plataforma Integrada de RED do MEC</strong> implica aceite das condições aqui elencadas.</p> - <p>Por “serviçoâ€, entende-se qualquer funcionalidade ou ferramenta que permita a interatividade com o usuário, como, por exemplo, usuário subir um recurso, postar um comentário, criar uma coleção ou enviar uma mensagem.</p> - <p>A aceitação destes "Termos de Uso" é indispensável à utilização da <strong>Plataforma Integrada de RED do MEC</strong>. Todos os usuários deverão ler, certificar-se de tê-los entendido e aceitar todas as condições neles estabelecidas. Dessa forma, deve ficar claro que a utilização desta "<strong>Plataforma Integrada de RED do MEC</strong>" implica aceitação completa deste documento intitulado Termos de Uso. Caso tenha dúvidas sobre os termos, utilize o formulário disponÃvel em “Contato†para saná-las.</p> - </div> - </Secao4> - </Grid> - <Grid item xs={12} md={1}></Grid> + </div> + </Grid> + <Grid item xs={12} md={1}></Grid> + </Grid> + </ImagemSeçao2> + + <Secao3 > + <Grid container > + <h3>Para melhor compreensão, podemos dividir os recursos em dois tipos:</h3> + <Grid item xs={12} md={1} ></Grid> + <Grid item xs={12} md={5} > + <div class="caixa aberto"> + <div class="texto"> + <span>Abertos</span> + <p>De acordo com a Declaração de Paris, são recursos que, no mÃnimo, têm uma licença de uso mais flexÃvel, que garante livre redistribuição. Adicionalmente, um recurso aberto deve utilizar um formato aberto, um formato de arquivo que permite a fácil edição por terceiros. Nenhum controle sobre o acesso (como cadastro e senha) deve existir para acesso a recursos abertos. Em sua maioria, são recursos gratuitos.</p> + </div> + </div> </Grid> - - <Grid container > - <Grid item xs={12} md={1}></Grid> - <Grid item xs={12} md={10}> - <div style={{ marginBottom:"50px",paddingTop: "20px"}}> - <SimpleExpansionPanels/> + <Grid item xs={12} md={5}> + <div class="caixa fechado"> + <div class="texto"> + <span>Fechados</span> + <p>São recursos que criam restrições no seu acesso, uso ou reuso. Como exemplo, podemos mencionar recursos que só são acessÃveis mediante cadastro ou que têm licenças restritivas (como “todos os direitos reservadosâ€, o sÃmbolo ©). Podem ser gratuitos ou pagos.</p> </div> - </Grid> - <Grid item xs={12} md={1}></Grid> - </Grid> - </div> - ); - } - } + </div> + </Grid> + <Grid item xs={12} md={1} ></Grid> + </Grid> + </Secao3> + + + + + <Grid container > + <Grid item xs={12} md={1}></Grid> + <Grid item xs={12} md={10}> + <Secao4> + <div class="texto" style={{ paddingTop: "70px" }}> + <p>O <a href="http://www.planalto.gov.br/ccivil_03/_ato2011-2014/2014/lei/l13005.htm" rel="noreferrer" target="_blank">Plano Nacional de Educação</a> (2014-2024) enfatiza nas metas 5 e 7 a importância dos recursos educacionais abertos para fomentar a qualidade da educação baÌsica. A <a href="http://portal.mec.gov.br/index.php?option=com_docman&view=download&alias=35541-res-cne-ces-001-14032016-pdf&category_slug=marco-2016-pdf&Itemid=30192" rel="noreferrer" target="_blank">Resolução CNE/CES nº 1</a>, de 11 de março de 2016, também destaca a importância dos recursos educacionais abertos para as instituições de educação superior e para as atividades de educação a distância.</p> + </div> + <div class="titulo"> + <h3>TERMOS DE USO</h3> + <p>InÃcio da vigência: agosto de 2017</p> + </div> + <div class="texto" style={{ paddingBottom: "40px" }}> + <p>Aqui estão os “Termos de Uso†da <strong>Plataforma Integrada de RED do MEC</strong>, isto é, as regras de funcionamento da Plataforma e seus serviços, e o que se espera de seus usuários. Por “usuárioâ€, entende-se qualquer pessoa que acesse o domÃnio portal.mec.gov.br, tanto para pesquisa (acesso) como para a inclusão de dados e informações (participação) mediante cadastro.</p> + <p>Fazem parte dos Termos de Uso as polÃticas de responsabilidade, de privacidade e confidencialidade, a licença de uso do conteúdo e as informações sobre como reportar violações.</p> + <p>Ao utilizar a <strong>Plataforma Integrada de RED do MEC</strong>, o usuário aceita todas as condições aqui estabelecidas. O uso da <strong>Plataforma Integrada de RED do MEC</strong> implica aceite das condições aqui elencadas.</p> + <p>Por “serviçoâ€, entende-se qualquer funcionalidade ou ferramenta que permita a interatividade com o usuário, como, por exemplo, usuário subir um recurso, postar um comentário, criar uma coleção ou enviar uma mensagem.</p> + <p>A aceitação destes "Termos de Uso" é indispensável à utilização da <strong>Plataforma Integrada de RED do MEC</strong>. Todos os usuários deverão ler, certificar-se de tê-los entendido e aceitar todas as condições neles estabelecidas. Dessa forma, deve ficar claro que a utilização desta "<strong>Plataforma Integrada de RED do MEC</strong>" implica aceitação completa deste documento intitulado Termos de Uso. Caso tenha dúvidas sobre os termos, utilize o formulário disponÃvel em “Contato†para saná-las.</p> + </div> + </Secao4> + </Grid> + <Grid item xs={12} md={1}></Grid> + </Grid> + + + <Grid container > + <Grid item xs={12} md={1}></Grid> + <Grid item xs={12} md={10}> + <div style={{ marginBottom: "50px", paddingTop: "20px" }}> + <SimpleExpansionPanels /> + </div> + </Grid> + <Grid item xs={12} md={1}></Grid> + </Grid> + </div> + ); +} -export default UserTerms; 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 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 03/12] 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 From 6f8b0e92b8d7e492e53d44aa8ba31e03776591fd Mon Sep 17 00:00:00 2001 From: Luis Felipe Risch <lfr20@inf.ufpr.br> Date: Fri, 14 May 2021 11:54:18 -0300 Subject: [PATCH 04/12] Fix admin bugs of permissions --- src/Admin/Pages/Pages/SubPages/Activity.js | 46 +-- .../Pages/Pages/SubPages/AproveTeacher.js | 27 +- .../Pages/Pages/SubPages/BlockedUsers.js | 1 + .../Pages/SubPages/CommunityQuestions.js | 27 +- src/Admin/Pages/Pages/SubPages/Complaints.js | 29 +- .../Pages/SubPages/EducationalObjects.js | 10 +- .../Pages/Pages/SubPages/Institutions.js | 5 +- src/Admin/Pages/Pages/SubPages/Languages.js | 2 +- .../Pages/Pages/SubPages/NoteVariables.js | 1 + src/Admin/Pages/Pages/SubPages/Permissions.js | 2 +- src/Admin/Pages/Pages/SubPages/Questions.js | 25 +- src/Admin/Pages/Pages/SubPages/Rating.js | 5 +- src/Admin/Pages/Pages/SubPages/SendEmail.js | 51 +-- src/Admin/Pages/Pages/SubPages/Users.js | 5 +- src/App.js | 291 +++++++++++++++--- 15 files changed, 317 insertions(+), 210 deletions(-) diff --git a/src/Admin/Pages/Pages/SubPages/Activity.js b/src/Admin/Pages/Pages/SubPages/Activity.js index bd43798c..6cb62ff1 100644 --- a/src/Admin/Pages/Pages/SubPages/Activity.js +++ b/src/Admin/Pages/Pages/SubPages/Activity.js @@ -16,33 +16,33 @@ GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ -import React, { useEffect, useState } from "react"; -import moment from 'moment'; +import React, { useEffect, useState } from "react" +import moment from 'moment' //imports from local files -import TableData from "../../../Components/Components/Table"; -import SnackBar from "../../../../Components/SnackbarComponent"; -import { Url } from "../../../Filters"; -import { getRequest } from '../../../../Components/HelperFunctions/getAxiosConfig'; -import LoadingSpinner from '../../../../Components/LoadingSpinner'; +import TableData from "../../../Components/Components/Table" +import SnackBar from "../../../../Components/SnackbarComponent" +import { Url } from "../../../Filters" +import { getRequest } from '../../../../Components/HelperFunctions/getAxiosConfig' +import LoadingSpinner from '../../../../Components/LoadingSpinner' import MobilePageHeader from '../../../Components/Components/MobileComponents/MobilePageHeader' import PageHeader from '../../../Components/Components/PageHeader' //imports from material ui -import { withStyles } from "@material-ui/core/styles"; -import TableBody from "@material-ui/core/TableBody"; -import TableCell from "@material-ui/core/TableCell"; -import MenuItem from "@material-ui/core/MenuItem"; -import TableRow from "@material-ui/core/TableRow"; -import TextField from "@material-ui/core/TextField"; -import IconButton from "@material-ui/core/IconButton"; -import { Button, Paper } from "@material-ui/core"; -import CircularProgress from "@material-ui/core/CircularProgress"; -import AddRoundedIcon from "@material-ui/icons/AddRounded"; -import UpdateRoundedIcon from "@material-ui/icons/UpdateRounded"; -import FilterListRoundedIcon from "@material-ui/icons/FilterListRounded"; -import VisibilityIcon from "@material-ui/icons/Visibility"; -import AllOutIcon from "@material-ui/icons/AllOut"; +import { withStyles } from "@material-ui/core/styles" +import TableBody from "@material-ui/core/TableBody" +import TableCell from "@material-ui/core/TableCell" +import MenuItem from "@material-ui/core/MenuItem" +import TableRow from "@material-ui/core/TableRow" +import TextField from "@material-ui/core/TextField" +import IconButton from "@material-ui/core/IconButton" +import { Button, Paper } from "@material-ui/core" +import CircularProgress from "@material-ui/core/CircularProgress" +import AddRoundedIcon from "@material-ui/icons/AddRounded" +import UpdateRoundedIcon from "@material-ui/icons/UpdateRounded" +import FilterListRoundedIcon from "@material-ui/icons/FilterListRounded" +import VisibilityIcon from "@material-ui/icons/Visibility" +import AllOutIcon from "@material-ui/icons/AllOut" //routers -import { Link } from 'react-router-dom'; +import { Link } from 'react-router-dom' import MobileList from "../../../Components/Components/MobileComponents/SimpleList" import styled from "styled-components" @@ -422,6 +422,8 @@ const Activity = () => { } } }; + + export default Activity; const StyledDivButton = styled(Paper)` diff --git a/src/Admin/Pages/Pages/SubPages/AproveTeacher.js b/src/Admin/Pages/Pages/SubPages/AproveTeacher.js index b6cbc697..c6078dba 100644 --- a/src/Admin/Pages/Pages/SubPages/AproveTeacher.js +++ b/src/Admin/Pages/Pages/SubPages/AproveTeacher.js @@ -16,20 +16,18 @@ GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ -import React, { useEffect, useState, useContext } from "react"; +import React, { useEffect, useState } from "react"; import moment from "moment"; import styled from "styled-components"; //imports from local files import TableData from "../../../Components/Components/Table"; import SnackBar from "../../../../Components/SnackbarComponent"; import { Url } from "../../../Filters"; -import { Store } from "../../../../Store"; import LoadingSpinner from "../../../../Components/LoadingSpinner"; import { getRequest, postRequest, } 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"; @@ -75,9 +73,7 @@ const StyledTableRow = withStyles((theme) => ({ }))(TableRow); const AproveTeacher = () => { - const { state } = useContext(Store); - const WINDOW_WIDTH = window.innerWidth; - + const WINDOW_WIDTH = window.innerWidth const ADD_ONE_LENGHT = [""]; const TOP_LABELS = [ "ESTADO DO PEDIDO", @@ -126,21 +122,6 @@ const AproveTeacher = () => { }); }; - 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); @@ -359,7 +340,7 @@ const AproveTeacher = () => { return <div>Error: {error.message}</div>; } else if (!isLoaded) { return <LoadingSpinner text="Carregando..." />; - } else if (CheckUserPermission()) { + } else { if (WINDOW_WIDTH <= 1130) { return ( <> @@ -760,7 +741,7 @@ const AproveTeacher = () => { </> ); } - } 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 0e2dc4da..ac2f09de 100644 --- a/src/Admin/Pages/Pages/SubPages/BlockedUsers.js +++ b/src/Admin/Pages/Pages/SubPages/BlockedUsers.js @@ -70,6 +70,7 @@ const StyledTableRow = withStyles((theme) => ({ const BlockedUsers = () => { 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 diff --git a/src/Admin/Pages/Pages/SubPages/CommunityQuestions.js b/src/Admin/Pages/Pages/SubPages/CommunityQuestions.js index c3a78462..52bc6b89 100644 --- a/src/Admin/Pages/Pages/SubPages/CommunityQuestions.js +++ b/src/Admin/Pages/Pages/SubPages/CommunityQuestions.js @@ -16,14 +16,12 @@ GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ -import React, { useEffect, useState, useContext } from "react"; +import React, { useEffect, useState } from "react"; import moment from 'moment'; //imports from local files import TableData from "../../../Components/Components/Table"; import SnackBar from "../../../../Components/SnackbarComponent"; -import Unauthorized from '../../../Components/Components/Unauthorized'; import { Url } from "../../../Filters"; -import { Store } from '../../../../Store'; import LoadingSpinner from '../../../../Components/LoadingSpinner'; import { getRequest } from '../../../../Components/HelperFunctions/getAxiosConfig'; import MobilePageHeader from "../../../Components/Components/MobileComponents/MobilePageHeader" @@ -67,7 +65,6 @@ const StyledTableRow = withStyles((theme) => ({ }))(TableRow); const CommunityQuestion = () => { - const { state } = useContext(Store); const ADD_ONE_LENGHT = [""]; const TOP_LABELS = [ @@ -80,7 +77,6 @@ const CommunityQuestion = () => { ]; //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 @@ -136,22 +132,6 @@ const CommunityQuestion = () => { .toString(); }; - const CheckUserPermission = () => { - let canUserEdit = false; - - if (state.userIsLoggedIn) { - const roles = [...state.currentUser.roles]; - for (let i = 0; i < roles.length; i++) - if (roles[i].name === 'admin' || roles[i].name === 'editor') - canUserEdit = true; - } - else { - canUserEdit = false; - } - - return canUserEdit; - } - const buildUrl = (message, email, name) => { if (message && email && name) return Url("contacts", `"message" : "${message}", "email" : "${email}", "name" : "${name}"`, currPage, "DESC") @@ -221,7 +201,7 @@ const CommunityQuestion = () => { return <div>Error: {error.message}</div>; } else if (!isLoaded) { return <LoadingSpinner text="Carregando..." /> - } else if (CheckUserPermission()) { + } else { if (WINDOW_WIDTH <= 1200) { return ( <> @@ -525,8 +505,7 @@ const CommunityQuestion = () => { </TableData> </> } - - } 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 0b1cc0a0..d2fb9de2 100644 --- a/src/Admin/Pages/Pages/SubPages/Complaints.js +++ b/src/Admin/Pages/Pages/SubPages/Complaints.js @@ -16,19 +16,17 @@ GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ -import React, { useEffect, useState, useContext } from "react"; +import React, { useEffect, useState } from "react"; import moment from "moment"; //imports from local files import TableData from "../../../Components/Components/Table"; import SnackBar from "../../../../Components/SnackbarComponent"; import { Url } from "../../../Filters"; -import { Store } from '../../../../Store'; import LoadingSpinner from '../../../../Components/LoadingSpinner'; import { getRequest } from '../../../../Components/HelperFunctions/getAxiosConfig' import MobileList from "../../../Components/Components/MobileComponents/SimpleList" import MobilePageHeader from "../../../Components/Components/MobileComponents/MobilePageHeader" import PageHeader from "../../../Components/Components/PageHeader" -import Unauthorized from "../../../Components/Components/Unauthorized"; //imports from material ui import { withStyles } from "@material-ui/core/styles"; import TableBody from "@material-ui/core/TableBody"; @@ -68,12 +66,9 @@ const StyledTableRow = withStyles((theme) => ({ }))(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 PORTAL_MEC = "https://plataformaintegrada.mec.gov.br/"; const TOP_LABELS = [ "ESTADO DO RECURSO", "ID", @@ -129,22 +124,6 @@ const Complaints = () => { }); }; - const CheckUserPermission = () => { - let canUserEdit = false; - - if (state.userIsLoggedIn) { - const roles = [...state.currentUser.roles]; - for (let i = 0; i < roles.length; i++) - if (roles[i].name === 'admin' || roles[i].name === 'editor') - canUserEdit = true; - } - else { - canUserEdit = false; - } - - return canUserEdit; - } - const handleChangeState = (e, type) => { const value = e.target.value; setStateOption(value); @@ -295,7 +274,7 @@ const Complaints = () => { return <div>Error: {error.message}</div>; } else if (!isLoaded) { return <LoadingSpinner text="Carregando..." /> - } else if (CheckUserPermission()) { + } else { if (WINDOW_WIDTH <= 994) { return ( <> @@ -643,7 +622,7 @@ const Complaints = () => { </> ); } - } 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 a5df3138..837797d4 100644 --- a/src/Admin/Pages/Pages/SubPages/EducationalObjects.js +++ b/src/Admin/Pages/Pages/SubPages/EducationalObjects.js @@ -18,7 +18,7 @@ along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/> import React, { useState, useEffect } from "react"; import moment from 'moment'; -// Imports from local files +// Imports from local file import TableData from "../../../Components/Components/Table"; import SnackBar from "../../../../Components/SnackbarComponent"; import AlertDialog from "../../../Components/Components/AlertDialog"; @@ -72,7 +72,6 @@ const StyledTableRow = withStyles((theme) => ({ const EducationalObjects = () => { const WINDOW_WIDTH = window.innerWidth - const ADD_ONE_LENGHT = [""]; const [error, setError] = useState(null); //Necessary to consult the API, catch errors @@ -253,11 +252,11 @@ const EducationalObjects = () => { if (error) { return <div>Error: {error.message}</div>; } - if (!isLoaded) { + else if (!isLoaded) { return <LoadingSpinner text="Carregando..." /> } else { //Words that defines that column - const topTable = [ + const TOP_TABLE = [ "CRIADO EM", "NOME", "DESCRIÇÃO", @@ -291,6 +290,7 @@ const EducationalObjects = () => { helperText: "Ao terminar de digitar no campo, retire o foco do campo de texto" }, ]; + if (WINDOW_WIDTH <= 1058) { return ( <div> @@ -507,7 +507,7 @@ const EducationalObjects = () => { <div style={{ height: "2em" }}></div> {/************** Start of display data in table **************/} - <TableData top={topTable}> + <TableData top={TOP_TABLE}> <TableBody> {items.map((row, index) => index === items.length - 1 ? ( diff --git a/src/Admin/Pages/Pages/SubPages/Institutions.js b/src/Admin/Pages/Pages/SubPages/Institutions.js index cf77c1e4..24d099a6 100644 --- a/src/Admin/Pages/Pages/SubPages/Institutions.js +++ b/src/Admin/Pages/Pages/SubPages/Institutions.js @@ -71,9 +71,10 @@ const StyledTableRow = withStyles((theme) => ({ const Institutions = () => { const WINDOW_WIDTH = window.innerWidth - const router = useHistory() 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 @@ -237,7 +238,7 @@ const Institutions = () => { if (error) { return <div>Error: {error.message}</div>; } - if (!isLoaded) { + else if (!isLoaded) { return <LoadingSpinner text="Carregando..." /> } else { //Words that defines that column diff --git a/src/Admin/Pages/Pages/SubPages/Languages.js b/src/Admin/Pages/Pages/SubPages/Languages.js index deb622b6..3d11c4a4 100644 --- a/src/Admin/Pages/Pages/SubPages/Languages.js +++ b/src/Admin/Pages/Pages/SubPages/Languages.js @@ -157,6 +157,7 @@ const Languages = () => { setIsLoaded(false) else setIsLoadingMoreItems(true) + getRequest( Url("languages", "", currPage, "DESC"), (data, header) => { @@ -186,7 +187,6 @@ const Languages = () => { ) }, [currPage]) - if (error) { return <div>Error: {error.message}</div>; } else if (!isLoaded) { diff --git a/src/Admin/Pages/Pages/SubPages/NoteVariables.js b/src/Admin/Pages/Pages/SubPages/NoteVariables.js index e3b15ae4..5e58e14d 100644 --- a/src/Admin/Pages/Pages/SubPages/NoteVariables.js +++ b/src/Admin/Pages/Pages/SubPages/NoteVariables.js @@ -67,6 +67,7 @@ const StyledTableRow = withStyles((theme) => ({ const NoteVariables = () => { 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) diff --git a/src/Admin/Pages/Pages/SubPages/Permissions.js b/src/Admin/Pages/Pages/SubPages/Permissions.js index c4aba3f8..89c3bb55 100644 --- a/src/Admin/Pages/Pages/SubPages/Permissions.js +++ b/src/Admin/Pages/Pages/SubPages/Permissions.js @@ -66,6 +66,7 @@ const UserPermissions = () => { 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 @@ -183,7 +184,6 @@ const UserPermissions = () => { ) }, [currPage]) - if (error) { return <div>Error: {error.message}</div>; } else if (!isLoaded) { diff --git a/src/Admin/Pages/Pages/SubPages/Questions.js b/src/Admin/Pages/Pages/SubPages/Questions.js index 58b80d4b..aa4532af 100644 --- a/src/Admin/Pages/Pages/SubPages/Questions.js +++ b/src/Admin/Pages/Pages/SubPages/Questions.js @@ -16,14 +16,12 @@ GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ -import React, { useEffect, useState, useContext } from 'react' +import React, { useEffect, useState } from 'react' import moment from 'moment'; //imports from local files import TableData from '../../../Components/Components/Table'; import SnackBar from '../../../../Components/SnackbarComponent'; -import Unauthorized from '../../../Components/Components/Unauthorized'; import { Url, EditFilter } from '../../../Filters'; -import { Store } from '../../../../Store'; import LoadingSpinner from '../../../../Components/LoadingSpinner'; import { getRequest, putRequest } from '../../../../Components/HelperFunctions/getAxiosConfig' import MobileList from "../../../Components/Components/MobileComponents/SimpleList" @@ -63,7 +61,6 @@ const StyledTableRow = withStyles((theme) => ({ }))(TableRow); const Questions = () => { - const { state } = useContext(Store); const ADD_ONE_LENGHT = [""]; const WINDOW_WIDTH = window.innerWidth @@ -93,22 +90,6 @@ const Questions = () => { }) } - 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; - } - const changeStateItem = (index, currState) => { const copyItems = [...items] copyItems[index].status = currState @@ -213,7 +194,7 @@ const Questions = () => { return <div>Error: {error.message}</div>; } else if (!isLoaded) { return <LoadingSpinner text="Carregando..." /> - } else if (CheckUserPermission()) { + } else { if (WINDOW_WIDTH <= 800) { return ( <> @@ -424,7 +405,7 @@ const Questions = () => { </> ); } - } 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 b6ecfe7e..8f00fd9d 100644 --- a/src/Admin/Pages/Pages/SubPages/Rating.js +++ b/src/Admin/Pages/Pages/SubPages/Rating.js @@ -30,7 +30,7 @@ import CircularProgress from '@material-ui/core/CircularProgress'; import AddRoundedIcon from '@material-ui/icons/AddRounded'; import UpdateRoundedIcon from '@material-ui/icons/UpdateRounded'; import DeleteRoundedIcon from '@material-ui/icons/DeleteRounded'; -//Local files +//Local files' import TableData from '../../../Components/Components/Table'; import SnackBar from '../../../../Components/SnackbarComponent'; import LoadingSpinner from '../../../../Components/LoadingSpinner'; @@ -68,6 +68,7 @@ const StyledTableRow = withStyles((theme) => ({ const Ratings = () => { const WINDOW_WIDTH = window.innerWidth const ADD_ONE_LENGHT = [""]; + const router = useHistory() const [error, setError] = useState(null); //Necessary to consult the API, catch errors @@ -150,7 +151,6 @@ const Ratings = () => { setOpenAlertDialog(!openAlertDialog); }; - useEffect(() => { if (currPage === 0) setIsLoaded(false) @@ -185,7 +185,6 @@ const Ratings = () => { ) }, [currPage]) - if (error) { return <div>Error: {error.message}</div>; } else if (!isLoaded) { diff --git a/src/Admin/Pages/Pages/SubPages/SendEmail.js b/src/Admin/Pages/Pages/SubPages/SendEmail.js index 5e9b05ed..c6e8c4d0 100644 --- a/src/Admin/Pages/Pages/SubPages/SendEmail.js +++ b/src/Admin/Pages/Pages/SubPages/SendEmail.js @@ -18,14 +18,12 @@ You should have received a copy of the GNU Affero General Public License along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ -import React, {useContext} from 'react'; +import React from 'react'; import Card from "@material-ui/core/Card"; import CardContent from "@material-ui/core/CardContent"; import { makeStyles } from "@material-ui/core/styles"; import { Typography } from '@material-ui/core'; import EmailInputs from '../../../Components/Components/Inputs/EmailInputs'; -import { Store } from '../../../../Store'; -import Unauthorized from '../../../Components/Components/Unauthorized'; const useStyles = makeStyles({ root: { @@ -57,41 +55,22 @@ const useStyles = makeStyles({ }); const SendEmail = ({ match }) => { - const { state } = useContext(Store); const classes = useStyles(); - const CheckUserPermission = () => { - let canUserEdit = false; - - if (state.userIsLoggedIn) { - const roles = [...state.currentUser.roles]; - for (let i = 0; i < roles.length; i++) - if (roles[i].name === 'admin' || roles[i].name === 'editor') - canUserEdit = true; - } - else { - canUserEdit = false; - } - - return canUserEdit; - } - - if(CheckUserPermission()){ - return ( - <Card> - <CardContent> - <Typography - className={classes.title} - color="inherit" - gutterBottom - > - Enviar email - </Typography> - <EmailInputs email={`${match.params.email}`} /> - </CardContent> - </Card> - ); - } else return <Unauthorized/> + return ( + <Card> + <CardContent> + <Typography + className={classes.title} + color="inherit" + gutterBottom + > + Enviar email + </Typography> + <EmailInputs email={`${match.params.email}`} /> + </CardContent> + </Card> + ); } export default SendEmail; \ No newline at end of file diff --git a/src/Admin/Pages/Pages/SubPages/Users.js b/src/Admin/Pages/Pages/SubPages/Users.js index 49f091d3..31857677 100644 --- a/src/Admin/Pages/Pages/SubPages/Users.js +++ b/src/Admin/Pages/Pages/SubPages/Users.js @@ -69,8 +69,10 @@ const StyledTableRow = withStyles((theme) => ({ const Users = () => { const ADD_ONE_LENGHT = ['']; - const router = useHistory() 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 @@ -224,7 +226,6 @@ const Users = () => { setEmail("") }, [showFilter]) - if (error) { return <div>Error: {error.message}</div>; } else if (!isLoaded) { diff --git a/src/App.js b/src/App.js index 7c06612f..d687e65a 100644 --- a/src/App.js +++ b/src/App.js @@ -17,6 +17,8 @@ You should have received a copy of the GNU Affero General Public License along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ import React, { useContext, useEffect, useState } from "react"; +import { Store } from './Store' +import Unauthorized from './Admin/Components/Components/Unauthorized' import Home from "./Pages/HomeFunction"; import Search from "./Pages/Search"; import Header from "./Components/Header"; @@ -36,7 +38,6 @@ import PasswordRecoveryPage from "./Pages/PasswordRecoveryPage.js"; import PageProfessor from "./Pages/PageProfessor.js"; import ResourcePage from "./Pages/ResourcePage"; import { BrowserRouter, Switch, Route } from "react-router-dom"; -import { Store } from "./Store"; import TermsPage from "./Pages/TermsPage.js"; import PublicationPermissionsPage from "./Pages/PublicationPermissionsPage.js"; import TabPlataformaMEC from "./Pages/TabsHelp/TabPlataformaMEC"; @@ -95,9 +96,25 @@ import AppBarAdmin from './Admin/Components/Components/AppBar' export default function App() { // eslint-disable-next-line - const { dispatch } = useContext(Store); + const { state, dispatch } = useContext(Store); const [hideFooter, setHideFooter] = useState(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; + } + useEffect(() => { setHideFooter(String(window.location.href).includes("iframe-colecao")); }, [window.location.href]); @@ -180,71 +197,257 @@ export default function App() { <div style={{ backgroundColor: " #D3D3D3" }}> <AppBarAdmin /> <div style={{ padding: "2em" }}> - <Route path="/admin/home" exact={true} component={Inframe} /> - <Route path="/admin/intitutions" component={Institution} /> - <Route path="/admin/institution/:id" component={InstitutionCard} /> + <Route path="/admin/home" exact={true} render={() => { + if (CheckUserPermission()) + return <Inframe /> + else + return <Unauthorized /> + }} /> + <Route path="/admin/intitutions" render={() => { + if (CheckUserPermission()) + return <Institution /> + else + return <Unauthorized /> + }} /> + <Route path="/admin/institution/:id" render={() => { + if (CheckUserPermission()) + return <InstitutionCard /> + else + return <Unauthorized /> + }} /> <Route path="/admin/institutionEdit/:id" - component={InstitutionsInput} + render={() => { + if (CheckUserPermission()) + return <InstitutionsInput /> + else + return <Unauthorized /> + }} /> <Route path="/admin/InstitutionCreate" - component={CreateInstitution} + render={() => { + if (CheckUserPermission()) + return <CreateInstitution /> + else + return <Unauthorized /> + }} /> - <Route path="/admin/noteVars" component={NoteVariables} /> - <Route path="/admin/noteVar/:id" component={NoteVarCard} /> - <Route path="/admin/noteVarEdit/:id" component={NoteVarInputs} /> - <Route path="/admin/languages" component={Languages} /> - <Route path="/admin/languageEdit/:id" component={EditLanguage} /> - <Route path="/admin/languageCreate" component={CreateLanguage} /> + <Route path="/admin/noteVars" render={() => { + if (CheckUserPermission()) + return <NoteVariables /> + else + return <Unauthorized /> + }} /> + <Route path="/admin/noteVar/:id" render={() => { + if (CheckUserPermission()) + return <NoteVarCard /> + else + return <Unauthorized /> + }} /> + <Route path="/admin/noteVarEdit/:id" render={() => { + if (CheckUserPermission()) + return <NoteVarInputs /> + else + return <Unauthorized /> + }} /> + <Route path="/admin/languages" render={() => { + if (CheckUserPermission()) + return <Languages /> + else + return <Unauthorized /> + }} /> + <Route path="/admin/languageEdit/:id" render={() => { + if (CheckUserPermission()) + return <EditLanguage /> + else + return <Unauthorized /> + }} /> + <Route path="/admin/languageCreate" render={() => { + if (CheckUserPermission()) + return <CreateLanguage /> + else + return <Unauthorized /> + }} /> <Route path="/admin/CommunityQuestions" - component={CommunityQuestions} + render={() => { + if (CheckUserPermission()) + return <CommunityQuestions /> + else + return <Unauthorized /> + }} /> <Route path="/admin/CommunityQuestion/:id" - component={CommunityCard} + render={() => { + if (CheckUserPermission()) + return <CommunityCard /> + else + return <Unauthorized /> + }} /> - <Route path="/admin/Collections" component={Collections} /> - <Route path="/admin/Collection/:id" component={CollectionCard} /> + <Route path="/admin/Collections" render={() => { + if (CheckUserPermission()) + return <Collections /> + else + return <Unauthorized /> + }} /> + <Route path="/admin/Collection/:id" render={() => { + if (CheckUserPermission()) + return <CollectionCard /> + else + return <Unauthorized /> + }} /> <Route path="/admin/EditCollection/:id" - component={EditCollection} + render={() => { + if (CheckUserPermission()) + return <EditCollection /> + else + return <Unauthorized /> + }} /> - <Route path="/admin/Ratings" component={Ratings} /> - <Route path="/admin/Rating/:id" component={RatingCard} /> - <Route path="/admin/EditRating/:id" component={EditRating} /> - <Route path="/admin/CreateRating" component={CreateRating} /> - <Route path="/admin/Questions" component={Questions} /> - <Route path="/admin/CreateQuestion" component={CreateQuestions} /> - <Route path="/admin/activities" component={Activity} /> - <Route path="/admin/activity/:id" component={ActivityCard} /> + <Route path="/admin/Ratings" render={() => { + if (CheckUserPermission()) + return <Ratings /> + else + return <Unauthorized /> + }} /> + <Route path="/admin/Rating/:id" render={() => { + if (CheckUserPermission()) + return <RatingCard /> + else + return <Unauthorized /> + }} /> + <Route path="/admin/EditRating/:id" render={() => { + if (CheckUserPermission()) + return <EditRating /> + else + return <Unauthorized /> + }} /> + <Route path="/admin/CreateRating" render={() => { + if (CheckUserPermission()) + return <CreateRating /> + else + return <Unauthorized /> + }} /> + <Route path="/admin/Questions" render={() => { + if (CheckUserPermission()) + return <Questions /> + else + return <Unauthorized /> + }} /> + <Route path="/admin/CreateQuestion" render={() => { + if (CheckUserPermission()) + return <CreateQuestions /> + else + return <Unauthorized /> + }} /> + <Route path="/admin/activities" render={() => { + if (CheckUserPermission()) + return <Activity /> + else + return <Unauthorized /> + }} /> + <Route path="/admin/activity/:id" render={() => { + if (CheckUserPermission()) + return <ActivityCard /> + else + return <Unauthorized /> + }} /> <Route path="/admin/learningObjects" - component={EducationalObject} - /> + render={() => { + if (CheckUserPermission()) + return <EducationalObject /> + else + return <Unauthorized /> + }} /> <Route path="/admin/learningObject/:id" - component={EducationalObjectCard} - /> + render={() => { + if (CheckUserPermission()) + return <EducationalObjectCard /> + else + return <Unauthorized /> + }} /> <Route path="/admin/learningObjectEdit/:id" - component={EducationalObjectEdit} - /> - <Route path="/admin/complaints" component={Complaints} /> - <Route path="/admin/complaint/:id" component={ComplaintCard} /> + render={() => { + if (CheckUserPermission()) + return <EducationalObjectEdit /> + else + return <Unauthorized /> + }} /> + <Route path="/admin/complaints" render={() => { + if (CheckUserPermission()) + return <Complaints /> + else + return <Unauthorized /> + }} /> + <Route path="/admin/complaint/:id" render={() => { + if (CheckUserPermission()) + return <ComplaintCard /> + else + return <Unauthorized /> + }} /> <Route path="/admin/users/teacher_requests" - component={AproveTeacher} - /> - <Route path="/admin/usersList" component={UserList} /> - <Route path="/admin/user/:id" component={UserCard} /> - <Route path="/admin/EditUser/:id" component={EditUser} /> - <Route path="/admin/permissions" component={UserPermissions} /> - <Route path="/admin/EditPermissions/:id" component={EditRole} /> - <Route path="/admin/CreateRole" component={CreateRole} /> - <Route path="/admin/BlockedUsers" component={BlockedUser} /> - <Route path="/admin/sendEmail/:email" component={SendEmail} /> + render={() => { + if (CheckUserPermission()) + return <AproveTeacher /> + else + return <Unauthorized /> + }} /> + <Route path="/admin/usersList" render={() => { + if (CheckUserPermission()) + return <UserList /> + else + return <Unauthorized /> + }} /> + <Route path="/admin/user/:id" render={() => { + if (CheckUserPermission()) + return <UserCard /> + else + return <Unauthorized /> + }} /> + <Route path="/admin/EditUser/:id" render={() => { + if (CheckUserPermission()) + return <EditUser /> + else + return <Unauthorized /> + }} /> + <Route path="/admin/permissions" render={() => { + if (CheckUserPermission()) + return <UserPermissions /> + else + return <Unauthorized /> + }} /> + <Route path="/admin/EditPermissions/:id" render={() => { + if (CheckUserPermission()) + return <EditRole /> + else + return <Unauthorized /> + }} /> + <Route path="/admin/CreateRole" render={() => { + if (CheckUserPermission()) + return <CreateRole /> + else + return <Unauthorized /> + }} /> + <Route path="/admin/BlockedUsers" render={() => { + if (CheckUserPermission()) + return <BlockedUser /> + else + return <Unauthorized /> + }} /> + <Route path="/admin/sendEmail/:email" ender={() => { + if (CheckUserPermission()) + return <SendEmail /> + else + return <Unauthorized /> + }} /> </div> </div> </Switch> -- GitLab From 9a29c330a4ad767bb4a046e9a861e71e175f223c Mon Sep 17 00:00:00 2001 From: Vinicius Gabriel Machado <vgm18@inf.ufpr.br> Date: Sun, 16 May 2021 03:23:28 -0300 Subject: [PATCH 05/12] just commiting one thing that i used in tests and forgot to remove, just in case this version goes live --- src/Components/MenuList.js | 3 --- src/Components/MobileDrawerMenu.js | 4 +--- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/src/Components/MenuList.js b/src/Components/MenuList.js index bed81e11..65ab3c6b 100644 --- a/src/Components/MenuList.js +++ b/src/Components/MenuList.js @@ -28,7 +28,6 @@ import Profile from '../img/default_profile0.png' import styled from 'styled-components' import {apiDomain} from '../env.js' import {deleteRequest} from './HelperFunctions/getAxiosConfig' -import { useHistory } from 'react-router-dom' const OverrideButton = styled(Button)` @@ -53,11 +52,9 @@ export default function MenuList(props) { userLoggedOut: !state.userIsLoggedIn, }) } - let history = useHistory() const handleLogout = () => { const url = `/auth/sign_out` deleteRequest(url, handleSuccessSignOut, (error) => {console.log(error)}) - history.push("/") } return ( diff --git a/src/Components/MobileDrawerMenu.js b/src/Components/MobileDrawerMenu.js index 12fec2ad..469fa378 100644 --- a/src/Components/MobileDrawerMenu.js +++ b/src/Components/MobileDrawerMenu.js @@ -20,7 +20,7 @@ import React, { useContext } from 'react' import { Store } from '../Store'; import Drawer from '@material-ui/core/Drawer'; import styled from 'styled-components' -import { Link, useHistory } from 'react-router-dom' +import { Link } from 'react-router-dom' import HomeIcon from '@material-ui/icons/Home'; import InfoIcon from '@material-ui/icons/Info'; import MailOutlineIcon from '@material-ui/icons/MailOutline'; @@ -102,11 +102,9 @@ export default function MobileDrawerMenu(props) { userLoggedOut: !state.userIsLoggedIn, }) } - let history = useHistory() const handleLogout = () => { const url = `/auth/sign_out` deleteRequest(url, handleSuccessSignOut, (error) => { console.log(error) }) - history.push("/") } return ( -- GitLab From 49bcadce0ff9e8e46ce34715e8d76bc616382335 Mon Sep 17 00:00:00 2001 From: Luis Felipe Risch <lfr20@inf.ufpr.br> Date: Mon, 17 May 2021 13:53:05 -0300 Subject: [PATCH 06/12] Fixed remaing bugs of admin --- .../Components/DataCards/ActivityCard.js | 8 ++- .../Components/DataCards/CollectionCard.js | 13 +++-- .../DataCards/CommunityQuestionCard.js | 8 ++- .../Components/DataCards/ComplaintsCard.js | 19 ++++--- .../DataCards/EducationalObjectsCard.js | 13 +++-- .../Components/DataCards/InstitutionsCard.js | 14 +++-- .../Components/DataCards/NoteVarCard.js | 9 +-- .../Components/DataCards/RatingCard.js | 13 +++-- .../Components/DataCards/UserCard.js | 49 ++++++++--------- .../Components/Inputs/EditCollection.js | 11 ++-- .../Components/Inputs/EditEducationalObect.js | 10 ++-- .../Components/Inputs/EditLanguage.js | 10 ++-- .../Components/Inputs/EditRating.js | 19 ++++--- .../Components/Components/Inputs/EditRoles.js | 10 ++-- .../Components/Components/Inputs/EditUser.js | 5 +- .../Components/Inputs/IntitutionsInputs.js | 11 ++-- .../Components/Inputs/NoteVarInputs.js | 7 ++- src/Admin/Components/Components/Table.js | 23 ++------ src/Admin/Pages/AdminLabelTabs/LabelTabs.js | 2 +- src/Admin/Pages/Pages/SubPages/Activity.js | 14 ++--- .../Pages/Pages/SubPages/AproveTeacher.js | 55 ++++++++++++------- .../Pages/Pages/SubPages/BlockedUsers.js | 35 ++++++++---- src/Admin/Pages/Pages/SubPages/Collections.js | 13 ++--- .../Pages/SubPages/CommunityQuestions.js | 46 ++++++++++------ src/Admin/Pages/Pages/SubPages/Complaints.js | 53 ++++++++++++------ .../Pages/SubPages/EducationalObjects.js | 12 ++-- .../Pages/Pages/SubPages/Institutions.js | 27 +++++---- src/Admin/Pages/Pages/SubPages/Languages.js | 25 ++++++--- .../Pages/Pages/SubPages/NoteVariables.js | 33 ++++++++--- src/Admin/Pages/Pages/SubPages/Permissions.js | 31 ++++++++--- src/Admin/Pages/Pages/SubPages/Questions.js | 31 ++++++++--- src/Admin/Pages/Pages/SubPages/Rating.js | 25 ++++++--- src/Admin/Pages/Pages/SubPages/SendEmail.js | 5 +- src/Admin/Pages/Pages/SubPages/Users.js | 50 +++++++++++------ src/App.js | 36 ++++++------ 35 files changed, 447 insertions(+), 298 deletions(-) diff --git a/src/Admin/Components/Components/DataCards/ActivityCard.js b/src/Admin/Components/Components/DataCards/ActivityCard.js index d3bdcbe1..915df2f9 100644 --- a/src/Admin/Components/Components/DataCards/ActivityCard.js +++ b/src/Admin/Components/Components/DataCards/ActivityCard.js @@ -32,7 +32,7 @@ import { getRequest } from '../../../../Components/HelperFunctions/getAxiosConfi import { Link } from 'react-router-dom' import LoadingSpinner from '../../../../Components/LoadingSpinner'; -const ActivityCard = ({ match }) => { +const ActivityCard = () => { const classes = useStyles(); const [error, setError] = useState(null); //Necessary to consult the API, catch errors @@ -48,7 +48,9 @@ const ActivityCard = ({ match }) => { //getting data from server useEffect(() => { - getRequest(GetAData("activities", match.params.id), + const urlParams = new URLSearchParams(window.location.search); + const query = urlParams.get("activity"); + getRequest(GetAData("activities", query), (data, header) => { setItem(data); setIsLoaded(true); @@ -120,7 +122,7 @@ const ActivityCard = ({ match }) => { </Link> </Grid> </Grid> - <div style={{height: "1em"}}/> + <div style={{ height: "1em" }} /> {DATA.map((info, index) => ( <div className={classes.displayColumn} key={index}> <Typography color="initial" className={classes.subTitle}> diff --git a/src/Admin/Components/Components/DataCards/CollectionCard.js b/src/Admin/Components/Components/DataCards/CollectionCard.js index fa06198a..a4ef28da 100644 --- a/src/Admin/Components/Components/DataCards/CollectionCard.js +++ b/src/Admin/Components/Components/DataCards/CollectionCard.js @@ -36,9 +36,11 @@ import LoadingSpinner from '../../../../Components/LoadingSpinner'; import SnackBar from '../../../../Components/SnackbarComponent'; import { getRequest, deleteRequest } from '../../../../Components/HelperFunctions/getAxiosConfig'; -const CollectionCard = ({ match }) => { +const CollectionCard = () => { let history = useHistory() const classes = useStyles(); + const urlParams = new URLSearchParams(window.location.search); + const id = urlParams.get("collection"); const [error, setError] = useState(null); //Necessary to consult the API, catch errors const [isLoaded, setIsLoaded] = useState(false); //Necessary to consult the API, wait until complete @@ -69,7 +71,6 @@ const CollectionCard = ({ match }) => { //Called when user want to delete one institution async function DeleteHandler() { - const id = match.params.id deleteRequest( DeleteFilter("collections", id), (data) => { @@ -93,7 +94,7 @@ const CollectionCard = ({ match }) => { useEffect(() => { getRequest( - GetAData("collections", match.params.id), + GetAData("collections", id), (data, header) => { setItem(data); setIsLoaded(true); @@ -178,14 +179,14 @@ const CollectionCard = ({ match }) => { </Button> </Link> - <Link style={{ textDecoration: 'none' }} to={`/admin/EditCollection/${item.id}`}> + <Link style={{ textDecoration: 'none' }} to={`/admin/EditCollection?collection=${item.id}`}> <Button startIcon={<EditRoundedIcon />} color="primary" variant="outlined" > Editar - </Button> + </Button> </Link> <Button @@ -198,7 +199,7 @@ const CollectionCard = ({ match }) => { </Button> </Grid> </Grid> - <div style={{height: "1em"}}/> + <div style={{ height: "1em" }} /> {DATA.map((info, index) => ( <div className={classes.displayColumn} key={index}> <Typography color="initial" className={classes.subTitle}> diff --git a/src/Admin/Components/Components/DataCards/CommunityQuestionCard.js b/src/Admin/Components/Components/DataCards/CommunityQuestionCard.js index 4ee4a144..b8ae952c 100644 --- a/src/Admin/Components/Components/DataCards/CommunityQuestionCard.js +++ b/src/Admin/Components/Components/DataCards/CommunityQuestionCard.js @@ -36,7 +36,7 @@ import Unauthorized from "../Unauthorized"; import { getRequest } from '../../../../Components/HelperFunctions/getAxiosConfig' import LoadingSpinner from '../../../../Components/LoadingSpinner'; -const CommunityQuestions = ({ match }) => { +const CommunityQuestions = () => { const { state } = useContext(Store); const classes = useStyles(); @@ -68,8 +68,10 @@ const CommunityQuestions = ({ match }) => { } useEffect(() => { + const urlParams = new URLSearchParams(window.location.search); + const query = urlParams.get("question"); getRequest( - GetAData("contacts", match.params.id), + GetAData("contacts", query), (data, header) => { setItem(data); setIsLoaded(true); @@ -100,7 +102,7 @@ const CommunityQuestions = ({ match }) => { subTitle: "Email", prop: item.email ? - <Link to={`/admin/sendEmail/${item.email}`} style={{ textDecoration: 'none' }}> + <Link to={`/admin/sendEmail/?email=${item.email}`} style={{ textDecoration: 'none' }}> <Button variant='text' color='primary' diff --git a/src/Admin/Components/Components/DataCards/ComplaintsCard.js b/src/Admin/Components/Components/DataCards/ComplaintsCard.js index 17f7623e..4ac22b4e 100644 --- a/src/Admin/Components/Components/DataCards/ComplaintsCard.js +++ b/src/Admin/Components/Components/DataCards/ComplaintsCard.js @@ -51,8 +51,10 @@ import { getRequest, postRequest } from '../../../../Components/HelperFunctions/ const PORTAL_MEC = "https://plataformaintegrada.mec.gov.br/"; -const CollectionCard = ({ match }) => { +const CollectionCard = () => { const classes = useStyles(); + const urlParams = new URLSearchParams(window.location.search); + const id = urlParams.get("id"); const [error, setError] = useState(null); //Necessary to consult the API, catch errors @@ -179,7 +181,7 @@ const CollectionCard = ({ match }) => { const reloadData = () => { setIsLoaded(false) getRequest( - GetAData("complaints", match.params.id), + GetAData("complaints", id), (data, header) => { setItem(data) setIsLoaded(true); @@ -212,7 +214,7 @@ const CollectionCard = ({ match }) => { HandleSnack('Alteração feito com sucesso!', true, 'success', '#228B22') reloadData() } - }, + }, (error) => { HandleSnack('Ocorreu algum erro', true, 'warning', '#FA8072') } @@ -566,13 +568,12 @@ const CollectionCard = ({ match }) => { const HandleComplainObj = async (method) => { postRequest( - MethodsToComplain("complaints", match.params.id, method), + MethodsToComplain("complaints", id, method), {}, (data) => { if (data.errors) HandleSnack('Ocorreu algum erro', true, 'warning', '#FA8072') - else - { + else { HandleSnack('Alteração feito com sucesso', true, 'success', '#228B22') reloadData() } @@ -595,7 +596,7 @@ const CollectionCard = ({ match }) => { useEffect(() => { getRequest( - GetAData("complaints", match.params.id), + GetAData("complaints", id), (data, header) => { setItem(data) setIsLoaded(true); @@ -685,7 +686,7 @@ const CollectionCard = ({ match }) => { > { - item.complainable_type === "User" ? `Usuário #${item.complainable_id}` : `Recurso #${item.complainable_id}` + item.complainable_type === "User" ? `Usuário #${item.complainable_id}` : `Recurso #${item.complainable_id}` } </Typography> </Grid> @@ -704,7 +705,7 @@ const CollectionCard = ({ match }) => { </Link> </Grid> </Grid> - <div style={{height: "1em"}}/> + <div style={{ height: "1em" }} /> {DATA.map((info, index) => ( <div className={classes.displayColumn} key={index}> <Typography color="initial" className={classes.subTitle}> diff --git a/src/Admin/Components/Components/DataCards/EducationalObjectsCard.js b/src/Admin/Components/Components/DataCards/EducationalObjectsCard.js index 493f577f..08a8f325 100644 --- a/src/Admin/Components/Components/DataCards/EducationalObjectsCard.js +++ b/src/Admin/Components/Components/DataCards/EducationalObjectsCard.js @@ -41,9 +41,11 @@ import { } from "../../../../Components/HelperFunctions/getAxiosConfig"; import SnackBar from "../../../../Components/SnackbarComponent"; -const CommunityQuestions = ({ match }) => { +const CommunityQuestions = () => { const classes = useStyles(); let history = useHistory(); + const urlParams = new URLSearchParams(window.location.search); + const id = urlParams.get("learnObj"); const [error, setError] = useState(null); //Necessary to consult the API, catch errors const [isLoaded, setIsLoaded] = useState(false); //Necessary to consult the API, wait until complete @@ -73,7 +75,6 @@ const CommunityQuestions = ({ match }) => { }); async function DeleteHandler() { - const id = match.params.id; deleteRequest( DeleteFilter("learning_objects", id), (data) => { @@ -97,7 +98,7 @@ const CommunityQuestions = ({ match }) => { useEffect(() => { getRequest( - GetAData("learning_objects", match.params.id), + GetAData("learning_objects", id), (data, header) => { setItem(data); setIsLoaded(true); @@ -264,7 +265,7 @@ const CommunityQuestions = ({ match }) => { href={ apiUrl + "/learning_objects/" + - match.params.id + + id + "/download" } > @@ -273,7 +274,7 @@ const CommunityQuestions = ({ match }) => { </Button> <Link style={{ textDecoration: "none" }} - to={`/admin/learningObjectEdit/${item.id}`} + to={`/admin/learningObjectEdit?learnObj=${item.id}`} > <Button startIcon={<EditRoundedIcon />} @@ -293,7 +294,7 @@ const CommunityQuestions = ({ match }) => { </Button> </Grid> </Grid> - <div style={{height: "1em"}}/> + <div style={{ height: "1em" }} /> {item.thumbnail ? ( <div style={{ marginTop: "1em", marginBottom: "1em" }}> <a target="_blank" rel="noreferrer" href={apiDomain + item.thumbnail}> diff --git a/src/Admin/Components/Components/DataCards/InstitutionsCard.js b/src/Admin/Components/Components/DataCards/InstitutionsCard.js index 817fcfad..b4981b7b 100644 --- a/src/Admin/Components/Components/DataCards/InstitutionsCard.js +++ b/src/Admin/Components/Components/DataCards/InstitutionsCard.js @@ -36,9 +36,12 @@ import { Link, useHistory } from 'react-router-dom'; import LoadingSpinner from '../../../../Components/LoadingSpinner'; import SnackBar from '../../../../Components/SnackbarComponent'; -const InstitutionCard = ({ match }) => { +const InstitutionCard = () => { const classes = useStyles(); - let history = useHistory() + let history = useHistory(); + const urlParams = new URLSearchParams(window.location.search); + const id = urlParams.get("institution"); + const [error, setError] = useState(null); //Necessary to consult the API, catch errors const [isLoaded, setIsLoaded] = useState(false); //Necessary to consult the API, wait until complete @@ -68,7 +71,6 @@ const InstitutionCard = ({ match }) => { }); async function DeleteHandler() { - const id = match.params.id deleteRequest( DeleteFilter("institutions", id), (data) => { @@ -92,7 +94,7 @@ const InstitutionCard = ({ match }) => { useEffect(() => { getRequest( - GetAData('institutions', match.params.id), + GetAData('institutions', id), (data, header) => { setIsLoaded(true); setItem(data); @@ -176,7 +178,7 @@ const InstitutionCard = ({ match }) => { </Button> </Link> - <Link style={{ textDecoration: 'none' }} to={`/admin/institutionEdit/${item.id}`}> + <Link style={{ textDecoration: 'none' }} to={`/admin/institutionEdit?institution=${item.id}`}> <Button startIcon={<EditRoundedIcon />} color="primary" @@ -196,7 +198,7 @@ const InstitutionCard = ({ match }) => { </Button> </Grid> </Grid> - <div style={{height: "1em"}}/> + <div style={{ height: "1em" }} /> {DATA.map((info, index) => ( <div className={classes.displayColumn} key={index}> <Typography color="initial" className={classes.subTitle}> diff --git a/src/Admin/Components/Components/DataCards/NoteVarCard.js b/src/Admin/Components/Components/DataCards/NoteVarCard.js index 6b72bddf..7c7b4356 100644 --- a/src/Admin/Components/Components/DataCards/NoteVarCard.js +++ b/src/Admin/Components/Components/DataCards/NoteVarCard.js @@ -34,9 +34,10 @@ import { getRequest } from '../../../../Components/HelperFunctions/getAxiosConfi import { Link } from 'react-router-dom'; import LoadingSpinner from '../../../../Components/LoadingSpinner'; -const NoteCard = ({ match }) => { - console.log(match); +const NoteCard = () => { const classes = useStyles(); + const urlParams = new URLSearchParams(window.location.search); + const id = urlParams.get("id"); const [error, setError] = useState(null); //Necessary to consult the API, catch errors const [isLoaded, setIsLoaded] = useState(false); //Necessary to consult the API, wait until complete @@ -52,7 +53,7 @@ const NoteCard = ({ match }) => { useEffect(() => { getRequest( - GetAData('scores', match.params.id), + GetAData('scores', id), (data, header) => { setIsLoaded(true); setItem(data); @@ -116,7 +117,7 @@ const NoteCard = ({ match }) => { </Button> </Link> - <Link style={{ textDecoration: 'none' }} to={`/admin/noteVarEdit/${item.id}`}> + <Link style={{ textDecoration: 'none' }} to={`/admin/noteVarEdit?id=${item.id}`}> <Button startIcon={<EditRoundedIcon />} color="primary" diff --git a/src/Admin/Components/Components/DataCards/RatingCard.js b/src/Admin/Components/Components/DataCards/RatingCard.js index c333b56c..b5f69a53 100644 --- a/src/Admin/Components/Components/DataCards/RatingCard.js +++ b/src/Admin/Components/Components/DataCards/RatingCard.js @@ -36,9 +36,11 @@ import { Link, useHistory } from 'react-router-dom'; import LoadingSpinner from '../../../../Components/LoadingSpinner'; import SnackBar from '../../../../Components/SnackbarComponent'; -const RatingCard = ({ match }) => { +const RatingCard = () => { const classes = useStyles(); - let history = useHistory() + let history = useHistory(); + const urlParams = new URLSearchParams(window.location.search); + const id = urlParams.get("rating"); const [error, setError] = useState(null); //Necessary to consult the API, catch errors const [isLoaded, setIsLoaded] = useState(false); //Necessary to consult the API, wait until complete @@ -68,7 +70,6 @@ const RatingCard = ({ match }) => { }; async function DeleteHandler() { - const id = match.params.id deleteRequest( DeleteFilter("ratings", id), (data) => { @@ -93,7 +94,7 @@ const RatingCard = ({ match }) => { useEffect(() => { getRequest( - GetAData('ratings', match.params.id), + GetAData('ratings', id), (data, header) => { setIsLoaded(true); setItem(data); @@ -165,7 +166,7 @@ const RatingCard = ({ match }) => { </Button> </Link> - <Link style={{ textDecoration: 'none' }} to={`/admin/EditRating/${item.id}`}> + <Link style={{ textDecoration: 'none' }} to={`/admin/EditRating?rating=${item.id}`}> <Button startIcon={<EditRoundedIcon />} color="primary" @@ -185,7 +186,7 @@ const RatingCard = ({ match }) => { </Button> </Grid> </Grid> - <div style={{height: "1em"}}/> + <div style={{ height: "1em" }} /> {DATA.map((info, index) => ( <div className={classes.displayColumn} key={index}> <Typography color="initial" className={classes.subTitle}> diff --git a/src/Admin/Components/Components/DataCards/UserCard.js b/src/Admin/Components/Components/DataCards/UserCard.js index d4e82906..a34f96b3 100644 --- a/src/Admin/Components/Components/DataCards/UserCard.js +++ b/src/Admin/Components/Components/DataCards/UserCard.js @@ -45,9 +45,12 @@ import { getRequest, postRequest, deleteRequest, putRequest } from '../../../../ //styles import styled from 'styled-components'; -const CollectionCard = ({ match }, props) => { +const CollectionCard = () => { let history = useHistory() const classes = useStyles(); + const urlParams = new URLSearchParams(window.location.search); + const id = urlParams.get("id"); + const [error, setError] = useState(null); //Necessary to consult the API, catch errors const [isLoaded, setIsLoaded] = useState(false); //Necessary to consult the API, wait until complete const [item, setItem] = useState({}); @@ -138,7 +141,7 @@ const CollectionCard = ({ match }, props) => { const reloadData = () => { setIsLoaded(false) getRequest( - GetAData("users", match.params.id), + GetAData("users", id), (data, header) => { setItem(data) setIsLoaded(true); @@ -159,13 +162,12 @@ const CollectionCard = ({ match }, props) => { url, body, (data) => { - if(data.errors) + if (data.errors) HandleSnack("Erro!", true, "warning", "#FA8072"); - else - { + else { HandleSnack(`${userName} aceito como professor!`, true, "success", "#228B22"); reloadData() - } + } }, (error) => { HandleSnack("Erro!", true, "warning", "#FA8072"); @@ -182,13 +184,12 @@ const CollectionCard = ({ match }, props) => { url, body, (data) => { - if(data.errors) + if (data.errors) HandleSnack("Erro!", true, "warning", "#FA8072"); - else - { - HandleSnack(`${userName} rejeitado como professor!`, true, "success", "#228B22"); - reloadData() - } + else { + HandleSnack(`${userName} rejeitado como professor!`, true, "success", "#228B22"); + reloadData() + } }, (error) => { HandleSnack("Erro!", true, "warning", "#FA8072"); @@ -200,10 +201,9 @@ const CollectionCard = ({ match }, props) => { deleteRequest( `/users/${userId}`, (data) => { - if(data.errors) + if (data.errors) HandleSnack("Erro!", true, "warning", "#FA8072") - else - { + else { HandleSnack(`${item.name} deletado com sucesso!`, true, "success", "#228B22"); history.goBack() } @@ -243,8 +243,8 @@ const CollectionCard = ({ match }, props) => { </Button> ) } - return <Typography color="textSecondary"> - Usuário não bloqueado + return <Typography color="textSecondary"> + Usuário não bloqueado </Typography> } @@ -294,16 +294,15 @@ const CollectionCard = ({ match }, props) => { const ReactiveUser = () => { putRequest( - `/users/${match.params.id}/reactivate_user`, + `/users/${id}/reactivate_user`, {}, (data) => { - if(data.errors) + if (data.errors) HandleSnack('Erro ao tentar reativar usuário!', true, 'warning', '#FA8072') - else - { + else { HandleSnack('Usuário foi reativado com sucesso!', true, 'success', '#228B22') reloadData() - } + } }, (error) => { HandleSnack('Erro ao tentar reativar usuário!', true, 'warning', '#FA8072') @@ -313,7 +312,7 @@ const CollectionCard = ({ match }, props) => { useEffect(() => { getRequest( - GetAData("users", match.params.id), + GetAData("users", id), (data, header) => { setItem(data) setIsLoaded(true); @@ -390,7 +389,7 @@ const CollectionCard = ({ match }, props) => { </Button> </Grid> <Grid item> - <Link to={`/admin/EditUser/${item.id}`} style={{ textDecoration: "none" }}> + <Link to={`/admin/EditUser?id=${item.id}`} style={{ textDecoration: "none" }}> <Button startIcon={<EditRoundedIcon />} color="primary" @@ -425,7 +424,7 @@ const CollectionCard = ({ match }, props) => { </Typography> { item.email ? - <Link to={`/admin/sendEmail/${item.email}`} style={{ textDecoration: 'none' }}> + <Link to={`/admin/sendEmail?email=${item.email}`} style={{ textDecoration: 'none' }}> <Button variant='text' color='primary' diff --git a/src/Admin/Components/Components/Inputs/EditCollection.js b/src/Admin/Components/Components/Inputs/EditCollection.js index 67917eb6..13aabcf1 100644 --- a/src/Admin/Components/Components/Inputs/EditCollection.js +++ b/src/Admin/Components/Components/Inputs/EditCollection.js @@ -38,14 +38,15 @@ import { Link } from 'react-router-dom'; import ClassicEditor from "@ckeditor/ckeditor5-build-classic" import { CKEditor } from '@ckeditor/ckeditor5-react'; -const EditCollection = ({ match }) => { +const EditCollection = () => { const { state } = useContext(Store); + const urlParams = new URLSearchParams(window.location.search); + const id = urlParams.get("collection"); const [error, setError] = useState(null); //Necessary to consult the API, catch errors const [isLoaded, setIsLoaded] = useState(false); //Necessary to consult the API, wait until complete const [isLoading, setIsLoading] = useState(false); - const id = match.params.id const [name, setName] = useState('') const [privacy, setPrivacy] = useState('') const [description, setDescription] = useState(''); @@ -149,10 +150,10 @@ const EditCollection = ({ match }) => { api, body, (data) => { - if(data.errors){ + if (data.errors) { HandleSnack(`${data.errors[0]}`, true, 'warning', '#FA8072') } - else{ + else { HandleSnack('A Coleção foi alterada com sucesso', true, 'success', '#228B22') } setIsLoading(false) @@ -166,7 +167,7 @@ const EditCollection = ({ match }) => { useEffect(() => { getRequest( - GetAData("collections", match.params.id), + GetAData("collections", id), (data, header) => { setIsLoaded(true); setError(false); diff --git a/src/Admin/Components/Components/Inputs/EditEducationalObect.js b/src/Admin/Components/Components/Inputs/EditEducationalObect.js index f5eca683..59963830 100644 --- a/src/Admin/Components/Components/Inputs/EditEducationalObect.js +++ b/src/Admin/Components/Components/Inputs/EditEducationalObect.js @@ -62,14 +62,14 @@ const useStyles = makeStyles((theme) => ({ let text; -const EditEducationalObject = ({ match }) => { +const EditEducationalObject = () => { const { state } = useContext(Store); + const urlParams = new URLSearchParams(window.location.search); + const id = urlParams.get("learnObj"); const theme = useTheme(); const classes = useStyles(); - const id = match.params.id; - const [error, setError] = useState(null); //Necessary to consult the API, catch errors const [isLoaded, setIsLoaded] = useState(false); //Necessary to consult the API, wait until complete const [isLoading, setIsLoading] = useState(false); //is loading to submit @@ -275,7 +275,7 @@ const EditEducationalObject = ({ match }) => { "#228B22" ); } else { - if(data.errors){ + if (data.errors) { HandleSnack(`${data.errors[0]}`, true, 'warning', '#FA8072') } if (data.author) { @@ -399,7 +399,7 @@ const EditEducationalObject = ({ match }) => { useEffect(() => { const urls = [ - `/learning_objects/${match.params.id}`, + `/learning_objects/${id}`, "/languages", "/object_types", ]; diff --git a/src/Admin/Components/Components/Inputs/EditLanguage.js b/src/Admin/Components/Components/Inputs/EditLanguage.js index 8215429e..44df71ce 100644 --- a/src/Admin/Components/Components/Inputs/EditLanguage.js +++ b/src/Admin/Components/Components/Inputs/EditLanguage.js @@ -37,15 +37,16 @@ import DeleteRoundedIcon from "@material-ui/icons/DeleteRounded"; import { Link, useHistory } from 'react-router-dom'; import Unauthorized from '../Unauthorized'; -const EditLanguage = ({ match }) => { +const EditLanguage = () => { const { state } = useContext(Store); let history = useHistory() + const urlParams = new URLSearchParams(window.location.search); + const id = urlParams.get("language"); const [error, setError] = useState(null); //Necessary to consult the API, catch errors const [isLoaded, setIsLoaded] = useState(false); //Necessary to consult the API, wait until complete const [isLoading, setIsLoading] = useState(false); - const id = match.params.id const [name, setName] = useState() const [code, setCode] = useState() @@ -67,7 +68,6 @@ const EditLanguage = ({ match }) => { }) async function DeleteHandler() { - const id = match.params.id deleteRequest( DeleteFilter("languages", id), (data) => { @@ -180,7 +180,7 @@ const EditLanguage = ({ match }) => { if (data.id) HandleSnack('A linguagem foi alterada com sucesso!', true, 'success', '#228B22') else { - if(data.errors){ + if (data.errors) { HandleSnack(`${data.errors[0]}`, true, 'warning', '#FA8072') } if (data.name) { @@ -215,7 +215,7 @@ const EditLanguage = ({ match }) => { useEffect(() => { getRequest( - GetAData("languages", match.params.id), + GetAData("languages", id), (data, header) => { setIsLoaded(true); setName(data.name) diff --git a/src/Admin/Components/Components/Inputs/EditRating.js b/src/Admin/Components/Components/Inputs/EditRating.js index a42363d6..1b8e0e6f 100644 --- a/src/Admin/Components/Components/Inputs/EditRating.js +++ b/src/Admin/Components/Components/Inputs/EditRating.js @@ -33,17 +33,18 @@ import LoadingSpinner from '../../../../Components/LoadingSpinner'; import { getRequest, putRequest } from '../../../../Components/HelperFunctions/getAxiosConfig' import { EditFilter, GetAData } from '../../../Filters'; //routers -import {Link} from 'react-router-dom'; +import { Link } from 'react-router-dom'; import Unauthorized from '../Unauthorized'; -const EditRating = ({ match }) => { +const EditRating = () => { const { state } = useContext(Store); + const urlParams = new URLSearchParams(window.location.search); + const id = urlParams.get("rating"); const [error, setError] = useState(null); //Necessary to consult the API, catch errors const [isLoaded, setIsLoaded] = useState(false); //Necessary to consult the API, wait until complete const [isLoading, setIsLoading] = useState(false); - const id = match.params.id const [name, setName] = useState() const [description, setDescription] = useState() @@ -161,7 +162,7 @@ const EditRating = ({ match }) => { api, body, (data, header) => { - if(data.errors) + if (data.errors) HandleSnack('Ocorreu algum erro', true, 'warning', '#FA8072') else HandleSnack('O rating foi alterada com sucesso', true, 'success', '#228B22') @@ -193,7 +194,7 @@ const EditRating = ({ match }) => { useEffect(() => { getRequest( - GetAData("ratings", match.params.id), + GetAData("ratings", id), (data, header) => { setIsLoaded(true); setName(data.name) @@ -209,8 +210,8 @@ const EditRating = ({ match }) => { if (error) { return <div> Houve um erro... </div> } else if (!isLoaded) { - return <LoadingSpinner text="Carregando..."/> - } else if(CheckUserPermission()){ + return <LoadingSpinner text="Carregando..." /> + } else if (CheckUserPermission()) { return ( <Card> <SnackBar @@ -233,7 +234,7 @@ const EditRating = ({ match }) => { </Typography> </Grid> <Grid item> - <Link style={{textDecoration: 'none'}} to={'/admin/Ratings'}> + <Link style={{ textDecoration: 'none' }} to={'/admin/Ratings'}> <Button startIcon={<ListRoundedIcon />} variant='outlined' @@ -282,7 +283,7 @@ const EditRating = ({ match }) => { </CardAction> </Card> ) - } else return <Unauthorized/> + } else return <Unauthorized /> } export default EditRating; \ No newline at end of file diff --git a/src/Admin/Components/Components/Inputs/EditRoles.js b/src/Admin/Components/Components/Inputs/EditRoles.js index 9b2ecaa1..d08e14b2 100644 --- a/src/Admin/Components/Components/Inputs/EditRoles.js +++ b/src/Admin/Components/Components/Inputs/EditRoles.js @@ -38,15 +38,16 @@ import { EditFilter, GetAData, DeleteFilter } from '../../../Filters'; import { Link, useHistory } from 'react-router-dom'; import Unauthorized from '../Unauthorized'; -const EditLanguage = ({ match }) => { +const EditLanguage = () => { const { state } = useContext(Store); let history = useHistory() + const urlParams = new URLSearchParams(window.location.search); + const id = urlParams.get("role"); const [error, setError] = useState(null); //Necessary to consult the API, catch errors const [isLoaded, setIsLoaded] = useState(false); //Necessary to consult the API, wait until complete const [isLoading, setIsLoading] = useState(false); - const id = match.params.id const [name, setName] = useState() const [desc, setDesc] = useState() const [snackInfo, setSnackInfo] = useState({ @@ -157,7 +158,7 @@ const EditLanguage = ({ match }) => { if (data.id) HandleSnack('A role foi alterada com sucesso', true, 'success', '#228B22') else { - if(data.errors){ + if (data.errors) { HandleSnack(`${data.errors[0]}`, true, 'warning', '#FA8072') } if (data.name) { @@ -182,7 +183,6 @@ const EditLanguage = ({ match }) => { } async function DeleteHandler() { - const id = match.params.id deleteRequest( DeleteFilter("roles", id), (data) => { @@ -206,7 +206,7 @@ const EditLanguage = ({ match }) => { useEffect(() => { getRequest( - GetAData("roles", match.params.id), + GetAData("roles", id), (data, header) => { setIsLoaded(true); setName(data.name) diff --git a/src/Admin/Components/Components/Inputs/EditUser.js b/src/Admin/Components/Components/Inputs/EditUser.js index 73a42e96..fe9a61c8 100644 --- a/src/Admin/Components/Components/Inputs/EditUser.js +++ b/src/Admin/Components/Components/Inputs/EditUser.js @@ -57,11 +57,12 @@ const useStyles = makeStyles((theme) => ({ }, })); -const EditUser = ({ match }) => { +const EditUser = () => { const classes = useStyles(); let history = useHistory(); const { state } = useContext(Store) - const id = match.params.id + const urlParams = new URLSearchParams(window.location.search); + const id = urlParams.get("id"); const [error, setError] = useState(id !== "-1" ? null : false); //Necessary to consult the API, catch errors const [isLoaded, setIsLoaded] = useState(id === "-1" ? true : false); //Necessary to consult the API, wait until complete diff --git a/src/Admin/Components/Components/Inputs/IntitutionsInputs.js b/src/Admin/Components/Components/Inputs/IntitutionsInputs.js index a4098e68..47031b7b 100644 --- a/src/Admin/Components/Components/Inputs/IntitutionsInputs.js +++ b/src/Admin/Components/Components/Inputs/IntitutionsInputs.js @@ -39,7 +39,7 @@ import { Link } from 'react-router-dom'; let id; -const EditInstitution = ({ match }) => { +const EditInstitution = () => { const { state } = useContext(Store); const [error, setError] = useState(null); //Necessary to consult the API, catch errors @@ -98,7 +98,7 @@ const EditInstitution = ({ match }) => { } setCountry(e.target.value) } - + // Handle snack infos const HandleSnack = (message, state, icon, color) => { setSnackInfo({ @@ -145,7 +145,7 @@ const EditInstitution = ({ match }) => { if (data.id) HandleSnack('A instituição foi criada com sucesso!', true, 'success', '#228B22') else { - if(data.errors){ + if (data.errors) { HandleSnack(`${data.errors[0]}`, true, 'warning', '#FA8072') } if (data.name) { @@ -209,8 +209,10 @@ const EditInstitution = ({ match }) => { ] useEffect(() => { + const urlParams = new URLSearchParams(window.location.search); + const id = urlParams.get("institution"); getRequest( - GetAData("institutions", match.params.id), + GetAData("institutions", id), (data, header) => { setIsLoaded(true); setName(data.name) @@ -218,7 +220,6 @@ const EditInstitution = ({ match }) => { setAdress(data.adress) setCity(data.city) setCountry(data.country) - id = data.id }, (error) => { setIsLoaded(true); diff --git a/src/Admin/Components/Components/Inputs/NoteVarInputs.js b/src/Admin/Components/Components/Inputs/NoteVarInputs.js index 8753d1a2..3cc63a70 100644 --- a/src/Admin/Components/Components/Inputs/NoteVarInputs.js +++ b/src/Admin/Components/Components/Inputs/NoteVarInputs.js @@ -37,14 +37,15 @@ import { EditFilter, GetAData } from '../../../Filters'; import { Link } from 'react-router-dom'; import Unauthorized from '../Unauthorized'; -const NoteVarInputs = ({ match }) => { +const NoteVarInputs = () => { const { state } = useContext(Store); + const urlParams = new URLSearchParams(window.location.search); + const id = urlParams.get("id"); const [error, setError] = useState(null); //Necessary to consult the API, catch errors const [isLoaded, setIsLoaded] = useState(false); //Necessary to consult the API, wait until complete const [isLoading, setIsLoading] = useState(false); - const id = match.params.id const [name, setName] = useState() const [code, setCode] = useState() const [weight, setWeight] = useState() @@ -217,7 +218,7 @@ const NoteVarInputs = ({ match }) => { useEffect(() => { getRequest( - GetAData("scores", match.params.id), + GetAData("scores", id), (data, header) => { setIsLoaded(true); setName(data.name) diff --git a/src/Admin/Components/Components/Table.js b/src/Admin/Components/Components/Table.js index 5e74b53f..ddb7a377 100644 --- a/src/Admin/Components/Components/Table.js +++ b/src/Admin/Components/Components/Table.js @@ -23,23 +23,7 @@ const StyledTableCell = withStyles((theme) => ({ const useStyles = makeStyles({ table: { minWidth: 700, - width : "100%" - }, - root: { - minWidth: 275, - boxShadow: '2px 2px 1px #A9A9A9' - }, - bullet: { - display: 'inline-block', - margin: '0 2px', - transform: 'scale(0.8)', - }, - title: { - fontSize: 28, - fontWeight: "500" - }, - pos: { - marginBottom: 12, + width: "100%" }, }); @@ -53,12 +37,13 @@ const TableData = (props) => { <TableRow> { props.top.map((top, index) => ( - index === 0 ? + top === "ID" ? <StyledTableCell key={index}> <div style={{ display: 'flex', flexDirection: 'row', alignItems: 'center' }}> {top} { - props.onIconPressed === undefined ? <div></div> : <IconButton onClick={props.onIconPressed} color='primary'> + props.onIconPressed && + <IconButton onClick={props.onIconPressed} color='primary'> <FilterListRoundedIcon style={{ color: 'white' }} /> </IconButton> } diff --git a/src/Admin/Pages/AdminLabelTabs/LabelTabs.js b/src/Admin/Pages/AdminLabelTabs/LabelTabs.js index 1c7e9ac5..9b2894cd 100644 --- a/src/Admin/Pages/AdminLabelTabs/LabelTabs.js +++ b/src/Admin/Pages/AdminLabelTabs/LabelTabs.js @@ -119,7 +119,7 @@ const TabsItens = [ }, { label: "Enviar email", - href: '/admin/sendEmail/none', + href: '/admin/sendEmail?email=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 6cb62ff1..54d37dc4 100644 --- a/src/Admin/Pages/Pages/SubPages/Activity.js +++ b/src/Admin/Pages/Pages/SubPages/Activity.js @@ -245,10 +245,10 @@ const Activity = () => { {items.map((row, index) => index === items.length - 1 ? ( <StyledDivButton - key="Load more" + key={new Date().toISOString() + row.created_at} > <Button - key={index} + key={new Date().toISOString() + row.created_at} color="primary" variant="text" // disabled={isLoadingMoreItems} @@ -268,12 +268,12 @@ const Activity = () => { ) : ( <> <MobileList - key={index} + key={new Date().toISOString() + row.created_at} title={row.id} subtitle={row.privacy} backColor={"#673ab7"} avatar={<AllOutIcon />} - href={`/admin/activity/${row.id}`} + href={`/admin/activity?activity=${row.id}`} reset={() => { }} @@ -371,7 +371,7 @@ const Activity = () => { <TableBody> {items.map((row, index) => index === items.length - 1 ? ( - <StyledTableRow key={row.created_at} style={{ padding: "1em" }}> + <StyledTableRow key={new Date().toISOString() + row.created_at} style={{ padding: "1em" }}> {/* Button to load more data */} <StyledTableCell> <Button @@ -393,7 +393,7 @@ const Activity = () => { </StyledTableCell> </StyledTableRow> ) : ( - <StyledTableRow key={index}> + <StyledTableRow key={new Date().toISOString() + row.created_at}> <StyledTableCell component="th" scope="row"> {DisplayDate(row.created_at)} </StyledTableCell> @@ -407,7 +407,7 @@ const Activity = () => { </StyledTableCell> <StyledTableCell align="right">{row.privacy}</StyledTableCell> <StyledTableCell align="right"> - <Link to={`/admin/activity/${row.id}`}> + <Link to={`/admin/activity?activity=${row.id}`}> <IconButton> <VisibilityIcon style={{ fill: "#00bcd4" }} /> </IconButton> diff --git a/src/Admin/Pages/Pages/SubPages/AproveTeacher.js b/src/Admin/Pages/Pages/SubPages/AproveTeacher.js index c6078dba..8fae644f 100644 --- a/src/Admin/Pages/Pages/SubPages/AproveTeacher.js +++ b/src/Admin/Pages/Pages/SubPages/AproveTeacher.js @@ -85,6 +85,7 @@ const AproveTeacher = () => { "AÇÕES", ]; //Labels from Table + const [invertList, setInvertList] = useState(false) const [error, setError] = useState(null); //Necessary to consult the API, catch errors const [isLoaded, setIsLoaded] = useState(false); //Necessary to consult the API, wait until complete const [items, setItems] = useState([]); //Necessary to consult the API, data @@ -273,25 +274,31 @@ const AproveTeacher = () => { ); }; - const buildUrl = (email, submitter_request, name) => { + const cleanArrayAndInvert = () => { + setInvertList(!invertList) + setCurrPage(0) + setItems([]) + } + + const buildUrl = (email, submitter_request, name, direction) => { if (email && submitter_request && name) - return Url("users", `"submitter_request" : "${submitter_request}", "email" : "${email}", "name" : "${name}"`, currPage, "DESC") + return Url("users", `"submitter_request" : "${submitter_request}", "email" : "${email}", "name" : "${name}"`, currPage, direction) else if (email && name) - return Url("users", `"email" : "${email}", "name" : "${name}"`, currPage, "DESC") + return Url("users", `"email" : "${email}", "name" : "${name}"`, currPage, direction) else if (email && submitter_request) - return Url("users", `"email" : "${email}", "submitter_request" : "${submitter_request}"`, currPage, "DESC") + return Url("users", `"email" : "${email}", "submitter_request" : "${submitter_request}"`, currPage, direction) else if (name && submitter_request) - return Url("users", `"name" : "${name}", "submitter_request" : "${submitter_request}"`, currPage, "DESC") + return Url("users", `"name" : "${name}", "submitter_request" : "${submitter_request}"`, currPage, direction) else if (email) - return Url("users", `"email" : "${email}"`, currPage, "DESC") + return Url("users", `"email" : "${email}"`, currPage, direction) else if (submitter_request) - return Url("users", `"submitter_request" : "${submitter_request}"`, currPage, "DESC") + return Url("users", `"submitter_request" : "${submitter_request}"`, currPage, direction) else if (name) - return Url("users", `"name" : ${name}`, currPage, "DESC") + return Url("users", `"name" : ${name}`, currPage, direction) else - return Url("users", "", currPage, "DESC") + return Url("users", "", currPage, direction) } useEffect(() => { @@ -300,7 +307,7 @@ const AproveTeacher = () => { else setIsLoadingMoreItems(true) getRequest( - buildUrl(email, option, name), + buildUrl(email, option, name, invertList ? "ASC" : "DESC"), (data, header) => { const arrData = [...data] if (arrData.length === 0) { @@ -326,7 +333,7 @@ const AproveTeacher = () => { setError(true) } ) - }, [currPage, option, email, name]) + }, [currPage, option, email, name, invertList]) useEffect(() => { setOption("requested") @@ -376,6 +383,13 @@ const AproveTeacher = () => { setShowFilter(!showFilter); }, icon: <FilterListRoundedIcon /> + }, + { + name: "Inverter lista", + isLoading: false, + func: () => { + cleanArrayAndInvert() + }, } ]} > @@ -441,7 +455,7 @@ const AproveTeacher = () => { index === items.length - 1 ? ( <StyledDivButton> <Button - key={index} + key={new Date().toISOString() + row.created_at} color="primary" variant="text" // disabled={isLoadingMoreItems} @@ -461,7 +475,7 @@ const AproveTeacher = () => { ) : ( <> <MobileList - key={index} + key={new Date().toISOString() + row.created_at} title={row.name} subtitle={row.id} backColor={"#00bcd4"} @@ -476,7 +490,7 @@ const AproveTeacher = () => { }} /> } - href={`/admin/user/${row.id}`} + href={`/admin/user?id=${row.id}`} reset={() => { }} @@ -484,7 +498,7 @@ const AproveTeacher = () => { { title: "Email", subtitle: row.email ? - <Link to={`/admin/sendEmail/${row.email}`} style={{ textDecoration: 'none' }}> + <Link to={`/admin/sendEmail?email=${row.email}`} style={{ textDecoration: 'none' }}> <Button variant='text' color='primary' @@ -647,11 +661,14 @@ const AproveTeacher = () => { <div style={{ height: "2em" }}></div> <Grid xs={12} container> - <TableData top={TOP_LABELS}> + <TableData + top={TOP_LABELS} + onIconPressed={cleanArrayAndInvert} + > <TableBody> {items.map((row, index) => index === items.length - 1 ? ( - <StyledTableRow key={index}> + <StyledTableRow key={new Date().toISOString() + row.created_at}> {/* Button to load more data */} <StyledTableCell> <Button @@ -674,7 +691,7 @@ const AproveTeacher = () => { </StyledTableRow> ) : ( <StyledTableRow - key={index} + key={new Date().toISOString() + row.created_at} style={{ flex: 1, width: "100%" }} > <StyledTableCell component="th" scope="row"> @@ -691,7 +708,7 @@ const AproveTeacher = () => { {DisplayDate(row.created_at)} </StyledTableCell> <StyledTableCell align="right"> - <Link to={`/admin/user/${row.id}`}> + <Link to={`/admin/user?id=${row.id}`}> <IconButton> <VisibilityIcon style={{ fill: "#00bcd4" }} /> </IconButton> diff --git a/src/Admin/Pages/Pages/SubPages/BlockedUsers.js b/src/Admin/Pages/Pages/SubPages/BlockedUsers.js index ac2f09de..e6083f39 100644 --- a/src/Admin/Pages/Pages/SubPages/BlockedUsers.js +++ b/src/Admin/Pages/Pages/SubPages/BlockedUsers.js @@ -71,6 +71,7 @@ const BlockedUsers = () => { const ADD_ONE_LENGHT = ['']; const WINDOW_WIDTH = window.innerWidth + const [invertList, setInvertList] = useState(false) const [error, setError] = useState(null); //Necessary to consult the API, catch errors const [isLoaded, setIsLoaded] = useState(false); //Necessary to consult the API, wait until complete const [items, setItems] = useState([]); //Necessary to consult the API, data @@ -190,13 +191,19 @@ const BlockedUsers = () => { .toString(); }; + const cleanArrayAndInvert = () => { + setInvertList(!invertList) + setCurrPage(0) + setItems([]) + } + useEffect(() => { if (currPage === 0) setIsLoaded(false) else setIsLoadingMoreItems(true) getRequest( - Url('users', `"state" : ${stateOpt}`, currPage, 'DESC'), + Url('users', `"state" : ${stateOpt}`, currPage, invertList ? "ASC" : 'DESC'), (data, header) => { const arrData = [...data] @@ -223,7 +230,7 @@ const BlockedUsers = () => { setError(true) } ) - }, [currPage, stateOpt]) + }, [currPage, stateOpt, invertList]) if (error) { return <div>Error: {error.message}</div>; @@ -259,6 +266,13 @@ const BlockedUsers = () => { }, icon: <UpdateRoundedIcon /> }, + { + name: "Inverter lista", + isLoading: false, + func: () => { + cleanArrayAndInvert() + }, + }, ]} > <Grid item> @@ -287,7 +301,7 @@ const BlockedUsers = () => { index === items.length - 1 ? ( <StyledDivButton> <Button - key={index} + key={new Date().toISOString() + row.created_at} color="primary" variant="text" // disabled={isLoadingMoreItems} @@ -307,7 +321,7 @@ const BlockedUsers = () => { ) : ( <> <MobileList - key={index} + key={new Date().toISOString() + row.created_at} title={row.name} subtitle={row.id} backColor={"#e81f4f"} @@ -322,7 +336,7 @@ const BlockedUsers = () => { }} /> } - href={`/admin/user/${row.id}`} + href={`/admin/user?id=${row.id}`} reset={() => { }} data={ @@ -330,7 +344,7 @@ const BlockedUsers = () => { { title: "Email", subtitle: row.email ? - <Link to={`/admin/sendEmail/${row.email}`} style={{ textDecoration: 'none' }}> + <Link to={`/admin/sendEmail?email=${row.email}`} style={{ textDecoration: 'none' }}> <Button variant='text' color='primary' @@ -419,11 +433,12 @@ const BlockedUsers = () => { <TableData top={topTable} + onIconPressed={cleanArrayAndInvert} > <TableBody> {items.map((row, index) => ( index === items.length - 1 ? - <StyledTableRow key={index}> + <StyledTableRow key={new Date().toISOString() + row.created_at}> {/* Button to load more data */} <StyledTableCell> <Button @@ -444,7 +459,7 @@ const BlockedUsers = () => { : - <StyledTableRow key={index}> + <StyledTableRow key={new Date().toISOString() + row.created_at}> <StyledTableCell component="th" scope="row">{row.id}</StyledTableCell> <StyledTableCell align="right"> {BlockStatus(row.state)} @@ -453,7 +468,7 @@ const BlockedUsers = () => { <StyledTableCell align="right"> { row.email ? - <Link to={`/admin/sendEmail/${row.email}`} style={{ textDecoration: 'none' }}> + <Link to={`/admin/sendEmail?email=${row.email}`} style={{ textDecoration: 'none' }}> <Button variant='text' color='primary' @@ -477,7 +492,7 @@ const BlockedUsers = () => { > Desbloquear </Button> - <Link to={`/admin/user/${row.id}`}> + <Link to={`/admin/user?id=${row.id}`}> <Button style={{ width: "100%" }} variant="contained" diff --git a/src/Admin/Pages/Pages/SubPages/Collections.js b/src/Admin/Pages/Pages/SubPages/Collections.js index 493d50a2..b312aa53 100644 --- a/src/Admin/Pages/Pages/SubPages/Collections.js +++ b/src/Admin/Pages/Pages/SubPages/Collections.js @@ -350,7 +350,7 @@ const Collections = () => { {items.map((row, index) => index === items.length - 1 ? ( <StyledDivButton - key="Load more" + key={new Date().toISOString() + row.created_at} > <Button color="primary" @@ -372,12 +372,12 @@ const Collections = () => { ) : ( <> <MobileList - key={index} + key={new Date().toISOString() + row.created_at} title={row.name} subtitle={row.privacy} backColor={"#e81f4f"} avatar={<PeopleRoundedIcon />} - href={`/admin/Collection/${row.id}`} + href={`/admin/Collection?collection=${row.id}`} reset={() => { }} @@ -517,10 +517,9 @@ const Collections = () => { <TableBody> {items.map((row, index) => index === items.length - 1 ? ( - <StyledTableRow key={row.created_at}> + <StyledTableRow key={new Date().toISOString() + row.created_at}> <StyledTableCell> <Button - key={index} color="primary" variant="text" // disabled={isLoadingMoreItems} @@ -539,7 +538,7 @@ const Collections = () => { </StyledTableCell> </StyledTableRow> ) : ( - <StyledTableRow key={index}> + <StyledTableRow key={new Date().toISOString() + row.created_at}> <StyledTableCell component="th" scope="row"> {row.name} </StyledTableCell> @@ -559,7 +558,7 @@ const Collections = () => { </StyledTableCell> <StyledTableCell align="right">{row.privacy}</StyledTableCell> <StyledTableCell align="right"> - <Link to={`/admin/Collection/${row.id}`}> + <Link to={`/admin/Collection?collection=${row.id}`}> <IconButton> <VisibilityIcon style={{ fill: "#00bcd4" }} /> </IconButton> diff --git a/src/Admin/Pages/Pages/SubPages/CommunityQuestions.js b/src/Admin/Pages/Pages/SubPages/CommunityQuestions.js index 52bc6b89..029c566a 100644 --- a/src/Admin/Pages/Pages/SubPages/CommunityQuestions.js +++ b/src/Admin/Pages/Pages/SubPages/CommunityQuestions.js @@ -85,6 +85,7 @@ const CommunityQuestion = () => { const [currPage, setCurrPage] = useState(0) //Works with the filter + const [invertList, setInvertList] = useState(false) const [showFilter, setShowFilter] = useState(false) const [valueOfMessageField, setValueOfMessageField] = useState("") const [message, setMessage] = useState(""); @@ -132,25 +133,31 @@ const CommunityQuestion = () => { .toString(); }; - const buildUrl = (message, email, name) => { + const cleanArrayAndInvert = () => { + setInvertList(!invertList) + setCurrPage(0) + setItems([]) + } + + const buildUrl = (message, email, name, direction) => { if (message && email && name) - return Url("contacts", `"message" : "${message}", "email" : "${email}", "name" : "${name}"`, currPage, "DESC") + return Url("contacts", `"message" : "${message}", "email" : "${email}", "name" : "${name}"`, currPage, direction) else if (message && name) - return Url("contacts", `"message" : "${message}", "name" : "${name}"`, currPage, "DESC") + return Url("contacts", `"message" : "${message}", "name" : "${name}"`, currPage, direction) else if (message && email) - return Url("contacts", `"message" : "${message}", "email" : "${email}"`, currPage, "DESC") + return Url("contacts", `"message" : "${message}", "email" : "${email}"`, currPage, direction) else if (name && email) - return Url("contacts", `"name" : "${name}", "email" : "${email}"`, currPage, "DESC") + return Url("contacts", `"name" : "${name}", "email" : "${email}"`, currPage, direction) else if (message) - return Url("contacts", `"message" : "${message}"`, currPage, "DESC") + return Url("contacts", `"message" : "${message}"`, currPage, direction) else if (email) - return Url("contacts", `"email" : "${email}"`, currPage, "DESC") + return Url("contacts", `"email" : "${email}"`, currPage, direction) else if (name) - return Url("contacts", `"name" : "${name}"`, currPage, "DESC") + return Url("contacts", `"name" : "${name}"`, currPage, direction) else - return Url("contacts", "", currPage, "DESC") + return Url("contacts", "", currPage, direction) } useEffect(() => { @@ -159,7 +166,7 @@ const CommunityQuestion = () => { else setIsLoadingMoreItems(true) getRequest( - buildUrl(message, email, name), + buildUrl(message, email, name, invertList ? "ASC" : "DESC"), (data, header) => { const arrData = [...data] if (arrData.length === 0) { @@ -185,7 +192,7 @@ const CommunityQuestion = () => { setError(true) } ) - }, [currPage, message, email, name]) + }, [currPage, message, email, name, invertList]) useEffect(() => { setCurrPage(0) @@ -237,6 +244,13 @@ const CommunityQuestion = () => { setShowFilter(!showFilter); }, icon: <FilterListRoundedIcon /> + }, + { + name: "Inverter lista de dados", + isLoading: false, + func: () => { + cleanArrayAndInvert() + }, } ]} > @@ -316,7 +330,7 @@ const CommunityQuestion = () => { subtitle={row.id} backColor={"#00bcd4"} avatar={<ContactSupportRoundedIcon />} - href={`/admin/CommunityQuestion/${row.id}`} + href={`/admin/CommunityQuestion?question=${row.id}`} reset={() => { }} data={ @@ -325,7 +339,7 @@ const CommunityQuestion = () => { title: "Email", subtitle: row.email ? - <Link to={`/admin/sendEmail/${row.email}`} style={{ textDecoration: 'none' }}> + <Link to={`/admin/sendEmail?email=${row.email}`} style={{ textDecoration: 'none' }}> <Button variant='text' color='primary' @@ -439,7 +453,7 @@ const CommunityQuestion = () => { <div style={{ height: "2em" }}></div> - <TableData top={TOP_LABELS}> + <TableData top={TOP_LABELS} onIconPressed={cleanArrayAndInvert}> <TableBody> {items.map((row, index) => index === items.length - 1 ? ( @@ -477,7 +491,7 @@ const CommunityQuestion = () => { <StyledTableCell align="right"> { row.email ? - <Link to={`/admin/sendEmail/${row.email}`} style={{ textDecoration: 'none' }}> + <Link to={`/admin/sendEmail?email=${row.email}`} style={{ textDecoration: 'none' }}> <Button variant='text' color='primary' @@ -492,7 +506,7 @@ const CommunityQuestion = () => { {row.message} </StyledTableCell> <StyledTableCell align="right"> - <Link to={`/admin/CommunityQuestion/${row.id}`}> + <Link to={`/admin/CommunityQuestion?question=${row.id}`}> <IconButton> <VisibilityIcon style={{ fill: "#00bcd4" }} /> </IconButton> diff --git a/src/Admin/Pages/Pages/SubPages/Complaints.js b/src/Admin/Pages/Pages/SubPages/Complaints.js index d2fb9de2..2c8dff2e 100644 --- a/src/Admin/Pages/Pages/SubPages/Complaints.js +++ b/src/Admin/Pages/Pages/SubPages/Complaints.js @@ -80,6 +80,7 @@ const Complaints = () => { "VISITAR", ]; //Labels from Table + const [invertList, setInvertList] = useState(false) const [error, setError] = useState(null); //Necessary to consult the API, catch errors const [isLoaded, setIsLoaded] = useState(false); //Necessary to consult the API, wait until complete const [items, setItems] = useState([]); //Necessary to consult the API, data @@ -207,25 +208,31 @@ const Complaints = () => { .toString(); }; - const buildUrl = (complainOpt, state, description) => { + const cleanArrayAndInvert = () => { + setInvertList(!invertList) + setCurrPage(0) + setItems([]) + } + + const buildUrl = (complainOpt, state, description, direction) => { if (complainOpt && (state >= 0 && state <= 2) && description) - return Url("complaints", `"state" : ${state}, "complaint_reason_id" : ${complainOpt}, "description" : "${description}"`, currPage, "DESC") + return Url("complaints", `"state" : ${state}, "complaint_reason_id" : ${complainOpt}, "description" : "${description}"`, currPage, direction) else if (complainOpt && description) - return Url("complaints", `"complaint_reason_id" : ${complainOpt}, "description" : "${description}"`, currPage, "DESC") + return Url("complaints", `"complaint_reason_id" : ${complainOpt}, "description" : "${description}"`, currPage, direction) else if (complainOpt && (state >= 0 && state <= 2)) - return Url("complaints", `"complaint_reason_id" : ${complainOpt}, "state" : ${state}`, currPage, "DESC") + return Url("complaints", `"complaint_reason_id" : ${complainOpt}, "state" : ${state}`, currPage, direction) else if (description && (state >= 0 && state <= 2)) - return Url("complaints", `"description" : "${description}", "state" : ${state}`, currPage, "DESC") + return Url("complaints", `"description" : "${description}", "state" : ${state}`, currPage, direction) else if (complainOpt) - return Url("complaints", `"complaint_reason_id" : ${complainOpt}`, currPage, "DESC") + return Url("complaints", `"complaint_reason_id" : ${complainOpt}`, currPage, direction) else if (state >= 0 && state <= 2) - return Url("complaints", `"state" : ${state}`, currPage, "DESC") + return Url("complaints", `"state" : ${state}`, currPage, direction) else if (description) - return Url("complaints", `"description" : ${description}`, currPage, "DESC") + return Url("complaints", `"description" : ${description}`, currPage, direction) else - return Url("complaints", "", currPage, "DESC") + return Url("complaints", "", currPage, direction) } useEffect(() => { @@ -234,7 +241,7 @@ const Complaints = () => { else setIsLoadingMoreItems(true) getRequest( - buildUrl(complainOption, stateOption, description), + buildUrl(complainOption, stateOption, description, invertList ? "ASC" : "DESC"), (data, header) => { const arrData = [...data] if (arrData.length === 0) { @@ -260,7 +267,7 @@ const Complaints = () => { setError(true) } ) - }, [currPage, complainOption, stateOption, description]) + }, [currPage, complainOption, stateOption, description, invertList]) useEffect(() => { setComplainOption() @@ -310,6 +317,13 @@ const Complaints = () => { setShowFilter(!showFilter); }, icon: <FilterListRoundedIcon /> + }, + { + name: "Inverter lista", + isLoading: false, + func: () => { + cleanArrayAndInvert() + }, } ]} > @@ -373,7 +387,7 @@ const Complaints = () => { {items.map((row, index) => index === items.length - 1 ? ( <StyledDivButton - key="Load more items" + key={new Date().toISOString() + row.created_at} > <Button color="primary" @@ -395,12 +409,12 @@ const Complaints = () => { ) : ( <> <MobileList - key={row.created_at} + key={new Date().toISOString() + row.created_at} title={row.complainable_type} subtitle={row.id} backColor={"#673ab7"} avatar={<AnnouncementRoundedIcon />} - href={`/admin/complaint/${row.id}`} + href={`/admin/complaint?id=${row.id}`} reset={() => { }} @@ -530,11 +544,14 @@ const Complaints = () => { <div style={{ height: "2em" }}></div> <Grid xs={12} container> - <TableData top={TOP_LABELS}> + <TableData + top={TOP_LABELS} + onIconPressed={cleanArrayAndInvert} + > <TableBody> {items.map((row, index) => index === items.length - 1 ? ( - <StyledTableRow key={row.created_at}> + <StyledTableRow key={new Date().toISOString() + row.created_at}> {/* Button to load more data */} <StyledTableCell> <Button @@ -557,7 +574,7 @@ const Complaints = () => { </StyledTableRow> ) : ( <StyledTableRow - key={index} + key={new Date().toISOString() + row.created_at} style={{ flex: 1, width: "100%" }} > <StyledTableCell component="th" scope="row"> @@ -577,7 +594,7 @@ const Complaints = () => { {DisplayDate(row.created_at)} </StyledTableCell> <StyledTableCell align="right"> - <Link to={`/admin/complaint/${row.id}`}> + <Link to={`/admin/complaint?id=${row.id}`}> <IconButton onClick={() => { }} diff --git a/src/Admin/Pages/Pages/SubPages/EducationalObjects.js b/src/Admin/Pages/Pages/SubPages/EducationalObjects.js index 837797d4..612272ca 100644 --- a/src/Admin/Pages/Pages/SubPages/EducationalObjects.js +++ b/src/Admin/Pages/Pages/SubPages/EducationalObjects.js @@ -369,7 +369,7 @@ const EducationalObjects = () => { index === items.length - 1 ? ( <StyledDivButton> <Button - key={index} + key={new Date().toISOString() + row.created_at} color="primary" variant="text" // disabled={isLoadingMoreItems} @@ -389,12 +389,12 @@ const EducationalObjects = () => { ) : ( <> <MobileList - key={index} + key={new Date().toISOString() + row.created_at} title={row.name} subtitle={row.id} backColor={"#673ab7"} avatar={<MenuBookRoundedIcon />} - href={`/admin/learningObject/${row.id}`} + href={`/admin/learningObject?learnObj=${row.id}`} reset={() => { }} @@ -511,7 +511,7 @@ const EducationalObjects = () => { <TableBody> {items.map((row, index) => index === items.length - 1 ? ( - <StyledTableRow key={index}> + <StyledTableRow key={new Date().toISOString() + row.created_at}> {/* Button to load more data */} <StyledTableCell> <Button @@ -534,7 +534,7 @@ const EducationalObjects = () => { </StyledTableCell> </StyledTableRow> ) : ( - <StyledTableRow key={index}> + <StyledTableRow key={new Date().toISOString() + row.created_at}> <StyledTableCell component="th" scope="row"> {DisplayDate(row.created_at)} </StyledTableCell> @@ -551,7 +551,7 @@ const EducationalObjects = () => { {row.score} </StyledTableCell> <StyledTableCell align="right"> - <Link to={`/admin/learningObject/${row.id}`}> + <Link to={`/admin/learningObject?learnObj=${row.id}`}> <IconButton> <VisibilityIcon style={{ fill: "#00bcd4" }} /> </IconButton> diff --git a/src/Admin/Pages/Pages/SubPages/Institutions.js b/src/Admin/Pages/Pages/SubPages/Institutions.js index 24d099a6..93d0af1a 100644 --- a/src/Admin/Pages/Pages/SubPages/Institutions.js +++ b/src/Admin/Pages/Pages/SubPages/Institutions.js @@ -74,7 +74,8 @@ const Institutions = () => { const ADD_ONE_LENGHT = [""]; const router = useHistory() - + + const [invertList, setInvertList] = useState(false) const [error, setError] = useState(null); //Necessary to consult the API, catch errors const [isLoaded, setIsLoaded] = useState(false); //Necessary to consult the API, wait until complete const [items, setItems] = useState([]); //Necessary to consult the API, data @@ -185,8 +186,14 @@ const Institutions = () => { } } + const cleanArrayAndInvert = () => { + setInvertList(!invertList) + setCurrPage(0) + setItems([]) + } + const buildUrl = () => { - return Url("institutions", `"name" : "${search}", "description" : "${description}", "city" : "${city}", "country" : "${country}"`, currPage, "DESC") + return Url("institutions", `"name" : "${search}", "description" : "${description}", "city" : "${city}", "country" : "${country}"`, currPage, invertList ? "ASC" : "DESC") } useEffect(() => { @@ -221,7 +228,7 @@ const Institutions = () => { setError(true) } ) - }, [currPage, description, country, search, city]) + }, [currPage, description, country, search, city, invertList]) useEffect(() => { setSeacrh("") @@ -369,7 +376,7 @@ const Institutions = () => { {items.map((row, index) => index === items.length - 1 ? ( <StyledDivButton - key="Load more" + key={new Date().toISOString() + row.created_at} > <Button color="primary" @@ -391,12 +398,12 @@ const Institutions = () => { ) : ( <> <MobileList - key={index} + key={new Date().toISOString() + row.created_at} title={row.name} subtitle={row.id} backColor={"#ff7f00"} avatar={<AccountBalanceRoundedIcon />} - href={`/admin/institution/${row.id}`} + href={`/admin/institution?institution=${row.id}`} reset={() => { }} @@ -516,11 +523,11 @@ const Institutions = () => { <div style={{ height: "2em" }}></div> {/************** Start of display data in table **************/} - <TableData top={topTable}> + <TableData top={topTable} onIconPressed={cleanArrayAndInvert}> <TableBody> {items.map((row, index) => index === items.length - 1 ? ( - <StyledTableRow key={row.created_at}> + <StyledTableRow key={new Date().toISOString() + row.created_at}> {/* Button to load more data */} <StyledTableCell> <Button @@ -541,7 +548,7 @@ const Institutions = () => { </StyledTableCell> </StyledTableRow> ) : ( - <StyledTableRow key={index}> + <StyledTableRow key={new Date().toISOString() + row.created_at}> <StyledTableCell component="th" scope="row"> {row.id} </StyledTableCell> @@ -554,7 +561,7 @@ const Institutions = () => { {row.country} </StyledTableCell> <StyledTableCell align="right"> - <Link to={`/admin/institution/${row.id}`}> + <Link to={`/admin/institution?institution=${row.id}`}> <IconButton> <VisibilityIcon style={{ fill: "#00bcd4" }} /> </IconButton> diff --git a/src/Admin/Pages/Pages/SubPages/Languages.js b/src/Admin/Pages/Pages/SubPages/Languages.js index 3d11c4a4..3f68cbf4 100644 --- a/src/Admin/Pages/Pages/SubPages/Languages.js +++ b/src/Admin/Pages/Pages/SubPages/Languages.js @@ -69,6 +69,7 @@ const Languages = () => { const WINDOW_WIDTH = window.innerWidth const router = useHistory() + const [invertList, setInvertList] = useState(false) const [error, setError] = useState(null); //Necessary to consult the API, catch errors const [isLoaded, setIsLoaded] = useState(false); //Necessary to consult the API, wait until complete const [items, setItems] = useState([]); //Necessary to consult the API, data @@ -151,6 +152,12 @@ const Languages = () => { } } + const cleanArrayAndInvert = () => { + setInvertList(!invertList) + setCurrPage(0) + setItems([]) + } + //getting data from server useEffect(() => { if (currPage === 0) @@ -159,7 +166,7 @@ const Languages = () => { setIsLoadingMoreItems(true) getRequest( - Url("languages", "", currPage, "DESC"), + Url("languages", "", currPage, invertList ? "ASC" : "DESC"), (data, header) => { const arrData = [...data] if (arrData.length === 0) { @@ -185,7 +192,7 @@ const Languages = () => { setError(true) } ) - }, [currPage]) + }, [currPage, invertList]) if (error) { return <div>Error: {error.message}</div>; @@ -243,7 +250,7 @@ const Languages = () => { {items.map((row, index) => index === items.length - 1 ? ( - <StyledDivButton key="Load"> + <StyledDivButton key={new Date().toISOString() + row.created_at}> <Button color="primary" variant="text" @@ -264,12 +271,12 @@ const Languages = () => { ) : ( <> <MobileList - key={row.created_at} + key={new Date().toISOString() + row.created_at} title={row.name} subtitle={row.id} backColor={"#e81f4f"} avatar={<LanguageRoundedIcon />} - href={`/admin/languageEdit/${row.id}`} + href={`/admin/languageEdit?language=${row.id}`} reset={() => { }} @@ -278,7 +285,6 @@ const Languages = () => { { title: "Code", subtitle: row.code - }, { title: "Deletar", @@ -348,11 +354,12 @@ const Languages = () => { <TableData top={TOP_LABELS} + onIconPressed={cleanArrayAndInvert} > <TableBody> {items.map((row, index) => ( index === items.length - 1 ? - <StyledTableRow key="Load more"> + <StyledTableRow key={new Date().toISOString() + row.created_at}> {/* Button to load more data */} <StyledTableCell> <Button @@ -374,12 +381,12 @@ const Languages = () => { : - <StyledTableRow key={row.created_at}> + <StyledTableRow key={new Date().toISOString() + 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}`}> + <Link to={`/admin/languageEdit?language=${row.id}`}> <IconButton> <EditRoundedIcon style={{ fill: '#00bcd4' }} /> </IconButton> diff --git a/src/Admin/Pages/Pages/SubPages/NoteVariables.js b/src/Admin/Pages/Pages/SubPages/NoteVariables.js index 5e58e14d..71b6abc8 100644 --- a/src/Admin/Pages/Pages/SubPages/NoteVariables.js +++ b/src/Admin/Pages/Pages/SubPages/NoteVariables.js @@ -68,6 +68,7 @@ const NoteVariables = () => { const WINDOW_WIDTH = window.innerWidth const ADD_ONE_LENGHT = [""]; + const [invertList, setInvertList] = useState(false) const [error, setError] = useState(null); //Necessary to consult the API, catch errors const [isLoaded, setIsLoaded] = useState(false); //Necessary to consult the API, wait until complete const [currPage, setCurrPage] = useState(0) @@ -91,13 +92,19 @@ const NoteVariables = () => { }) } + const cleanArrayAndInvert = () => { + setInvertList(!invertList) + setCurrPage(0) + setItems([]) + } + useEffect(() => { if (currPage === 0) setIsLoaded(false) else setIsLoadingMoreItems(true) getRequest( - Url("scores", "", currPage, "DESC"), + Url("scores", "", currPage, invertList ? "ASC" : "DESC"), (data, header) => { const arrData = [...data] if (arrData.length === 0) { @@ -123,7 +130,7 @@ const NoteVariables = () => { setError(true) } ) - }, [currPage]) + }, [currPage, invertList]) if (error) { return <div>Error: {error.message}</div>; @@ -160,6 +167,13 @@ const NoteVariables = () => { }, icon: <UpdateRoundedIcon /> }, + { + name: "Inverter lista", + isLoading: false, + func: () => { + cleanArrayAndInvert() + }, + }, ]} > </MobilePageHeader> @@ -168,7 +182,7 @@ const NoteVariables = () => { {items.map((row, index) => index === items.length - 1 ? ( - <StyledDivButton key="Load"> + <StyledDivButton key={new Date().toISOString() + row.created_at}> <Button color="primary" variant="text" @@ -189,12 +203,12 @@ const NoteVariables = () => { ) : ( <> <MobileList - key={row.created_at} + key={new Date().toISOString() + row.created_at} title={row.name} subtitle={row.id} backColor={"#e81f4f"} avatar={<TrendingUpRoundedIcon />} - href={`/admin/noteVar/${row.id}`} + href={`/admin/noteVar?id=${row.id}`} reset={() => { }} data={ @@ -239,7 +253,7 @@ const NoteVariables = () => { })} /> <PageHeader - title="Linguagens" + title="Variáveis de nota" actions={[ { name: "Atualizar", @@ -257,11 +271,12 @@ const NoteVariables = () => { <TableData top={topTable} + onIconPressed={cleanArrayAndInvert} > <TableBody> {items.map((row, index) => ( index === items.length - 1 ? - <StyledTableRow key="Load more"> + <StyledTableRow key={new Date().toISOString() + row.created_at}> {/* Button to load more data */} <StyledTableCell> <Button @@ -282,7 +297,7 @@ const NoteVariables = () => { : - <StyledTableRow key={row.created_at}> + <StyledTableRow key={new Date().toISOString() + row.created_at}> <StyledTableCell component="th" scope="row">{row.id}</StyledTableCell> <StyledTableCell align="right">{row.name}</StyledTableCell> <StyledTableCell align="right">{row.code}</StyledTableCell> @@ -302,7 +317,7 @@ const NoteVariables = () => { } </StyledTableCell> <StyledTableCell align="right"> - <Link to={`/admin/noteVar/${row.id}`}> + <Link to={`/admin/noteVar?id=${row.id}`}> <IconButton> <VisibilityIcon style={{ fill: '#00bcd4' }} /> </IconButton> diff --git a/src/Admin/Pages/Pages/SubPages/Permissions.js b/src/Admin/Pages/Pages/SubPages/Permissions.js index 89c3bb55..d8484ac1 100644 --- a/src/Admin/Pages/Pages/SubPages/Permissions.js +++ b/src/Admin/Pages/Pages/SubPages/Permissions.js @@ -69,6 +69,7 @@ const UserPermissions = () => { const router = useHistory() + const [invertList, setInvertList] = useState(false) const [error, setError] = useState(null); //Necessary to consult the API, catch errors const [isLoaded, setIsLoaded] = useState(false); //Necessary to consult the API, wait until complete const [items, setItems] = useState([]); //Necessary to consult the API, data @@ -150,13 +151,19 @@ const UserPermissions = () => { setOpenAlertDialog(!openAlertDialog); }; + const cleanArrayAndInvert = () => { + setInvertList(!invertList) + setCurrPage(0) + setItems([]) + } + useEffect(() => { if (currPage === 0) setIsLoaded(false) else setIsLoadingMoreItems(true) getRequest( - Url("roles", "", currPage, "DESC"), + Url("roles", "", currPage, invertList ? "ASC" : "DESC"), (data, header) => { const arrData = [...data] if (arrData.length === 0) { @@ -182,7 +189,7 @@ const UserPermissions = () => { setError(true) } ) - }, [currPage]) + }, [currPage, invertList]) if (error) { return <div>Error: {error.message}</div>; @@ -231,6 +238,13 @@ const UserPermissions = () => { router.push('/admin/CreateRole') }, icon: <AddRoundedIcon /> + }, + { + name: "Inverter lista", + isLoading: false, + func: () => { + cleanArrayAndInvert() + }, } ]} > @@ -240,7 +254,7 @@ const UserPermissions = () => { {items.map((row, index) => index === items.length - 1 ? ( - <StyledDivButton key="Load"> + <StyledDivButton key={new Date().toISOString() + row.created_at}> <Button color="primary" variant="text" @@ -261,12 +275,12 @@ const UserPermissions = () => { ) : ( <> <MobileList - key={row.created_at} + key={new Date().toISOString() + row.created_at} title={row.name} subtitle={row.id} backColor={"#ff7f00"} avatar={<AccountCircleRoundedIcon />} - href={`/admin/EditPermissions/${row.id}`} + href={`/admin/EditPermissions?role=${row.id}`} reset={() => { }} data={ @@ -343,11 +357,12 @@ const UserPermissions = () => { <TableData top={TOP_LABELS} + onIconPressed={cleanArrayAndInvert} > <TableBody> {items.map((row, index) => ( index === items.length - 1 ? - <StyledTableRow key="Load more"> + <StyledTableRow key={new Date().toISOString() + row.created_at}> {/* Button to load more data */} <StyledTableCell> <Button @@ -369,12 +384,12 @@ const UserPermissions = () => { : - <StyledTableRow key={row.created_at}> + <StyledTableRow key={new Date().toISOString() + 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}`}> + <Link to={`/admin/EditPermissions?role=${row.id}`}> <Button style={{ width: "100%", marginBottom: "0.5em" }} variant="contained" diff --git a/src/Admin/Pages/Pages/SubPages/Questions.js b/src/Admin/Pages/Pages/SubPages/Questions.js index aa4532af..296c62d7 100644 --- a/src/Admin/Pages/Pages/SubPages/Questions.js +++ b/src/Admin/Pages/Pages/SubPages/Questions.js @@ -67,6 +67,7 @@ const Questions = () => { const TOP_LABELS = ['ID', 'CRIAÇÃO EM', 'DESCRIÇÃO', 'STATUS', 'ATUALIZAÇÃO EM'] //Labels from Table const router = useHistory() + const [invertList, setInvertList] = useState(false) const [error, setError] = useState(null); //Necessary to consult the API, catch errors const [isLoaded, setIsLoaded] = useState(false); //Necessary to consult the API, wait until complete const [items, setItems] = useState([]); //Necessary to consult the API, data @@ -155,13 +156,19 @@ const Questions = () => { .toString(); }; + const cleanArrayAndInvert = () => { + setInvertList(!invertList) + setCurrPage(0) + setItems([]) + } + useEffect(() => { if (currPage === 0) setIsLoaded(false) else setIsLoadingMoreItems(true) getRequest( - Url("questions", "", currPage, "DESC"), + Url("questions", "", currPage, invertList ? "ASC" : "DESC"), (data, header) => { const arrData = [...data] if (arrData.length === 0) { @@ -187,7 +194,7 @@ const Questions = () => { setError(true) } ) - }, [currPage]) + }, [currPage, invertList]) if (error) { @@ -228,7 +235,15 @@ const Questions = () => { func: () => { router.push('/admin/CreateQuestion') }, - } + icon: <AddRoundedIcon /> + }, + { + name: "Inverter lista", + isLoading: false, + func: () => { + cleanArrayAndInvert() + }, + }, ]} > </MobilePageHeader> @@ -238,7 +253,7 @@ const Questions = () => { {items.map((row, index) => index === items.length - 1 ? ( <StyledDivButton - key="Load" + key={new Date().toISOString() + row.created_at} > <Button color="primary" @@ -260,7 +275,7 @@ const Questions = () => { ) : ( <> <MobileList - key={row.created_at} + key={new Date().toISOString() + row.created_at} title={row.id} subtitle={DisplayDate(row.created_at)} backColor={"#673ab7"} @@ -339,6 +354,7 @@ const Questions = () => { func: () => { router.push('/admin/CreateQuestion') }, + icon: <AddRoundedIcon /> } ]} > @@ -348,11 +364,12 @@ const Questions = () => { <TableData top={TOP_LABELS} + onIconPressed={cleanArrayAndInvert} > <TableBody> {items.map((row, index) => ( index === items.length - 1 ? - <StyledTableRow key="Load more"> + <StyledTableRow key={new Date().toISOString() + row.created_at}> {/* Button to load more data */} <StyledTableCell> <Button @@ -374,7 +391,7 @@ const Questions = () => { : - <StyledTableRow key={row.created_at}> + <StyledTableRow key={new Date().toISOString() + 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> diff --git a/src/Admin/Pages/Pages/SubPages/Rating.js b/src/Admin/Pages/Pages/SubPages/Rating.js index 8f00fd9d..71f648dd 100644 --- a/src/Admin/Pages/Pages/SubPages/Rating.js +++ b/src/Admin/Pages/Pages/SubPages/Rating.js @@ -71,6 +71,7 @@ const Ratings = () => { const router = useHistory() + const [invertList, setInvertList] = useState(false) const [error, setError] = useState(null); //Necessary to consult the API, catch errors const [isLoaded, setIsLoaded] = useState(false); //Necessary to consult the API, wait until complete const [items, setItems] = useState([]); //Necessary to consult the API, data @@ -151,13 +152,19 @@ const Ratings = () => { setOpenAlertDialog(!openAlertDialog); }; + const cleanArrayAndInvert = () => { + setInvertList(!invertList) + setCurrPage(0) + setItems([]) + } + useEffect(() => { if (currPage === 0) setIsLoaded(false) else setIsLoadingMoreItems(true) getRequest( - Url("ratings", "", currPage, "DESC"), + Url("ratings", "", currPage, invertList ? "ASC" : "DESC"), (data, header) => { const arrData = [...data] if (arrData.length === 0) { @@ -183,7 +190,7 @@ const Ratings = () => { setError(true) } ) - }, [currPage]) + }, [currPage, invertList]) if (error) { return <div>Error: {error.message}</div>; @@ -244,9 +251,8 @@ const Ratings = () => { {items.map((row, index) => index === items.length - 1 ? ( - <StyledDivButton key="Load"> + <StyledDivButton key={new Date().toISOString() + row.created_at}> <Button - key={index} color="primary" variant="text" // disabled={isLoadingMoreItems} @@ -266,12 +272,12 @@ const Ratings = () => { ) : ( <> <MobileList - key={row.created_at} + key={new Date().toISOString() + row.created_at} title={row.name} subtitle={row.id} backColor={"#00bcd4"} avatar={<StarRoundedIcon />} - href={`/admin/Rating/${row.id}`} + href={`/admin/Rating?rating=${row.id}`} reset={() => { }} @@ -348,11 +354,12 @@ const Ratings = () => { <TableData top={topTable} + onIconPressed={cleanArrayAndInvert} > <TableBody> {items.map((row, index) => ( index === items.length - 1 ? - <StyledTableRow key={row.created_at}> + <StyledTableRow key={new Date().toISOString() + row.created_at}> {/* Button to load more data */} <StyledTableCell> <Button @@ -373,12 +380,12 @@ const Ratings = () => { : - <StyledTableRow key={row.created_at}> + <StyledTableRow key={new Date().toISOString() + 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}`}> + <Link to={`/admin/Rating?rating=${row.id}`}> <IconButton> <VisibilityIcon style={{ fill: '#00bcd4' }} /> </IconButton> diff --git a/src/Admin/Pages/Pages/SubPages/SendEmail.js b/src/Admin/Pages/Pages/SubPages/SendEmail.js index c6e8c4d0..aff09bc8 100644 --- a/src/Admin/Pages/Pages/SubPages/SendEmail.js +++ b/src/Admin/Pages/Pages/SubPages/SendEmail.js @@ -54,8 +54,11 @@ const useStyles = makeStyles({ }, }); + const SendEmail = ({ match }) => { const classes = useStyles(); + const urlParams = new URLSearchParams(window.location.search); + const email = urlParams.get("email"); return ( <Card> @@ -67,7 +70,7 @@ const SendEmail = ({ match }) => { > Enviar email </Typography> - <EmailInputs email={`${match.params.email}`} /> + <EmailInputs email={email} /> </CardContent> </Card> ); diff --git a/src/Admin/Pages/Pages/SubPages/Users.js b/src/Admin/Pages/Pages/SubPages/Users.js index 31857677..95e8d38f 100644 --- a/src/Admin/Pages/Pages/SubPages/Users.js +++ b/src/Admin/Pages/Pages/SubPages/Users.js @@ -73,6 +73,7 @@ const Users = () => { const router = useHistory() + const [invertList, setInvertList] = useState(false) const [error, setError] = useState(null); //Necessary to consult the API, catch errors const [isLoaded, setIsLoaded] = useState(false); //Necessary to consult the API, wait until complete const [items, setItems] = useState([]); //Necessary to consult the API, data @@ -174,15 +175,21 @@ const Users = () => { ) } - const buildUrl = (email, name) => { + const cleanArrayAndInvert = () => { + setInvertList(!invertList) + setCurrPage(0) + setItems([]) + } + + const buildUrl = (email, name, direction) => { if (email && name) - return Url("users", `"email" : "${email}", "name" : "${name}"`, currPage, "DESC") + return Url("users", `"email" : "${email}", "name" : "${name}"`, currPage, direction) if (email) - return Url("users", `"email" : "${email}"`, currPage, "DESC") + return Url("users", `"email" : "${email}"`, currPage, direction) if (name) - return Url("users", `"name" : "${name}"`, currPage, "DESC") + return Url("users", `"name" : "${name}"`, currPage, direction) else - return Url("users", "", currPage, "DESC") + return Url("users", "", currPage, direction) } useEffect(() => { @@ -191,7 +198,7 @@ const Users = () => { else setIsLoadingMoreItems(true) getRequest( - buildUrl(email, name), + buildUrl(email, name, invertList ? "ASC" : "DESC"), (data, header) => { const arrData = [...data] if (arrData.length === 0) { @@ -217,7 +224,7 @@ const Users = () => { setIsLoadingMoreItems(false) } ) - }, [currPage, email, name]) + }, [currPage, email, name, invertList]) useEffect(() => { setNameValue("") @@ -272,7 +279,15 @@ const Users = () => { name: "Novo", isLoading: false, func: () => { - router.push('/admin/EditUser/-1') + router.push('/admin/EditUser?id=-1') + }, + icon: <AddRoundedIcon /> + }, + { + name: "Inverter lista", + isLoading: false, + func: () => { + cleanArrayAndInvert() }, } ]} @@ -307,9 +322,8 @@ const Users = () => { {items.map((row, index) => index === items.length - 1 ? ( - <StyledDivButton> + <StyledDivButton key={new Date().toISOString() + row.created_at}> <Button - key={index} color="primary" variant="text" // disabled={isLoadingMoreItems} @@ -329,7 +343,7 @@ const Users = () => { ) : ( <> <MobileList - key={index} + key={new Date().toISOString() + row.created_at} title={row.name} subtitle={row.id} backColor={"#00bcd4"} @@ -344,14 +358,14 @@ const Users = () => { }} /> } - href={`/admin/user/${row.id}`} + href={`/admin/user?id=${row.id}`} reset={() => { }} data={[ { title: "Email", subtitle: row.email ? - <Link to={`/admin/sendEmail/${row.email}`} style={{ textDecoration: 'none' }}> + <Link to={`/admin/sendEmail?email=${row.email}`} style={{ textDecoration: 'none' }}> <Button variant='text' color='primary' @@ -440,8 +454,9 @@ const Users = () => { name: "Novo", isLoading: false, func: () => { - router.push('/admin/EditUser/-1') + router.push('/admin/EditUser?id=-1') }, + icon: <AddRoundedIcon /> } ]} > @@ -475,11 +490,12 @@ const Users = () => { <TableData top={topTable} + onIconPressed={cleanArrayAndInvert} > <TableBody> {items.map((row, index) => ( index === items.length - 1 ? - <StyledTableRow key={index}> + <StyledTableRow key={new Date().toISOString() + row.created_at}> {/* Button to load more data */} <StyledTableCell> <Button @@ -500,7 +516,7 @@ const Users = () => { : - <StyledTableRow key={index}> + <StyledTableRow key={new Date().toISOString() + row.created_at}> <StyledTableCell component="th" scope="row">{row.id}</StyledTableCell> <StyledTableCell align="right">{row.name}</StyledTableCell> <StyledTableCell align="right">{row.email ? row.email : ""}</StyledTableCell> @@ -528,7 +544,7 @@ const Users = () => { </Button> </StyledTableCell> <StyledTableCell align="right"> - <Link to={`/admin/user/${row.id}`}> + <Link to={`/admin/user?id=${row.id}`}> <IconButton> <VisibilityIcon style={{ fill: '#00bcd4' }} /> </IconButton> diff --git a/src/App.js b/src/App.js index d687e65a..dda0148c 100644 --- a/src/App.js +++ b/src/App.js @@ -209,14 +209,14 @@ export default function App() { else return <Unauthorized /> }} /> - <Route path="/admin/institution/:id" render={() => { + <Route path="/admin/institution" render={() => { if (CheckUserPermission()) return <InstitutionCard /> else return <Unauthorized /> }} /> <Route - path="/admin/institutionEdit/:id" + path="/admin/institutionEdit" render={() => { if (CheckUserPermission()) return <InstitutionsInput /> @@ -239,13 +239,13 @@ export default function App() { else return <Unauthorized /> }} /> - <Route path="/admin/noteVar/:id" render={() => { + <Route path="/admin/noteVar" render={() => { if (CheckUserPermission()) return <NoteVarCard /> else return <Unauthorized /> }} /> - <Route path="/admin/noteVarEdit/:id" render={() => { + <Route path="/admin/noteVarEdit" render={() => { if (CheckUserPermission()) return <NoteVarInputs /> else @@ -257,7 +257,7 @@ export default function App() { else return <Unauthorized /> }} /> - <Route path="/admin/languageEdit/:id" render={() => { + <Route path="/admin/languageEdit" render={() => { if (CheckUserPermission()) return <EditLanguage /> else @@ -279,7 +279,7 @@ export default function App() { }} /> <Route - path="/admin/CommunityQuestion/:id" + path="/admin/CommunityQuestion" render={() => { if (CheckUserPermission()) return <CommunityCard /> @@ -293,14 +293,14 @@ export default function App() { else return <Unauthorized /> }} /> - <Route path="/admin/Collection/:id" render={() => { + <Route path="/admin/Collection" render={() => { if (CheckUserPermission()) return <CollectionCard /> else return <Unauthorized /> }} /> <Route - path="/admin/EditCollection/:id" + path="/admin/EditCollection" render={() => { if (CheckUserPermission()) return <EditCollection /> @@ -314,13 +314,13 @@ export default function App() { else return <Unauthorized /> }} /> - <Route path="/admin/Rating/:id" render={() => { + <Route path="/admin/Rating" render={() => { if (CheckUserPermission()) return <RatingCard /> else return <Unauthorized /> }} /> - <Route path="/admin/EditRating/:id" render={() => { + <Route path="/admin/EditRating" render={() => { if (CheckUserPermission()) return <EditRating /> else @@ -350,7 +350,7 @@ export default function App() { else return <Unauthorized /> }} /> - <Route path="/admin/activity/:id" render={() => { + <Route path="/admin/activity" render={() => { if (CheckUserPermission()) return <ActivityCard /> else @@ -365,7 +365,7 @@ export default function App() { return <Unauthorized /> }} /> <Route - path="/admin/learningObject/:id" + path="/admin/learningObject" render={() => { if (CheckUserPermission()) return <EducationalObjectCard /> @@ -373,7 +373,7 @@ export default function App() { return <Unauthorized /> }} /> <Route - path="/admin/learningObjectEdit/:id" + path="/admin/learningObjectEdit" render={() => { if (CheckUserPermission()) return <EducationalObjectEdit /> @@ -386,7 +386,7 @@ export default function App() { else return <Unauthorized /> }} /> - <Route path="/admin/complaint/:id" render={() => { + <Route path="/admin/complaint" render={() => { if (CheckUserPermission()) return <ComplaintCard /> else @@ -406,13 +406,13 @@ export default function App() { else return <Unauthorized /> }} /> - <Route path="/admin/user/:id" render={() => { + <Route path="/admin/user" render={() => { if (CheckUserPermission()) return <UserCard /> else return <Unauthorized /> }} /> - <Route path="/admin/EditUser/:id" render={() => { + <Route path="/admin/EditUser" render={() => { if (CheckUserPermission()) return <EditUser /> else @@ -424,7 +424,7 @@ export default function App() { else return <Unauthorized /> }} /> - <Route path="/admin/EditPermissions/:id" render={() => { + <Route path="/admin/EditPermissions" render={() => { if (CheckUserPermission()) return <EditRole /> else @@ -442,7 +442,7 @@ export default function App() { else return <Unauthorized /> }} /> - <Route path="/admin/sendEmail/:email" ender={() => { + <Route path="/admin/sendEmail" render={() => { if (CheckUserPermission()) return <SendEmail /> else -- GitLab From 37c890afc9c1e9f35e93e0c99644702ba935cfa4 Mon Sep 17 00:00:00 2001 From: Luis Felipe Risch <lfr20@inf.ufpr.br> Date: Tue, 18 May 2021 10:48:05 -0300 Subject: [PATCH 07/12] Fixed last bugs of admin --- .../Components/DataCards/ComplaintsCard.js | 2 +- .../Components/Inputs/CreateInstitution.js | 23 +- .../Components/Inputs/CreateLanguage.js | 43 ++-- .../Components/Inputs/CreateRole.js | 23 +- .../Components/Components/Inputs/EditRoles.js | 21 +- .../Components/Inputs/EmailInputs.js | 239 +++++++++++------- .../Components/Inputs/IntitutionsInputs.js | 28 +- .../Components/Inputs/NoteVarInputs.js | 43 ++-- src/Admin/Pages/AdminLabelTabs/LabelTabs.js | 2 +- src/Admin/Pages/Pages/SubPages/Activity.js | 2 +- .../Pages/Pages/SubPages/AproveTeacher.js | 2 +- .../Pages/Pages/SubPages/BlockedUsers.js | 2 +- src/Admin/Pages/Pages/SubPages/Collections.js | 2 +- .../Pages/SubPages/CommunityQuestions.js | 2 +- src/Admin/Pages/Pages/SubPages/Complaints.js | 2 +- .../Pages/SubPages/EducationalObjects.js | 4 +- .../Pages/Pages/SubPages/Institutions.js | 2 +- src/Admin/Pages/Pages/SubPages/Languages.js | 2 +- .../Pages/Pages/SubPages/NoteVariables.js | 2 +- src/Admin/Pages/Pages/SubPages/Permissions.js | 2 +- src/Admin/Pages/Pages/SubPages/Questions.js | 2 +- src/Admin/Pages/Pages/SubPages/Rating.js | 2 +- src/Admin/Pages/Pages/SubPages/Users.js | 2 +- src/env.js | 2 +- 24 files changed, 267 insertions(+), 189 deletions(-) diff --git a/src/Admin/Components/Components/DataCards/ComplaintsCard.js b/src/Admin/Components/Components/DataCards/ComplaintsCard.js index 4ac22b4e..4c3fc133 100644 --- a/src/Admin/Components/Components/DataCards/ComplaintsCard.js +++ b/src/Admin/Components/Components/DataCards/ComplaintsCard.js @@ -359,7 +359,7 @@ const CollectionCard = () => { case "User": return ( <CardActions> - <Link to={`/admin/user/${item.complainable_id}`}> + <Link to={`/admin/user?id=${item.complainable_id}`}> <Button variant="contained" color="primary" diff --git a/src/Admin/Components/Components/Inputs/CreateInstitution.js b/src/Admin/Components/Components/Inputs/CreateInstitution.js index 95208457..b4f001f0 100644 --- a/src/Admin/Components/Components/Inputs/CreateInstitution.js +++ b/src/Admin/Components/Components/Inputs/CreateInstitution.js @@ -138,18 +138,21 @@ const CreateInstitution = (props) => { if (data.id) HandleSnack('A instituição foi criada com sucesso', true, 'success', '#228B22') else { - if(data.errors){ + if (data.errors) { HandleSnack(`${data.errors[0]}`, true, 'warning', '#FA8072') } - if (data.name) { - let nameError = ""; - data.name.map((msg) => ( - nameError = nameError + msg + " e " - )) - setErrorInName({ - error: true, - message: nameError - }) + else { + if (data.name) { + let nameError = ""; + data.name.map((msg) => ( + nameError = nameError + msg + " e " + )) + setErrorInName({ + error: true, + message: nameError + }) + } + HandleSnack('Você precisa preencher algumas informações obrigatórias', true, 'warning', '#FFC125') } } setIsLoading(false) diff --git a/src/Admin/Components/Components/Inputs/CreateLanguage.js b/src/Admin/Components/Components/Inputs/CreateLanguage.js index 4e40599b..c9a65901 100644 --- a/src/Admin/Components/Components/Inputs/CreateLanguage.js +++ b/src/Admin/Components/Components/Inputs/CreateLanguage.js @@ -123,28 +123,31 @@ const CreateLanguage = (props) => { if (data.id) HandleSnack('A linguagem foi criada com sucesso', true, 'success', '#228B22') else { - if(data.errors){ + if (data.errors) { HandleSnack(`${data.errors[0]}`, true, 'warning', '#FA8072') } - if (data.name) { - let nameError = ""; - data.name.map((msg) => ( - nameError = nameError + msg + " e " - )) - setErrorInName({ - error: true, - message: nameError - }) - } - if (data.code) { - let codeError = ""; - data.code.map((msg) => ( - codeError = codeError + msg + " e " - )) - setErrorInCode({ - error: true, - message: codeError - }) + else { + if (data.name) { + let nameError = ""; + data.name.map((msg) => ( + nameError = nameError + msg + " e " + )) + setErrorInName({ + error: true, + message: nameError + }) + } + if (data.code) { + let codeError = ""; + data.code.map((msg) => ( + codeError = codeError + msg + " e " + )) + setErrorInCode({ + error: true, + message: codeError + }) + } + HandleSnack('Você precisa preencher algumas informações obrigatórias', true, 'warning', '#FFC125') } } setIsLoading(false) diff --git a/src/Admin/Components/Components/Inputs/CreateRole.js b/src/Admin/Components/Components/Inputs/CreateRole.js index 042616ca..94afb024 100644 --- a/src/Admin/Components/Components/Inputs/CreateRole.js +++ b/src/Admin/Components/Components/Inputs/CreateRole.js @@ -124,18 +124,21 @@ const CreateRole = (props) => { if (data.id) HandleSnack('A role foi criada com sucesso!', true, 'success', '#228B22') else { - if(data.errors){ + if (data.errors) { HandleSnack(`${data.errors[0]}`, true, 'warning', '#FA8072') } - if (data.name) { - let errorName = ""; - data.name.map((err) => ( - errorName = errorName + err + " e " - )) - setErrorInName({ - error: true, - message: errorName - }) + else { + if (data.name) { + let errorName = ""; + data.name.map((err) => ( + errorName = errorName + err + " e " + )) + setErrorInName({ + error: true, + message: errorName + }) + } + HandleSnack('Você precisa preencher algumas informações obrigatórias', true, 'warning', '#FFC125') } } setIsLoading(false) diff --git a/src/Admin/Components/Components/Inputs/EditRoles.js b/src/Admin/Components/Components/Inputs/EditRoles.js index d08e14b2..4b3aa488 100644 --- a/src/Admin/Components/Components/Inputs/EditRoles.js +++ b/src/Admin/Components/Components/Inputs/EditRoles.js @@ -161,15 +161,18 @@ const EditLanguage = () => { if (data.errors) { HandleSnack(`${data.errors[0]}`, true, 'warning', '#FA8072') } - if (data.name) { - let errorName = ""; - data.name.map((err) => ( - errorName = errorName + err + " e " - )) - setErrorInName({ - error: true, - message: errorName - }) + else { + HandleSnack('Você precisa preencher algumas informações obrigatórias', true, 'warning', '#FFC125') + if (data.name) { + let errorName = ""; + data.name.map((err) => ( + errorName = errorName + err + " e " + )) + setErrorInName({ + error: true, + message: errorName + }) + } } } setIsLoading(false) diff --git a/src/Admin/Components/Components/Inputs/EmailInputs.js b/src/Admin/Components/Components/Inputs/EmailInputs.js index 438b27cb..f75e8b48 100644 --- a/src/Admin/Components/Components/Inputs/EmailInputs.js +++ b/src/Admin/Components/Components/Inputs/EmailInputs.js @@ -34,8 +34,6 @@ import { postRequest } from '../../../../Components/HelperFunctions/getAxiosConf import ClassicEditor from "@ckeditor/ckeditor5-build-classic" import { CKEditor } from '@ckeditor/ckeditor5-react'; -let sendToAll = false; - const useStyles = makeStyles((theme) => ({ root: { display: 'flex', @@ -52,11 +50,13 @@ const useStyles = makeStyles((theme) => ({ const EmailInputs = (props) => { const classes = useStyles(); - const [option, setOption] = useState("Todos os usuários"); //labels of the text field 'to' - const [index, setIndex] = useState(0); //Used to display something above the text field 'to' depending on what the user clicks + const [option, setOption] = useState(props.email ? "Emails" : "All"); //labels of the text field 'to' + const [isToEmails, setIsToEmails] = useState(props.email ? true : false) + const [isToAll, setIsToAll] = useState(props.email ? false : true) + const [isToRoles, setIsToRoles] = useState(false) // Capture th text insert by the user in the fields - const [emails, setEmails] = useState(props.email === "none" ? "" : props.email); + const [emails, setEmails] = useState(props.email ? props.email : ""); const [emailsAdress, setEmailsAdress] = useState([]); const [subject, setSubject] = useState(""); const [message, setMessage] = useState(""); @@ -153,12 +153,22 @@ const EmailInputs = (props) => { const handleChange = (e) => { const value = e.target.value; - if (value === "All") { - sendToAll = true; - } else { - sendToAll = false; + if (value === 'All') { + setIsToAll(true) + setIsToEmails(false) + setIsToRoles(false) + } + if (value === 'Emails') { + setIsToEmails(true) + setIsToRoles(false) + setIsToAll(false) + } + if (value === 'Roles') { + setIsToRoles(true) + setIsToAll(false) + setIsToEmails(false) } - setOption(value); + setOption(value) }; const handleChangeCheckBox = (i) => { @@ -188,7 +198,7 @@ const EmailInputs = (props) => { const OnKeyPressHandler = (key) => { if (key === 13) { - if (!isEmpty(emails)) { + if (!itsEmpty(emails)) { if (emails.includes("@")) { const arr = [...emailsAdress]; arr.push(emails); @@ -218,10 +228,6 @@ const EmailInputs = (props) => { setEmailsAdress(copyEmail); }; - const isEmpty = (text) => { - return text.length === 0 ? true : false; - }; - // Handle snack infos const HandleSnack = (message, state, icon, color) => { setSnackInfo({ @@ -238,44 +244,100 @@ const EmailInputs = (props) => { setEmailsAdress([]); }; + const itsEmpty = (obj) => { + return obj.length === 0 + } + const submitRequest = async () => { - // setIsSending(true); - const rolesArr = []; - for (let index = 0; index < roles.length; index++) { - const role = roles[index] - if (role.isChecked) - rolesArr.push(role.value) - } + setIsSending(true); + const rolesArr = []; const api = `/email`; const body = { "email": { - "all_users": sendToAll, + "all_users": isToAll, "subject": subject, "body": message, - "emails": emailsAdress, - "roles": rolesArr, + "emails": isToEmails ? emailsAdress : [], + "roles": isToRoles ? rolesArr : [], }, }; - postRequest( - api, - body, - (data, header) => { - HandleSnack( - "O email foi enviado com sucesso", - true, - "success", - "#228B22" - ); - setIsSending(false); - CleanFields(); - }, - (error) => { - HandleSnack("Ocorreu algum erro", true, "warning", "#FA8072"); - setIsSending(false); - CleanFields(); - } - ) + + for (let index = 0; index < roles.length; index++) { + const role = roles[index] + if (role.isChecked) + rolesArr.push(role.value) + } + + if (isToRoles && !itsEmpty(rolesArr) && !itsEmpty(subject) && !itsEmpty(body)) + postRequest( + api, + body, + (data, header) => { + HandleSnack( + "O email foi enviado com sucesso", + true, + "success", + "#228B22" + ); + setIsSending(false); + CleanFields(); + }, + (error) => { + HandleSnack("Ocorreu algum erro", true, "warning", "#FA8072"); + setIsSending(false); + CleanFields(); + } + ) + else if (isToEmails && !itsEmpty(emailsAdress) && !itsEmpty(subject) && !itsEmpty(body)) + postRequest( + api, + body, + (data, header) => { + HandleSnack( + "O email foi enviado com sucesso", + true, + "success", + "#228B22" + ); + setIsSending(false); + CleanFields(); + }, + (error) => { + HandleSnack("Ocorreu algum erro", true, "warning", "#FA8072"); + setIsSending(false); + CleanFields(); + } + ) + else if (isToAll && !itsEmpty(emailsAdress) && !itsEmpty(subject) && !itsEmpty(body)) + postRequest( + api, + body, + (data, header) => { + HandleSnack( + "O email foi enviado com sucesso", + true, + "success", + "#228B22" + ); + setIsSending(false); + CleanFields(); + }, + (error) => { + HandleSnack("Ocorreu algum erro", true, "warning", "#FA8072"); + setIsSending(false); + CleanFields(); + } + ) + else { + HandleSnack( + "Você precisa preencher todos os campos!", + true, + "warning", + "#FFC125" + ); + setIsSending(false); + } }; return ( @@ -327,7 +389,6 @@ const EmailInputs = (props) => { > {options.map((option, index) => ( <MenuItem - onClick={() => setIndex(index)} key={option.value} value={option.value} > @@ -336,8 +397,8 @@ const EmailInputs = (props) => { ))} </TextField> <div style={{ height: "1em" }} /> - - {index === 0 ? null : index === 1 ? ( + { + isToRoles && <FormGroup style={{ marginBottom: "1em" }}> {roles.map((role, index) => ( <FormControlLabel @@ -354,45 +415,45 @@ const EmailInputs = (props) => { /> ))} </FormGroup> - ) : ( - <> - <div - style={{ - display: "flex", - flexDirection: "row", - flexWrap: "wrap", - justifyContent: "Space-between", - marginBottom: "1em" - }} - > - {emailsAdress.map((email, index) => ( - <li key={index} style={{ listStyleType: "none", marginBottom: "0.5em" }}> - <Chip - label={email} - onDelete={() => HandleDelete(index)} - classes={classes.chip} - /> - </li> - ))} - </div> - - <TextField - id="outlined-input" - label="Emails" - rows={1} - error={errorInEmails.error} - helperText={errorInEmails.message} - value={emails} - onKeyPress={(key) => OnKeyPressHandler(key.which)} - onChange={EmailsHandler} - // onBlur={ShowEmails} - placeholder="Digite um email por vez e pressione Enter" - variant="outlined" - style={{ marginBottom: "1em" }} - /> - </> - )} - + } + { + isToEmails && + <> + <div + style={{ + display: "flex", + flexDirection: "row", + flexWrap: "wrap", + justifyContent: "Space-between", + marginBottom: "1em" + }} + > + {emailsAdress.map((email, index) => ( + <li key={index} style={{ listStyleType: "none", marginBottom: "0.5em" }}> + <Chip + label={email} + onDelete={() => HandleDelete(index)} + classes={classes.chip} + /> + </li> + ))} + </div> + <TextField + id="outlined-input" + label="Emails" + rows={1} + error={errorInEmails.error} + helperText={errorInEmails.message} + value={emails} + onKeyPress={(key) => OnKeyPressHandler(key.which)} + onChange={EmailsHandler} + // onBlur={ShowEmails} + placeholder="Digite um email por vez e pressione Enter" + variant="outlined" + style={{ marginBottom: "1em" }} + /> + </> + } <TextField id="outlined-input" label="Assunto" @@ -403,7 +464,7 @@ const EmailInputs = (props) => { onChange={SubjectHandler} variant="outlined" /> - </form> + </form > <div style={{ height: "1em" }} /> @@ -432,10 +493,10 @@ const EmailInputs = (props) => { color="primary" startIcon={<SendRoundedIcon />} > - {isSending ? <CircularProgress /> : "Enviar"} + {isSending ? <CircularProgress size={24} /> : "Enviar"} </Button> </div> - </div> + </div > ); }; diff --git a/src/Admin/Components/Components/Inputs/IntitutionsInputs.js b/src/Admin/Components/Components/Inputs/IntitutionsInputs.js index 47031b7b..148f006f 100644 --- a/src/Admin/Components/Components/Inputs/IntitutionsInputs.js +++ b/src/Admin/Components/Components/Inputs/IntitutionsInputs.js @@ -37,10 +37,10 @@ import { EditFilter, GetAData } from '../../../Filters'; //Routers import { Link } from 'react-router-dom'; -let id; - const EditInstitution = () => { const { state } = useContext(Store); + const urlParams = new URLSearchParams(window.location.search); + const id = urlParams.get("institution"); const [error, setError] = useState(null); //Necessary to consult the API, catch errors const [isLoaded, setIsLoaded] = useState(false); //Necessary to consult the API, wait until complete @@ -148,15 +148,18 @@ const EditInstitution = () => { if (data.errors) { HandleSnack(`${data.errors[0]}`, true, 'warning', '#FA8072') } - if (data.name) { - let errorName = ""; - data.name.map((err) => ( - errorName = errorName + err + " e " - )) - setErrorInName({ - error: true, - message: errorName - }) + else { + HandleSnack('Você precisa preencher algumas informações obrigatórias', true, 'warning', '#FFC125') + if (data.name) { + let errorName = ""; + data.name.map((err) => ( + errorName = errorName + err + " e " + )) + setErrorInName({ + error: true, + message: errorName + }) + } } } setIsLoading(false) @@ -209,8 +212,7 @@ const EditInstitution = () => { ] useEffect(() => { - const urlParams = new URLSearchParams(window.location.search); - const id = urlParams.get("institution"); + getRequest( GetAData("institutions", id), (data, header) => { diff --git a/src/Admin/Components/Components/Inputs/NoteVarInputs.js b/src/Admin/Components/Components/Inputs/NoteVarInputs.js index 3cc63a70..3c1542ec 100644 --- a/src/Admin/Components/Components/Inputs/NoteVarInputs.js +++ b/src/Admin/Components/Components/Inputs/NoteVarInputs.js @@ -166,28 +166,31 @@ const NoteVarInputs = () => { if (data.id) HandleSnack('A variável de nota foi atualizada com sucesso!', true, 'success', '#228B22') else { - if(data.errors){ + if (data.errors) { HandleSnack(`${data.errors[0]}`, true, 'warning', '#FA8072') } - if (data.name) { - let errorName = ""; - data.name.map((err) => ( - errorName = errorName + err + " e " - )) - setErrorInName({ - error: true, - message: errorName - }) - } - if(data.weight){ - let weightError = ""; - data.weight.map((err) => ( - weightError = weightError + err + " e " - )) - setErrorInWeight({ - error: true, - message : weightError - }) + else { + HandleSnack('Você precisa preencher algumas informações obrigatórias', true, 'warning', '#FFC125') + if (data.name) { + let errorName = ""; + data.name.map((err) => ( + errorName = errorName + err + " e " + )) + setErrorInName({ + error: true, + message: errorName + }) + } + if (data.weight) { + let weightError = ""; + data.weight.map((err) => ( + weightError = weightError + err + " e " + )) + setErrorInWeight({ + error: true, + message: weightError + }) + } } } setIsLoading(false) diff --git a/src/Admin/Pages/AdminLabelTabs/LabelTabs.js b/src/Admin/Pages/AdminLabelTabs/LabelTabs.js index 9b2894cd..54b2a0fd 100644 --- a/src/Admin/Pages/AdminLabelTabs/LabelTabs.js +++ b/src/Admin/Pages/AdminLabelTabs/LabelTabs.js @@ -119,7 +119,7 @@ const TabsItens = [ }, { label: "Enviar email", - href: '/admin/sendEmail?email=none', + href: '/admin/sendEmail', icon: <EmailRoundedIcon style={{ fill: blue }} />, }, ]; diff --git a/src/Admin/Pages/Pages/SubPages/Activity.js b/src/Admin/Pages/Pages/SubPages/Activity.js index 54d37dc4..c87c1b25 100644 --- a/src/Admin/Pages/Pages/SubPages/Activity.js +++ b/src/Admin/Pages/Pages/SubPages/Activity.js @@ -393,7 +393,7 @@ const Activity = () => { </StyledTableCell> </StyledTableRow> ) : ( - <StyledTableRow key={new Date().toISOString() + row.created_at}> + <StyledTableRow key={new Date().toISOString() + index}> <StyledTableCell component="th" scope="row"> {DisplayDate(row.created_at)} </StyledTableCell> diff --git a/src/Admin/Pages/Pages/SubPages/AproveTeacher.js b/src/Admin/Pages/Pages/SubPages/AproveTeacher.js index 8fae644f..b8f7203a 100644 --- a/src/Admin/Pages/Pages/SubPages/AproveTeacher.js +++ b/src/Admin/Pages/Pages/SubPages/AproveTeacher.js @@ -691,7 +691,7 @@ const AproveTeacher = () => { </StyledTableRow> ) : ( <StyledTableRow - key={new Date().toISOString() + row.created_at} + key={new Date().toISOString() + index} style={{ flex: 1, width: "100%" }} > <StyledTableCell component="th" scope="row"> diff --git a/src/Admin/Pages/Pages/SubPages/BlockedUsers.js b/src/Admin/Pages/Pages/SubPages/BlockedUsers.js index e6083f39..84a4419b 100644 --- a/src/Admin/Pages/Pages/SubPages/BlockedUsers.js +++ b/src/Admin/Pages/Pages/SubPages/BlockedUsers.js @@ -459,7 +459,7 @@ const BlockedUsers = () => { : - <StyledTableRow key={new Date().toISOString() + row.created_at}> + <StyledTableRow key={new Date().toISOString() + index}> <StyledTableCell component="th" scope="row">{row.id}</StyledTableCell> <StyledTableCell align="right"> {BlockStatus(row.state)} diff --git a/src/Admin/Pages/Pages/SubPages/Collections.js b/src/Admin/Pages/Pages/SubPages/Collections.js index b312aa53..dd15cbae 100644 --- a/src/Admin/Pages/Pages/SubPages/Collections.js +++ b/src/Admin/Pages/Pages/SubPages/Collections.js @@ -538,7 +538,7 @@ const Collections = () => { </StyledTableCell> </StyledTableRow> ) : ( - <StyledTableRow key={new Date().toISOString() + row.created_at}> + <StyledTableRow key={new Date().toISOString() + index}> <StyledTableCell component="th" scope="row"> {row.name} </StyledTableCell> diff --git a/src/Admin/Pages/Pages/SubPages/CommunityQuestions.js b/src/Admin/Pages/Pages/SubPages/CommunityQuestions.js index 029c566a..4c93b941 100644 --- a/src/Admin/Pages/Pages/SubPages/CommunityQuestions.js +++ b/src/Admin/Pages/Pages/SubPages/CommunityQuestions.js @@ -478,7 +478,7 @@ const CommunityQuestion = () => { </StyledTableCell> </StyledTableRow> ) : ( - <StyledTableRow key={index}> + <StyledTableRow key={new Date().toISOString() + index}> <StyledTableCell component="th" scope="row"> {row.id} </StyledTableCell> diff --git a/src/Admin/Pages/Pages/SubPages/Complaints.js b/src/Admin/Pages/Pages/SubPages/Complaints.js index 2c8dff2e..d03514dc 100644 --- a/src/Admin/Pages/Pages/SubPages/Complaints.js +++ b/src/Admin/Pages/Pages/SubPages/Complaints.js @@ -574,7 +574,7 @@ const Complaints = () => { </StyledTableRow> ) : ( <StyledTableRow - key={new Date().toISOString() + row.created_at} + key={new Date().toISOString() + index} style={{ flex: 1, width: "100%" }} > <StyledTableCell component="th" scope="row"> diff --git a/src/Admin/Pages/Pages/SubPages/EducationalObjects.js b/src/Admin/Pages/Pages/SubPages/EducationalObjects.js index 612272ca..69d0dfc3 100644 --- a/src/Admin/Pages/Pages/SubPages/EducationalObjects.js +++ b/src/Admin/Pages/Pages/SubPages/EducationalObjects.js @@ -144,7 +144,7 @@ const EducationalObjects = () => { HandleSnack("Ocorreu algum erro", true, "warning", "#FA8072"); else { HandleSnack( - "A instituição foi deletada com sucesso", + "O objeto educacional foi deletada com sucesso", true, "success", "#228B22" @@ -534,7 +534,7 @@ const EducationalObjects = () => { </StyledTableCell> </StyledTableRow> ) : ( - <StyledTableRow key={new Date().toISOString() + row.created_at}> + <StyledTableRow key={new Date().toISOString() + index}> <StyledTableCell component="th" scope="row"> {DisplayDate(row.created_at)} </StyledTableCell> diff --git a/src/Admin/Pages/Pages/SubPages/Institutions.js b/src/Admin/Pages/Pages/SubPages/Institutions.js index 93d0af1a..7f713b9e 100644 --- a/src/Admin/Pages/Pages/SubPages/Institutions.js +++ b/src/Admin/Pages/Pages/SubPages/Institutions.js @@ -548,7 +548,7 @@ const Institutions = () => { </StyledTableCell> </StyledTableRow> ) : ( - <StyledTableRow key={new Date().toISOString() + row.created_at}> + <StyledTableRow key={new Date().toISOString() + index}> <StyledTableCell component="th" scope="row"> {row.id} </StyledTableCell> diff --git a/src/Admin/Pages/Pages/SubPages/Languages.js b/src/Admin/Pages/Pages/SubPages/Languages.js index 3f68cbf4..c38ac1e1 100644 --- a/src/Admin/Pages/Pages/SubPages/Languages.js +++ b/src/Admin/Pages/Pages/SubPages/Languages.js @@ -381,7 +381,7 @@ const Languages = () => { : - <StyledTableRow key={new Date().toISOString() + row.created_at}> + <StyledTableRow key={new Date().toISOString() + index}> <StyledTableCell component="th" scope="row">{row.id}</StyledTableCell> <StyledTableCell align="right">{row.name}</StyledTableCell> <StyledTableCell align="right">{row.code}</StyledTableCell> diff --git a/src/Admin/Pages/Pages/SubPages/NoteVariables.js b/src/Admin/Pages/Pages/SubPages/NoteVariables.js index 71b6abc8..1ad35f99 100644 --- a/src/Admin/Pages/Pages/SubPages/NoteVariables.js +++ b/src/Admin/Pages/Pages/SubPages/NoteVariables.js @@ -297,7 +297,7 @@ const NoteVariables = () => { : - <StyledTableRow key={new Date().toISOString() + row.created_at}> + <StyledTableRow key={new Date().toISOString() + index}> <StyledTableCell component="th" scope="row">{row.id}</StyledTableCell> <StyledTableCell align="right">{row.name}</StyledTableCell> <StyledTableCell align="right">{row.code}</StyledTableCell> diff --git a/src/Admin/Pages/Pages/SubPages/Permissions.js b/src/Admin/Pages/Pages/SubPages/Permissions.js index d8484ac1..787ac0de 100644 --- a/src/Admin/Pages/Pages/SubPages/Permissions.js +++ b/src/Admin/Pages/Pages/SubPages/Permissions.js @@ -384,7 +384,7 @@ const UserPermissions = () => { : - <StyledTableRow key={new Date().toISOString() + row.created_at}> + <StyledTableRow key={new Date().toISOString() + index}> <StyledTableCell component="th" scope="row">{row.id}</StyledTableCell> <StyledTableCell align="right">{row.name}</StyledTableCell> <StyledTableCell align="right">{row.description}</StyledTableCell> diff --git a/src/Admin/Pages/Pages/SubPages/Questions.js b/src/Admin/Pages/Pages/SubPages/Questions.js index 296c62d7..ca32e0cd 100644 --- a/src/Admin/Pages/Pages/SubPages/Questions.js +++ b/src/Admin/Pages/Pages/SubPages/Questions.js @@ -391,7 +391,7 @@ const Questions = () => { : - <StyledTableRow key={new Date().toISOString() + row.created_at}> + <StyledTableRow key={new Date().toISOString() + index}> <StyledTableCell component="th" scope="row">{row.id}</StyledTableCell> <StyledTableCell align="right">{DisplayDate(row.created_at)}</StyledTableCell> <StyledTableCell align="right">{row.description}</StyledTableCell> diff --git a/src/Admin/Pages/Pages/SubPages/Rating.js b/src/Admin/Pages/Pages/SubPages/Rating.js index 71f648dd..22d57d40 100644 --- a/src/Admin/Pages/Pages/SubPages/Rating.js +++ b/src/Admin/Pages/Pages/SubPages/Rating.js @@ -380,7 +380,7 @@ const Ratings = () => { : - <StyledTableRow key={new Date().toISOString() + row.created_at}> + <StyledTableRow key={new Date().toISOString() + index}> <StyledTableCell component="th" scope="row">{row.id}</StyledTableCell> <StyledTableCell align="right">{row.name}</StyledTableCell> <StyledTableCell align="right">{row.description}</StyledTableCell> diff --git a/src/Admin/Pages/Pages/SubPages/Users.js b/src/Admin/Pages/Pages/SubPages/Users.js index 95e8d38f..cb31af1e 100644 --- a/src/Admin/Pages/Pages/SubPages/Users.js +++ b/src/Admin/Pages/Pages/SubPages/Users.js @@ -516,7 +516,7 @@ const Users = () => { : - <StyledTableRow key={new Date().toISOString() + row.created_at}> + <StyledTableRow key={new Date().toISOString() + index}> <StyledTableCell component="th" scope="row">{row.id}</StyledTableCell> <StyledTableCell align="right">{row.name}</StyledTableCell> <StyledTableCell align="right">{row.email ? row.email : ""}</StyledTableCell> diff --git a/src/env.js b/src/env.js index b7359157..82bf229b 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.portalmec.c3sl.ufpr.br', +var apiDomain = 'https://api.portalmectest.c3sl.ufpr.br', apiVersion = 'v1', apiUrl = apiDomain + '/' + apiVersion; -- GitLab From e83c6d5bf92dbaaa81a522e4c53f875e1a8ed2b7 Mon Sep 17 00:00:00 2001 From: Vinicius Gabriel Machado <vgm18@inf.ufpr.br> Date: Tue, 18 May 2021 15:00:57 -0300 Subject: [PATCH 08/12] fixed problems in public user page. Paging, some components not updating, crash in tabRede when user not logged in and overlapping in activities --- src/Components/ColCardOwnerOptions.js | 5 +- src/Components/CollectionCardFunction.js | 1 + src/Components/ModalExcluirColecao.js | 1 + .../TabPanels/PanelComponents/TemplateRede.js | 2 +- .../PublicUserPageTabs/LastCollections.js | 2 +- .../PublicUserPageTabs/TabColecoes.js | 163 +++++++++------- .../TabPanels/PublicUserPageTabs/TabRede.js | 176 +++++++++++++----- .../TabPanels/UserPageTabs/PanelColecoes.js | 10 +- src/Pages/PublicUserPage.js | 33 ++-- 9 files changed, 257 insertions(+), 136 deletions(-) diff --git a/src/Components/ColCardOwnerOptions.js b/src/Components/ColCardOwnerOptions.js index 279ffa96..a0757806 100644 --- a/src/Components/ColCardOwnerOptions.js +++ b/src/Components/ColCardOwnerOptions.js @@ -42,7 +42,6 @@ export default function ColCardOwnerOptions (props) { } const [modalExcluirOpen, toggleModalExcluir] = useState(false) - const openModalExcluir = () => {toggleModalExcluir(true)} const [modalEditarOpen, toggleModalEditar] = useState(false) @@ -50,7 +49,7 @@ export default function ColCardOwnerOptions (props) { return ( <> <ModalExcluirColecao id={props.id} - open={modalExcluirOpen} handleClose={() => {toggleModalExcluir(false)}} + open={modalExcluirOpen} handleClose={() => {toggleModalExcluir(false)}} removeColl={props.removeColl} /> <ModalEditarColecao id={props.id} open={modalEditarOpen} handleClose={() => {toggleModalEditar(false)}} @@ -78,7 +77,7 @@ export default function ColCardOwnerOptions (props) { <ListItemIcon><CreateIcon /></ListItemIcon>Editar </StyledMenuItem> - <StyledMenuItem onClick={openModalExcluir}> + <StyledMenuItem onClick={() => {toggleModalExcluir(true)}} > <ListItemIcon><DeleteForeverIcon /></ListItemIcon>Excluir </StyledMenuItem> diff --git a/src/Components/CollectionCardFunction.js b/src/Components/CollectionCardFunction.js index 85f59e03..6f7322e7 100644 --- a/src/Components/CollectionCardFunction.js +++ b/src/Components/CollectionCardFunction.js @@ -272,6 +272,7 @@ export default function CollectionCardFunction(props) { id={props.id} changeColName={changeColName} changeColPrivacy={changeColPrivacy} + removeColl={props.removeColl} /> </Grid> </Grid> diff --git a/src/Components/ModalExcluirColecao.js b/src/Components/ModalExcluirColecao.js index 879112ae..f23b819d 100644 --- a/src/Components/ModalExcluirColecao.js +++ b/src/Components/ModalExcluirColecao.js @@ -31,6 +31,7 @@ export default function ModalExcluirColecao (props) { function handleDeleteSuccess (data) { toggleSnackbar(true) + props.removeColl(props.id) props.handleClose() } const handleDelete = () => { diff --git a/src/Components/TabPanels/PanelComponents/TemplateRede.js b/src/Components/TabPanels/PanelComponents/TemplateRede.js index 4fd33640..c792b7d2 100644 --- a/src/Components/TabPanels/PanelComponents/TemplateRede.js +++ b/src/Components/TabPanels/PanelComponents/TemplateRede.js @@ -76,7 +76,7 @@ export default function PanelTemplateRede(props) { props.sliceArr.map((card) => <> { - card.follower && + card.follower && card.followable && <Grid item xs={12} sm={6} md={'auto'} lg={3} key={card.id}> {RenderContactCard(card, props.follower)} </Grid> diff --git a/src/Components/TabPanels/PublicUserPageTabs/LastCollections.js b/src/Components/TabPanels/PublicUserPageTabs/LastCollections.js index 553b9788..6e32577f 100644 --- a/src/Components/TabPanels/PublicUserPageTabs/LastCollections.js +++ b/src/Components/TabPanels/PublicUserPageTabs/LastCollections.js @@ -54,7 +54,7 @@ export default function LastCols(props) { <StyledGrid container spacing={1} style={{ paddingLeft: "0.5em" }}> { props.collections.slice(0, 4).map((card) => - <Grid item md={3} xs={12} key={card.id}> + <Grid item container md={3} xs={12} key={card.id}> <CollectionCardFunction name={card.name} tags={card.tags} diff --git a/src/Components/TabPanels/PublicUserPageTabs/TabColecoes.js b/src/Components/TabPanels/PublicUserPageTabs/TabColecoes.js index 22fe8e4d..4b46dc07 100644 --- a/src/Components/TabPanels/PublicUserPageTabs/TabColecoes.js +++ b/src/Components/TabPanels/PublicUserPageTabs/TabColecoes.js @@ -17,79 +17,104 @@ 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, { useState, useEffect } from 'react' -import { HeaderGrid, ContainerStyled, Carregados, StyledGrid } from '../StyledComponents.js' -import Grid from '@material-ui/core/Grid'; -import CollectionCardFunction from '../../CollectionCardFunction.js' -import { ButtonMostrarMaisColecao } from '../PanelComponents/ButtonsArea.js' - -export default function TabRecursos(props) { - const [arr, setArr] = useState([]) - const [colsSlice, setSlice] = useState([]) - const handleSlice = (newArr) => { setSlice(newArr) } - +import { fetchAllRequest, getRequest } from '../../HelperFunctions/getAxiosConfig' +import PanelTemplateColecao from '../PanelComponents/TemplateColecao.js' +import LoadingSpinner from '../../LoadingSpinner.js' + +export default function TabColecoes(props) { + const [loading, handleLoading] = useState(true) + + const [errorInUserColl, setErrorInUserColl] = useState(false) + + const [userCollections, setUserCollections] = useState([]) + + const [currLimitUserColl, setCurrLimitUserColl] = useState(4) + + const [loadingMoreUserColl, setLoadingMoreUserColl] = useState(false); + + const [endOfUserColl, setEndOfUserColl] = useState(false); + + function handleSuccess(responseArr, headersArr) { + setErrorInUserColl(responseArr[0].errors ? true : false) + + handleLoading(false) + setUserCollections(responseArr[0]) + + if (headersArr[0].has('X-Total-Count')) { + setEndOfUserColl(headersArr[0].get('X-Total-Count')); + } + } + + function handleError(error) { + handleLoading(false) + setErrorInUserColl(true) + } + + const getInfo = () => { + const urls = [ + `/users/${props.id}/collections?offset=0&limit=4`, + ] + fetchAllRequest(urls, handleSuccess, handleError) + } + useEffect(() => { - setArr(props.collections) - setSlice(props.collections.slice(0, 4)) + handleLoading(true) + getInfo() }, []) - - const showMore = (quantity) => { - var sliceLength = colsSlice.length - handleSlice(arr.slice(0, sliceLength + quantity)) + + const showMoreUserCollections = (limite) => { + const limit = limite; + setLoadingMoreUserColl(true); + setCurrLimitUserColl(currLimitUserColl + limit) + const url = `/users/${props.id}/collections?offset=${currLimitUserColl}&limit=${limit}`; + getRequest(url, + (data) => { + if (data.errors) { + setLoadingMoreUserColl(false); + setEndOfUserColl(true) + setErrorInUserColl(true) + } + else if (data.length >= 1) { + let currData = [...userCollections]; + currData = [...currData.concat(data)]; + setLoadingMoreUserColl(false); + setUserCollections(currData); + } + else { + setLoadingMoreUserColl(false); + setEndOfUserColl(true) + } + }, + (error) => { + setLoadingMoreUserColl(false); + setEndOfUserColl(true) + setErrorInUserColl(true) + } + ) } return ( - <ContainerStyled style={{ flexDirection: "column" }}> - - <HeaderGrid container> - <Grid item xs={12}> - <h3>Coleções públicas <b style={{ fontWeight: "500" }}>({props.count})</b></h3> - </Grid> - </HeaderGrid> - - <StyledGrid container spacing={1} style={{ paddingLeft: "30px", paddingRight: "15px" }}> - { - colsSlice.map((card) => - <Grid item xs={12} sm={6} md={'auto'} lg={3} key={card.id}> - <CollectionCardFunction - name={card.name} - tags={card.tags} - rating={card.review_average} - id={card.id} - author={card.owner.name} - description={card.description} - thumbnails={card.items_thumbnails} - avatar={card.owner.avatar} - likeCount={card.likes_count} - followed={card.followed} - liked={card.liked} - collections={card.collection_items} - authorID={card.owner.id} - /> - </Grid> - ) - } - </StyledGrid> - - <Carregados> - <p style={{ margin: "0 0 10px", fontSize: "14px" }}> - Carregados {colsSlice.length} de {arr.length} - </p> - - { - props.count > 5 && - <React.Fragment> - <ButtonMostrarMaisColecao onClick={() => { showMore(4) }}> - <span style={{ color: "#fff", fontSize: "14px", fontWeight: "500" }}>MOSTRAR MAIS 4</span> - </ButtonMostrarMaisColecao> - - <ButtonMostrarMaisColecao onClick={() => { showMore(20) }}> - <span style={{ color: "#fff", fontSize: "14px", fontWeight: "500" }}>MOSTRAR MAIS 20</span> - </ButtonMostrarMaisColecao> - </React.Fragment> - } - - </Carregados> - - </ContainerStyled> + <> + { + loading ? + ( + <LoadingSpinner text={'CARREGANDO COLEÇÕES'} /> + ) + : + ( + <PanelTemplateColecao + title={"Coleções Públicas"} + length={userCollections.length} + noContentText={props.username + " não possui nenhuma coleção."} + sliceArr={userCollections} + showMore={showMoreUserCollections} + loadingMore={loadingMoreUserColl} + end={endOfUserColl} + followed={false} + error={errorInUserColl} + /> + ) + } + </> ) } diff --git a/src/Components/TabPanels/PublicUserPageTabs/TabRede.js b/src/Components/TabPanels/PublicUserPageTabs/TabRede.js index a9350fd3..6b8a8a8e 100644 --- a/src/Components/TabPanels/PublicUserPageTabs/TabRede.js +++ b/src/Components/TabPanels/PublicUserPageTabs/TabRede.js @@ -18,35 +18,94 @@ along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/> import React, {useState, useEffect} from 'react' import PanelTemplateRede from '../PanelComponents/TemplateRede.js' -import {fetchAllRequest} from '../../HelperFunctions/getAxiosConfig' +import { fetchAllRequest, getRequest } from '../../HelperFunctions/getAxiosConfig' +import LoadingSpinner from '../../LoadingSpinner.js' export default function TabRede (props) { - const [followers, setFollowers] = useState([]) - const [followersSlice, setFollowersSlice] = useState([]) - + const [loading, handleLoading] = useState(true) + + const [errorInFollowing, setErrorInFollowing] = useState(false) + const [errorInFollowers, setErrorInFollowers] = useState(false) + + const [followingList, setFollowing] = useState([]) + const [currFollowingLimit, setCurrFollowingLimit] = useState(12) + const [loadingMoreFollowing, setLoadingFollowing] = useState(false) const [endOfFollowing, setEndOfFollowing] = useState(false) + + const [followersList, setFollowers] = useState([]) + const [currFollowerLimit, setFollowersLimit] = useState(12) + const [loadingMoreFollowers, setLoadingMoreFollowers] = useState(false) const [endOfFollowers, setEndOfFollowers] = useState(false) - const showMoreFollowers = () => { - let varSlice = followersSlice.length - setFollowersSlice(followers.slice(0, varSlice + 4)) - } - const showAllFollowers = () => {setFollowersSlice(followers)} - - const [following, setFollowing] = useState([]) - const [followingSlice, setFollowingSlice] = useState([]) - const showMoreFollowing = (num) => { - let varSlice = followingSlice.length - setFollowingSlice(following.slice(0, varSlice + num)) - } - const showAllFollowing = () => {setFollowingSlice(following)} - - function handleSuccess (responseArr, headersArr) { + const showMoreFollowing = (limite) => { + setLoadingFollowing(true); + const limit = limite; + setCurrFollowingLimit(currFollowingLimit + limit) + const url = `/users/${props.id}/following/User?offset=${currFollowingLimit}&limit=${limit}`; + getRequest(url, + (data) => { + if (data.errors) { + setLoadingFollowing(false); + setEndOfFollowing(true); + setErrorInFollowing(true); + } + else if (data.length >= 1) { + let currData = [...followingList]; + currData = [...currData.concat(data)]; + setLoadingFollowing(false); + setFollowing(currData); + } + else { + setLoadingFollowing(false); + setEndOfFollowing(true); + } + }, + (error) => { + setLoadingFollowing(false); + setEndOfFollowing(true); + setErrorInFollowing(true); + } + ) + } + + const showMoreFollowers = (limite) => { + setLoadingMoreFollowers(true); + const limit = limite; + setFollowersLimit(currFollowerLimit + limit) + const url = `/users/${props.id}/followers?offset=${currFollowerLimit}&limit=${limit}`; + getRequest(url, + (data) => { + if (data.errors) { + setLoadingMoreFollowers(false); + setEndOfFollowers(true); + setErrorInFollowers(true); + } + else { + if (data.length >= 1) { + let currData = [...followersList]; + currData = [...currData.concat(data)]; + setLoadingMoreFollowers(false); + setFollowers(currData); + } + else { + setLoadingMoreFollowers(false); + setEndOfFollowers(true) + } + } + }, + (error) => { + setLoadingMoreFollowers(false); + setEndOfFollowers(true); + setErrorInFollowers(true); + } + ) + } + + async function handleSuccess (responseArr, headersArr) { + setErrorInFollowing(responseArr[0].errors ? true : false) // prevent of crashing the portal, do not remove it + setErrorInFollowers(responseArr[1].errors ? true : false) // prevent of crashing the portal, do not remove it setFollowers(responseArr[0]) - setFollowersSlice(responseArr[0].slice(0,4)) - setFollowing(responseArr[1]) - setFollowingSlice(responseArr[1].slice(0,4)) if (headersArr[1].has('X-Total-Count')) { setEndOfFollowing(headersArr[1].get('X-Total-Count')); @@ -54,38 +113,63 @@ export default function TabRede (props) { if (headersArr[0].has('X-Total-Count')) { setEndOfFollowers(headersArr[0].get('X-Total-Count')); } + handleLoading(false) + } + + function handleErrors() { + setLoadingMoreFollowers(false); + setEndOfFollowers(true); + setErrorInFollowers(true); } useEffect( () => { + handleLoading(true) const urls = [`/users/${props.id}/followers`, `/users/${props.id}/following/User`] - fetchAllRequest(urls, handleSuccess, (error) => {console.log(error)}) + fetchAllRequest(urls, handleSuccess, handleErrors) }, []) return ( - <React.Fragment> - <PanelTemplateRede - title={"Seguidores"} - length={followers.length} - sliceArr={followersSlice} - showMore={showMoreFollowers} - showAll={showAllFollowers} - follower={true} - end={endOfFollowers} - noContentText={props.username + ' não possui nenhum seguidor'} - /> - - <PanelTemplateRede - title={"Seguindo"} - length={following.length} - sliceArr={followingSlice} - showMore={showMoreFollowing} - showAll={showAllFollowing} - follower={false} - end={endOfFollowing} - noContentText={props.username + ' não segue nenhum usuário'} - /> - </React.Fragment> + <> + { + loading ? + ( + [ + <LoadingSpinner text={'CARREGANDO...'} /> + ] + ) + : + ( + [ + <React.Fragment> + <PanelTemplateRede + title={"Seguidores"} + length={followersList.length} + sliceArr={followersList} + showMore={showMoreFollowers} + follower={true} + end={endOfFollowers} + loadingMore={loadingMoreFollowers} + error={errorInFollowers} + noContentText={props.username + ' não possui nenhum seguidor'} + /> + + <PanelTemplateRede + title={"Seguindo"} + length={followingList.length} + sliceArr={followingList} + showMore={showMoreFollowing} + follower={false} + end={endOfFollowing} + loadingMore={loadingMoreFollowing} + error={errorInFollowing} + noContentText={props.username + ' não segue nenhum usuário'} + /> + </React.Fragment> + ] + ) + } + </> ) } diff --git a/src/Components/TabPanels/UserPageTabs/PanelColecoes.js b/src/Components/TabPanels/UserPageTabs/PanelColecoes.js index 420071c2..eef4d1ea 100644 --- a/src/Components/TabPanels/UserPageTabs/PanelColecoes.js +++ b/src/Components/TabPanels/UserPageTabs/PanelColecoes.js @@ -50,6 +50,12 @@ export default function TabPanelColecoes(props) { const [endOfUserColl, setEndOfUserColl] = useState(false); const [endOfFollowedColl, setEndOfFollowedColl] = useState(false); + const removeColl = (itemId) => { + let newSlice = userCollections.filter(item => item.id !== itemId); + setUserCollections(newSlice); + setEndOfUserColl(String(endOfUserColl - 1)) + }; + function handleSuccess(responseArr, headersArr) { setErrorInUserColl(responseArr[0].errors ? true : false) setErrorInFollowedColl(responseArr[1].errors ? true : false) @@ -181,10 +187,11 @@ export default function TabPanelColecoes(props) { end={endOfUserColl} callback={getInfo} error={errorInUserColl} + removeColl={removeColl} /> <PanelTemplateColecao - title={"Coleções que eu sigo"} + title={"Coleções que você segue"} length={followedCollections.length} noContentText={"Você ainda não segue nenhuma coleção."} sliceArr={followedCollections} @@ -272,6 +279,7 @@ function Tentativa(props) { liked={card.liked} collections={card.collection_items} authorID={card.owner.id} + removeColl={props.removeColl} /> </Grid> ) diff --git a/src/Pages/PublicUserPage.js b/src/Pages/PublicUserPage.js index 2571305e..070d3cb4 100644 --- a/src/Pages/PublicUserPage.js +++ b/src/Pages/PublicUserPage.js @@ -42,7 +42,7 @@ function RenderFollowContainer(props) { const { state } = useContext(Store) const [followed, setFollowed] = useState(props.followed) const toggleFollowed = () => { setFollowed(!followed) } - console.log(followed); + return ( <FollowContainer> <> @@ -103,7 +103,7 @@ export default function PublicUserPage(props) { const { state } = useContext(Store) /*user info variables--------------------------------------*/ const WIDTH = window.innerWidth; - const id = props.match.params.userId + const [id, setId] = useState(props.match.params.userId) const [loading, setLoading] = useState(false); @@ -148,10 +148,12 @@ export default function PublicUserPage(props) { /*Component Will Mount*/ useEffect(() => { + const id = props.match.params.userId + setId(id) const urls = [`/users/${id}`, `/users/${id}/learning_objects`, `/users/${id}/collections`, `/users/${id}/following/User`] setLoading(true); fetchAllRequest(urls, handleSuccess, (error) => { console.log(error) }) - }, [state.currentUser.id]) + }, [state.currentUser.id, props.match.params.userId]) /*---------------------------------------------------------*/ return ( @@ -238,18 +240,19 @@ export default function PublicUserPage(props) { </div> </Grid> - <Grid item xs={12}> - {tabValue === 0 && - <TabInicio id={id} user={userData} learningObjs={learningObjArr} collections={collectionsArr} />} - {tabValue === 1 && - <TabRecursos count={userData.learning_objects_count} learningObjs={learningObjArr} id={id} />} - {tabValue === 2 && - <TabColecoes count={userData.collections_count} collections={collectionsArr} - />} - {tabValue === 3 && - <TabRede id={id} username={userData.name} />} - - </Grid> + { + !loading && + <Grid item xs={12}> + {tabValue === 0 && + <TabInicio id={id} user={userData} learningObjs={learningObjArr} collections={collectionsArr} />} + {tabValue === 1 && + <TabRecursos count={userData.learning_objects_count} learningObjs={learningObjArr} id={id} />} + {tabValue === 2 && + <TabColecoes id={id} username={userData.name} />} + {tabValue === 3 && + <TabRede id={id} username={userData.name} />} + </Grid> + } </Grid> </BackgroundDiv> </React.Fragment> -- GitLab From 0999189b510d133f99ab0469c959278d714b190c Mon Sep 17 00:00:00 2001 From: Vinicius Gabriel Machado <vgm18@inf.ufpr.br> Date: Thu, 20 May 2021 13:08:58 -0300 Subject: [PATCH 09/12] fix bugs --- src/Components/MenuBar.js | 2 +- src/Components/MobileDrawerMenu.js | 2 +- src/Components/UploadPageComponents/UploadFileWrapper.js | 6 +++--- src/env.js | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Components/MenuBar.js b/src/Components/MenuBar.js index 0f1b536b..67f91119 100644 --- a/src/Components/MenuBar.js +++ b/src/Components/MenuBar.js @@ -193,7 +193,7 @@ export default function MenuBar(props) { <React.Fragment> <ButtonPubRecursoStyled onClick={props.openLogin}>PUBLICAR RECURSO?</ButtonPubRecursoStyled> <ButtonStyled onClick={props.openLogin}><ExitToAppIcon style={{ color: "#00bcd4" }} />Entrar</ButtonStyled> - <ButtonStyled onClick={props.openSignUp}>Cadastre-se</ButtonStyled> + <ButtonStyled onClick={props.openSignUp}>Cadastre-<span style={{textTransform: 'lowercase'}}>se</span></ButtonStyled> </React.Fragment> ) } diff --git a/src/Components/MobileDrawerMenu.js b/src/Components/MobileDrawerMenu.js index 469fa378..654ee7b9 100644 --- a/src/Components/MobileDrawerMenu.js +++ b/src/Components/MobileDrawerMenu.js @@ -172,7 +172,7 @@ export default function MobileDrawerMenu(props) { <div> <ButtonStyled onClick={props.openSignUp}> - Cadastre-se + Cadastre-<span style={{textTransform: 'lowercase'}}>se</span> </ButtonStyled> </div> </div> diff --git a/src/Components/UploadPageComponents/UploadFileWrapper.js b/src/Components/UploadPageComponents/UploadFileWrapper.js index 123512f2..b8919a54 100644 --- a/src/Components/UploadPageComponents/UploadFileWrapper.js +++ b/src/Components/UploadPageComponents/UploadFileWrapper.js @@ -22,7 +22,7 @@ import ChooseLink from './ChooseLinkSection.js' import {WrapperBox, BlueButton, GrayButton} from './StyledComponents.js'; import {DottedBox} from './StyledComponents.js'; import {getAxiosConfigFromJSON, updateHeaders, deleteRequest, putRequest} from '../HelperFunctions/getAxiosConfig.js' -import AddAPhotoIcon from '@material-ui/icons/AddAPhoto'; +import AttachFileIcon from '@material-ui/icons/AttachFile'; import axios from 'axios' import {apiUrl} from '../../env'; import DoneIcon from '@material-ui/icons/Done'; @@ -246,7 +246,7 @@ export default function UploadFileWrapper (props) { onDrop={e => handleDrop(e)} onDragOver={e => handleDragOver(e)} > - <AddAPhotoIcon className="icon"/> + <AttachFileIcon className="icon"/> <input type="file" onChange = {(e) => {onFileChange(e.target.files[0])}} @@ -255,7 +255,7 @@ export default function UploadFileWrapper (props) { /> <BlueButton> <label htmlFor="upload-file" style={{width : "inherit", cursor : "pointer"}}> - ESCOLHER IMAGEM + ESCOLHER ARQUIVO </label> </BlueButton> <span style={{marginTop : "6px"}}>Ou arrastar e soltar o arquivo aqui</span> 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 From 9622a67fc70cfe2853ec6c46e8979b1099766176 Mon Sep 17 00:00:00 2001 From: Luis Felipe Risch <lfr20@inf.ufpr.br> Date: Thu, 20 May 2021 13:14:16 -0300 Subject: [PATCH 10/12] Add maintence banner in the top of the page --- src/App.js | 3 +++ src/Components/maintenance.js | 19 +++++++++++++++++++ 2 files changed, 22 insertions(+) create mode 100644 src/Components/maintenance.js diff --git a/src/App.js b/src/App.js index dda0148c..c9742324 100644 --- a/src/App.js +++ b/src/App.js @@ -52,6 +52,7 @@ import CollectionPage from "./Pages/CollectionPage.js"; import FormationMaterialPage from "./Pages/FormationMaterialPage.js"; import FormationMaterialIframe from "./Pages/FormationMaterialIframe.js"; import MaterialPage from "./Pages/MaterialPage"; +import Maintence from './Components/maintenance' import NoteVariables from "./Admin/Pages/Pages/SubPages/NoteVariables"; import Institution from "./Admin/Pages/Pages/SubPages/Institutions"; @@ -92,6 +93,7 @@ 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 AppBarAdmin from './Admin/Components/Components/AppBar' +import Maintenance from "./Components/maintenance"; export default function App() { // eslint-disable-next-line @@ -147,6 +149,7 @@ export default function App() { return ( <BrowserRouter basename="/react"> + <Maintenance /> <Header /> <div style={{ diff --git a/src/Components/maintenance.js b/src/Components/maintenance.js new file mode 100644 index 00000000..f39358e4 --- /dev/null +++ b/src/Components/maintenance.js @@ -0,0 +1,19 @@ +import React from 'react' +import styled from 'styled-components' + +export default function Maintenance() { + return ( + <MaintenanceDiv> + Estamos em manuntenção. Em breve voltaremos! + </MaintenanceDiv> + ) +} + +const MaintenanceDiv = styled.div` + z-index: 1000; + position: fixed; + color:white; + background-color: red; + text-align: center; + width: 100%; +` \ No newline at end of file -- GitLab From bff63bcb98f9211f8ce95c3a8ddab30ff785873f Mon Sep 17 00:00:00 2001 From: Luis Felipe Risch <lfr20@inf.ufpr.br> Date: Thu, 20 May 2021 13:14:58 -0300 Subject: [PATCH 11/12] Changed to production --- src/env.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 From 49e75bf942cbefa0506544f180d207e3345f061b Mon Sep 17 00:00:00 2001 From: Luis Felipe Risch <lfr20@inf.ufpr.br> Date: Thu, 20 May 2021 13:15:18 -0300 Subject: [PATCH 12/12] fixed Cadastre-Se to Cadastre-se --- src/Components/MenuBar.js | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/Components/MenuBar.js b/src/Components/MenuBar.js index 0f1b536b..7cf1153b 100644 --- a/src/Components/MenuBar.js +++ b/src/Components/MenuBar.js @@ -107,7 +107,7 @@ export default function MenuBar(props) { { name: "Favoritos", href: "/perfil", value: '2' }, { name: "Coleções", href: "/perfil", value: '3' }, { name: "Rede", href: "/perfil", value: '4' }, - { name: "Configurações", href: "/editarperfil", value: '5'}, + { name: "Configurações", href: "/editarperfil", value: '5' }, ] if (state.currentUser.roles) { @@ -116,15 +116,15 @@ export default function MenuBar(props) { const userRoles = [...state.currentUser.roles] while (!canUserAdmin && index < userRoles.length) { - if(userRoles[index].id === 3 || userRoles[index].id === 7) + if (userRoles[index].id === 3 || userRoles[index].id === 7) canUserAdmin = true index++ } - - if(canUserAdmin) + + if (canUserAdmin) minhaArea.push({ - name: "Administrador", - href: "/admin/home", + name: "Administrador", + href: "/admin/home", value: '6', }) } @@ -186,14 +186,14 @@ export default function MenuBar(props) { </div> <MenuList items={minhaArea} /> - + </> ) : ( <React.Fragment> <ButtonPubRecursoStyled onClick={props.openLogin}>PUBLICAR RECURSO?</ButtonPubRecursoStyled> <ButtonStyled onClick={props.openLogin}><ExitToAppIcon style={{ color: "#00bcd4" }} />Entrar</ButtonStyled> - <ButtonStyled onClick={props.openSignUp}>Cadastre-se</ButtonStyled> + <ButtonStyled onClick={props.openSignUp}>Cadastre-<span style={{textTransform: 'lowercase'}}>se</span></ButtonStyled> </React.Fragment> ) } -- GitLab