From 84efe671070f209c9d87094e5a80c33174186edc Mon Sep 17 00:00:00 2001 From: Lucas Schoenfelder <les17@inf.ufpr.br> Date: Tue, 11 Feb 2020 10:03:19 -0300 Subject: [PATCH] layout de edicao de perfil pronto; falta adicionar as rotas --- src/Components/LoginContainerFunction.js | 4 +- src/Components/LoginModal.js | 2 +- src/Components/MenuBar.js | 12 +- src/Components/MenuList.js | 7 +- src/Components/SignUpContainerFunction.js | 2 +- .../TabPanels/TabPanelAtividades.js | 4 +- .../TabPanels/TabPanelEditarPerfil.js | 38 +-- .../TabPanels/TabPanelGerenciarConta.js | 235 +++++++++++++++++- .../TabPanelSolicitarContaProfessor.js | 113 ++++++++- src/Pages/EditProfilePage.js | 91 ++++++- src/Pages/RecuperarSenha.js | 0 src/Pages/UserPage.js | 6 +- src/Store.js | 3 +- 13 files changed, 455 insertions(+), 62 deletions(-) create mode 100644 src/Pages/RecuperarSenha.js diff --git a/src/Components/LoginContainerFunction.js b/src/Components/LoginContainerFunction.js index aae88a65..5a0301f1 100644 --- a/src/Components/LoginContainerFunction.js +++ b/src/Components/LoginContainerFunction.js @@ -35,7 +35,7 @@ function validateUserInput(type, input) { } } else if (type === 'senha') { - if(input.length < 1) { + if(input.length < 8) { flag = true } } @@ -170,7 +170,7 @@ export default function LoginContainer (props) { handleChange={e => handleChange(e, 'senha')} required={true} error = {formSenha.dict.key} - help = {formSenha.dict.key ? "Faltou digitar sua senha." : ""} + help = {formSenha.dict.key ? (formSenha.dict.value.length == 0 ? "Faltou digitar sua senha." : "A senha precisa ter no mÃnimo 8 caracteres.") : ""} /> <br/> diff --git a/src/Components/LoginModal.js b/src/Components/LoginModal.js index 90601b64..9c41e3e1 100644 --- a/src/Components/LoginModal.js +++ b/src/Components/LoginModal.js @@ -40,7 +40,7 @@ const StyledLogin = styled(Modal)` border-radius : 4px; ` -function Alert(props) { +export function Alert(props) { return <MuiAlert elevation={6} variant="filled" {...props} />; } diff --git a/src/Components/MenuBar.js b/src/Components/MenuBar.js index 0b13e96a..f9e0a187 100644 --- a/src/Components/MenuBar.js +++ b/src/Components/MenuBar.js @@ -109,12 +109,12 @@ export default function MenuBar(props){ ] const minhaArea = [ - { name: "Perfil e Atividades", href: "/perfil"}, - { name: "Recursos Publicados", href: "/perfil/recursos-publicados"}, - { name: "Favoritos", href: "/perfil/favoritos"}, - { name: "Coleções", href: "/perfil/colecoes"}, - { name: "Rede", href: "/perfil/rede"}, - { name: "Configurações", href: "/perfil/cofiguracoes/editarperfil"}, + { name: "Perfil e Atividades", href: "/perfil", value : '0'}, + { name: "Recursos Publicados", href: "/perfil", value : '1'}, + { name: "Favoritos", href: "/perfil", value : '2'}, + { name: "Coleções", href: "/perfil", value : '3'}, + { name: "Rede", href: "/perfil", value : '4'}, + { name: "Configurações", href: "/editarperfil"}, ] return( diff --git a/src/Components/MenuList.js b/src/Components/MenuList.js index 910af9cf..d3f2a6ea 100644 --- a/src/Components/MenuList.js +++ b/src/Components/MenuList.js @@ -108,8 +108,11 @@ export default function MenuList(props) { { props.items.map((item)=> - <Link key={item.name} to={item.href} style={{textDecoration:"none"}} ><MenuItem style= {{fontSize:"14px", padding:"5px 20px", color:"#666"}}>{item.name}</MenuItem></Link> - ) + <Link to={{ + pathname : item.href, + state : item.value + }} style={{textDecoration:"none"}} ><MenuItem style= {{fontSize:"14px", padding:"5px 20px", color:"#666"}}>{item.name}</MenuItem></Link> + ) } <StyledButtonSair onClick={handleLogout}> <StyledMenuItem disableGutters={true}>Sair<StyledExitToAppIcon/></StyledMenuItem></StyledButtonSair> diff --git a/src/Components/SignUpContainerFunction.js b/src/Components/SignUpContainerFunction.js index 23e63006..84817081 100644 --- a/src/Components/SignUpContainerFunction.js +++ b/src/Components/SignUpContainerFunction.js @@ -46,7 +46,7 @@ function validateUserInput(type, input) { } } else if (type === 'senha') { - if(input.length < 1) { + if(input.length < 8) { flag = true } } diff --git a/src/Components/TabPanels/TabPanelAtividades.js b/src/Components/TabPanels/TabPanelAtividades.js index 5e416be8..eda3b1e5 100644 --- a/src/Components/TabPanels/TabPanelAtividades.js +++ b/src/Components/TabPanels/TabPanelAtividades.js @@ -17,9 +17,9 @@ export default function TabPanelAtividades (props) { axios.get(`${apiUrl}/feed`, props.config) .then( (response) => { handleLoading(false) - console.log(response) + //console.log(response) setNotifications(response.data) - console.log(response.data.length) + //console.log(response.data.length) setLength(response.data.length) }, (error) => { diff --git a/src/Components/TabPanels/TabPanelEditarPerfil.js b/src/Components/TabPanels/TabPanelEditarPerfil.js index e2503a72..67fc6a10 100644 --- a/src/Components/TabPanels/TabPanelEditarPerfil.js +++ b/src/Components/TabPanels/TabPanelEditarPerfil.js @@ -97,9 +97,9 @@ export default function TabPanelEditarPerfil (props) { } return ( - <ContainerDIv> - <h1 style={{fontSize:"30px", fontWeight:"300", marginTop:"0", marginBottom:"10px"}}>Editar Perfil </h1> - <ContentDiv> + <div className="card-config"> + <h1 style={{fontWeight:"300"}}>Editar Perfil </h1> + <div className='content-div'> <div style={{padding:"0", display:"flex", flexDirection:"column"}}> <HeaderContainer> <div style={{position:"relative", height:"100%"}}> @@ -158,8 +158,8 @@ export default function TabPanelEditarPerfil (props) { <ButtonConfirmar onClick={e => handleSubmit(e)}><span>SALVAR ALTERAÇÕES</span></ButtonConfirmar> </ButtonsDiv> </div> - </ContentDiv> - </ContainerDIv> + </div > + </div> ) } @@ -196,7 +196,7 @@ const ButtonConfirmar = styled(Button)` border : 0 !important; ` -const ButtonCancelar = styled(Button)` +export const ButtonCancelar = styled(Button)` height : 36px !important; padding-left : 16px !important; padding-right : 16px !important; @@ -269,29 +269,3 @@ const HeaderContainer = styled.div` height : 150px; border-radius : 8px; ` - -const ContentDiv = styled.div` - display : flex; - flex-direction : column; - align-content : stretch; - align-items : stretch; - font-family : 'Roboto', sans serif !important; - font-size : 14px; - justify-content : center; - line-height : 20px; - text-align : center; - color : #666; -` - -const ContainerDIv = styled.div` - box-shadow : 0 0 5px 0rgba(0,0,0,.25); - background-color : #fff; - text-align : start; - margin-left : auto; - margin-right : auto; - padding : 40px; - margin : 20px 0 20px 10px; - border-radius : 3px; - display : flex; - flex-direction : column; -` diff --git a/src/Components/TabPanels/TabPanelGerenciarConta.js b/src/Components/TabPanels/TabPanelGerenciarConta.js index cb552890..0c94d8b7 100644 --- a/src/Components/TabPanels/TabPanelGerenciarConta.js +++ b/src/Components/TabPanels/TabPanelGerenciarConta.js @@ -1,7 +1,238 @@ -import React from 'react' +import React, {useState} from 'react' +import Paper from '@material-ui/core/Paper'; +import Button from '@material-ui/core/Button'; +import FormInput from "../FormInput.js" +import {CompletarCadastroButton} from './TabPanelSolicitarContaProfessor.js' +import {ButtonCancelar} from './TabPanelEditarPerfil.js' + +function validateUserInput(type, input, confirmation) { + let flag = false + + if (type === 'senha') { + if(input.length < 8) { + flag = true + } + } + else if (type === 'confirmacao') { + if (input !== confirmation) + flag = true + } + + return flag +} + +function validateUserEmail(input) { + let flag = false + + if(input.split("").filter(x => x === "@").length !== 1 || !(input.match(/^([\w.%+-]+)@([\w-]+\.)+([\w]{2,})$/i))) { + flag = true + } + return flag +} export default function TabPanelGerenciarConta (props) { + const [senhaAtual, setSenhaAtual] = useState( + { + dict : { + key : false, + value : localStorage.getItem("@portalmec/senha") || "" + } + } + ) + + const [novaSenha, setNovaSenha] = useState( + { + dict : { + key : false, + value : "" + } + } + ) + + const [novaSenhaConfirmacao, setNovaSenhaConfirmacao] = useState( + { + dict : { + key : false, + value : "" + } + } + ) + + const [novoEmail, setNovoEmail] = useState( + { + dict : { + key : false, + value : "" + } + } + ) + + const handleChangeSenha = (e, type) => { + const userInput = e.target.value + const flag = (type === 'confirmacao' ? validateUserInput('confirmacao', userInput, novaSenha.dict.value) : validateUserInput('senha', userInput, '')) + + if(type === 'senhaAtual') { + setSenhaAtual({...senhaAtual, dict : { + key : flag, + value : userInput + }}) + console.log(senhaAtual) + } + else if(type === 'novaSenha') { + setNovaSenha({...novaSenha, dict : { + key : flag, + value : userInput + }}) + console.log(novaSenha) + } + else if (type === 'confirmacao'){ + setNovaSenhaConfirmacao({...novaSenhaConfirmacao, dict : { + key : flag, + value : userInput + }}) + console.log(novaSenhaConfirmacao) + } + } + + const handleChangeEmail = (e) => { + const userInput = e.target.value + const flag = validateUserEmail(userInput) + + setNovoEmail({...novoEmail, dict : { + key : flag, + value : userInput + }}) + + console.log(novoEmail) + } + + const limpaCamposForm = () => { + setSenhaAtual({...senhaAtual, dict : { + key : false, + value : '' + }}) + + setNovaSenha({...novaSenha, dict : { + key : false, + value : '' + }}) + + setNovaSenhaConfirmacao({...novaSenhaConfirmacao, dict : { + key : false, + value : '' + }}) + } + + const onSubmit = (e, type) => { + e.preventDefault() + + if (type === 'senha'){ + if (senhaAtual.dict.value === localStorage.getItem("@portalmec/senha")) { + const login = {senhaAtual : senhaAtual.dict.value, novaSenha : novaSenha.dict.value, novaSenhaConfirmacao : novaSenhaConfirmacao.dict.value} + + if (!(senhaAtual.dict.key || novaSenha.dict.key || novaSenhaConfirmacao.dict.key)) { + console.log(login) + limpaCamposForm() + props.handleSnackbar() + } + } + else { + console.log(localStorage.getItem("@portalmec/senha"), senhaAtual.dict.value) + } + } + else { + console.log(novoEmail.dict.value) + } + + } + return ( - <span>a</span> + <> + <Paper elevation={3} style= {{width:"100%"}}> + <div className='card-config'> + <div className='content-div'> + <h1>Gerenciar Conta</h1> + <div style={{display : "flex", flexDirection : "column"}}> + <form style={{width:"500px", margin : "0 0 20px 0"}} onSubmit={e => onSubmit(e, 'senha')}> + <h4 style={{display:"flex", justifyContent:"flex-start", fontSize:"18px"}}>Alterar Senha</h4> + <FormInput + inputType={"password"} + name={"Senha Atual"} + value={senhaAtual.dict.value} + placeholder={"Senha atual"} + handleChange={e => handleChangeSenha(e, 'senhaAtual')} + required={true} + error={senhaAtual.dict.key} + help={ senhaAtual.dict.key ? "Faltou inserir sua senha atual" : ""} + /> + <FormInput + inputType={"password"} + name={"Nova senha"} + value={novaSenha.dict.value} + placeholder={"Nova senha"} + handleChange={e => handleChangeSenha(e, 'novaSenha')} + required={true} + error={novaSenha.dict.key} + help={ novaSenha.dict.key ? (novaSenha.dict.value.length == 0 ? "Faltou definir uma nova senha" : "A senha precisa ter no mÃnimo 8 caracteres.") : ""} + /> + <FormInput + inputType={"password"} + name={"Digite novamente a nova senha"} + value={novaSenhaConfirmacao.dict.value} + placeholder={"Digite novamente a nova senha"} + handleChange={e => handleChangeSenha(e, 'confirmacao')} + required={true} + error={novaSenhaConfirmacao.dict.key} + help={ novaSenhaConfirmacao.dict.key ? "As senhas devem ser iguais" : ""} + /> + <div style={{display:"flex", flexDirection:"row", justifyContent:"space-evenly"}}> + <span style={{paddingTop:"0.7em"}}><a href="recuperar-senha" style={{textAlign: "flex-start", color:"#00bcd4"}}>Esqueceu a senha?</a></span> + <div style={{margin:"0"}}> + <ButtonCancelar onClick={limpaCamposForm}>Limpar Campos</ButtonCancelar> + <CompletarCadastroButton type="submit">Alterar Senha</CompletarCadastroButton> + </div> + </div> + </form> + </div> + </div> + </div> + </Paper> + <Paper elevation={3} style= {{width:"100%"}}> + <div className='card-config'> + <div className='content-div'> + <div style={{display : "flex", flexDirection : "column"}}> + <form style={{width:"500px"}} onSubmit={(e) => onSubmit(e, 'email')}> + <h4 style={{display:"flex", justifyContent:"flex-start", fontSize:"18px"}}>Alterar e-mail</h4> + <FormInput + inputType={"text"} + name={"email"} + value={novoEmail.dict.value} + placeholder={"E-mail"} + handleChange={e => handleChangeEmail(e)} + required={true} + error = {novoEmail.dict.key} + /> + <div style={{margin:"0", display:"flex", justifyContent:"flex-start"}}> + <CompletarCadastroButton type="submit">SALVAR ALTERAÇÕES</CompletarCadastroButton> + </div> + </form> + </div> + </div> + </div> + </Paper> + <Paper elevation={3} style= {{width:"100%"}}> + <div className='card-config'> + <div className='content-div'> + <div> + <h4 style={{display:"flex", justifyContent:"flex-start", fontSize:"18px"}}>Conta</h4> + <span style={{margin:"0", display:"flex", justifyContent:"flex-start"}}>Antes de excluir a sua conta, saiba que ela será removida permanentemente.</span> + </div> + <div style={{margin:"0", display:"flex", justifyContent:"flex-start"}}> + <ButtonCancelar style={{color:'#eb4034'}}>EXCLUIR CONTA</ButtonCancelar> + </div> + </div> + </div> + </Paper> + </> ) } diff --git a/src/Components/TabPanels/TabPanelSolicitarContaProfessor.js b/src/Components/TabPanels/TabPanelSolicitarContaProfessor.js index c350edba..cd461887 100644 --- a/src/Components/TabPanels/TabPanelSolicitarContaProfessor.js +++ b/src/Components/TabPanels/TabPanelSolicitarContaProfessor.js @@ -1,7 +1,116 @@ -import React from 'react' +import React, {useContext} from 'react' +import { Store } from '../../Store.js'; +import styled from 'styled-components' +import Button from '@material-ui/core/Button'; +//3 casos + //Professor nao cadastrado (nao pediu OU submitter_request = rejected) + //Professor em análise (submitter_request = requested) + //Professor aceito (submitter_request = accepted) export default function TabPanelSolicitarContaProfessor (props) { + const {state, dispatch} = useContext(Store) + return ( - <span>a</span> + <div className='card-config'> + <div className='content-div'> + { + state.currentUser.submitter_request == 'default' || state.currentUser.submitter_request == 'rejected' ? + ( + [ + <div style={{paddingLeft:"100px", paddingRight:"101px"}}> + <ImageDiv/> + <StyledH2>Você é professor(a) da educação básica e gostaria de colaborar com a Plataforma?</StyledH2> + <StyledP>Ao ser identificado como professor(a), você poderá publicar e compartilhar recursos educacionais + digitais na plataforma com toda a comunidade escolar do paÃs. + </StyledP> + <div> + <CompletarCadastroButton> + SIM, COMPLETAR CADASTRO + </CompletarCadastroButton> + </div> + </div> + ] + ) + : + ( + [ + <> + { + state.currentUser.submitter_request == 'requested' ? + ( + [ + <span>Requested</span> + ] + ) + : + ( + [ + <span>Professor</span> + ] + ) + } + </> + ] + ) + } + </div> + </div> ) } + +export const CompletarCadastroButton = styled(Button)` + background-color : #00bcd4 !important; + color : #fff !important; + font-family : 'Roboto',sans-serif !important; + font-size : 14px !important; + font-weight : bold !important; + height : 36px !important; + border-radius : 3px !important; + padding-left : 16px !important; + padding-right : 16px !important; + outline : none !important; + margin : 6px 8px !important; + white-space : nowrap !important; + text-transform : uppercase !important; + font-weight : bold !important; + font-size : 14px !important; + font-style : inherit !important; + font-variant : inherit !important; + font-family : inherit !important; + text-decoration : none !important; + overflow : hidden !important; + display : inline-block !important; + position : relative !important; + cursor : pointer !important; + min-height : 36px !important; + min-width : 88px !important; + vertical-align : middle !important; + align-items : center !important; + text-align : center !important; + box-sizing : border-box !important; + border : 0 !important; +` + +const StyledP = styled.p` + font-size : 15px; + line-height : 22px; + text-align : left; + padding-bottom : 20px; +` + +const StyledH2 = styled.h2` + font-weight : 200; + font-size : 26px; + line-height : 36px; + text-align : left; + padding-bottom : 20px; +` + +const ImageDiv = styled.div` + background-image : url(https://plataformaintegrada.mec.gov.br/img/Publicar.png); + display : block; + height : 114px; + background-size : contain; + background-position : center center; + background-repeat : no-repeat; +` diff --git a/src/Pages/EditProfilePage.js b/src/Pages/EditProfilePage.js index f3f4e041..59ee4f37 100644 --- a/src/Pages/EditProfilePage.js +++ b/src/Pages/EditProfilePage.js @@ -9,6 +9,10 @@ import Paper from '@material-ui/core/Paper'; import TabPanelEditarPerfil from '../Components/TabPanels/TabPanelEditarPerfil.js' import TabPanelSolicitarContaProfessor from '../Components/TabPanels/TabPanelSolicitarContaProfessor.js' import TabPanelGerenciarConta from '../Components/TabPanels/TabPanelGerenciarConta.js' +import Snackbar from '@material-ui/core/Snackbar'; +import MuiAlert from '@material-ui/lab/Alert'; +import {Alert} from '../Components/LoginModal.js' +import Grid from '@material-ui/core/Grid' export default function EditProfilePage (props) { const [tabs, setTabs] = useState([ @@ -19,8 +23,21 @@ export default function EditProfilePage (props) { setTabValue(newValue) } + const [snackbarOpened, handleSnackbar] = useState(false) + const handleCloseSnackbar = (event, reason) => { + if (reason === 'clickaway') { + return; + } + + handleSnackbar(false); + } return ( <div style={{backgroundColor:"#f4f4f4", color:"#666"}}> + <Snackbar open={snackbarOpened} autoHideDuration={1000} onClose={handleCloseSnackbar} + anchorOrigin = {{ vertical:'top', horizontal:'right' }} + > + <Alert severity="success" style={{backgroundColor:"#00acc1"}}>Senha alterada com sucesso!</Alert> + </Snackbar> <BreadcrumbsDiv> <StyledBreadcrumbs> <Link to="/" style={{color:"#00bcd4", textDecoration:"none"}}> @@ -38,8 +55,9 @@ export default function EditProfilePage (props) { </StyledBreadcrumbs> </BreadcrumbsDiv> - <MainContainerDiv> - <div style={{width : "auto", fontFamily:"Roboto"}}> + <div style={{justifyContent:"center", width:"1170px", margin:"auto"}}> + <MainContainerDiv container spacing={3}> + <Grid item xs={3} style={{width : "auto", fontFamily:"Roboto"}} > <Paper elevation={3} style= {{width:"max-content"}}> <ConfiguracoesMenu> <h4 style={{marginTop:"10px", fontFamily:"inherit", display:"flex", justifyContent:"center"}}> @@ -58,19 +76,74 @@ export default function EditProfilePage (props) { </StyledTabs> </ConfiguracoesMenu> </Paper> - </div> - <div style={{width : "auto", paddingLeft:"1em"}}> - <Paper elevation={3} style= {{width:"max-content"}}> - {tabValue === 0 && <TabPanelEditarPerfil/>} + </Grid> + <TabContentDiv item xs={9}> + <Paper elevation={3} style= {{width:"100%"}}> + {tabValue === 0 && <TabPanelEditarPerfil />} {tabValue === 1 && <TabPanelSolicitarContaProfessor/>} - {tabValue === 2 && <TabPanelGerenciarConta/>} </Paper> - </div> + {tabValue === 2 && <TabPanelGerenciarConta handleSnackbar={() => {handleSnackbar(true)}}/>} + </TabContentDiv> </MainContainerDiv> + </div> </div> ) } +const TabContentDiv = styled(Grid)` + width : auto; + + .card-config { + padding : 40px; + margin : 20px 0 20px 10px; + border-radius : 3px; + box-shadow : 0 0 5px 0rgba(0,0,0,.25); + background-color : #fff; + text-align : start; + margin-left : auto; + margin-right : auto; + display : flex; + flex-direction : column; + } + + .content-div { + display : flex; + flex-direction : column; + align-content : stretch; + align-items : stretch; + font-family : 'Roboto', sans serif !important; + font-size : 14px; + justify-content : center; + line-height : 20px; + text-align : center; + color : #666; + } + + .h2 { + margin-top : 20px; + margin-bottom : 10px; + } + + .p { + margin : 0 0 10px; + } + + .h1 { + font-size : 30px; + font-weight : 300; + margin-top : 0; + margin-bottom : 10px; + } + + .h4 { + font-size : 18px; + margin-top : 10px; + margin-bottom : 10px; + font-weight : 500; + line-height : 1.1; + } +` + const StyledTabs = styled(Tabs)` .Mui-selected { background-color : #f4f4f4; @@ -91,7 +164,7 @@ const ConfiguracoesMenu = styled.div` text-align : start; ` -const MainContainerDiv = styled.div` +const MainContainerDiv = styled(Grid)` padding : 0; width : 1170; margin-right : auto; diff --git a/src/Pages/RecuperarSenha.js b/src/Pages/RecuperarSenha.js new file mode 100644 index 00000000..e69de29b diff --git a/src/Pages/UserPage.js b/src/Pages/UserPage.js index 2b9ce6e0..28b81c21 100644 --- a/src/Pages/UserPage.js +++ b/src/Pages/UserPage.js @@ -44,7 +44,9 @@ import ModalAlterarAvatar from '../Components/ModalAlterarAvatar.js' export default function UserPage (props){ const {state, dispatch} = useContext(Store) const [hoverAlterarFoto, handleAlterarFoto] = React.useState(false) - const [tabValue, setTabValue] = useState(0); + const [tabValue, setTabValue] = useState( + Number(props.location.state) || 0 + ); const [tabs, setTabs] = useState([ 'Atividades', 'Meus Recursos', 'Favoritos', 'Coleções', 'Rede' ]) @@ -249,7 +251,7 @@ export default function UserPage (props){ } -const HeaderDiv = styled.div` +export const HeaderDiv = styled.div` background-color : #f4f4f4; color : #666; font-size : 14px; diff --git a/src/Store.js b/src/Store.js index 8fc1382a..3225fef5 100644 --- a/src/Store.js +++ b/src/Store.js @@ -46,7 +46,8 @@ const initialState = { userCover : '', uid : '', followCount : 0, - collectionsCount : 0 + collectionsCount : 0, + submitter_request : 'default' } } -- GitLab