From 813e2b658930bcdd46dac2ae070c766b1c4a7306 Mon Sep 17 00:00:00 2001 From: Lucas Schoenfelder <les17@inf.ufpr.br> Date: Mon, 1 Mar 2021 21:18:21 -0300 Subject: [PATCH] refactor home screen --- src/App.js | 2 +- src/Components/AreasSubPagesFunction.js | 405 ++++++++++++++++++++++++ src/Components/EcFooter.js | 31 +- src/Components/Funcionalities.js | 2 +- src/Components/HomeScreenSearchBar.js | 174 ++++++++++ src/Components/SearchBar.js | 98 +++--- src/Components/SearchSectionFunction.js | 163 ++++++++++ src/Components/StatsBarFunction.js | 160 ++++++++++ src/Pages/HomeFunction.js | 39 +++ src/img/banner-mobile.jpg | Bin 0 -> 25900 bytes 10 files changed, 1009 insertions(+), 65 deletions(-) create mode 100644 src/Components/AreasSubPagesFunction.js create mode 100644 src/Components/HomeScreenSearchBar.js create mode 100644 src/Components/SearchSectionFunction.js create mode 100644 src/Components/StatsBarFunction.js create mode 100644 src/Pages/HomeFunction.js create mode 100644 src/img/banner-mobile.jpg diff --git a/src/App.js b/src/App.js index 80523ca9..48b49a74 100644 --- a/src/App.js +++ b/src/App.js @@ -17,7 +17,7 @@ You should have received a copy of the GNU Affero General Public License along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ import React, { useContext, useEffect, useState } from 'react'; -import Home from './Pages/Home'; +import Home from './Pages/HomeFunction'; import Search from './Pages/Search' import Header from './Components/Header' import EcFooter from './Components/EcFooter'; diff --git a/src/Components/AreasSubPagesFunction.js b/src/Components/AreasSubPagesFunction.js new file mode 100644 index 00000000..3bbb14e3 --- /dev/null +++ b/src/Components/AreasSubPagesFunction.js @@ -0,0 +1,405 @@ +/*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 "./carousel.css"; +import { Col, Row, Container, Hidden, Visible } from "react-grid-system"; +import styled from 'styled-components' +import MaterialCard from "./MaterialCard"; +import "react-responsive-carousel/lib/styles/carousel.min.css"; +import { Carousel } from "react-responsive-carousel"; +import recursos from "../img/ilustra_recursos_digitais.png"; +import materiais from "../img/ilustra_materiais.png"; +import colecoes from "../img/ilustra_colecoes.png"; +import ResourceCardFunction from "./ResourceCardFunction.js"; +import CollectionCardFunction from "./CollectionCardFunction.js"; +import colecoes_obj from './FormationMaterialsResources/formationMaterials'; +import ExpandedMaterial from './ExpandedMaterials'; +import {getRequest} from './HelperFunctions/getAxiosConfig.js' +import Grid from '@material-ui/core/Grid'; + + +function objectsPerPage () { + var pageWidth = window.innerWidth + if (pageWidth >= 1200) { + return 3 + } + else { + if (pageWidth > 766) { + return 2 + } + else { + return 1 + } + } +} + +function ReqResources () { + const [rows, setRows] = useState([]) + + function onSuccessfulGet (data) { + var aux = [] + var resources_per_page = objectsPerPage() + for (let i = 0; i < 12 / resources_per_page; i++) { + aux.push(data.slice(i * resources_per_page, resources_per_page * (i + 1))) + } + setRows(aux) + } + + useEffect(() => { + const url = `/learning_objects?limit=12&sort=["published_at", "desc"]` + + getRequest(url, (data) => onSuccessfulGet(data), (error) => {console.log(error)}) + }, []) + + return ( + <Carousel showThumbs={false} infiniteLoop={true} showStatus={false}> + { + rows.map((row, index) => ( + <Row style={{ paddingBottom: "5px", margin: '0 auto', width: "80%", justifyContent: "center" }} key={(index + 1)}> + {row.map((card) => ( + <div style={{ marginLeft: 10, display: 'flex' }} key={card.id * (index + 1)}> + <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.review_average} + author={card.publisher.name} + tags={card.tags} + href={"/recurso/" + card.id} + downloadableLink={card.default_attachment_location} + /> + </div> + ))} + </Row> + ))} + </Carousel> + ) +} + +function ReqCollections () { + const [rows, setRows] = useState([]) + + function onSuccessfulGet (data) { + var aux = [] + var collections_per_page = objectsPerPage() + for (let i = 0; i < 12 / collections_per_page; i++) { + aux.push(data.slice(i * collections_per_page, collections_per_page * (i + 1))) + } + setRows(aux) + } + + useEffect(() => { + const url = `/collections?limit=12&sort=["updated_at", "desc"]` + + getRequest(url, (data) => onSuccessfulGet(data), (error) => {console.log(error)}) + }, []) + + return ( + <Carousel showThumbs={false} infiniteLoop={true} showStatus={false}> + { + rows.map((row, index) => ( + <Row style={{ paddingBottom: "5px", margin: '0 auto', width: "80%", justifyContent: "center" }} key={(index + 1)}> + {row.map((card) => ( + <div style={{ marginLeft: 10, display: 'flex' }} key={card.id * (index + 1)}> + <CollectionCardFunction + name={card.name} + tags={card.tags} + rating={card.score} + id={card.id} + author={card.owner.name} + description={card.description} + thumbnails={card.items_thumbnails} + avatar={card.owner.avatar} + likeCount={card.likes_count} + followed={card.followed} + liked={card.liked} + collections={card.collection_items} + authorID={card.owner.id} + /> + </div> + ))} + </Row> + ))} + </Carousel> + ) +} + +function TabRecurso () { + const text = "Nesta área, você tem acesso a Recursos Educacionais Digitais, isto é, a vídeos, animações e a outros recursos destinados à educação. São Recursos de portais parceiros do MEC e de professores que, como você, atuam na Educação Básica!" + + return ( + <React.Fragment> + <div style={{ backgroundColor: "#ff7f00", position: "relative" }}> + <StyledTab container> + <Grid item md={3} xs={12}> + <img + src={recursos} + alt="aba recursos" + style={{ float: "left", marginRight: 20, marginBottom: 20, marginLeft: window.innerWidth >= 825 ? "25%" : "0px" }} + /> + </Grid> + { + window.innerWidth <= 501 && + <h4> + Recursos Educacionais Digitais + </h4> + } + <Grid item md={6} xs={12}> + <p> + {text} + </p> + </Grid> + </StyledTab> + </div> + { + window.innerWidth > 501 && + <Container style={{ padding: "20px" }}> + <p + style={{ + paddingBottom: "5px", + borderBottom: "1px solid #ff7f00", + color: "#ff7f00", + }} + > + Recursos mais recentes{" "} + </p> + <Hidden sm xs> + <ReqResources /> + </Hidden> + <Visible sm xs> + <ReqResources /> + </Visible> + </Container> + } + </React.Fragment> + ) +} + +function TabColecoes () { + const text = "Nesta área, você tem acesso às coleções criadas e organizadas pelos usuários da plataforma. É mais uma possibilidade de buscar recursos educacionais para sua aula!" + + return ( + <React.Fragment> + <div style={{ backgroundColor: "#673ab7", position: "relative" }}> + <StyledTab container> + <Grid item md={3} xs={12}> + <img + src={colecoes} + alt="aba recursos" + style={{ float: "left", marginRight: 20, marginBottom: 20, marginLeft: window.innerWidth >= 825 ? "25%" : "0px" }} + /> + </Grid> + { + window.innerWidth <= 501 && + <h4> + Coleções dos Usuários + </h4> + } + <Grid item md={6} xs={12}> + <p> + {text} + </p> + </Grid> + </StyledTab> + </div> + { + window.innerWidth > 501 && + <Container style={{ padding: "20px" }}> + <p + style={{ + paddingBottom: "5px", + borderBottom: "1px solid #673ab7", + color: "#673ab7", + }} + > + Coleções mais recentes{" "} + </p> + <ReqCollections /> + </Container> + } + </React.Fragment> + ) +} + +function TabMateriais () { + const text = "Nesta área, você acessa livremente materiais completos de formação, como cursos já oferecidos pelo MEC e seus parceiros. São conteúdos elaborados por equipes multidisciplinares e de autoria de pesquisadores e educadores renomados nas áreas." + + const materials = colecoes_obj() + + const [currMaterial, setCurrMaterial] = useState({ + open : false, + material : {} + }) + + const handleExpandMaterial = (id) => { + if (id !== currMaterial.material.id) + setCurrMaterial({ + open: true, + material: { ...materials[id] } + }) + else { + setCurrMaterial({ + open: false, + material: {} + }) + } + } + + return ( + <React.Fragment> + <div style={{ backgroundColor: "#e81f4f", position: "relative" }}> + <StyledTab container> + <Grid item md={3} xs={12}> + <img + src={materiais} + alt="aba recursos" + style={{ float: "left", marginRight: 20, marginBottom: 20, marginLeft: window.innerWidth >= 825 ? "25%" : "0px" }} + /> + </Grid> + { + window.innerWidth <= 501 && + <h4> + Materiais de formação + </h4> + } + <Grid item md={6} xs={12}> + <p> + {text} + </p> + </Grid> + </StyledTab> + </div> + { + window.innerWidth > 501 && + <Container style={{ padding: "20px" }}> + <p + style={{ + paddingBottom: "5px", + borderBottom: "1px solid #e81f4f", + color: "#e81f4f", + }} + > + Materiais mais recentes{" "} + </p> + <Carousel + style={{ padding: "20px" }} + showThumbs={false} + infiniteLoop={true} + showStatus={false} + > + <Row> + { + materials.map((material, index) => { + return ( + <Col md={3} key={index}> + <MaterialCard + name={material.name} + thumb={material.img} + score={material.score} + modules={material.topics} + handleExpand={handleExpandMaterial} + id={index} + /> + </Col> + )}) + } + </Row> + </Carousel> + { + currMaterial.open ? + <ExpandedMaterial material={currMaterial.material} /> + : + null + } + </Container> + } + </React.Fragment > + ) +} + +export default function AreasSubPages (props) { + + const areaRender = () => { + switch (props.banner) { + case "Recursos": + return <TabRecurso/> + case "Materiais": + return <TabMateriais/> + case "Colecoes": + return <TabColecoes/> + default: + return null + } + } + + return ( + <React.Fragment> + { + window.innerWidth <= 501 ? ( + <React.Fragment> + <TabRecurso/> + <TabMateriais/> + <TabColecoes/> + </React.Fragment> + ) : ( + areaRender() + ) + } + </React.Fragment> + ) +} + +const StyledTab = styled(Grid)` + display : flex; + justify-content : center; + @media screen and (min-width : 502px) { + text-align : justify; + } + @media screen and (max-width : 502px) { + text-align : center; + } + color : #fff; + min-height : 190px; + padding : 20px 10px 20px 10px; + + img { + float : left; + max-height : 155px; + } + + .MuiGrid-grid-xs-12 { + display : flex; + justify-content : center; + } + + h4 { + font-size : 18px; + margin : 10px !important; + } + + p { + line-height : 1.42857143; + } + +` diff --git a/src/Components/EcFooter.js b/src/Components/EcFooter.js index f033939d..2bdf8a2f 100644 --- a/src/Components/EcFooter.js +++ b/src/Components/EcFooter.js @@ -22,14 +22,19 @@ import eduConectada from '../img/educa-conectada.png'; import styled from 'styled-components'; import {Link} from 'react-router-dom' -const blueFooter={ - backgroundColor: "#00bcd4", - color: "white", - display: "block", - paddingTop: "2em", - paddingBottom: "2em", - verticalAlign: "bottom", -} +const BlueFooter = styled.div` + background-color : #00bcd4; + color : white; + display : block; + padding-top : 2em; + @media screen and (min-width : 502px) { + padding-bottom : 2em; + } + + vertical-align: bottom; +` + + const listStyle={ listStyleType: "none", fontSize: "80%", @@ -44,10 +49,10 @@ const WhiteLink = styled(Link)` class EcFooter extends Component{ render(){ return( - <div style={blueFooter}> + <BlueFooter> <Container> <Row> - <Col md={4} sm={5} xs={5}> + <Col md={4} sm={6} xs={6} style={window.innerWidth < 502 && {textAlign : "center"} }> <h4>Sobre</h4> <ul style={listStyle}> <li> <WhiteLink to="/sobre">Sobre a Plataforma</WhiteLink> </li> @@ -56,7 +61,7 @@ class EcFooter extends Component{ <li> <WhiteLink to="/contato">Contato</WhiteLink> </li> </ul> </Col> - <Col md={4} sm={5} xs={5}> + <Col md={4} sm={6} xs={6} style={window.innerWidth < 502 && {textAlign : "center"} }> <h4>Ajuda</h4> <ul style={listStyle}> <li> <WhiteLink to="/ajuda">Central de Ajuda</WhiteLink> </li> @@ -66,12 +71,12 @@ class EcFooter extends Component{ <li> <WhiteLink to="/gerenciando-conta">Gerenciando a Conta</WhiteLink> </li> </ul> </Col> - <Col md={4} sm={12} xs={12}> + <Col md={4} sm={12} xs={12} style={window.innerWidth < 502 && {textAlign : "center"} }> <img src={eduConectada} height="50%" alt="logo educação conectada"/> </Col> </Row> </Container> - </div> + </BlueFooter> ) } } diff --git a/src/Components/Funcionalities.js b/src/Components/Funcionalities.js index dad67072..d183d855 100644 --- a/src/Components/Funcionalities.js +++ b/src/Components/Funcionalities.js @@ -45,7 +45,7 @@ const caption={ class Funcionalities extends Component{ render(){ return( - <Container style={{textAlign: "center"}}> + <Container style={{textAlign: "center", paddingBottom : "20px", color : "#666"}}> <h2>Aqui na Plataforma você pode:</h2> <Row style={imgRow}> <Col sm={4} md={4}> diff --git a/src/Components/HomeScreenSearchBar.js b/src/Components/HomeScreenSearchBar.js new file mode 100644 index 00000000..8e372592 --- /dev/null +++ b/src/Components/HomeScreenSearchBar.js @@ -0,0 +1,174 @@ +/*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, useContext } from 'react' +import { Redirect } from 'react-router-dom' +import Grid from '@material-ui/core/Grid'; +import styled from 'styled-components' +import Menu from '@material-ui/core/Menu'; +import { Store } from '../Store'; +import { List, ListItem, ListItemIcon, ListItemText, RadioGroup, Radio, FormControl, Select, MenuItem, Button, FormControlLabel, TextField } from '@material-ui/core' +import ArrowDropDownIcon from '@material-ui/icons/ArrowDropDown'; +import SearchIcon from '@material-ui/icons/Search'; +import {Link} from 'react-router-dom' + +export default function HomeScreenSearchBar (props) { + const [ query, setQuery ] = useState('') + const [ searchClass, setSearchClass ] = useState('LearningObject') + + const { state, dispatch } = useContext(Store) + + const [ goSearch, setGoSearch ] = useState(false) + + useEffect(()=>{ + if(window.location.pathname.includes('busca')){ + const urlParams = new URLSearchParams(window.location.search) + const urlQuery = urlParams.get('query') + const urlSearchClass = urlParams.get('search_class') + if( searchClass !== urlSearchClass || query !== urlQuery){ + setQuery(urlQuery) + setSearchClass(urlSearchClass) + } + } + },[]) + + useEffect(()=>setGoSearch(false),[goSearch]) + + const handleChange = ( event ) => { + setQuery(event.target.value) + } + + const handleKeyDown = (event) => { + if(event.key === 'Enter' || event.type === 'click'){ + dispatch({ + type: 'SAVE_SEARCH', + newSearch: { + query: query!==''?query:'*', + class: searchClass + } + }) + setGoSearch(true) + } + } + + const options = [ + {text : "Recursos", value : "LearningObject", color : "#ff7f00"}, + {text : "Coleções", value : "Collection", color : "#673ab7"}, + {text : "Usuários", value : "User", color : "#00bcd4"}, + ] + const [anchorEl, setAnchorEl] = React.useState(null); + const [selectedIndex, setSelectedIndex] = React.useState(0); + + const handleClickListItem = (event) => { + setAnchorEl(event.currentTarget); + }; + + const handleMenuItemClick = (event, index, value) => { + console.log(value) + setSelectedIndex(index); + setSearchClass(value) + setAnchorEl(null); + }; + + const handleClose = () => { + setAnchorEl(null); + }; + + const WIDTH = window.innerWidth; + + return ( + + <Bar> + <Grid container> + <Grid item xs={7}> + <TextField + id="standard-search" + placeholder="O que você está buscando" + type="search" + margin="normal" + value={query} + onChange={handleChange} + onKeyPress={handleKeyDown} + /> + </Grid> + <Grid item xs={3}> + <List component="nav" aria-label="Recurso"> + <ListItem + button + aria-haspopup="true" + aria-controls="lock-menu" + aria-label="Recurso" + onClick={handleClickListItem} + > + <ListItemText + style={{color : options[selectedIndex].color}} + primary={options[selectedIndex].text} + /> + <ListItemIcon> + <ArrowDropDownIcon/> + </ListItemIcon> + </ListItem> + </List> + <Menu + id="simple-menu" + anchorEl={anchorEl} + keepMounted + open={Boolean(anchorEl)} + onClose={handleClose} + > + {options.map((option, index) => ( + <MenuItem + key={option.value} + selected={index === selectedIndex} + onClick={(event) => handleMenuItemClick(event, index, option.value)} + style={{color : option.color}} + > + {option.text} + </MenuItem> + ))} + </Menu> + </Grid> + <Grid item xs={2}> + <div style={{height : "100%"}}> + <Link to ="/busca"> + <Button className="custom-button" style={{backgroundColor : options[selectedIndex].color, color : "#fff"}}> + <SearchIcon fontSize="large"/> + </Button> + </Link> + </div> + </Grid> + </Grid> + </Bar> + ) +} + +const Bar = styled.div` + background-color : #fff !important; + border-radius : 5px !important; + .MuiList-root { + border-left: 1px solid #ccc !important; + } + + .custom-button { + height: 100% !important; + width: 100% !important; + border-top-right-radius: 0 !important; + border-top-left-radius: 0 !important; + margin: 0 !important; + } +` diff --git a/src/Components/SearchBar.js b/src/Components/SearchBar.js index a38c6b27..faca3453 100644 --- a/src/Components/SearchBar.js +++ b/src/Components/SearchBar.js @@ -23,7 +23,6 @@ import IconSearch from '@material-ui/icons/Search' import { RadioGroup, Radio, FormControl, Select, MenuItem, Button, FormControlLabel, TextField } from '@material-ui/core' import styled from 'styled-components' - import { Store } from '../Store'; @@ -97,13 +96,13 @@ const Flex = styled.span ` color: #787380; ` -export default function SearchBar() { +export default function SearchBar(props) { const [ query, setQuery ] = useState('') const [ searchClass, setSearchClass ] = useState('LearningObject') const { state, dispatch } = useContext(Store) - const [ goSearch, setGoSearch ] = useState(false) + const [ goSearch, setGoSearch ] = useState(false) useEffect(()=>{ if(window.location.pathname.includes('busca')){ @@ -122,7 +121,7 @@ export default function SearchBar() { const handleChange = ( event ) => { setQuery(event.target.value) } - + const handleKeyDown = (event) => { if(event.key === 'Enter' || event.type === 'click'){ dispatch({ @@ -133,54 +132,53 @@ export default function SearchBar() { } }) setGoSearch(true) - } + } } return ( - <Bar> - {goSearch && <Redirect to={`/busca?query=${state.search.query}&search_class=${state.search.class}`} />} - <TextFieldStyled - id="standard-search" - label="O que você está buscando" - type="search" - margin="normal" - value={query} - onChange={handleChange} - onKeyPress={handleKeyDown} - /> - <Flex> - <ButtonStyled onClick={handleKeyDown} ><IconSearchStyled /></ButtonStyled> - <Flex style={{"justifyContent": 'middle', 'flexDirection':'column'}}> - <div>Pressione "Enter"</div> - <div>ou click na lupa</div> - </Flex> - <DividerVertical /> - { state.windowSize.width >=900? - <RadioGroupStyled row={true} - aria-label="Tipo" - name="types" value={searchClass} - onChange={ - (event)=> setSearchClass(event.target.value) - } - > - <FormControlLabelStyled value="LearningObject" control={<RadioStyled />} label="Recursos"/> - <FormControlLabelStyled value="Collection" control={<RadioStyled />} label="Coleções"/> - <FormControlLabelStyled value="User" control={<RadioStyled />} label="Usuários" /> - </RadioGroupStyled> - : - <FormControl> - <SelectStyled - value={searchClass} - onChange={(event)=> setSearchClass(event.target.value)} - > - <MenuItemStyled value="LearningObject" aria-label="Recursos">Recursos</MenuItemStyled> - <MenuItemStyled value="Collection" aria-label="Coleções">Coleções</MenuItemStyled> - <MenuItemStyled value="User" aria-label="Usuários">Usuários</MenuItemStyled> - </SelectStyled> - </FormControl> - } - </Flex> - </Bar> + <Bar> + {goSearch && <Redirect to={`/busca?query=${state.search.query}&search_class=${state.search.class}`} />} + <TextFieldStyled + id="standard-search" + label="O que você está buscando" + type="search" + margin="normal" + value={query} + onChange={handleChange} + onKeyPress={handleKeyDown} + /> + <Flex> + <ButtonStyled onClick={handleKeyDown} ><IconSearchStyled /></ButtonStyled> + <Flex style={{"justifyContent": 'middle', 'flexDirection':'column'}}> + <div>Pressione "Enter"</div> + <div>ou click na lupa</div> + </Flex> + <DividerVertical /> + { state.windowSize.width >=900? + <RadioGroupStyled row={true} + aria-label="Tipo" + name="types" value={searchClass} + onChange={ + (event)=> setSearchClass(event.target.value) + } + > + <FormControlLabelStyled value="LearningObject" control={<RadioStyled />} label="Recursos"/> + <FormControlLabelStyled value="Collection" control={<RadioStyled />} label="Coleções"/> + <FormControlLabelStyled value="User" control={<RadioStyled />} label="Usuários" /> + </RadioGroupStyled> + : + <FormControl> + <SelectStyled + value={searchClass} + onChange={(event)=> setSearchClass(event.target.value)} + > + <MenuItemStyled value="LearningObject" aria-label="Recursos">Recursos</MenuItemStyled> + <MenuItemStyled value="Collection" aria-label="Coleções">Coleções</MenuItemStyled> + <MenuItemStyled value="User" aria-label="Usuários">Usuários</MenuItemStyled> + </SelectStyled> + </FormControl> + } + </Flex> + </Bar> ) } - diff --git a/src/Components/SearchSectionFunction.js b/src/Components/SearchSectionFunction.js new file mode 100644 index 00000000..028fb37b --- /dev/null +++ b/src/Components/SearchSectionFunction.js @@ -0,0 +1,163 @@ +/*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 '../App.css'; +import styled from 'styled-components' +import banner from '../img/bannerBusca.jpg'; +import bannerMobile from '../img/banner-mobile.jpg' +// import SearchBar from './SearchBar'; +import {Row} from 'react-grid-system'; +import {MdInfoOutline} from "react-icons/md" +import { FaRegPlayCircle} from "react-icons/fa"; +import ModalVideoApresentacao from "./ModalVideoApresentacao.js" +import {Link} from 'react-router-dom' +import Grid from '@material-ui/core/Grid'; +import HomeScreenSearchBar from './HomeScreenSearchBar' + +export default function SearchSection (props) { + const [modalOpen, handleModal] = useState(false) + const toggleModal = () => {handleModal(!modalOpen)} + + const WIDTH = window.innerWidth; + return ( + <React.Fragment> + <ModalVideoApresentacao open={modalOpen} handleClose={toggleModal}/> + <Banner> + <StyledGrid container direction="row" justify="center"> + <Grid item style={{paddingRight : "15px", paddingLeft : "15px", paddingBottom : "120px"}}> + <div className="title"> + <h2> + Plataforma MEC de Recursos Educacionais Digitais + </h2> + <h3> + Encontre e compartilhe vídeos, animações e muitos outros Recursos + </h3> + </div> + <HomeScreenSearchBar/> + <div className="links"> + <Link to="/sobre"> + <MdInfoOutline size="24px" style={{verticalAlign: "middle", paddingRight : "5px"}}/> + {WIDTH <= 501 ? ("SOBRE") : ("SOBRE A PLATAFORMA")} + </Link> + <span onClick={toggleModal} style={{cursor : "pointer"}}> + <FaRegPlayCircle size="20px" style={{verticalAlign: "middle", paddingRight : "5px"}}/> + {WIDTH <= 501 ? ("VÍDEO") : ("VÍDEO DE APRESENTAÇÃO")} + </span> + </div> + </Grid> + </StyledGrid> + { + WIDTH > 501 && + <Row justify="center" style={{marginLeft:0, marginRight:0}}> + <button className="recurso" + onClick={() => {props.function("Recursos")}}> + Recursos Educacionais Digitais + </button> + + <button className="material-formacao" + onClick={() => {props.function("Materiais")}}> + Materiais de Formação + </button> + + <button className="colecao" + onClick={() => {props.function("Colecoes")}}> + Coleções dos Usuários + </button> + </Row> + } + </Banner> + </React.Fragment> + ) +} + +const StyledGrid = styled(Grid)` + margin-right : auto !important; + margin-left auto !important; + color : #fff !important; + text-align : center !important; +` + +const Banner = styled.div` + width : 100%; + @media screen and (max-width : 501px) { + background-image : url(${bannerMobile}); + } + @media screen and (min-width : 502px) { + background-image : url(${banner}); + } + background-size : cover; + text-align : center; + + .title { + color : white; + padding-top : 80px; + font-size : 22px; + + h2 { + margin-top : 0 !important; + margin-bottom : 10px !important; + } + + h3 { + font-weight : 100; + font-size : 24px; + margin : 0 !important; + } + } + + .links { + margin-top : 20px; + color : white; + + a { + color : #fff; + text-decoration : none !important; + outline : none; + padding-right : 10px; + } + } + + button { + align-items: flex-start; + font-size: 1.14em; + text-align: center; + cursor: pointer; + border-top-left-radius: 15px; + border-top-right-radius: 15px; + line-height: 1.42857143; + width: 25%; + margin-top: 1%; + color: white; + padding: 1.2%; + border-width: 5%; + border-style: none; + border-image: initial; + outline : none; + } + + .recurso { + background-color : #ff7f00; + } + .material-formacao { + background-color : #e81f4f; + } + .colecao { + background-color : #673ab7; + } +` diff --git a/src/Components/StatsBarFunction.js b/src/Components/StatsBarFunction.js new file mode 100644 index 00000000..8b58fc3e --- /dev/null +++ b/src/Components/StatsBarFunction.js @@ -0,0 +1,160 @@ +/*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 { apiUrl } from "../env"; +import axios from "axios"; +import mapaBrasil from '../img/mapa-brasil-line-icon.svg'; +import Grid from '@material-ui/core/Grid'; + +export default function (props) { + const [available_resources, setAvailableResources] = useState(0) + const [month_publications, setMonthPublications] = useState(0) + const [month_downloads, setMonthDownloads] = useState(0) + + useEffect(() => { + axios.get(`${apiUrl}/statistics`) + .then( + (res) => { + setAvailableResources(res.data.count) + setMonthPublications(res.data.month_publications) + setMonthDownloads(res.data.month_downloads) + }) + }, []) + + return ( + <StatsTab> + <StyledGrid container> + <Grid item md={6} xs={12} className="first"> + <img src={mapaBrasil} height="83px" alt="mapa do brasil"/> + <span className="total"> + <span className="numeros"> + {available_resources} + </span> + <span className="legenda"> + Recursos disponíveis + </span> + </span> + </Grid> + + <Grid item md={6} xs={12} className="second"> + <span className="title"> + ESSE MÊS: + </span> + <span className="enviados"> + <span className="numeros"> + {month_downloads} + </span> + + <span className="legenda"> + Baixados + </span> + </span> + <span className="enviados"> + <span className="numeros"> + {month_publications} + </span> + + <span className="legenda"> + Publicados + </span> + </span> + + </Grid> + </StyledGrid> + </StatsTab> + ) + +} + +const StatsTab = styled.div` + padding : 20px 0; + color : #fff; + background-color : #00bcd4; +` + +const StyledGrid = styled(Grid)` + vertical-align : middle !important; + + .first { + display : flex !important; + @media screen and (max-width : 502px) { + justify-content : center !important; + border-bottom : 1px dotted #fff !important; + padding-bottom : 10px !important; + } + @media screen and (min-width : 502px) { + justify-content : right !important; + text-align : right !important; + border-right : 1px dotted #fff !important; + } + + img { + height : 70px; + } + + } + + .total { + text-align : center; + display : inline-block; + line-height : 1; + padding : 0 20px; + } + + .numeros { + display : block; + font-weight : 700; + font-size : 2.1em; + } + + .legenda { + @media screen and (min-width : 502px) { + font-size : 1.285em; + } + font-weight : 300; + } + + .title { + @media screen and (min-width : 502px) { + font-size : 1.42em; + } + line-height : 1; + } + + .enviados { + text-align : center; + display : inline-block; + line-height : 1; + padding : 0 20px; + } + + .second { + @media screen and (min-width : 502px) { + padding-left : 20px; + } + @media screen and (max-width : 502px) { + justify-content : center !important; + text-align : center !important; + padding-top : 10px !important; + font-size : 16px; + } + } + +` diff --git a/src/Pages/HomeFunction.js b/src/Pages/HomeFunction.js new file mode 100644 index 00000000..e2288df4 --- /dev/null +++ b/src/Pages/HomeFunction.js @@ -0,0 +1,39 @@ +/*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 './Styles/Home.css'; +import SearchSection from '../Components/SearchSectionFunction'; +import SubPages from '../Components/AreasSubPagesFunction'; +import StatsBar from '../Components/StatsBarFunction'; +import Funcionalities from '../Components/Funcionalities'; + +export default function App (props) { + const [bannerState, handleChangeBanner] = useState("Recursos") + + const changeBanner = (parameter) => {handleChangeBanner(parameter)} + + return ( + <React.Fragment> + <SearchSection function={changeBanner} banner={bannerState}/> + <SubPages banner={bannerState}/> + <StatsBar/> + <Funcionalities/> + </React.Fragment> + ) +} diff --git a/src/img/banner-mobile.jpg b/src/img/banner-mobile.jpg new file mode 100644 index 0000000000000000000000000000000000000000..d44ce9b0fc82df45cd1e9b9a069c6b309392defc GIT binary patch literal 25900 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 Keuks{|C<0uue+xJ literal 0 HcmV?d00001 -- GitLab