From 2339682a51417320849214d2e153a23a42c6dc3a Mon Sep 17 00:00:00 2001 From: Lucas Schoenfelder <les17@inf.ufpr.br> Date: Mon, 8 Jun 2020 17:06:23 -0300 Subject: [PATCH] wip --- .../UploadPageComponents/ChooseLinkSection.js | 99 ++++++ .../UploadPageComponents/DragAndDrop.js | 86 ++++++ .../UploadPageComponents/FileUploadStage.js | 60 ++++ .../UploadPageComponents/LearnObjInfo.js | 35 +++ .../UploadPageComponents/StyledComponents.js | 287 ++++++++++++++++++ .../UploadPageComponents/UploadFileWrapper.js | 84 +++++ 6 files changed, 651 insertions(+) create mode 100644 src/Components/UploadPageComponents/ChooseLinkSection.js create mode 100644 src/Components/UploadPageComponents/DragAndDrop.js create mode 100644 src/Components/UploadPageComponents/FileUploadStage.js create mode 100644 src/Components/UploadPageComponents/LearnObjInfo.js create mode 100644 src/Components/UploadPageComponents/StyledComponents.js create mode 100644 src/Components/UploadPageComponents/UploadFileWrapper.js diff --git a/src/Components/UploadPageComponents/ChooseLinkSection.js b/src/Components/UploadPageComponents/ChooseLinkSection.js new file mode 100644 index 00000000..ef282d1d --- /dev/null +++ b/src/Components/UploadPageComponents/ChooseLinkSection.js @@ -0,0 +1,99 @@ +/*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 styled from 'styled-components' +import LinkIcon from '../../img/link_icon.svg' +import { Button } from '@material-ui/core'; +import TextField from '@material-ui/core/TextField'; +import UndoIcon from '@material-ui/icons/Undo'; +import {WrapperBox, StyledTextField, BlueButton, GrayButton} from './StyledComponents.js' + +export default function ChooseLink (props) { + const [linkSent, setLinkSent] = useState(false) + const [link, setLink] = useState({flag : false, value : ""}) + const handleLink = (e) => { + let userInput = e.target.value + const urlRegex = new RegExp( + "(?:(?:(?:https?|ftp):\/\/))(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,}))\.?)(?::\d{2,5})*(?:[/?#]\S*)?", "i" + ) + let flag = !(urlRegex.test(userInput)) + setLink({...link, + flag : flag, + value : userInput} + ) + } + + const handleSubmit = (e) => { + e.preventDefault() + console.log(link.flag) + if (!link.flag) { + props.submit(link.value) + setLinkSent(true) + } + } + + + return ( + <WrapperBox> + <div className="inner"> + <div className="upload-title"> Enviar Link</div> + + <div className="flex-column"> + <p>Insira o link da página do recurso abaixo:</p> + <form onSubmit={(e) => {handleSubmit(e)}}> + <StyledTextField + id = {"choose-link-form"} + label={"Exemplo: http://google.com"} + type = {"text"} + value = {link.value} + onChange = {e => {handleLink(e)}} + helperText = {link.flag ? "Faltou inserir um endereço eletrônico" : ""} + multiline={true} + rowsMax = {"10"} + rows={1} + error = {link.flag} + required = {true} + disabled={linkSent} + /> + + <div className="buttons-div"> + { + linkSent ? + ( + <BlueButton onClick={() => {setLinkSent(false)}}>Editar</BlueButton> + ) + : + ( + <> + <GrayButton onClick={() => {props.handleNextStage("default")}}> + <span className="button-text"> + <UndoIcon className="icon"/>Voltar + </span> + </GrayButton> + <BlueButton type="submit">SALVAR</BlueButton> + </> + ) + } + </div> + </form> + </div> + </div> + </WrapperBox> + ) +} diff --git a/src/Components/UploadPageComponents/DragAndDrop.js b/src/Components/UploadPageComponents/DragAndDrop.js new file mode 100644 index 00000000..c8f03aa7 --- /dev/null +++ b/src/Components/UploadPageComponents/DragAndDrop.js @@ -0,0 +1,86 @@ +/*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 CloudUploadIcon from '@material-ui/icons/CloudUpload'; +import {DottedBox, BlueButton} from './StyledComponents.js'; + +export default function DragAndDrop (props) { + const [dropDepth, setDropDepth] = useState(0) + const [inDropZone, toggleInDropZone] = useState(false) + const [fileList, setFileList] = useState([]) + + const handleDragEnter = e => { + e.preventDefault(); + e.stopPropagation(); + + setDropDepth(dropDepth + 1) + }; + + const handleDragLeave = e => { + e.preventDefault(); + e.stopPropagation(); + + setDropDepth(dropDepth - 1) + if (dropDepth > 0) + toggleInDropZone(true) + }; + + const handleDragOver = e => { + e.preventDefault(); + e.stopPropagation(); + e.dataTransfer.dropEffect = 'copy'; + toggleInDropZone(true) + }; + + const handleDrop = e => { + e.preventDefault(); + e.stopPropagation(); + let files = [...e.dataTransfer.files] + if (files && files.length > 0) { + props.acceptFile(files) + } + }; + + const handleUpload = (e, selectorFiles : FileList) => { + e.preventDefault(); + props.acceptFile(selectorFiles[0]) + } + return ( + <DottedBox + onDrop={e => handleDrop(e)} + onDragOver={e => handleDragOver(e)} + onDragEnter={e => handleDragEnter(e)} + onDragLeave={e => handleDragLeave(e)} + > + <CloudUploadIcon className="icon"/> + <input + type="file" + onChange = {(e) => handleUpload(e, e.target.files)} + id="upload-file" + style={{display : "none"}} + /> + <BlueButton> + <label htmlFor="upload-file" style={{width : "inherit", cursor : "pointer"}}> + ESCOLHER O ARQUIVO + </label> + </BlueButton> + <span style={{marginTop : "6px"}}>Ou arrastar e soltar o arquivo aqui</span> + </DottedBox> + ) +} diff --git a/src/Components/UploadPageComponents/FileUploadStage.js b/src/Components/UploadPageComponents/FileUploadStage.js new file mode 100644 index 00000000..7b10d066 --- /dev/null +++ b/src/Components/UploadPageComponents/FileUploadStage.js @@ -0,0 +1,60 @@ +/*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, useEffect} from 'react' +import styled from 'styled-components' +import {WrapperBox} from './StyledComponents.js' +import DoneIcon from '@material-ui/icons/Done'; +import DeleteIcon from '@material-ui/icons/Delete'; + +export default function FileUploadStage (props) { + const [uploading, toggleUploading] = useState(true) + + useEffect( () => { + console.log(props.files) + console.log('chamada pro backend enviando o arquivo') + }, []) + + return ( + <WrapperBox> + <div className="inner"> + <div className="upload-title"> + {uploading ? 'Carregando arquivo' : 'O arquivo foi carregado'} + </div> + + <div className="uploading"> + <div className="upload-item"> + <div className="item-info"> + <div className="file-status"> + <DoneIcon className="icon icon-margin"/> file name + </div> + <div className="remove-file"> + Excluir <DeleteIcon className="icon icon-remove"/> + </div> + </div> + </div> + <div className="warning"> + <span>Não se esqueça de preencher as</span> + <br/> + <span>informações sobre o recurso ao lado.</span> + </div> + </div> + </div> + </WrapperBox> + ) +} diff --git a/src/Components/UploadPageComponents/LearnObjInfo.js b/src/Components/UploadPageComponents/LearnObjInfo.js new file mode 100644 index 00000000..0839b40f --- /dev/null +++ b/src/Components/UploadPageComponents/LearnObjInfo.js @@ -0,0 +1,35 @@ +/*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 {InfoBox} from './StyledComponents.js' +import Radio from '@material-ui/core/Radio'; +import RadioGroup from '@material-ui/core/RadioGroup'; +import FormControl from '@material-ui/core/FormControl'; + + + +export default function LearnObjInfo (props) { + return ( + <InfoBox> + <FormControl> + <Radio disableRipple color="default"/> + </FormControl> + </InfoBox> + ) +} diff --git a/src/Components/UploadPageComponents/StyledComponents.js b/src/Components/UploadPageComponents/StyledComponents.js new file mode 100644 index 00000000..5127987b --- /dev/null +++ b/src/Components/UploadPageComponents/StyledComponents.js @@ -0,0 +1,287 @@ +/*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 styled from 'styled-components' +import { Button } from '@material-ui/core'; +import TextField from '@material-ui/core/TextField'; + +export const DottedBox = styled.div` + align-self : center; + width : 320px; + background-color : #f4f4f4; + border : 2px dashed #00bcd4; + align-items : center; + border-radius : 10px; + display : flex; + flex-direction : column; + padding : 20px 0; + color : #666; + + .icon { + font-size : 40px !important; + color : #00bcd4 !important; + margin-bottom : 10px !important; + vertical-align : middle !important; + font-weight : normal !important; + font-style : normal !important; + line-height : 1 !important; + letter-spacing : normal !important; + text-transform : none !important; + display : inline-block !important; + white-space : nowrap !important; + word-wrap : normal !important; + direction : ltr !important; + padding-right : 2px; + } +` + +export const BlueButton = styled(Button)` + &:hover { + background-color : #00acc1 !important; + } + color : #fff !important; + background-color : #00bcd4 !important; + height : 36px !important; + box-shadow : 0 2px 5px 0 rgba(0,0,0,.26) !important; + font-weight : 600 !important; + min-width : 88px !important; + align-self : center !important; + padding : 16px !important; +` + +export const GrayButton = styled(Button)` + &:hover { + background-color : rgba(158,158,158,0.2) !important; + } + height : 36px !important; + font-weight : 600 !important; + color : #666 !important; + background-color: transparent; + min-width : 88px !important; + height : 36px !important; + + .icon { + vertical-align : middle !important; + font-weight : normal !important; + font-style : normal !important; + font-size : 24px !important; + line-height : 1 !important; + letter-spacing : normal !important; + text-transform : none !important; + display : inline-block !important; + white-space : nowrap !important; + word-wrap : normal !important; + direction : ltr !important; + padding-right : 2px; + color : inherit !important; + } + + .button-text { + cursor : pointer; + line-height : 36px; + text-align : center; + color : currentColor; + white-space : nowrap; + text-transform : uppercase; + font-weight : 600; + font-size : 14px; + font-style : inherit; + font-variant : inherit; + } +` + +export const WrapperBox = styled.div` + padding : 0; + margin-bottom : 15px; + display : block; + border-radius : 3px; + box-shadow : 0 1px 3px rgba(0,0,0,.12),0 1px 2px rgba(0,0,0,.24); + background-color : #fff; + font-size : 14px; + + .inner { + display : block; + padding : 20px; + } + + .upload-title { + text-align : center; + font-size : 26px; + margin-bottom : 10px; + font-weight : lighter; + } + + .flex-column { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-orient: vertical; + -webkit-box-direction: normal; + -ms-flex-direction: column; + flex-direction: column; + + p { + margin : 0 0 10px; + } + + .buttons-div { + padding-top : 10px; + padding-left : 15px; + padding-right : 15px; + display: flex; + flex-direction : row; + justify-content : space-evenly; + text-align : center; + } + } + + .strike-box { + display : flex; + flex-direction : row; + justify-content : center; + + .strike { + border-bottom : solid 1px #e5e5e5; + display : inline-block; + vertical-align : middle; + width : 40%; + margin-bottom : 2em; + } + + h3 { + margin : 20px 0; + font-weight : 400; + overflow : hidden; + text-align : center; + font-size : 14px; + color : #666; + padding : 0 5px; + } + } + + .enviar-link-texto { + padding-left : 15px; + padding-right : 15px; + text-align : center; + font-size : 14px; + margin-bottom : 5px; + + img { + height : 35px; + vertical-align : middle; + } + } + + .uploading { + margin-top : 30px; + + .upload-item { + margin-bottom : 5px; + + .item-info { + display : flex; + flex-direction : row; + justify-content : space-between; + align-items : center; + padding : 5px 0; + font-size : 14px; + + .icon { + vertical-align : middle !important; + font-weight : normal !important; + font-style : normal !important; + font-size : 24px !important; + line-height : 1 !important; + letter-spacing : normal !important; + text-transform : none !important; + display : inline-block !important; + white-space : nowrap !important; + word-wrap : normal !important; + direction : ltr !important; + padding-right : 2px; + } + + .file-status { + .icon-margin { + color : #00bcd4; + margin-right : 5px; + } + } + + remove-file { + .icon-remove { + color : #666; + font-size : 20px; + } + } + } + } + + .warning { + padding: 40px 0 20px 0; + margin-top: 40px; + border-top: solid 1px #f4f4f4; + text-align: center; + + span { + font-size : 16px; + font-weight : lighter; + } + } + } +` + +export const StyledTextField = styled(TextField)` + font-size : 14px; + width : 100% !important; + full-width : 100% !important; + margin-bottom : 18px !important; + + .MuiFormControl-root { + margin : 18px 0 !important; + } + .MuiInputLabel-formControl { + position : relative ! important; + } + + .MuiFormHelperText-root { + text-align : left; + font-size : 14px !important ; + } + + label.Mui-focused { + color : #00bcd4; + } + + label.Mui-focused.Mui-error { + color : red; + } + + .MuiInput-underline::after { + border-bottom: 2px solid #00bcd4; + } +` + +export const InfoBox = styled.div` + background-color : #fff; + padding : 30px; + box-shadow : 0 1px 3px rgba(0,0,0,.12),0 1px 2px rgba(0,0,0,.24); + margin-bottom : 30px; + border-radius : 3px; +` diff --git a/src/Components/UploadPageComponents/UploadFileWrapper.js b/src/Components/UploadPageComponents/UploadFileWrapper.js new file mode 100644 index 00000000..59c4522f --- /dev/null +++ b/src/Components/UploadPageComponents/UploadFileWrapper.js @@ -0,0 +1,84 @@ +/*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 LinkIcon from '../../img/link_icon.svg' +import ChooseLink from './ChooseLinkSection.js' +import {WrapperBox, StyledTextField, BlueButton, GrayButton} from './StyledComponents.js'; +import DragAndDrop from './DragAndDrop.js' +import FileUploadStage from './FileUploadStage.js' + +export default function UploadFileWrapper (props) { + /*----------------------------------------------------------------- + - Wrapper for file upload box + - has three different stages: + - Default, contained within this function's default return + - Choosing Link: displayed when the user selects "ENVIAR LINK"; renders "ChooseLinkSection.js" + - 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 + */ + + const [stage, setStage] = useState("default") + const handleNextStage = (newStage) => {setStage(newStage)} + + const [files, setFile] = useState([]) + + const acceptFile = (files) => { + setFile(files) + setStage("fileSelected") + } + + switch (stage) { + case "fileSelected": + return( + <FileUploadStage files={files}/> + ) + case "choosingLink": + return ( + <ChooseLink handleNextStage={handleNextStage} submit={props.submit}/> + ) + break; + default: + return( + <WrapperBox> + <div className="inner"> + <div className="upload-title"> Enviar Recurso</div> + <div className="flex-column"> + + <DragAndDrop acceptFile={acceptFile}/> + + <div className="strike-box"> + <div className="strike"/><h3>ou</h3><div className="strike"/> + </div> + + <div className="enviar-link-texto"> + <img src={LinkIcon}/> + <br/> + <span>Enviar link de um recurso de outro site</span> + </div> + + <BlueButton onClick={ () => {handleNextStage("choosingLink")} }>ENVIAR LINK</BlueButton> + </div> + </div> + </WrapperBox> + ) + } + +} -- GitLab