diff --git a/package-lock.json b/package-lock.json index 2f3fe024370c53cca58d47ade1263abfa8cf7c9b..8966c047e184beb875625ece3e4010da442722d9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1545,6 +1545,74 @@ "loader-utils": "^1.1.0" } }, + "@syncfusion/ej2-base": { + "version": "18.2.44", + "resolved": "https://registry.npmjs.org/@syncfusion/ej2-base/-/ej2-base-18.2.44.tgz", + "integrity": "sha512-q1aHQr9DXpCQh1iqWsYcIg2eGzsQZXBCu6XvFzMIXp6aWFu6fmW/2WYceg+F5B3cVfo1xCivthdrhlHzxiicGg==", + "requires": { + "@syncfusion/ej2-icons": "~18.2.44" + } + }, + "@syncfusion/ej2-buttons": { + "version": "18.2.44", + "resolved": "https://registry.npmjs.org/@syncfusion/ej2-buttons/-/ej2-buttons-18.2.44.tgz", + "integrity": "sha512-mKhZ8DJEiRHyGdfQgti72Ul0UmTxVgPYzBnpB80/iif67tWsxLnqVJ53CWgxkXJq0fm6fAneIFSXztMffN2fmw==", + "requires": { + "@syncfusion/ej2-base": "~18.2.44" + } + }, + "@syncfusion/ej2-icons": { + "version": "18.2.44", + "resolved": "https://registry.npmjs.org/@syncfusion/ej2-icons/-/ej2-icons-18.2.44.tgz", + "integrity": "sha512-4jOb0RtpTU+s+IXbaQxxcWhFpXXn9aYyakGmrF7A6smbpndM7do28mDybJMFIns/IoRsQokOnrDhqqAIaoDRVQ==" + }, + "@syncfusion/ej2-inputs": { + "version": "18.2.45", + "resolved": "https://registry.npmjs.org/@syncfusion/ej2-inputs/-/ej2-inputs-18.2.45.tgz", + "integrity": "sha512-1lyunOQFT77PXB2gZuJjmgRfyQqFcsTBmj9fGA5PIm5dwipsq4fy6IKOhTMcGCO64q7NZieNXcWOWdSws0lqAQ==", + "requires": { + "@syncfusion/ej2-base": "~18.2.44", + "@syncfusion/ej2-buttons": "~18.2.44", + "@syncfusion/ej2-popups": "~18.2.44", + "@syncfusion/ej2-splitbuttons": "~18.2.44" + } + }, + "@syncfusion/ej2-popups": { + "version": "18.2.44", + "resolved": "https://registry.npmjs.org/@syncfusion/ej2-popups/-/ej2-popups-18.2.44.tgz", + "integrity": "sha512-+1riSvOH+nhoQtRbgX3Yl2W50Ql5YceiaucyQXNV/WKC9JqHuamRj3PINzd11HjAubvkAMOoYLQQ7B7wP4UmaA==", + "requires": { + "@syncfusion/ej2-base": "~18.2.44", + "@syncfusion/ej2-buttons": "~18.2.44" + } + }, + "@syncfusion/ej2-react-base": { + "version": "18.2.44", + "resolved": "https://registry.npmjs.org/@syncfusion/ej2-react-base/-/ej2-react-base-18.2.44.tgz", + "integrity": "sha512-lvIdLzDd2f3V9CEpHBV0FLnJVbb0Nucu7qbdOKQ4dQDRCO0QfM3dqyuC6Wd20R0cyaNGyjucXIpqcueLPtqSvA==", + "requires": { + "@syncfusion/ej2-base": "~18.2.44" + } + }, + "@syncfusion/ej2-react-inputs": { + "version": "18.2.45", + "resolved": "https://registry.npmjs.org/@syncfusion/ej2-react-inputs/-/ej2-react-inputs-18.2.45.tgz", + "integrity": "sha512-lH5e/YNASvqBcXt4ix8YVDv/lWBwM9F7tKiwPXckKnfNX01s2iZg+u+Dw+W3Cj7KIulpg60CHQkFoPtCm2uVkQ==", + "requires": { + "@syncfusion/ej2-base": "~18.2.44", + "@syncfusion/ej2-inputs": "18.2.45", + "@syncfusion/ej2-react-base": "~18.2.44" + } + }, + "@syncfusion/ej2-splitbuttons": { + "version": "18.2.44", + "resolved": "https://registry.npmjs.org/@syncfusion/ej2-splitbuttons/-/ej2-splitbuttons-18.2.44.tgz", + "integrity": "sha512-zR/q7OTow5CtV3ZJ2mTHdOhkYr6TeWTg3I4I47lee+6H9EFrryURmi3iyhVHaLQEG/RHW7o53kr9d7qqQwyFyQ==", + "requires": { + "@syncfusion/ej2-base": "~18.2.44", + "@syncfusion/ej2-popups": "~18.2.44" + } + }, "@types/parse-json": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", @@ -6431,6 +6499,26 @@ "locate-path": "^2.0.0" } }, + "fine-uploader": { + "version": "5.16.2", + "resolved": "https://registry.npmjs.org/fine-uploader/-/fine-uploader-5.16.2.tgz", + "integrity": "sha1-DYeNoc0nU/gGg6wJHfXa/5/7jEQ=" + }, + "fine-uploader-wrappers": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/fine-uploader-wrappers/-/fine-uploader-wrappers-1.0.1.tgz", + "integrity": "sha1-BEqUMgdr0CrBQEhm7G4Zf8Zi/L8=", + "requires": { + "object-assign": "4.1.0" + }, + "dependencies": { + "object-assign": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.0.tgz", + "integrity": "sha1-ejs9DpgGPUP0wD8uiubNUahog6A=" + } + } + }, "flat-cache": { "version": "1.3.4", "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.4.tgz", @@ -13958,6 +14046,37 @@ "resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-5.1.6.tgz", "integrity": "sha512-X1Y+0jR47ImDVr54Ab6V9eGk0Hnu7fVWGeHQSOXHf/C2pF9c6uy3gef8QUeuUiWlNb0i08InPSE5a/KJzNzw1Q==" }, + "react-fine-uploader": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/react-fine-uploader/-/react-fine-uploader-1.1.1.tgz", + "integrity": "sha512-aUOZO3Wr8OynK2LyF2QMPHSe6gWSonNyk/hgo6olBRim92T/sa07pcy/sR2ljucrv9IaJC61Qb8ZGGfcs/I82A==", + "requires": { + "fine-uploader-wrappers": "^1.0.1", + "object-assign": "4.1.1", + "react-transition-group": "2.x" + }, + "dependencies": { + "dom-helpers": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-3.4.0.tgz", + "integrity": "sha512-LnuPJ+dwqKDIyotW1VzmOZ5TONUN7CwkCR5hrgawTUbkBGYdeoNLZo6nNfGkCrjtE1nXXaj7iMMpDa8/d9WoIA==", + "requires": { + "@babel/runtime": "^7.1.2" + } + }, + "react-transition-group": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-2.9.0.tgz", + "integrity": "sha512-+HzNTCHpeQyl4MJ/bdE0u6XRMe9+XG/+aL4mCxVN4DnPBQ0/5bfHWPDuOZUzYdMj94daZaZdCCc1Dzt9R/xSSg==", + "requires": { + "dom-helpers": "^3.4.0", + "loose-envify": "^1.4.0", + "prop-types": "^15.6.2", + "react-lifecycles-compat": "^3.0.4" + } + } + } + }, "react-google-login": { "version": "5.1.20", "resolved": "https://registry.npmjs.org/react-google-login/-/react-google-login-5.1.20.tgz", @@ -14007,6 +14126,11 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, + "react-lifecycles-compat": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz", + "integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==" + }, "react-recaptcha": { "version": "2.3.10", "resolved": "https://registry.npmjs.org/react-recaptcha/-/react-recaptcha-2.3.10.tgz", diff --git a/package.json b/package.json index 5eca8c3bbe67d01931459ffcec7546c473c1fe7b..717525b3312961c92fe54772ca13bb3d873f9a20 100644 --- a/package.json +++ b/package.json @@ -7,10 +7,12 @@ "@material-ui/icons": "^4.5.1", "@material-ui/lab": "^4.0.0-alpha.40", "@material-ui/styles": "^4.9.0", + "@syncfusion/ej2-react-inputs": "^18.2.45", "axios": "^0.19.2", "base64-img": "^1.0.4", "binary-extensions": "^2.0.0", "build": "^0.1.4", + "fine-uploader": "^5.16.2", "image-to-base64": "^2.0.1", "material-design-icons": "^3.0.1", "moment": "^2.24.0", @@ -18,6 +20,7 @@ "react-dom": "^16.12.0", "react-dropdown": "^1.7.0", "react-easy-crop": "^2.1.0", + "react-fine-uploader": "^1.1.1", "react-google-login": "^5.0.7", "react-grid-system": "^4.4.11", "react-icons": "^3.8.0", diff --git a/src/Components/AreasSubPages.js b/src/Components/AreasSubPages.js index 1a7627cc8b2dd1551225884705c2fe3a844c309d..f911ec1d0d1058885610be48f29f8b8387635106 100644 --- a/src/Components/AreasSubPages.js +++ b/src/Components/AreasSubPages.js @@ -69,48 +69,55 @@ class ReqResources extends Component { {row1.map(card => <Col md={3} sm={6} key={card.id}> <ResourceCardFunction avatar = {card.publisher.avatar} + id={card.id} thumbnail = {card.thumbnail} type = {card.object_type ? card.object_type : "Outros"} title={card.name} published={card.state === "published" ? true : false} likeCount={card.likes_count} liked={card.liked} - rating={card.score} + rating={card.review_average} author={card.author} tags={card.educational_stages} href={'/recurso/' + card.id} + downloadableLink={card.default_attachment_location} /></Col>)} </Row> <Row> {row2.map(card => <Col md={3} sm={6} key={card.id}> <ResourceCardFunction avatar = {card.publisher.avatar} + id={card.id} thumbnail = {card.thumbnail} type = {card.object_type ? card.object_type : "Outros"} title={card.name} published={card.state === "published" ? true : false} likeCount={card.likes_count} liked={card.liked} - rating={card.score} + rating={card.review_average} author={card.author} tags={card.educational_stages} href={'/recurso/' + card.id} + downloadableLink={card.default_attachment_location} + /></Col>)} </Row> <Row> {row3.map(card => <Col md={3} sm={6} key={card.id}> <ResourceCardFunction avatar = {card.publisher.avatar} + id={card.id} thumbnail = {card.thumbnail} type = {card.object_type ? card.object_type : "Outros"} title={card.name} published={card.state === "published" ? true : false} likeCount={card.likes_count} liked={card.liked} - rating={card.score} + rating={card.review_average} author={card.author} tags={card.educational_stages} href={'/recurso/' + card.id} + downloadableLink={card.default_attachment_location} /></Col>)} </Row> diff --git a/src/Components/ButtonGuardarColecao.js b/src/Components/ButtonGuardarColecao.js index fd13f0da5a618b0793968ae0aab505c7f4ea510c..65ae71a2ab7c2de703e21e81679c32f7c4454481 100644 --- a/src/Components/ButtonGuardarColecao.js +++ b/src/Components/ButtonGuardarColecao.js @@ -1,14 +1,31 @@ -import React from 'react' +import React, {useState, useContext} from 'react' +import {Store} from '../Store.js' import Button from '@material-ui/core/Button'; import styled from 'styled-components' import CreateNewFolderIcon from '@material-ui/icons/CreateNewFolder'; +import GuardarModal from './GuardarModal' export default function ButtonGuardarColecao (props) { - {/*add function*/} + const {state} = useContext(Store) + const [saveToCol, toggleSave] = useState(false) + const handleGuardar = () => { + if(state.currentUser.id === '') { + console.log('abrir login modal'); + } + else { + toggleSave(true); + } + } + return ( - <StyledButton> + <> + <GuardarModal open={saveToCol} handleClose={() => {toggleSave(false)}} + thumb={props.thumb} title={props.title} recursoId={props.learningObjectId} + /> + <StyledButton onClick={handleGuardar}> <CreateNewFolderIcon/> GUARDAR </StyledButton> + </> ) } diff --git a/src/Components/CardOptions.js b/src/Components/CardOptions.js index 6e06eeabf551fb935694870709011fff0f6080bc..4c10b4239ef6950f63020e83d6f3631c81fb3e96 100644 --- a/src/Components/CardOptions.js +++ b/src/Components/CardOptions.js @@ -27,6 +27,7 @@ import DownloadIcon from '@material-ui/icons/CloudDownload'; import ShareIcon from '@material-ui/icons/Share'; import AddIcon from '@material-ui/icons/CreateNewFolder'; import ReportIcon from '@material-ui/icons/Error'; + export default function SimpleMenu() { const [anchorEl, setAnchorEl] = React.useState(null); @@ -51,30 +52,25 @@ export default function SimpleMenu() { onClose={handleClose} > <MenuItem onClick={handleClose}> - <ListItemIcon> - <OpenIcon /> - </ListItemIcon> - Abrir</MenuItem> + <ListItemIcon><OpenIcon /></ListItemIcon>Abrir + </MenuItem> + <MenuItem onClick={handleClose}> - <ListItemIcon> - <DownloadIcon /> - </ListItemIcon> - Baixar</MenuItem> + <ListItemIcon><DownloadIcon /></ListItemIcon>Baixar + </MenuItem> + <MenuItem onClick={handleClose}> - <ListItemIcon> - <ShareIcon /> - </ListItemIcon> - Compartilhar</MenuItem> + <ListItemIcon><ShareIcon /></ListItemIcon>Compartilhar + </MenuItem> + <MenuItem onClick={handleClose}> - <ListItemIcon> - <AddIcon /> - </ListItemIcon> - Guardar</MenuItem> + <ListItemIcon><AddIcon /></ListItemIcon>Guardar + </MenuItem> + <MenuItem onClick={handleClose}> - <ListItemIcon> - <ReportIcon /> - </ListItemIcon> - Reportar</MenuItem> + <ListItemIcon><ReportIcon /></ListItemIcon>Reportar + </MenuItem> + </Menu> </div> ); diff --git a/src/Components/CloseModalButton.js b/src/Components/CloseModalButton.js index 59e5c46c4e417fd8cd6c241139bc409ed3067b25..00e8b3c34553c1ced9ba1b6e397fd5f404ef571d 100644 --- a/src/Components/CloseModalButton.js +++ b/src/Components/CloseModalButton.js @@ -15,7 +15,7 @@ const StyledCloseModalButton = styled(Button)` display : inline-block; position : relative; float : right !important; - margin-right : -8px !important; + margin-right : 4px !important; background : transparent !important; min-width: 0 !important; width : 40px; diff --git a/src/Components/ColCardOwnerOptions.js b/src/Components/ColCardOwnerOptions.js new file mode 100644 index 0000000000000000000000000000000000000000..76b5b750be97631f4262bc89408dac4524116fdb --- /dev/null +++ b/src/Components/ColCardOwnerOptions.js @@ -0,0 +1,94 @@ +/*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, {useState} from 'react'; +import Button from '@material-ui/core/Button'; +import Menu from '@material-ui/core/Menu'; +import ListItemIcon from '@material-ui/core/ListItemIcon'; +import MenuItem from '@material-ui/core/MenuItem'; +import OpenIcon from '@material-ui/icons/OpenInNew'; +import CreateIcon from '@material-ui/icons/Create'; +import DeleteForeverIcon from '@material-ui/icons/DeleteForever'; +import {Link} from 'react-router-dom' +import MoreVertIcon from '@material-ui/icons/MoreVert'; +import styled from 'styled-components' +import ModalExcluirColecao from './ModalExcluirColecao.js' + +export default function ColCardOwnerOptions (props) { + const [anchorEl, setAnchorEl] = React.useState(null); + + function handleClick(event) { + setAnchorEl(event.currentTarget); + } + + function handleClose() { + setAnchorEl(null); + } + + const [modalExcluirOpen, toggleModalExcluir] = useState(false) + const openModalExcluir = () => {toggleModalExcluir(true)} + + return ( + <> + <ModalExcluirColecao id={props.id} + open={modalExcluirOpen} handleClose={() => {toggleModalExcluir(false)}} + /> + + <div style={{fontSize: "12px"}}> + <Button aria-controls="simple-menu" aria-haspopup="true" onClick={handleClick} style={{color : "#666"}}> + OPÇÕES <MoreVertIcon style={{color : "inherit"}}/> + </Button> + <Menu + id="simple-menu" + anchorEl={anchorEl} + keepMounted + open={Boolean(anchorEl)} + onClose={handleClose} + > + <StyledMenuItem> + <Link to={"/colecao-do-usuario/" + props.id}> + <ListItemIcon><OpenIcon /></ListItemIcon>Abrir + </Link> + </StyledMenuItem> + + <StyledMenuItem onClick={() => {console.log('TODO: MODAL EDITAR COLECAO')}}> + <ListItemIcon><CreateIcon /></ListItemIcon>Editar + </StyledMenuItem> + + <StyledMenuItem onClick={openModalExcluir}> + <ListItemIcon><DeleteForeverIcon /></ListItemIcon>Excluir + </StyledMenuItem> + + + </Menu> + </div> + </> + ) +} + +export const StyledMenuItem = styled(MenuItem)` + color : #666 !important; + + .MuiSvgIcon-root { + vertical-align : middle !important; + } + a { + text-decoration : none !important; + color : #666 !important; + } +` diff --git a/src/Components/ColCardPublicOptions.js b/src/Components/ColCardPublicOptions.js new file mode 100644 index 0000000000000000000000000000000000000000..2ba27fd6551072f69d9218be353c78d2e84413eb --- /dev/null +++ b/src/Components/ColCardPublicOptions.js @@ -0,0 +1,102 @@ +/*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, {useState} from 'react'; +import Button from '@material-ui/core/Button'; +import Menu from '@material-ui/core/Menu'; +import ListItemIcon from '@material-ui/core/ListItemIcon'; +import MenuItem from '@material-ui/core/MenuItem'; +import OpenIcon from '@material-ui/icons/OpenInNew'; +import {Link} from 'react-router-dom' +import MoreVertIcon from '@material-ui/icons/MoreVert'; +import styled from 'styled-components' +import ErrorIcon from '@material-ui/icons/Error'; +import ReportModal from './ReportModal.js' +import {getAxiosConfig} from '../Components/HelperFunctions/getAxiosConfig' +import axios from 'axios' +import {apiUrl} from '../env'; + +export default function ColCardPublicOptions (props) { + const [anchorEl, setAnchorEl] = React.useState(null); + + function handleClick(event) { + setAnchorEl(event.currentTarget); + } + + function handleClose() { + setAnchorEl(null); + } + + const [reportModalOpen, toggleReportModal] = useState(false) + const handleReportModal = (value) => {toggleReportModal(value)} + + const handleUnfollow = () => { + let config = getAxiosConfig() + let payload = {} + + axios.put( (`${apiUrl}/collections/` + props.id + '/follow'),payload, config).then( + (response) => {console.log(response.data)}, (error) => {console.log(error)}) + } + + return ( + <> + <ReportModal open={reportModalOpen} handleClose={() => handleReportModal(false)} + form="colecao" complainableId={props.id} + complainableType={"Collection"} + /> + <div style={{fontSize: "12px"}}> + <Button aria-controls="simple-menu" aria-haspopup="true" onClick={handleClick} style={{color : "#666"}}> + <MoreVertIcon style={{color : "inherit"}}/> + </Button> + <Menu + id="simple-menu" + anchorEl={anchorEl} + keepMounted + open={Boolean(anchorEl)} + onClose={handleClose} + > + <StyledMenuItem> + <Link to={"/colecao-do-usuario/" + props.id}> + <ListItemIcon><OpenIcon /></ListItemIcon>Abrir + </Link> + </StyledMenuItem> + + <StyledMenuItem onClick={handleUnfollow}> + <ListItemIcon><ErrorIcon /></ListItemIcon>Deixar de Seguir + </StyledMenuItem> + + <StyledMenuItem onClick={() => {handleReportModal(true)}}> + <ListItemIcon><ErrorIcon /></ListItemIcon>Reportar + </StyledMenuItem> + </Menu> + </div> + </> + ) +} + +export const StyledMenuItem = styled(MenuItem)` + color : #666 !important; + + .MuiSvgIcon-root { + vertical-align : middle !important; + } + a { + text-decoration : none !important; + color : #666 !important; + } +` diff --git a/src/Components/CollectionCardFunction.js b/src/Components/CollectionCardFunction.js index c1cb1415e67b5e81b62ebc087e52040c28ab75dc..424c0de04b6d1bb4082a7fc098d6cf3b07834a87 100644 --- a/src/Components/CollectionCardFunction.js +++ b/src/Components/CollectionCardFunction.js @@ -16,7 +16,8 @@ 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, useContext} from 'react'; +import {Store} from '../Store.js' import Card from '@material-ui/core/Card'; import {apiDomain, apiUrl} from '../env'; import Options from './CardOptions' @@ -34,9 +35,13 @@ import FolderIcon from '@material-ui/icons/Folder'; import FavoriteIcon from '@material-ui/icons/Favorite'; import AddIcon from '@material-ui/icons/Add'; import CheckIcon from '@material-ui/icons/Check'; - +import LockIcon from '@material-ui/icons/Lock'; +import ColCardOwnerOptions from './ColCardOwnerOptions.js' +import ColCardPublicOptions from './ColCardPublicOptions' export default function CollectionCardFunction (props) { + const {state} = useContext(Store) + const [userAvatar, setUserAvatar] = useState(props.avatar ? (`${apiDomain}` + props.avatar) : noAvatar) const [followingHover, handleFollowingHover] = useState(false) @@ -147,13 +152,16 @@ export default function CollectionCardFunction (props) { </Header> <Description> {/*renders rating, number of learning objects and likes count*/} - <Rating - name="customized-empty" - value={props.rating*10} - precision={0.5} - style={{color:"#666"}} - emptyIcon={<StarBorderIcon fontSize="inherit" />} - /> + { + props.authorID !== state.currentUser.id && + <Rating + name="customized-empty" + value={props.rating*10} + precision={0.5} + style={{color:"#666"}} + emptyIcon={<StarBorderIcon fontSize="inherit" />} + /> + } <Footer> <Type> @@ -172,22 +180,49 @@ export default function CollectionCardFunction (props) { </CardReaDiv> - <CardReaFooter> {/*renders following/unfollow and follow button*/} - { - props.followed ? - ( - [ - RenderFollowingButton() - ] - ) - : - ( - [ - RenderFollowButton() - ] - ) - } - </CardReaFooter> + { + props.authorID === state.currentUser.id ? + ( + <CardReaFooter style={{justifyContent : "space-between"}}> {/*renders following/unfollow and follow button*/} + <Grid container> + <Grid item xs={6} style={{display : "flex", justifyContent : "center"}}> + { + props.privacy === 'private' && + <LockIcon style={{color : "#666"}}/> + } + </Grid> + <Grid item xs={6} style={{display : "flex", justifyContent : "flex-end"}}> + <ColCardOwnerOptions + id={props.id} + /> + </Grid> + </Grid> + </CardReaFooter> + ) + : + ( + <CardReaFooter> {/*renders following/unfollow and follow button*/} + { + props.followed ? + ( + [ + RenderFollowingButton() + ] + ) + : + ( + [ + RenderFollowButton() + ] + ) + } + <ColCardPublicOptions + id={props.id} + /> + </CardReaFooter> + ) + } + </CardDiv> </StyledCard> ) @@ -274,6 +309,7 @@ const CardReaFooter = styled.div` display : flex; justify-content : center; align-items : center; + border-top : 1px solid #e5e5e5; .MuiSvgIcon-root { font-family: 'Material Icons'; diff --git a/src/Components/ContactButtons/FollowButton.js b/src/Components/ContactButtons/FollowButton.js index e4ab416271284ad5d2ec05c25ff2aed5e76662b4..09362df143e866e793127eec5d6394c62acbdbf9 100644 --- a/src/Components/ContactButtons/FollowButton.js +++ b/src/Components/ContactButtons/FollowButton.js @@ -16,38 +16,36 @@ 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, {useContext, useState} from 'react' +import React, {useState} from 'react' import PersonAddIcon from '@material-ui/icons/PersonAdd'; import styled from 'styled-components' import Button from '@material-ui/core/Button'; import axios from 'axios' import {apiUrl} from '../../env'; -import { Store } from '../../Store.js'; +import {getAxiosConfig} from '../HelperFunctions/getAxiosConfig' export default function FollowButton (props) { - const {state} = useContext(Store) const handleFollow = (followerID) => { const id = followerID console.log('id: ', id) - {/*const header = { - 'Accept': 'application/json', - 'Content-Type': 'application/json', - 'Access-Token': state.currentUser.accessToken, - 'Client': state.currentUser.clientToken, - 'Uid': sessionStorage.getItem('@portalmec/uid'), - 'Host': 'api.portalmec.c3sl.ufpr.br', - 'Cookie': '' - } - if (id != -1){ - axios.post( (`${apiUrl}/users/` + id + '/follow'), header - ).then( (response) => { - console.log(response) - }, (error) => { - console.log(error) - }) - }*/} + let payload = {} + const header = getAxiosConfig() + + axios.put((`${apiUrl}/users/` + id + '/follow'), payload, header).then( + (response) => { + if ( response.headers['access-token'] ) { + sessionStorage.setItem('@portalmec/accessToken', response.headers['access-token']) + } + console.log(response) + props.toggleFollowed() + }, + (error) => { + console.log(error) + } + ) + } return ( @@ -62,8 +60,31 @@ export default function FollowButton (props) { } export function NoIcon (props) { + + const handleFollow = (followerID) => { + const id = followerID + console.log('id: ', id) + + if (id != undefined) { + let payload = {} + const header = getAxiosConfig() + + axios.put((`${apiUrl}/users/` + id + '/follow'), payload, header).then( + (response) => { + if ( response.headers['access-token'] ) { + sessionStorage.setItem('@portalmec/accessToken', response.headers['access-token']) + } + console.log(response) + }, + (error) => { + console.log(error) + } + ) + } + } + return ( - <NoIconButton>seguir</NoIconButton> + <NoIconButton onClick={() => handleFollow(props.followableID)}>seguir</NoIconButton> ) } diff --git a/src/Components/ContactButtons/FollowingButton.js b/src/Components/ContactButtons/FollowingButton.js index 13285307af85f2c25c83e201dd3cf2039e05f94a..6fa7464a760885e617f37a1028aafc496b2b2610 100644 --- a/src/Components/ContactButtons/FollowingButton.js +++ b/src/Components/ContactButtons/FollowingButton.js @@ -16,17 +16,16 @@ 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, {useContext, useState} from 'react' +import React, {useState} from 'react' import styled from 'styled-components' import Button from '@material-ui/core/Button'; import FollowingIcon from '../../img/how_to_reg-24px.png' import ModalConfirmarUnfollow from '../ModalConfirmarUnfollow.js' import axios from 'axios' import {apiUrl} from '../../env'; -import { Store } from '../../Store.js'; +import {getAxiosConfig} from '../HelperFunctions/getAxiosConfig' export default function FollowingButton (props) { - const {state} = useContext(Store) const [modalOpen, toggleModal] = useState(false) const [unfollowID, setUnfollowID] = useState(-1) @@ -43,26 +42,22 @@ export default function FollowingButton (props) { const id = unfollowID console.log('id: ', id) - const header = { - 'Accept': 'application/json', - 'Content-Type': 'application/json', - 'Access-Token': state.currentUser.accessToken, - 'Client': state.currentUser.clientToken, - 'Uid': sessionStorage.getItem('@portalmec/uid'), - 'Host': 'api.portalmec.c3sl.ufpr.br', - 'Cookie': '' - } - - console.log('header: ', header) - - {/*if (id != -1) { - axios.delete((`${apiUrl}/users/` + id + '/follow'), header - ).then( (response) => { - console.log(response) - }, (error) => { + let payload = {} + const header = getAxiosConfig() + + axios.put((`${apiUrl}/users/` + id + '/follow'), payload, header).then( + (response) => { + if ( response.headers['access-token'] ) { + sessionStorage.setItem('@portalmec/accessToken', response.headers['access-token']) + } + console.log(response) + props.toggleFollowed() + toggleModal(false) + }, + (error) => { console.log(error) - }) - }*/} + } + ) } return ( diff --git a/src/Components/ContactCard.js b/src/Components/ContactCard.js index 7370561d724724c90bed686c607a63f1315f2d6b..83ce16ab91084f1761c0395ba4a9d16f66b232b6 100644 --- a/src/Components/ContactCard.js +++ b/src/Components/ContactCard.js @@ -49,21 +49,8 @@ export default function ImgMediaCard(props) { const classes = useStyles(); const {state} = useContext(Store) - const [coverStyle, setCoverStyle] = useState({}) - - const createRequestHeader = () => { - const header = { - 'Accept': 'application/json', - 'Content-Type': 'application/json', - 'Access-Token': state.currentUser.accessToken, - 'Client': state.currentUser.clientToken, - 'Uid': sessionStorage.getItem('@portalmec/uid'), - 'Host': 'api.portalmec.c3sl.ufpr.br', - 'Cookie': '' - } - return header - } - + const [followedBoolean, setFollowedBoolean] = useState(props.followed) + const toggleFollowed = () => {setFollowedBoolean(!followedBoolean)} return ( <StyledCard> <CardDiv> @@ -100,20 +87,20 @@ export default function ImgMediaCard(props) { <div style={{display : "flex", justifyContent : "center"}}> { - props.followed ? + followedBoolean ? ( [ - <FollowingButton followedID={props.followerID}/> + <FollowingButton followedID={props.followerID} toggleFollowed={toggleFollowed}/> ] ) : ( [ - <FollowButton followerID={props.followerID}/> + <FollowButton followerID={props.followerID} toggleFollowed={toggleFollowed}/> ] ) } - <Options/> {/*options menu missing functionalities*/} + <Options followableID={props.followerID} followed={followedBoolean}/> </div> </UserInfo> </CardContent> diff --git a/src/Components/ContactCardOptions.js b/src/Components/ContactCardOptions.js index 57cc1e4e3c4c95881480bb7741fc67254325ba0f..7cccf882fd8c034fd113d80dee2f2ecc7528b0e1 100644 --- a/src/Components/ContactCardOptions.js +++ b/src/Components/ContactCardOptions.js @@ -16,7 +16,8 @@ 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, {useContext, useState} from 'react'; +import {Store} from '../Store.js' import styled from 'styled-components' import Button from '@material-ui/core/Button'; import Menu from '@material-ui/core/Menu'; @@ -26,52 +27,101 @@ import MoreVertIcon from '@material-ui/icons/MoreVert'; import OpenIcon from '@material-ui/icons/OpenInNew'; import ReportIcon from '@material-ui/icons/Error'; import PersonAddIcon from '@material-ui/icons/PersonAdd'; +import axios from 'axios' +import {apiUrl} from '../env'; +import {getAxiosConfig} from './HelperFunctions/getAxiosConfig' +import ReportModal from './ReportModal.js' +import {Link} from 'react-router-dom' -export default function SimpleMenu() { - const [anchorEl, setAnchorEl] = React.useState(null); +export default function SimpleMenu(props) { + const {state} = useContext(Store) + const [anchorEl, setAnchorEl] = React.useState(null); - function handleClick(event) { - setAnchorEl(event.currentTarget); - } + function handleClick(event) { + setAnchorEl(event.currentTarget); + } + + function handleClose() { + setAnchorEl(null); + } + const handleFollow = (followerID) => { + const id = followerID + console.log('id: ', id) - function handleClose() { - setAnchorEl(null); - } + let payload = {} + const header = getAxiosConfig() + axios.put((`${apiUrl}/users/` + id + '/follow'), payload, header).then( + (response) => { + if ( response.headers['access-token'] ) { + sessionStorage.setItem('@portalmec/accessToken', response.headers['access-token']) + } + console.log(response) + }, + (error) => { + console.log(error) + } + ) + } + + const [reportModal, toggleReportModal] = useState(false) + const handleModal = (value) => { + toggleReportModal(value) + {/*if (state.currentUser.id) { + toggleReportModal(!reportModal) + } + else { + toggleLoginModal(true) + }*/} + } return ( - <div style={{fontSize: "12px", display : "flex", flexDirection : "column", justifyContent : "center"}}> - <ButtonNoWidth aria-controls="simple-menu" aria-haspopup="true" onClick={handleClick} style={{color : "#666"}}> - <MoreVertIcon style={{color : "#666"}}/> - </ButtonNoWidth> - <Menu - id="simple-menu" - anchorEl={anchorEl} - keepMounted - open={Boolean(anchorEl)} - onClose={handleClose} - > - <MenuItem onClick={handleClose}> - <ListItemIcon> - <OpenIcon /> - </ListItemIcon> - Abrir - </MenuItem> - - <MenuItem onClick={handleClose}> - <ListItemIcon> - <PersonAddIcon /> - </ListItemIcon> - Seguir - </MenuItem> - - <MenuItem onClick={handleClose}> - <ListItemIcon> - <ReportIcon /> - </ListItemIcon> - Reportar - </MenuItem> - </Menu> - </div> + <> + { + reportModal && + <ReportModal open={reportModal} handleClose={() => handleModal(false)} + form="user" complainableId={props.followableID} + complainableType={"User"} + {...props}/> + } + <div style={{fontSize: "12px", display : "flex", flexDirection : "column", justifyContent : "center"}}> + <ButtonNoWidth aria-controls="simple-menu" aria-haspopup="true" onClick={handleClick} style={{color : "#666"}}> + <MoreVertIcon style={{color : "#666"}}/> + </ButtonNoWidth> + <Menu + id="simple-menu" + anchorEl={anchorEl} + keepMounted + open={Boolean(anchorEl)} + onClose={handleClose} + > + <StyledMenuItem onClick={handleClose}> + <Link to={"/usuario-publico/" + props.followableID}> + <ListItemIcon><OpenIcon /></ListItemIcon>Abrir + </Link> + </StyledMenuItem> + + { + props.followed ? + ( + <StyledMenuItem onClick={() => {handleFollow(props.followableID);handleClose()}}> + <ListItemIcon><ReportIcon /></ListItemIcon>Deixar de Seguir + </StyledMenuItem> + ) + : + ( + <StyledMenuItem onClick={() => {handleFollow(props.followableID);handleClose()}}> + <ListItemIcon><PersonAddIcon /></ListItemIcon>Seguir + </StyledMenuItem> + ) + } + + + <StyledMenuItem onClick={() => {handleModal(true); handleClose()}}> + <ListItemIcon><ReportIcon /></ListItemIcon>Reportar + </StyledMenuItem> + </Menu> + </div> + </> ); } @@ -98,3 +148,14 @@ const ButtonNoWidth = styled(Button)` padding-left : 4px !important; } ` + +const StyledMenuItem = styled(MenuItem)` + color : #666 !important; + .MuiSvgIcon-root { + vertical-align : middle !important; + } + a { + text-decoration : none !important; + color : #666 !important; + } +` diff --git a/src/Components/GreyButton.js b/src/Components/GreyButton.js new file mode 100644 index 0000000000000000000000000000000000000000..a2d687d5e50382fb1a39ec7bcf6bd5d3d314b47d --- /dev/null +++ b/src/Components/GreyButton.js @@ -0,0 +1,56 @@ +/*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 { Button } from '@material-ui/core'; +import styled from 'styled-components' + +export default function GreyButton (props) { + return ( + <StyledButton onClick={props.callback}> + {props.text} + </StyledButton> + ) +} + +const StyledButton = styled(Button)` + &:hover { + background-color : rgba(158,158,158,0.2) !important; + } + max-height : 36px !important; + + background-color : transparent !important; + color : #666 !important; + text-decoration : none !important; + outline : none !important; + text-align : center !important; + + .button-text { + cursor : pointer; + line-height : 36px; + text-align : center; + color : currentColor; + white-space : nowrap; + text-transform : uppercase; + font-weight : 600 !important; + font-size : 14px; + font-style : inherit; + font-variant : inherit; + padding : 6px 16px !important; + } +` diff --git a/src/Components/GuardarModal.js b/src/Components/GuardarModal.js index fd835a17ad8b37d74eea8a242a8e71304e182a60..e43a63fc3a122cf882407e8f59d6c3676fc35955 100644 --- a/src/Components/GuardarModal.js +++ b/src/Components/GuardarModal.js @@ -32,6 +32,7 @@ import PublicIcon from '@material-ui/icons/Public'; import LockIcon from '@material-ui/icons/Lock'; import LoadingSpinner from './LoadingSpinner.js' import CriarColecaoForm from './CriarColecaoForm.js' +import SnackbarComponent from './SnackbarComponent' function CloseModalButton (props) { return ( @@ -91,18 +92,23 @@ export default function ReportModal (props) { sessionStorage.setItem('@portalmec/accessToken', response.headers['access-token']) } console.log(response) - props.handleSnackbar(4) + toggleSnackbar(true) setCreating(false) props.handleClose() }, (error) => {console.log(error)}) } + const [snackbarOpen, toggleSnackbar] = useState(false) + return ( + <React.Fragment> + <SnackbarComponent snackbarOpen={snackbarOpen} severity={"info"} handleClose={() => {toggleSnackbar(false)}} text={"O Recurso foi guardado na coleção!"} + /> <StyledModal aria-labelledby="transition-modal-title" aria-describedby="transition-modal-description" open={props.open} - + centered="true" onClose={props.handleClose} closeAfterTransition @@ -190,6 +196,7 @@ export default function ReportModal (props) { </Container> </Fade> </StyledModal> + </React.Fragment> ) } diff --git a/src/Components/LoginContainerFunction.js b/src/Components/LoginContainerFunction.js index 3aef0866eee02c55fcadadc2751a4af19c46f206..b3c63046bd565a7a00da162dc072abbf99c7cf4a 100644 --- a/src/Components/LoginContainerFunction.js +++ b/src/Components/LoginContainerFunction.js @@ -26,6 +26,7 @@ import LabeledCheckbox from './Checkbox.js' import FormInput from "./FormInput.js" import GoogleLogo from "../img/logo_google.svg" import ValidateUserInput from '../Components/FormValidationFunction.js' +import {Link} from 'react-router-dom' export default function LoginContainer (props) { const [formEmail, setEmail] = useState( @@ -156,7 +157,7 @@ export default function LoginContainer (props) { <RememberRecover> <LabeledCheckbox label={<StyledLabel><StyledSpan>Lembrar-me</StyledSpan></StyledLabel>} handleChange={() => setCheckbox(!checkboxControl)}/> - <UserForgotTheirPasswordSpan>Esqueceu a senha? <a href="recuperar-senha" style={{textAlign: "right", color:"#4cd0e1"}}>Clique aqui!</a></UserForgotTheirPasswordSpan> + <UserForgotTheirPasswordSpan>Esqueceu a senha? <Link to={"recuperar-senha"} style={{textAlign: "right", color:"#4cd0e1"}} onClick={props.handleClose}>Clique aqui!</Link></UserForgotTheirPasswordSpan> </RememberRecover> <ConfirmContainerStyled> diff --git a/src/Components/MenuBar.js b/src/Components/MenuBar.js index 88137922b4a81d8dfc4782b697379197dc67ab14..8ea5f1620e085fcf23fa8ae0b867a8bb3df1ef84 100644 --- a/src/Components/MenuBar.js +++ b/src/Components/MenuBar.js @@ -38,12 +38,12 @@ const ContainerStyled = styled(Container)` border-top: 1px rgba(0,0,0,.1) solid; padding: 5px; - *{ - margin-left: 10px; - } + ` const ButtonStyled = styled(Button)` text-transform: capitalize !important; + margin : 0 8px !important; + font-weight : normal !important; ` const ButtonPublicarRecurso = styled(Button)` @@ -56,6 +56,10 @@ const ButtonPublicarRecurso = styled(Button)` text-transform: capitalize !important; font-stretch : expanded; max-width: 200 !important; + .MuiSvgIcon-root { + vertical-align : middle !important; + margin-right : 5px !important; + } ` const IconSearchStyled = styled(IconSearch)` @@ -87,6 +91,8 @@ const ButtonPubRecursoStyled = styled(Button)` border : 1.5px #666 solid !important; color: #666; box-shadow: none; + margin : 0 8px !important; + font-weight : normal !important; ` diff --git a/src/Components/ModalConfirmarUnfollow.js b/src/Components/ModalConfirmarUnfollow.js index cc15d0b9a40e1aea666cf453fc67af1df6abc7f6..f8deb98a454280ce7a6c78f952caabf12f3e2527 100644 --- a/src/Components/ModalConfirmarUnfollow.js +++ b/src/Components/ModalConfirmarUnfollow.js @@ -8,36 +8,54 @@ import { Store } from '../Store.js'; import axios from 'axios' import {apiUrl} from '../env'; import CloseIcon from '@material-ui/icons/Close'; +import CloseModalButton from './CloseModalButton' const StyledModal = styled(Modal)` - margin : 0 !important; - margin-left : 0 !important; + .djXaxP{ + margin : 0 !important; + } display : flex; align-items: center; justify-content : center; text-align : center; padding : 10px !important; - border-radius : 4px; max-width : none; max-height : none; - min-width: 1500px; - min-height: 150px !important; ` const HeaderDiv = styled.div` - max-width : 100%; display : flex; + flex-direction : row; align-items : center; - align-content : center; + text-align : center; + margin : 20px 30px; + + h3 { + font-size : 24px; + margin-top : 20px; + margin-bottpm : 10px + font-weight : normal; + color : #666 + } ` const ContentContainer = styled.div` - width : 30%; box-sizing : border-box; background-color : white; max-width : none; align : center; + display : flex; + flex-direction : column; + min-width : 240px; + max-height : none; + position : relative; + padding : 10px; border-radius : 4px; - font-family : 'Roboto', sans serif; + color : #666; + + @media screen and (max-width : 899px) { + width : 100%; + max-height : 600px; + } ` const ButtonCancelar = styled(Button)` &:hover { @@ -56,7 +74,7 @@ const ButtonConfirmar = styled(Button)` border-radius : 3px !important; ` -export default function IllegalContentModal (props) { +export default function ModalConfirmarUnfollow (props) { const text = { header : "Tem certeza que deseja deixar de seguir este usuário?", explanation : "Este usuário deixará de fazer parte da sua rede." @@ -67,7 +85,7 @@ export default function IllegalContentModal (props) { aria-labelledby="transition-modal-title" aria-describedby="transition-modal-description" open={props.open} - + centered="true" onClose={props.handleClose} closeAfterTransition @@ -80,12 +98,10 @@ export default function IllegalContentModal (props) { <ContentContainer> <HeaderDiv> <span style={{width:"32px"}}/> - <h3 style={{fontSize : "24px", marginTop:"20px", marginBottom:"10px", fontWeight : "normal"}}> + <h3> {text.header} </h3> - <Button style={{marginRight:"0", color:"000"}} onClick={props.handleClose}> - <CloseIcon style={{color:"#666", cursor:"pointer", verticalAlign:"middle"}}/> - </Button> + <CloseModalButton handleClose={props.handleClose}/> </HeaderDiv> <div style={{display : "flex", flexDirection : "column", padding : "20px 30px"}}> <div style={{marginTop : "0", textAlign : "center", marginBottom : "20px"}}> diff --git a/src/Components/ModalExcluirColecao.js b/src/Components/ModalExcluirColecao.js new file mode 100644 index 0000000000000000000000000000000000000000..9c1b61b65600d0bef69cf3ee21bd37ec03216f7c --- /dev/null +++ b/src/Components/ModalExcluirColecao.js @@ -0,0 +1,157 @@ +/*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, {useState} from 'react'; +import { Button } from '@material-ui/core'; +import Modal from '@material-ui/core/Modal'; +import Backdrop from '@material-ui/core/Backdrop'; +import Fade from '@material-ui/core/Fade'; +import styled from 'styled-components' +import {Store} from '../Store.js' +import axios from 'axios' +import {apiUrl} from '../env'; +import GreyButton from './GreyButton.js' +import PurpleButton from './PurpleButton.js' +import {getAxiosConfig} from '../Components/HelperFunctions/getAxiosConfig' +import SnackbarComponent from './SnackbarComponent' + +export default function ModalExcluirColecao (props) { + const [snackbarOpen, toggleSnackbar] = useState(false) + + const handleDelete = () => { + let config = getAxiosConfig() + + axios.delete( (`${apiUrl}/collections/` + props.id), config + ).then( (response) => { + if ( response.headers['access-token'] ) { + sessionStorage.setItem('@portalmec/accessToken', response.headers['access-token']) + } + console.log(response) + toggleSnackbar(true) + props.handleClose() + }, (error) => {console.log(error);}) + } + + return ( + <StyledModal + aria-labelledby="transition-modal-title" + aria-describedby="transition-modal-description" + open={props.open} + + centered="true" + onClose={props.handleClose} + closeAfterTransition + BackdropComponent={Backdrop} + BackdropProps={{ + timeout: 500, + }} + > + <Fade in={props.open}> + <> + <SnackbarComponent snackbarOpen={snackbarOpen} severity={"info"} handleClose={() => {toggleSnackbar(false)}} text={"Coleção excluÃda com sucesso"}/> + <Container> + <Header> + <h2>Tem certeza que deseja excluir esta Coleção?</h2> + </Header> + + <Content> + <p>A exclusão de uma coleção é permanente. Não é possÃvel desfazer.</p> + <ButtonsDiv> + <GreyButton + callback={props.handleClose} + text={"CANCELAR"} + /> + <PurpleButton + callback={handleDelete} + text={"EXCLUIR"} + /> + </ButtonsDiv> + </Content> + </Container> + </> + </Fade> + </StyledModal> + ) +} + +const ButtonsDiv = styled.div` + display : flex; + align-items : center; + align-content : center; + justify-content : space-evenly; + padding-top : 20px; + +` + +const Content = styled.div` + padding : 10px 30px 20px; + overflow : visible; + display : flex; + flex-direction : column; + + p { + margin : 0 0 10px; + } +` + +const Header = styled.div` + display : flex; + flex-direction : row; + align-items : center; + text-align : center; + margin : 20px 30px; + + h2 { + font-size : 26px; + font-weight : lighter; + color : #666 + } +` + +const StyledModal = styled(Modal)` + .djXaxP{ + margin : 0 !important; + } + display : flex; + align-items: center; + justify-content : center; + text-align : center; + padding : 10px !important; + max-width : none; + max-height : none; +` + +const Container = styled.div` + box-sizing : border-box; + background-color : white; + max-width : none; + align : center; + display : flex; + flex-direction : column; + min-width : 240px; + max-height : none; + position : relative; + padding : 10px; + border-radius : 4px; + color : #666; + + @media screen and (max-width : 899px) { + width : 100%; + max-height : 600px; + } +` diff --git a/src/Components/PasswordRecoveryComponents/Default.js b/src/Components/PasswordRecoveryComponents/Default.js index db733e0805dd5e5d6ef50f0066c24ec2caf79ff3..ddbb4f43a3128596508fa1696a5fe4aa59820015 100644 --- a/src/Components/PasswordRecoveryComponents/Default.js +++ b/src/Components/PasswordRecoveryComponents/Default.js @@ -17,7 +17,7 @@ export default function Default (props) { error = {props.error} /> <div style={{display:"flex", justifyContent:"center"}}> - <CompletarCadastroButton onClick={(e) => props.onSubmit(e, props.value)}>BUSCAR</CompletarCadastroButton> + <CompletarCadastroButton type="submit" >BUSCAR</CompletarCadastroButton> </div> </form> </div> diff --git a/src/Components/PasswordRecoveryComponents/Error.js b/src/Components/PasswordRecoveryComponents/Error.js index 387d333eadd483302f10598315f131d71b46f101..38ea3937b4b3713e2ac3b363f8d582ff6d21c0f4 100644 --- a/src/Components/PasswordRecoveryComponents/Error.js +++ b/src/Components/PasswordRecoveryComponents/Error.js @@ -2,11 +2,11 @@ import React from 'react' import {CompletarCadastroButton} from '../TabPanels/UserPageTabs/PanelSolicitarContaProfessor.js' import FormInput from "../FormInput.js" -export default function Default (props) { +export default function Error (props) { return ( <div style={{overflow:"hidden", display:"inline-block"}}> <h2 style={{fontSize:"32px", fontWeight:"200", marginBottom:"20px"}}>Ops! Não encontramos essa conta</h2> - <p>{props.email}</p> + <p>{props.value}</p> <p>Verifique se o e-mail foi digitado corretamente ou se você utilizou algum outro e-mail.</p> <form onSubmit={(e) => props.onSubmit(e)}> <FormInput @@ -19,7 +19,7 @@ export default function Default (props) { error = {props.error} /> <div style={{display:"flex", justifyContent:"center"}}> - <CompletarCadastroButton onClick={(e) => props.onSubmit(e, props.value)}>BUSCAR</CompletarCadastroButton> + <CompletarCadastroButton type="submit" >BUSCAR</CompletarCadastroButton> </div> </form> </div> diff --git a/src/Components/PasswordRecoveryComponents/Success.js b/src/Components/PasswordRecoveryComponents/Success.js index 7ee31805eb6787594953a5ab4b6268cd361ab82f..d366bc3c8958f7560816e5ee27fe0172c0fb2789 100644 --- a/src/Components/PasswordRecoveryComponents/Success.js +++ b/src/Components/PasswordRecoveryComponents/Success.js @@ -6,7 +6,7 @@ export default function Default (props) { return ( <div style={{overflow:"hidden", display:"inline-block", fontSize:"14px", textAlign:"start"}}> <h2 style={{fontSize:"32px", fontWeight:"200", marginBottom:"20px"}}>Feito! Confira seu e-mail</h2> - <p> Enviamos um link para <span style={{color:"#00bcd4"}}>{props.email}</span> que permite alterar sua senha. </p> + <p> Enviamos um link para <span style={{color:"#00bcd4"}}>{String(props.email)}</span> que permite alterar sua senha. </p> <p style={{marginBottom:"30px"}}> Caso não chegue em sua caixa de entrada, dê uma olhada em outras pastas, como lixo eletrônico ou spam. </p> <p> Não é o seu e-mail? <span style={{color:"#00bcd4", cursor:"pointer"}} onClick={() => {props.changeSwitch('default')}}> Tente Novamente.</span></p> </div> diff --git a/src/Components/PurpleButton.js b/src/Components/PurpleButton.js new file mode 100644 index 0000000000000000000000000000000000000000..1b57b823d14aedd9bb2604fa0de6b9a4ea73da72 --- /dev/null +++ b/src/Components/PurpleButton.js @@ -0,0 +1,52 @@ +/*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 { Button } from '@material-ui/core'; +import styled from 'styled-components' + +export default function PurpleButton (props) { + return ( + <StyledButton onClick={props.callback}> + {props.text} + </StyledButton> + ) +} + +const StyledButton = styled(Button)` + max-height : 36px !important; + background-color : #673ab7 !important; + color : #fff !important; + text-decoration : none !important; + outline : none !important; + text-align : center !important; + + .button-text { + cursor : pointer; + line-height : 36px; + text-align : center; + color : currentColor; + white-space : nowrap; + text-transform : uppercase; + font-weight : 600 !important; + font-size : 14px; + font-style : inherit; + font-variant : inherit; + padding : 6px 16px !important; + } +` diff --git a/src/Components/ReportColecaoForm.js b/src/Components/ReportColecaoForm.js new file mode 100644 index 0000000000000000000000000000000000000000..fcea00e793912b73c072b2b146a33d809be9402c --- /dev/null +++ b/src/Components/ReportColecaoForm.js @@ -0,0 +1,153 @@ +/*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, {useContext} from 'react'; +import { Button } from '@material-ui/core'; +import styled from 'styled-components' +import Radio from '@material-ui/core/Radio'; +import RadioGroup from '@material-ui/core/RadioGroup'; +import FormControlLabel from '@material-ui/core/FormControlLabel'; +import FormControl from '@material-ui/core/FormControl'; +import TextField from '@material-ui/core/TextField'; +import {StyledFormControl, ButtonsDiv, ButtonCancelar} from './ReportUserForm.js' +import { withStyles } from '@material-ui/core/styles'; + +const StyledRadio = withStyles({ + root: { + color: '#666', + '&$checked': { + color: '#673ab7', + }, + }, + checked: {}, +})((props) => <Radio color="default" {...props} />); + +export default function ReportColecaoForm (props) { + const [value, setValue] = React.useState(-1); + + const handleChange = (event) => { + setValue(event.target.value); + }; + + /*values are set according to backend complaint id*/ + const [options] = React.useState([ + {value : "1", text : 'A Coleção viola os direitos autorais.'}, + {value : "2", text : 'A Coleção contém conteúdo ofensivo/abusivo.'}, + {value : "5", text : 'A descrição da Coleção não corresponde ao seu conteúdo.'} + ]) + + const [moreInfo, setMoreInfo] = React.useState({ + key : false, + value : "", + }) + + const handleChangeMoreInfo = (e) => { + const userInput = e.target.value + + const flag = userInput.length > 150 ? true : false + + setMoreInfo({...moreInfo, + key : flag, + value : userInput + }) + } + + const handleSubmit = (e) => { + e.preventDefault() + const finalRadioValue = value + const finalMoreInfo = moreInfo + + if( finalRadioValue != -1 && !(finalMoreInfo.key)) { + props.handleSubmit(finalRadioValue, finalMoreInfo.value) + } + else { + console.log('oops') + } + } + + return ( + <form onSubmit={(e) => handleSubmit(e)} style={{textAlign : "left"}}> + <StyledFormControl component="fieldset"> + <RadioGroup value={value} onChange={handleChange}> + { + options.map(option => + <FormControlLabel value={option.value} control={<StyledRadio/>} label={option.text} /> + ) + } + </RadioGroup> + </StyledFormControl> + + <StyledTextField + id = {"report-text-field"} + label={"Escreva mais sobre o problema"} + value = {moreInfo.value} + onChange = {e => handleChangeMoreInfo(e)} + helperText = {moreInfo.value.length + '/150'} + multiline={true} + rowsMax = {"5"} + error = {moreInfo.key} + required = {false} + helperText ={moreInfo.value.length + '/150'} + style={{width : "100%"}} + /> + + <ButtonsDiv> + <ButtonCancelar onClick={props.handleClose}>CANCELAR</ButtonCancelar> + <ButtonEnviar type="submit">ENVIAR</ButtonEnviar> + </ButtonsDiv> + </form> + ) +} + +const StyledTextField = styled(TextField)` + .MuiFormHelperText-root { + text-align : left; + } + + label.Mui-focused { + color : #673ab7; + } + + label.Mui-focused.Mui-error { + color : red; + } + + .MuiInput-underline::after { + border-bottom: 2px solid #673ab7; + } +` +const ButtonEnviar = styled(Button)` + background-color : #673ab7 !important; + color : #fff !important; + font-size: 14px !important; + font-weight: 500 !important; + height: 36px !important; + border-radius: 3px !important; + padding-left: 16px !important; + padding-right: 16px !important; + box-shadow: 0 2px 5px 0 rgba(0,0,0,.26) !important; + outline : none !important; + min-width : 88px !important; + vertical-align : middle !important; + margin : 6px 8px !important; + text-decoration : none !important; + + .MuiButton-label { + padding-right : 16px; + padding-left : 16px; + } +` diff --git a/src/Components/ReportModal.js b/src/Components/ReportModal.js index 16a8c269b0120c0e08d4dbb921ad3aba3b1f919f..ed472b3890cda0cbc7bd02e7aa6b1f44714e0131 100644 --- a/src/Components/ReportModal.js +++ b/src/Components/ReportModal.js @@ -29,6 +29,7 @@ import {apiUrl} from '../env'; import CloseIcon from '@material-ui/icons/Close'; import ReportUserForm from './ReportUserForm.js' import ReportRecursoForm from './ReportRecursoForm.js' +import ReportColecaoForm from './ReportColecaoForm.js' function CloseModalButton (props) { return ( @@ -56,22 +57,24 @@ export default function ReportModal (props) { } console.log(payload) - {/* - axios.post(`${apiUrl}/complaints`, - { - "complaint" : { - "user_id" : state.currentUser.id, - "description" : description, - "complainable_id" : props.complainableId, - "complainable_type" : props.complainableType, - "complaint_reason_id" : complaint_reason_id - } - }).then( (response) => {console.log(response)}, (error) => {console.log(error)}) - */} + axios.post(`${apiUrl}/complaints`, + { + "complaint" : { + "user_id" : state.currentUser.id, + "description" : description, + "complainable_id" : props.complainableId, + "complainable_type" : props.complainableType, + "complaint_reason_id" : complaint_reason_id + } + }).then( (response) => {console.log(response)}, (error) => {console.log(error)}) } const renderForm = (formType) => { switch (formType) { + case 'colecao': + return ( + <ReportColecaoForm handleClose={props.handleClose} handleSubmit={handleSubmit}/> + ) case 'recurso': return ( <ReportRecursoForm handleClose={props.handleClose} handleSubmit={handleSubmit}/> @@ -89,7 +92,7 @@ export default function ReportModal (props) { aria-labelledby="transition-modal-title" aria-describedby="transition-modal-description" open={props.open} - + centered="true" onClose={props.handleClose} closeAfterTransition diff --git a/src/Components/ReportRecursoForm.js b/src/Components/ReportRecursoForm.js index e327503047237c929f0e4167b486d6c8900372eb..66704bde8cda4ddad3c60c4aaf3ecd22e74760f8 100644 --- a/src/Components/ReportRecursoForm.js +++ b/src/Components/ReportRecursoForm.js @@ -24,6 +24,17 @@ import FormControlLabel from '@material-ui/core/FormControlLabel'; import FormControl from '@material-ui/core/FormControl'; import TextField from '@material-ui/core/TextField'; import {StyledFormControl, StyledTextField, ButtonsDiv, ButtonCancelar, ButtonEnviar} from './ReportUserForm.js' +import { withStyles } from '@material-ui/core/styles'; + +const StyledRadio = withStyles({ + root: { + color: '#666', + '&$checked': { + color: '#ff7f00', + }, + }, + checked: {}, +})((props) => <Radio color="default" {...props} />); export default function ReportRecursoForm (props) { const [value, setValue] = React.useState(-1); @@ -74,7 +85,7 @@ export default function ReportRecursoForm (props) { <RadioGroup value={value} onChange={handleChange}> { options.map(option => - <FormControlLabel value={option.value} control={<Radio color="orange"/>} label={option.text} /> + <FormControlLabel value={option.value} control={<StyledRadio/>} label={option.text} /> ) } </RadioGroup> diff --git a/src/Components/ReportUserForm.js b/src/Components/ReportUserForm.js index 57c26f5d90c2b3e604e358131953c58636b9f111..2ed7bd88d9cf7b29803d97788159116764263390 100644 --- a/src/Components/ReportUserForm.js +++ b/src/Components/ReportUserForm.js @@ -23,6 +23,16 @@ import RadioGroup from '@material-ui/core/RadioGroup'; import FormControlLabel from '@material-ui/core/FormControlLabel'; import FormControl from '@material-ui/core/FormControl'; import TextField from '@material-ui/core/TextField'; +import { withStyles } from '@material-ui/core/styles'; + +const StyledRadio = withStyles({ + root: { + '&$checked': { + color: '#ff7f00 !important', + }, + }, + checked: {}, +})((props) => <Radio color="default" {...props} />); export default function ReportForm (props) { const [value, setValue] = React.useState(-1); @@ -72,7 +82,7 @@ export default function ReportForm (props) { <RadioGroup value={value} onChange={handleChange}> { options.map(option => - <FormControlLabel value={option.value} control={<Radio color="orange"/>} label={option.text} /> + <FormControlLabel value={option.value} control={<StyledRadio/>} label={option.text} /> ) } </RadioGroup> @@ -165,9 +175,7 @@ export const StyledFormControl = styled(FormControl)` .MuiFormControlLabel-root { color : #666; } - .MuiIconButton-label { - color : #666; - } + .PrivateRadioButtonIcon-checked { color : orange; } diff --git a/src/Components/ResourceCardFunction.js b/src/Components/ResourceCardFunction.js index 7c3d54c8288dc3d3d390f97001274a363fc57087..8ff31bd892ff7c08aaacbc4ca208b1b0f12d0917 100644 --- a/src/Components/ResourceCardFunction.js +++ b/src/Components/ResourceCardFunction.js @@ -18,8 +18,9 @@ along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/> import React, {useState, useEffect} from 'react'; import Card from '@material-ui/core/Card'; +import axios from 'axios' import {apiDomain, apiUrl} from '../env'; -import Options from './CardOptions' +import ResourceCardOptions from './ResourceCardOptions' import noAvatar from "../img/default_profile.png"; import { makeStyles } from '@material-ui/core/styles'; import Button from '@material-ui/core/Button'; @@ -49,6 +50,8 @@ import Slide from '@material-ui/core/Slide'; import Grid from '@material-ui/core/Grid'; import {Link} from 'react-router-dom'; import {getDefaultThumbnail} from './HelperFunctions/getDefaultThumbnail' +import GetIconByName from './UploadPageComponents/GetIconByName' +import {getAxiosConfig} from './HelperFunctions/getAxiosConfig' const types = [{label: "Animação", thumb: animacao}, {label: "Apresentação", thumb: apresentacao}, {label: "Aplicativo" , thumb: aplicativo}, {label: "Ãudio", thumb: audio}, {label: "Vazio", thumb: vazio}, {label: "Imagem", thumb: imagem}, {label: "Gráfico", thumb: grafico}, {label: "Jogo", thumb: jogo}, {label: "Livro", thumb: livro}, {label:"Livro digital", thumb: livro}, {label: "Mapa", thumb: mapa}, {label: "Outros", thumb: outros}, {label: "Software Educacional", thumb:software}, {label: "Software", thumb:software}, {label: "Texto", thumb:texto}, {label: "VÃdeo", thumb:video}] @@ -59,6 +62,7 @@ export default function ResourceCardFunction (props) { const [userAvatar, setUserAvatar] = useState(noAvatar) const [slideIn, setSlide] = useState(false) const controlSlide = () => {setSlide(!slideIn)} + const [liked, toggleLiked] = useState(props.liked) useEffect( () => { //decide which thumbnail to use @@ -75,6 +79,14 @@ export default function ResourceCardFunction (props) { }, []) + const handleLike = () => { + let payload = {} + let config = getAxiosConfig() + + axios.put( (`${apiUrl}/learning_objects/` + props.id + '/like'),payload, config + ).then( (response) => {toggleLiked(!liked)}, (error) => {console.log(error)}) + } + const SlideAnimationContent = () => { return ( <SlideContentDiv> @@ -132,7 +144,7 @@ export default function ResourceCardFunction (props) { props.published && <Rating name="customized-empty" - value={props.rating*10} + value={props.rating} precision={0.5} style={{color:"#666"}} emptyIcon={<StarBorderIcon fontSize="inherit" />} @@ -141,7 +153,7 @@ export default function ResourceCardFunction (props) { <Footer> <Type> - <MoreIcon style={{color:"#ff7f00"}}/> {/*get icon based on object type*/} + {GetIconByName(label)} <span>{label}</span> </Type> @@ -149,8 +161,8 @@ export default function ResourceCardFunction (props) { props.published && <LikeCounter> <span>{props.likeCount}</span> - <ButtonNoWidth> - <FavoriteIcon style={{color : props.liked ? "red" : "#666" }}/> + <ButtonNoWidth onClick={handleLike}> + <FavoriteIcon style={{color : liked ? "red" : "#666" }}/> </ButtonNoWidth> </LikeCounter> } @@ -162,9 +174,15 @@ export default function ResourceCardFunction (props) { props.published && <CardReaFooter> <div style={{display : "flex", height : "100%"}}> - <ButtonGuardarColecao/> + <ButtonGuardarColecao thumb={props.thumbnail} title={props.title} recursoId={props.id} + /> </div> - <Options/> + <ResourceCardOptions + learningObjectId={props.id} + downloadableLink = {props.downloadableLink} + thumb={props.thumbnail} + title={props.title} + /> </CardReaFooter> } </CardDiv> @@ -283,10 +301,17 @@ export const LikeCounter = styled.div` const Type = styled.div` line-height : 1; - .MuiSvgIcon-root { - font-size : 21px; - vertical-align : middle; + + .icon { + height : 27px; + width : 27px; padding-right : .4em; + vertical-align : middle + align-self : center; + + .st1 { + fill : #ff7f00; + } } ` diff --git a/src/Components/ResourceCardOptions.js b/src/Components/ResourceCardOptions.js new file mode 100644 index 0000000000000000000000000000000000000000..53d401f0e2659ccd84189205998aaf0901ab7218 --- /dev/null +++ b/src/Components/ResourceCardOptions.js @@ -0,0 +1,187 @@ +/*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, {useContext, useState} from 'react'; +import {Store} from '../Store.js' +import styled from 'styled-components' +import Button from '@material-ui/core/Button'; +import Menu from '@material-ui/core/Menu'; +import ListItemIcon from '@material-ui/core/ListItemIcon'; +import MenuItem from '@material-ui/core/MenuItem'; +import MoreVertIcon from '@material-ui/icons/MoreVert'; +import OpenIcon from '@material-ui/icons/OpenInNew'; +import ReportIcon from '@material-ui/icons/Error'; +import axios from 'axios' +import {apiUrl} from '../env'; +import {getAxiosConfig} from './HelperFunctions/getAxiosConfig' +import ReportModal from './ReportModal.js' +import {Link} from 'react-router-dom' +import DownloadIcon from '@material-ui/icons/CloudDownload'; +import ShareIcon from '@material-ui/icons/Share'; +import AddIcon from '@material-ui/icons/CreateNewFolder'; +import GuardarModal from './GuardarModal' +import ShareModal from './ShareModal' +import SnackbarComponent from './SnackbarComponent' + +export default function ResourceCardOptions (props) { + const {state} = useContext(Store) + const [anchorEl, setAnchorEl] = React.useState(null); + + function handleClick(event) { + setAnchorEl(event.currentTarget); + } + + function handleClose() { + setAnchorEl(null); + } + + const [reportModal, toggleReportModal] = useState(false) + const handleModalReportar = (value) => { + toggleReportModal(value) + {/*if (state.currentUser.id) { + toggleReportModal(!reportModal) + } + else { + toggleLoginModal(true) + }*/} + } + + const [saveToCol, toggleSave] = useState(false) + const handleGuardar = () => { + if(state.currentUser.id === '') { + console.log('abrir login modal'); + } + else { + toggleSave(true); + } + handleClose() + } + + const enableDownload = () => { + const url = props.downloadableLink + window.open(url, '_blank'); + toggleSnackbar(true) + } + + const [shareOpen, toggleShare] = useState(false) + + const handleShare = () => { + if(state.currentUser.id === '') { + console.log('abrir login modal'); + } + else { + toggleShare(true); + } + handleClose() + } + const getShareablePageLink = () => { + return (window.location.href + "/recurso/" + props.learningObjectId) + } + + const [snackbarOpen, toggleSnackbar] = useState(false) + + return ( + <React.Fragment> + <ReportModal open={reportModal} handleClose={() => handleModalReportar(false)} + form="recurso" complainableId={props.learningObjectId} + complainableType={"LearningObject"} + {...props} + /> + <GuardarModal open={saveToCol} handleClose={() => {toggleSave(false)}} + thumb={props.thumb} title={props.title} recursoId={props.learningObjectId} + /> + <ShareModal open={shareOpen} handleClose={() => {toggleShare(false)}} + thumb={props.thumb} title={props.title} link={getShareablePageLink()} + /> + <SnackbarComponent snackbarOpen={snackbarOpen} severity={"info"} handleClose={() => {toggleSnackbar(false)}} text={"Baixando o Recurso... Lembre-se de relatar sua experiência após o uso do Recurso!"} + /> + <div style={{fontSize: "12px", display : "flex", flexDirection : "column", justifyContent : "center"}}> + <ButtonNoWidth aria-controls="simple-menu" aria-haspopup="true" onClick={handleClick} style={{color : "#666"}}> + <MoreVertIcon style={{color : "#666"}}/> + </ButtonNoWidth> + <Menu + id="simple-menu" + anchorEl={anchorEl} + keepMounted + open={Boolean(anchorEl)} + onClose={handleClose} + > + <StyledMenuItem onClick={handleClose}> + <Link to={"/recurso/" + props.learningObjectId}> + <ListItemIcon><OpenIcon /></ListItemIcon>Abrir + </Link> + </StyledMenuItem> + + { + props.downloadableLink && + <StyledMenuItem onClick={() => {enableDownload(); handleClose()}}> + <ListItemIcon><DownloadIcon /></ListItemIcon>Baixar + </StyledMenuItem> + } + + <StyledMenuItem onClick={handleShare}> + <ListItemIcon><ShareIcon /></ListItemIcon>Compartilhar + </StyledMenuItem> + + <StyledMenuItem onClick={handleGuardar}> + <ListItemIcon><AddIcon /></ListItemIcon>Guardar + </StyledMenuItem> + + <StyledMenuItem onClick={() => {handleModalReportar(true); handleClose()}}> + <ListItemIcon><ReportIcon /></ListItemIcon>Reportar + </StyledMenuItem> + </Menu> + </div> + </React.Fragment> + ); +} + +const ButtonNoWidth = styled(Button)` + width : 24px !important; + min-width : 24px !important; + max-height : 24px !important; + padding : 0 !important; + background-color : #fff !important; + color : #a5a5a5 !important; + border : 0 !important; + + .MuiButton-root { + width : 24px !important; + min-width : 12px !important; + } + + .MuiSvgIcon-root { + padding-right : 0 !important; + vertical-align : middle; + } + + .MuiButton-label { + padding-left : 4px !important; + } + ` + +const StyledMenuItem = styled(MenuItem)` + color : #666 !important; + .MuiSvgIcon-root { + vertical-align : middle !important; + } + a { + text-decoration : none !important; + color : #666 !important; + } +` diff --git a/src/Components/ResourcePageComponents/Footer.js b/src/Components/ResourcePageComponents/Footer.js index 83a932f6cf51cb7c4ebd1b532150df46f210ccd8..ea2253c4718394b629ae4603ce7d1645d3142d43 100644 --- a/src/Components/ResourcePageComponents/Footer.js +++ b/src/Components/ResourcePageComponents/Footer.js @@ -120,7 +120,6 @@ export default function Footer (props) { <GuardarModal open={saveToCol} handleClose={() => {toggleSave(false)}} thumb={props.thumb} title={props.title} recursoId={props.recursoId} - handleSnackbar={props.handleSnackbar} /> <RedirectModal open={redirectOpen} handleClose={() => {toggleRedirect(false)}} link={props.link} diff --git a/src/Components/ResourcePageComponents/Sobre.js b/src/Components/ResourcePageComponents/Sobre.js index 630ca9c4d060f13ab4149cb17fe8c55a0acb72c0..1b4bfa627f4d5d8d4b8b2c612c607845c706b4c7 100644 --- a/src/Components/ResourcePageComponents/Sobre.js +++ b/src/Components/ResourcePageComponents/Sobre.js @@ -33,6 +33,7 @@ import DateRangeIcon from '@material-ui/icons/DateRange'; import UpdateIcon from '@material-ui/icons/Update'; import AssignmentIcon from '@material-ui/icons/Assignment'; import License from '../../img/cc_license.png' +import ContactCardOptions from '../ContactCardOptions.js' function AdditionalInfoItem (props) { return ( @@ -111,7 +112,7 @@ export default function Sobre (props) { <img src={License} alt="license"/> </a> <p> - {props.license.name}<br/>4.0 Internacional + {props.license.name} </p> </div> } @@ -128,7 +129,8 @@ export default function Sobre (props) { Informação não disponÃvel. </p> </div> - }/>) + } + key={"no-license"}/>) } setAdditionalInfo(aux) }, []) @@ -194,12 +196,12 @@ export default function Sobre (props) { </Link> </div> - <div style={{paddingTop : "0.75em"}}> + <div style={{paddingTop : "0.75em", display : "flex", justifyContent : "center"}}> { (props.id != state.currentUser.id) && <> - <NoIcon/> - <MoreVertIcon style={{verticalAlign : "middle"}}/> + <NoIcon followableID={props.id}/> + <ContactCardOptions followableID={props.id}/> </> } </div> diff --git a/src/Components/ResourcePageComponents/TextoObjeto.js b/src/Components/ResourcePageComponents/TextoObjeto.js index ca77e9b02f1eea3861611ec6d91e42b0639767e3..ff88dff912cbc6b6358312fdc7b1362eed643d57 100644 --- a/src/Components/ResourcePageComponents/TextoObjeto.js +++ b/src/Components/ResourcePageComponents/TextoObjeto.js @@ -95,6 +95,19 @@ export default function TextoObjeto (props) { ) } + const checkAccessLevel = (levelToCheck) => { + if (state.currentUser.id != '') { + return(checkUserRole(levelToCheck)) + } + else { + return(false) + } + } + + const checkUserRole = (userRole) => { + return(state.currentUser.roles.filter((role) => role.name === userRole).length > 0) + } + return ( <TextoObjetoDiv> <Snackbar open={snackbarOpen} autoHideDuration={1000} onClose={() => {toggleSnackbar(false)}} @@ -107,12 +120,15 @@ export default function TextoObjeto (props) { <Grid container style={{paddingLeft : "15px"}}> <Grid item xs={11}> <h3>{props.name}</h3> - <Firulas - rating={props.rating} - likesCount={props.likesCount} - liked={props.likedBool} - recursoId={props.recursoId} - /> + { + props.stateRecurso !== "submitted" && + <Firulas + rating={props.rating} + likesCount={props.likesCount} + liked={props.likedBool} + recursoId={props.recursoId} + /> + } { infos.map( (info) => @@ -165,9 +181,12 @@ export default function TextoObjeto (props) { {/*|| checkUserRole('publisher')*/} {props.id === state.currentUser.id && <React.Fragment> - <Link to={"/editar-recurso/" + props.recursoId}> - <Button style={{color : "#666"}}><EditIcon/></Button> - </Link> + { + (checkAccessLevel('publisher') || props.stateRecurso === "draft") && + <Link to={"/editar-recurso/" + props.recursoId}> + <Button style={{color : "#666"}}><EditIcon/></Button> + </Link> + } <Button style={{color : "#666"}} onClick={() => {handleDelete()}}><DeleteForeverIcon/></Button> </React.Fragment> } diff --git a/src/Components/SnackbarComponent.js b/src/Components/SnackbarComponent.js new file mode 100644 index 0000000000000000000000000000000000000000..74730d3c4b949a6e4af69f5799ba6bad09961fca --- /dev/null +++ b/src/Components/SnackbarComponent.js @@ -0,0 +1,33 @@ +/*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 Alert from '../Components/Alert.js'; +import Snackbar from '@material-ui/core/Snackbar'; + +export default function SnackbarComponent (props) { + return ( + <Snackbar open={props.snackbarOpen} autoHideDuration={1000} onClose={props.handleClose} + anchorOrigin = {{ vertical:'top', horizontal:'right' }} + > + <Alert severity={props.severity} style={{backgroundColor:"#00acc1"}}> + {props.text} + </Alert> + </Snackbar> + ) +} diff --git a/src/Components/TabPanels/PanelComponents/TemplateColecao.js b/src/Components/TabPanels/PanelComponents/TemplateColecao.js index acd17dcfb6a4f17e78a1eb53e2f68808f582ae6a..dfb193fc5a5db0774c39c7df8095153eedc36c59 100644 --- a/src/Components/TabPanels/PanelComponents/TemplateColecao.js +++ b/src/Components/TabPanels/PanelComponents/TemplateColecao.js @@ -35,11 +35,14 @@ export default function PanelTemplateColecao (props) { type={card.followable.object_type} description={card.followable.description} author={card.followable.owner.name} + authorID={card.followable.owner.id} avatar={card.followable.owner.avatar} thumbnails={card.followable.items_thumbnails} likeCount={card.followable.likes_count} liked={card.followable.liked} followed={card.followable.followed} + privacy={card.followable.privacy} + id={card.followable.id} /> ) } @@ -52,11 +55,14 @@ export default function PanelTemplateColecao (props) { description={card.description} author={card.owner.name} avatar={card.owner.avatar} + authorID={card.owner.id} thumbnails={card.items_thumbnails} likeCount={card.likes_count} + privacy={card.privacy} liked={card.liked} followed={card.followed} tags={card.tags} + id={card.id} /> ) } @@ -80,6 +86,7 @@ export default function PanelTemplateColecao (props) { ( [ <React.Fragment> + <StyledGrid container spacing={1} style={{paddingLeft : "30px", paddingRight : "15px"}}> { props.sliceArr.map( (card) => diff --git a/src/Components/TabPanels/PanelComponents/TemplateCuradoria.js b/src/Components/TabPanels/PanelComponents/TemplateCuradoria.js index 51110b38f473c3f443017d345b4dbad8a8b95c01..132b96efa8ba381fa3ad1eb5cdfc0fb66611965f 100644 --- a/src/Components/TabPanels/PanelComponents/TemplateCuradoria.js +++ b/src/Components/TabPanels/PanelComponents/TemplateCuradoria.js @@ -48,6 +48,7 @@ export default function Template (props) { props.sliceArr.map( (card) => <Grid item md={3} xs={12} key={card.id}> <ResourceCardFunction + id={card.learning_object.id} avatar = {card.submitter.avatar} thumbnail = {card.learning_object.thumbnail} type = {card.learning_object.object_type ? card.learning_object.object_type : "Outros"} @@ -55,6 +56,7 @@ export default function Template (props) { published={false} tags={card.educational_stages} href={"/recurso/" + card.learning_object.id} + downloadableLink={card.default_attachment_location} /> </Grid> ) diff --git a/src/Components/TabPanels/PanelComponents/TemplateRecurso.js b/src/Components/TabPanels/PanelComponents/TemplateRecurso.js index 4407bcf2ffe6b9a491ec2c400f5cf63cc0039cf3..6d46e423e6c596efbff5a2725d7ba5d8bb26feab 100644 --- a/src/Components/TabPanels/PanelComponents/TemplateRecurso.js +++ b/src/Components/TabPanels/PanelComponents/TemplateRecurso.js @@ -49,15 +49,18 @@ export default function Template (props) { <Grid item md={3} xs={12} key={card.id}> <ResourceCardFunction avatar = {card.publisher.avatar} + id={card.id} thumbnail = {card.thumbnail} type = {card.object_type !== null? card.object_type : "Outros"} title={card.name} published={card.state === "published" ? true : false} likeCount={card.likes_count} liked={card.liked} - rating={card.score} + rating={card.review_average} tags={card.educational_stages} href={"/recurso/" + card.id} + downloadableLink={card.default_attachment_location} + /> </Grid> ) diff --git a/src/Components/TabPanels/PublicUserPageTabs/LastLearnObj.js b/src/Components/TabPanels/PublicUserPageTabs/LastLearnObj.js index 23507b228b38b80d5a65b53e24e942237cb06081..d1c3b1315e2a13da178548ceb5259e4bc47f2a63 100644 --- a/src/Components/TabPanels/PublicUserPageTabs/LastLearnObj.js +++ b/src/Components/TabPanels/PublicUserPageTabs/LastLearnObj.js @@ -45,14 +45,18 @@ export default function LastLearnObjs (props) { <Grid item md={3} xs={12} key={card.id}> <ResourceCardFunction avatar = {card.publisher.avatar} + id={card.id} thumbnail = {card.thumbnail} - type = {card.object_type ? card.object_type : "Outros"} + type = {card.object_type !== null? card.object_type : "Outros"} title={card.name} published={card.state === "published" ? true : false} likeCount={card.likes_count} liked={card.liked} - rating={card.score} + rating={card.review_average} tags={card.educational_stages} + href={"/recurso/" + card.id} + downloadableLink={card.default_attachment_location} + /> </Grid> ) diff --git a/src/Components/TabPanels/PublicUserPageTabs/TabRecursos.js b/src/Components/TabPanels/PublicUserPageTabs/TabRecursos.js index 1281f43b73e5d4b7383c46a324fccaaffd5d7d84..ce445d9ad57aa2b6627018314a45741b23ad1b5b 100644 --- a/src/Components/TabPanels/PublicUserPageTabs/TabRecursos.js +++ b/src/Components/TabPanels/PublicUserPageTabs/TabRecursos.js @@ -35,14 +35,17 @@ export default function TabRecursos (props) { <Grid item md={3} xs={12} key={card.id}> <ResourceCardFunction avatar = {card.publisher.avatar} + id={card.id} thumbnail = {card.thumbnail} type = {card.object_type ? card.object_type : "Outros"} title={card.name} published={card.state === "published" ? true : false} likeCount={card.likes_count} liked={card.liked} - rating={card.score} + rating={card.review_average} tags={card.educational_stages} + downloadableLink={card.default_attachment_location} + /> </Grid> ) diff --git a/src/Components/TabPanels/StyledComponents.js b/src/Components/TabPanels/StyledComponents.js index 81aa7e85c18af601c0b11657a85394fba9b57126..2570be1d40a302c096a4432e8feede85b95f3685 100644 --- a/src/Components/TabPanels/StyledComponents.js +++ b/src/Components/TabPanels/StyledComponents.js @@ -216,6 +216,9 @@ export const StyledTabs = styled(Tabs)` .MuiTab-textColorPrimary.Mui-selected { color : #00bcd4; } + .PrivateTabIndicator-colorPrimary-4 { + background-color : #00bcd4 !important; + } ` export const RodapeDiv = styled.div` diff --git a/src/Components/TabPanels/UserPageTabs/PanelColecoes.js b/src/Components/TabPanels/UserPageTabs/PanelColecoes.js index f39a6752f87df2de03aba93b94ce1a9508a12b28..f7883396f3359173d24eace08e1826429bdd8210 100644 --- a/src/Components/TabPanels/UserPageTabs/PanelColecoes.js +++ b/src/Components/TabPanels/UserPageTabs/PanelColecoes.js @@ -50,7 +50,7 @@ export default function TabPanelColecoes (props) { .then( (responseArr) => { console.log('responseArr Colecoes: ', responseArr) if (responseArr[1].headers['access-token']) { - sessionStorage.setItem('@portalmec/accessToken', responseArr[0].headers['access-token']) + sessionStorage.setItem('@portalmec/accessToken', responseArr[1].headers['access-token']) } handleLoading(false) @@ -118,7 +118,6 @@ export default function TabPanelColecoes (props) { sliceArr={userCollectionsSlice} showMore={showMoreUserCollections} showAll={showAllUserCollections} - followed={false} callback={getInfo} /> @@ -187,11 +186,14 @@ function Tentativa (props) { description={card.description} author={card.owner.name} avatar={card.owner.avatar} + authorID={card.owner.id} thumbnails={card.items_thumbnails} likeCount={card.likes_count} liked={card.liked} followed={card.followed} tags={card.tags} + privacy={card.privacy} + id={card.id} /> </Grid> ) diff --git a/src/Components/UploadPageComponents/FineUploaderDropzone.js b/src/Components/UploadPageComponents/FineUploaderDropzone.js new file mode 100644 index 0000000000000000000000000000000000000000..33f1f06de4e1799b390588927bae25d4ec0bb812 --- /dev/null +++ b/src/Components/UploadPageComponents/FineUploaderDropzone.js @@ -0,0 +1,30 @@ +import React from 'react' +import Dropzone from 'react-fine-uploader/dropzone' +import FineUploaderTraditional from 'fine-uploader-wrappers' +import {apiUrl, apiDomain} from '../../env.js' + +export default function FineUploaderDropzone (props) { + + const uploader = new FineUploaderTraditional({ + options: { + request: { + endpoint: `${apiUrl}/learning_objects/` + props.draftID + '/chunk' + }, + chunking : { + enabled : true, + partSize : 10000000, + }, + deleteFile : { + enabled : true, + endpoint: `${apiUrl}/learning_objects/` + props.draftID + '/chunk' + } + } + }) + return ( + <Dropzone style={ { border: '1px dotted', height: 200, width: 200 } } + uploader={ uploader } + > + <span>Drop Files Here</span> + </Dropzone> + ) +} diff --git a/src/Components/UploadPageComponents/PartTwo.js b/src/Components/UploadPageComponents/PartTwo.js index f11efe367098ce78ad940a6294cf97becef46543..49b5b49f89f710161a9fb35746fb6779d28cb9e4 100644 --- a/src/Components/UploadPageComponents/PartTwo.js +++ b/src/Components/UploadPageComponents/PartTwo.js @@ -36,7 +36,7 @@ import {getAxiosConfig} from '../HelperFunctions/getAxiosConfig' import DisplayThumbnail from './PartTwoComponents/DisplayThumbnail.js' import CustomCircularProgress from './PartTwoComponents/CustomCircularProgress'; -function LoadingDiv () { +export function LoadingDiv () { return ( <div style={{width : "100%", display : "flex", alignItems : "center", justifyContent : "center", color : "#666"}}> <CustomCircularProgress/> CARREGANDO IMAGEM diff --git a/src/Components/UploadPageComponents/PartTwoComponents/DisplayThumbnail.js b/src/Components/UploadPageComponents/PartTwoComponents/DisplayThumbnail.js index be2920f8b0e9dda8098806aa8fd9eba63744ce8d..b18e67edd046ef6f3f3bc786ba9df8e7fc00a1b4 100644 --- a/src/Components/UploadPageComponents/PartTwoComponents/DisplayThumbnail.js +++ b/src/Components/UploadPageComponents/PartTwoComponents/DisplayThumbnail.js @@ -15,7 +15,19 @@ export default function DisplayThumbnail (props) { return ( <React.Fragment> <StyledFormLabel component="legend" style={{fontSize : "14px", marginBottom : "10px"}}> - <b>Editando Imagem</b> <span style={{color : "#a5a5a5"}}>(Deixe seu recurso completo, para que todos o entendam melhor.)</span> + { + props.onEditPage ? + ( + <b style={{fontWeight : "ligther"}}>Imagem ilustrativa do recurso</b> + ) + : + ( + <> + <b>Editando Imagem</b> + <span style={{color : "#a5a5a5"}}>(Deixe seu recurso completo, para que todos o entendam melhor.)</span> + </> + ) + } </StyledFormLabel> <ImagemCarregada container> <Grid item xs={windowWidth > 990 ? 6 : 12}> @@ -24,11 +36,14 @@ export default function DisplayThumbnail (props) { <div className="alterar-imagem"> <input type="file" onChange = {(e) => handleUpload(e, e.target.files)} id="upload-file-thumbnail" style={{display : "none"}} /> - <label htmlFor="upload-file-thumbnail" style={{width : "inherit", cursor : "pointer"}}> + <label htmlFor="upload-file-thumbnail" style={{height : "100%", width : "inherit", cursor : "pointer"}}> <div className="interacoes"> SUBSTITUIR <AddAPhotoIcon/> </div> </label> + <div className="interacoes" onClick={() => {props.handleDelete()}}> + DELETAR <AddAPhotoIcon/> + </div> </div> </div> </Grid> @@ -72,7 +87,6 @@ const ImagemCarregada = styled(Grid)` width : 100%; justify-content : flex-end; background-color : rgba(0,0,0,.5); - height : 50px; .interacoes { cursor : pointer; diff --git a/src/Components/UploadPageComponents/PartTwoComponents/DragAndDropThumbnail.js b/src/Components/UploadPageComponents/PartTwoComponents/DragAndDropThumbnail.js index 49546df02f7521da804af1375a2bc477bfd44526..c472b5f8a309cab8f91a465fba22e3d97030ef33 100644 --- a/src/Components/UploadPageComponents/PartTwoComponents/DragAndDropThumbnail.js +++ b/src/Components/UploadPageComponents/PartTwoComponents/DragAndDropThumbnail.js @@ -67,7 +67,18 @@ export default function DragAndDropThumbnail (props) { return ( <FormControl style={{width : "100%"}}> <StyledFormLabel component="legend" style={{fontSize : "14px", marginBottom : "10px"}}> - <b>Imagem Ilustrativa do Recurso</b> <span style={{color : "#a5a5a5"}}>(Deixe seu recurso completo, para que todos o entendam melhor.)</span> + { + props.onEditPage ? + ( + <b style={{textAlign : "center", fontSize : "26px", fontWeight : "ligther"}}>Inserir Imagem Ilustrativa</b> + ) + : + ( + <> + <b>Imagem Ilustrativa do Recurso</b> <span style={{color : "#a5a5a5"}}>(Deixe seu recurso completo, para que todos o entendam melhor.)</span> + </> + ) + } </StyledFormLabel> <DottedBox onDrop={e => handleDrop(e)} diff --git a/src/Components/UploadPageComponents/UploadFileWrapper.js b/src/Components/UploadPageComponents/UploadFileWrapper.js index 59c4522fd8afec5f4305d9b2c1a81b7894838781..14f7a44788d88468a959cff4a1bc2475dea4d227 100644 --- a/src/Components/UploadPageComponents/UploadFileWrapper.js +++ b/src/Components/UploadPageComponents/UploadFileWrapper.js @@ -22,7 +22,8 @@ import ChooseLink from './ChooseLinkSection.js' import {WrapperBox, StyledTextField, BlueButton, GrayButton} from './StyledComponents.js'; import DragAndDrop from './DragAndDrop.js' import FileUploadStage from './FileUploadStage.js' - +import { UploaderComponent } from '@syncfusion/ej2-react-inputs'; +import FineUploaderDropzone from './FineUploaderDropzone' export default function UploadFileWrapper (props) { /*----------------------------------------------------------------- - Wrapper for file upload box @@ -32,7 +33,7 @@ export default function UploadFileWrapper (props) { - Uploading File: displayed when the user chooses a file to upload. The file upload box is in "DragAndDrop.js", and the actual upload view is in "FileUploadStage.js" - Props used: - - submit : called when the user clicks "ENVIAR" inside ChooseLinkSection; renders the alert snackbar to let them know the link was submitted + - submit : called when the user clicks "ENVIAR" inside ChooseLinkSection; renders the alert snackbar to let them know the link was submitted */ const [stage, setStage] = useState("default") @@ -41,6 +42,7 @@ export default function UploadFileWrapper (props) { const [files, setFile] = useState([]) const acceptFile = (files) => { + console.log(files) setFile(files) setStage("fileSelected") } @@ -61,9 +63,9 @@ export default function UploadFileWrapper (props) { <div className="inner"> <div className="upload-title"> Enviar Recurso</div> <div className="flex-column"> - + <UploaderComponent /> <DragAndDrop acceptFile={acceptFile}/> - + {/*<FineUploaderDropzone draftID={props.draftID}/>*/} <div className="strike-box"> <div className="strike"/><h3>ou</h3><div className="strike"/> </div> diff --git a/src/Pages/EditLearningObjectPage.js b/src/Pages/EditLearningObjectPage.js index 96fed1f7190761fc2e67baa90156c75fe2442cb6..3b1436dd2df296e36f0d84e29612d825568d1496 100644 --- a/src/Pages/EditLearningObjectPage.js +++ b/src/Pages/EditLearningObjectPage.js @@ -39,6 +39,12 @@ import EducationalStage from '../Components/UploadPageComponents/PartTwoComponen import SubjectsAndThemes from '../Components/UploadPageComponents/PartTwoComponents/SubjectsAndThemes.js' import Licenca from '../Components/UploadPageComponents/PartTwoComponents/Licenca.js' import { Button } from '@material-ui/core'; +import {LoadingDiv} from '../Components/UploadPageComponents/PartTwo.js' +import EditThumbnail from '../Components/UploadPageComponents/PartTwoComponents/EditThumbnail.js' +import DisplayThumbnail from '../Components/UploadPageComponents/PartTwoComponents/DisplayThumbnail.js' +import CustomCircularProgress from '../Components/UploadPageComponents/PartTwoComponents/CustomCircularProgress'; +import DragAndDropThumbnail from '../Components/UploadPageComponents/PartTwoComponents/DragAndDropThumbnail' + export default function EditLearningObjectPage (props) { const recursoId = props.match.params.recursoId @@ -58,6 +64,10 @@ export default function EditLearningObjectPage (props) { sessionStorage.setItem('@portalmec/accessToken', response.headers['access-token']) } setLearningObject(response.data) + if(response.data.thumbnail) { + setThumbnail(response.data.thumbnail) + setThumbnailStage('done') + } setUpdatedInfo({...updatedInfo, ['id'] : response.data.id}) toggleLoading(false) }, (error) => {console.log(error)} @@ -92,7 +102,7 @@ export default function EditLearningObjectPage (props) { }, (error) => {console.log(error)} ) - }, []) + }, [, state.currentUser.id]) const [object, setObject] = useState() const handleChooseObject = (obj) => { @@ -151,6 +161,100 @@ export default function EditLearningObjectPage (props) { ) } + const [thumbnailStage, setThumbnailStage] = useState('default') + + const [thumbnail, setThumbnail] = useState('') + const [tempUrl, setTempUrl] = useState('') + + const acceptFile = (file) => { + const objectURL = URL.createObjectURL(file) + console.log('acceptFile: ', file) + setTempUrl(objectURL) + setThumbnailStage('editing') + } + const updateThumb = (newThumbnail) => { + setThumbnail(newThumbnail) + console.log('updateThumb: ', thumbnail) + + } + + const finalizeThumb = () => { + setThumbnailStage('uploading') + let config = { + headers : { + 'Accept': 'application/json', + 'Content-Type': 'application/json', + } + } + config.headers["access-Token"] = sessionStorage.getItem('@portalmec/accessToken'); + config.headers.client = sessionStorage.getItem('@portalmec/clientToken') + config.headers.uid = sessionStorage.getItem('@portalmec/uid') + + let fdThumb = new FormData() + fdThumb.set('learning_object[thumbnail]', thumbnail) + axios.put((`${apiUrl}/learning_objects/` + learningObject.id), fdThumb, config).then( + (response) => { + setThumbnailStage('done') + console.log(response.data) + if ( response.headers['access-token'] ) { + sessionStorage.setItem('@portalmec/accessToken', response.headers['access-token']) + } + if(response.data.thumbnail) { + setThumbnail(response.data.thumbnail) + setThumbnailStage('done') + } + }, + (error) => { + setThumbnailStage('default') + } + ) + } + + const handleDeleteThumbnail = () => { + let config = { + headers : { + 'Accept': 'application/json', + 'Content-Type': 'application/json', + } + } + config.headers["access-Token"] = sessionStorage.getItem('@portalmec/accessToken'); + config.headers.client = sessionStorage.getItem('@portalmec/clientToken') + config.headers.uid = sessionStorage.getItem('@portalmec/uid') + + let fdThumb = new FormData() + fdThumb.set('learning_object[thumbnail]', null) + axios.put((`${apiUrl}/learning_objects/` + learningObject.id), fdThumb, config).then( + (response) => { + setThumbnailStage('default') + console.log(response.data) + if ( response.headers['access-token'] ) { + sessionStorage.setItem('@portalmec/accessToken', response.headers['access-token']) + } + }, + (error) => { + console.log(error) + } + ) + } + + const chooseRenderStageThumbnail = () => { + switch(thumbnailStage) { + case 'uploading': + return (<LoadingDiv/>) + break; + case 'done': + return (<DisplayThumbnail acceptFile={acceptFile} thumbnail={`${apiDomain}` + thumbnail} onEditPage={true} handleDelete={handleDeleteThumbnail}/>) + break; + case 'editing': + return (<EditThumbnail finalizeThumb={finalizeThumb} tempImgURL={tempUrl} updateThumb={updateThumb}/>) + break; + default : + return (<DragAndDropThumbnail acceptFile={acceptFile} onEditPage={true}/>) + break; + + } + } +{/*PEGAR A THUMBNAIL JA EXISTENTE SE HOUVER*/} return ( <React.Fragment> <Snackbar open={snackbarOpen} autoHideDuration={1000} onClose={() => {toggleSnackbar(false)}} @@ -176,6 +280,10 @@ export default function EditLearningObjectPage (props) { <h2>Editar Recurso</h2> </div> + <Grid item xs={12} style={{paddingBottom : "40px"}}> + {chooseRenderStageThumbnail()} + </Grid> + <Grid container style={{paddingLeft : "15px", paddingRight : "15px"}}> <Grid item xs={12} style={{paddingBottom : "40px"}}> <NewTitle draftID={learningObject.id} initialValue={learningObject.name} diff --git a/src/Pages/PasswordRecoveryPage.js b/src/Pages/PasswordRecoveryPage.js index 70895507161afa2a6272b01898fb5bd798d65d33..82038103ec38d07b3cedb99394d567b9f62b2f22 100644 --- a/src/Pages/PasswordRecoveryPage.js +++ b/src/Pages/PasswordRecoveryPage.js @@ -8,19 +8,21 @@ import ValidateUserInput from '../Components/FormValidationFunction.js' import {CompletarCadastroButton} from '../Components/TabPanels/UserPageTabs/PanelSolicitarContaProfessor.js' import Default from '../Components/PasswordRecoveryComponents/Default.js' import Success from '../Components/PasswordRecoveryComponents/Success.js' +import CaseError from '../Components/PasswordRecoveryComponents/Error.js' import {Store} from '../Store.js' -import Error from '../Components/PasswordRecoveryComponents/Error.js' import CustomizedBreadcrumbs from '../Components/TabPanels/Breadcrumbs.js' +import {apiUrl, apiDomain} from '../env'; +import axios from 'axios' + export default function PasswordRecoveryPage (props) { const {state, dispatch} = useContext(Store) const [formEmail, setEmail] = useState( { - dict : { - key : false, - value : "" - } + key : false, + value : "" + } ) @@ -28,32 +30,40 @@ export default function PasswordRecoveryPage (props) { const userInput = e.target.value const flag = ValidateUserInput('email', userInput) - setEmail({...formEmail, dict : { + setEmail({...formEmail, key : flag, value : userInput - }}) - console.log(formEmail) + }) } const [aux, setCase] = useState('default') - const handleChangeSwitch = (value) => setCase(value); + const handleChangeSwitch = (value) => { + console.log(value) + if (value !== "success") { + setEmail({key : false, value : ""}) + } + setCase(value) + }; - const onSubmit = (e, email) => { + const onSubmit = (e) => { e.stopPropagation() - const query = email - - setEmail({...formEmail, dict : { - key : false, - value : '' - }}) - handleChangeSwitch('error') + const payload = { + "email" : formEmail.value, + "redirect_url" : "https://plataformaintegrada.mec.gov.br/recuperar-senha#/alterar-senha" + } + axios.post((`${apiUrl}/auth/password`), payload).then( + (response) => { + console.log(response) + handleChangeSwitch(response.data.success ? "success" : "error") + }, + (error) => {console.log(error)}) } const components = { - default : <Default handleChange={handleChange} onSubmit={onSubmit} value={formEmail.dict.value} error={formEmail.dict.key}/>, - success : <Success email={state.currentUser.email} changeSwitch={handleChangeSwitch}/>, - error : <Error email={state.currentUser.email} handleChange={handleChange} onSubmit={onSubmit} value={formEmail.dict.value} error={formEmail.dict.key}/> + default : <Default handleChange={handleChange} onSubmit={onSubmit} value={formEmail.value} error={formEmail.key}/>, + success : <Success email={formEmail.value} changeSwitch={handleChangeSwitch}/>, + error : <CaseError handleChange={handleChange} onSubmit={onSubmit} value={formEmail.value} error={formEmail.key}/> } const switchFunction = (value) => { diff --git a/src/Pages/PublicUserPage.js b/src/Pages/PublicUserPage.js index a073ebdca4a7d50c8af1d4d7f4a4d072df6107f6..2c38097a295c96674ee4935aa944af8a223181c7 100644 --- a/src/Pages/PublicUserPage.js +++ b/src/Pages/PublicUserPage.js @@ -74,7 +74,7 @@ const RenderUserProfileInfo = (userName) => { return ( <UserProfileInfoDiv> <p - style={{fontSize:"28px", color:"#fff", marginBottom : "2px", fontWeight:"500", borderRadius : "5px"}} + style={{fontSize:"28px", color:"#fff", marginBottom : "2px", fontWeight:"500", borderRadius : "5px", textShadow : "0 1px 2px rgba(0,0,0,.45)"}} > {userName} </p> @@ -193,7 +193,7 @@ export default function PublicUserPage (props) { > { tabs.map( (tab) => - <Tab label ={tab} key={tab} + <Tab label={tab} key={tab} disabled={tab === "Recursos" && learningObjArr.length === 0 || tab === "Coleções" && collectionsArr.length === 0} /> ) diff --git a/src/Pages/ResourcePage.js b/src/Pages/ResourcePage.js index 5a565144adaf05fed1b44f710dd075d9b185a429..9ed188d5fd6539de5da9d98253e1921c5f91a3b2 100644 --- a/src/Pages/ResourcePage.js +++ b/src/Pages/ResourcePage.js @@ -188,12 +188,12 @@ export default function LearningObjectPage (props){ <img src={apiDomain + recurso.thumbnail}/> } - {/*adicionar opcoes caso o usuario seja o publisher*/} - {/*adicionar links para os botoes de editar/deletar*/} - {/*implementar checkUserRole('publisher')*/} + + + <TextoObjeto name={recurso.name} - rating={recurso.rating} + rating={recurso.review_average} recursoId={id} likesCount={recurso.likes_count} likedBool={recurso.liked} @@ -208,8 +208,8 @@ export default function LearningObjectPage (props){ audioUrl={recurso.default_attachment_location} /> </div> - {/*adicionar funcionalidade nos botoes do footer*/} - {/*"Você já reportou esse recurso"*/} + + <Footer recursoId={id} downloadableLink = {recurso.default_attachment_location} @@ -226,8 +226,7 @@ export default function LearningObjectPage (props){ <Grid item xs={12}> <Card> - {/*add option to MoreVertIcon*/} - {/*change render method on additional item info*/} + {/*todo: change render method on additional item info*/} <Sobre avatar={recurso.publisher ? (recurso.publisher.avatar ? (apiDomain + recurso.publisher.avatar) : noAvatar) : noAvatar} publisher={recurso.publisher ? recurso.publisher.name : undefined} diff --git a/src/Pages/UploadPage.js b/src/Pages/UploadPage.js index bc12609c6f72d2b9ffe9741947bf0f276597d2c2..08992d894710d1aea35e801a59ad364dd83ac540 100644 --- a/src/Pages/UploadPage.js +++ b/src/Pages/UploadPage.js @@ -137,7 +137,7 @@ export default function UploadPage (props) { <div className="container"> <Grid container spacing={2}> <Grid item md={4} xs={12}> - <UploadFileWrapper submit={handleChooseObject}/> + <UploadFileWrapper submit={handleChooseObject} draftID={draft.id}/> </Grid> <Grid item md={8} xs={12}> <InfoBox>