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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 literal 0 HcmV?d00001 -- GitLab