Skip to content
Snippets Groups Projects
Commit 6efacda7 authored by Vinícius de Lima Gonçalves's avatar Vinícius de Lima Gonçalves
Browse files

Created components MenuBar, SearchBar and prototype of page Search

parent f780fe9c
No related branches found
No related tags found
1 merge request!6Insert headers
Source diff could not be displayed: it is too large. Options to address this: view the blob.
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
"@material-ui/styles": "^4.0.0", "@material-ui/styles": "^4.0.0",
"axios": "^0.19.0", "axios": "^0.19.0",
"binary-extensions": "^2.0.0", "binary-extensions": "^2.0.0",
"material-design-icons": "^3.0.1",
"react": "^16.8.4", "react": "^16.8.4",
"react-dom": "^16.8.4", "react-dom": "^16.8.4",
"react-grid-system": "^4.4.2", "react-grid-system": "^4.4.2",
...@@ -15,7 +16,16 @@ ...@@ -15,7 +16,16 @@
"react-responsive-carousel": "^3.1.47", "react-responsive-carousel": "^3.1.47",
"react-router-dom": "^5.0.0", "react-router-dom": "^5.0.0",
"react-scripts": "2.1.3", "react-scripts": "2.1.3",
"react-star-ratings": "^2.3.0" "react-star-ratings": "^2.3.0",
"styled-components": "^4.3.2"
},
"devDependencies": {
"eslint": "^5.6.0",
"eslint-config-prettier": "^6.0.0",
"eslint-plugin-prettier": "^3.1.0",
"eslint-plugin-react": "^7.14.2",
"eslint-plugin-react-hooks": "^1.6.1",
"prettier": "1.18.2"
}, },
"scripts": { "scripts": {
"start": "react-scripts start", "start": "react-scripts start",
......
import React, { useContext, useEffect } from 'react';
import Home from './Pages/Home';
import Search from './Pages/Search'
import Header from './Components/Header'
import EcFooter from './Components/EcFooter';
import GNUAGPLfooter from './Components/AGPLFooter';
import UserPage from './Pages/UserPage';
import {BrowserRouter, Switch, Route} from 'react-router-dom';
import { Store } from './Store'
export default function App(){
// eslint-disable-next-line
const { state, dispatch } = useContext(Store)
useEffect(()=>{
dispatch({
type: 'WINDOW_SIZE',
innerWindow: {
width: window.innerWidth,
height: window.innerHeight
}
})
},[])
useEffect(()=>{
const setWindowSize = () => {
dispatch({
type: 'WINDOW_SIZE',
innerWindow: {
width: window.innerWidth,
height: window.innerHeight
}
})
}
window.addEventListener('resize',setWindowSize)
return () => window.removeEventListener('resize',setWindowSize)
},[window.innerWidth,window.innerHeight])
return(
<BrowserRouter>
<Header />
<div style={{backgroundImage: "linear-gradient(to right,#ff7f00,#e81f4f,#673ab7,#00bcd4)", height:"5px"}}></div>
<Switch>
<Route path="/" exact={true} component={Home}/>
<Route path="/busca" component={Search} />
<Route path="/usuario" component={UserPage} />
</Switch>
<EcFooter/>
<GNUAGPLfooter/>
</BrowserRouter>
)
}
\ No newline at end of file
import React, { useState, useRef, useEffect, useContext } from 'react'
import { Link } from 'react-router-dom'
import { Button, Grow, Paper, Popper, MenuItem, MenuList } from '@material-ui/core';
import { withStyles } from '@material-ui/styles';
import styled from 'styled-components'
import { Store } from '../Store';
const styles = theme => ({
root: {
display: 'flex',
},
paper: {
marginRight: '2px',
},
});
const DropdownStyled = styled.div`
*{
margin: 0 !important;
text-decoration: none;
}
Button{
text-transform: capitalize;
}
`
function Dropdown(props) {
const [open, setOpen] = useState(false);
const innerDropdown = useRef(null)
const { state , dispatch } = useContext(Store)
useEffect(()=>{
const handleClickOutside = (event) => {
innerDropdown.current && !innerDropdown.current.contains(event.target) && setOpen(false)
}
document.addEventListener('mousedown', handleClickOutside)
return () => document.removeEventListener('mousedown', handleClickOutside)
},[])
const handleToggle = () => {
setOpen(true)
if(state.searchOpen)
dispatch({
type: 'HANDLE_SEARCH_BAR',
opened: false
})
}
return (
<DropdownStyled ref={innerDropdown}>
<Button
aria-controls="menu-list-grow"
aria-haspopup="true"
onClick={handleToggle}
>
{props.name}
</Button>
{ open &&
<Popper open={open} keepMounted transition disablePortal>
{({ TransitionProps, placement }) => (
<Grow
{...TransitionProps}
style={{ transformOrigin: placement === 'bottom' ? 'center top' : 'center bottom' }}
>
<Paper id="menu-list-grow">
<MenuList>
{
props.items.map((item)=>
<Link key={item.name} to={item.href} ><MenuItem>{item.name}</MenuItem></Link>
)
}
</MenuList>
</Paper>
</Grow>
)}
</Popper>
}
</DropdownStyled>
);
}
export default withStyles(styles)(Dropdown)
import React, { useContext } from 'react'
import AcessibilityBar from './AcessibilityBar'
import MenuBar from './MenuBar'
import SearchBar from './SearchBar'
import { Store } from '../Store';
export default function Header(props){
const { state, dispatch } = useContext(Store)
const handleClickSearch = (open) => {
dispatch({
type: "HANDLE_SEARCH_BAR",
opened: !state.searchOpen
})
}
return(
<>
<AcessibilityBar />
<MenuBar openSearchBar={handleClickSearch} />
{ state.searchOpen &&
<SearchBar />
}
</>
)
}
\ No newline at end of file
import React, {Component} from 'react'; import React from 'react';
import {Row, Col, Container} from 'react-grid-system' import { Link } from 'react-router-dom'
import { Container } from 'react-grid-system'
import logo from '../img/logo_small.svg'
import '../App.css'; import '../App.css';
import Dropdown from './Dropdown';
import { Button } from '@material-ui/core';
import IconSearch from '@material-ui/icons/Search'
import tumbnail from '../img/logo_small.svg' import styled from 'styled-components'
import BT from './Button';
import Menulist from './menulist'; const ContainerStyled = styled(Container)`
import { Link } from 'react-router-dom' *{ text-decoration: none }
import {IoIosMenu} from "react-icons/io"; display: flex;
// const logosStyle={ align-items: center;
// borderRight:"1px rgba(0,0,0,.1) solid", border-top: 1px rgba(0,0,0,.1) solid;
// paddingTop:"20px", padding: 5px;
// paddingBottom:"5px", *{
// paddingLeft: "0px", margin-left: 10px;
// paddingRight: "0px", }
// justifyContent:"left", `
// display:"inline-flex" const ButtonStyled = styled(Button)`
// }; text-transform: capitalize !important;
const rowStyle={ `
verticalAlign: "left" const IconSearchStyled = styled(IconSearch)`
}; color: #16b8dd;
`
const ImageStyled = styled.img`
height: 50px;
width: auto;
cursor: pointer;
margin: 0 10px;
`
export default function MenuBar(props){
const menuSobre = [
{ name: "Sobre a Plataforma", href: "" },
{ name: "Portais Parceiros", href: "" },
{ name: "Termos de Uso", href: "" },
{ name: "Contato", href: "" }
]
const menuAjuda = [
{ name: "Central de Ajuda", href: ""},
{ name: "Publicando Recursos", href: ""},
{ name: "Encontrando Recursos", href: ""},
{ name: "Participando da Rede", href: ""},
{ name: "Gerenciando a Conta", href: ""}
]
class MenuBar extends Component{ return(
render(){ <ContainerStyled fluid={true} >
return( <Link to="/"> <ImageStyled src={logo} alt="Plataforma Integrada" /> </Link>
<Container fluid={true} style={{borderTop:"1px rgba(0,0,0,.1) solid", textAlign: "center"}}> <Dropdown name="Sobre" items={menuSobre}/>
<Row style={rowStyle}> <Dropdown name="Ajuda" items={menuAjuda}/>
<Col sm={2} md={1}> <a href="http://educacaoconectada.mec.gov.br/" rel="noopener noreferrer" target="_blank" >
<Link to="/"> <img src={tumbnail} height="35" alt="Logo Plataforma MEC" style={{padding: "10px"}}/></Link> <ButtonStyled >Educação Conectada</ButtonStyled>
</Col> </a>
<Col sm={2} md={2} style={{padding:"0px", alingItens: "left", alignSelf:"center"}}><Menulist children={<IoIosMenu/>} label={"Menu"}/></Col> <ButtonStyled onClick={props.openSearchBar} ><IconSearchStyled />Buscar</ButtonStyled>
<Col sm={2} md={2} style={{padding:"0px", paddingTop: "-5px", alignSelf:"center"}}><Menulist label={"Ajuda"}/></Col> </ContainerStyled>
<Col sm={2} md={2} style={{padding:"0px", alignSelf:"center"}}>< Link to ="/usuario">Busca</Link></Col> );
<Col sm={4} md={3}style={{paddingTop:"10px"}} justify="Right"> }
<BT name="Entrar"/> \ No newline at end of file
<BT name="Cadastre-se"/>
</Col>
</Row>
</Container>
);
}
}
export default MenuBar;
import React, {Component} from 'react'; import React, { useState, useEffect, useContext } from 'react'
import '../App.css'; import { Redirect } from 'react-router-dom'
import {Row, Col} from 'react-grid-system';
import Button from '@material-ui/core/Button';
import Select from './Select';
import TextField from '@material-ui/core/TextField';
import {IoIosSearch} from 'react-icons/io';
// const barStyle={
// backgroundColor: "white",
// border: "none"
// };
// const searchButton={
// backgroundColor: "white",
// border: "none",
// borderRadius: "0"
// };
class SearchBar extends Component {
constructor (props) {
super(props)
this.state = {
content: '',
filter: "Recursos",
showMenu: false,
}
this.handleChange = this.handleChange.bind(this);
}
handleSearch (e) { import IconSearch from '@material-ui/icons/Search'
alert("Busca: "+ this.state.content)
}
openMenu () { import { RadioGroup, Radio, FormControl, Select, MenuItem, Button, FormControlLabel, TextField } from '@material-ui/core'
console.log(this.state.showMenu) import styled from 'styled-components'
if(this.setState === true)
this.setState({ import { Store } from '../Store';
showMenu: false
})
else { const dividerStyled = {
this.setState({ background: '#e0e0e0',
showMenu: true width: '1px',
}) content: "",
} display: 'block',
top: '0',
bottom: '0',
right: '0',
minHeight: '70px',
margin: '0 30px'
}
const DividerVertical = () => <em style={dividerStyled}></em>
const ButtonStyled = styled(Button)`
text-transform: capitalize !important;
`
const IconSearchStyled = styled(IconSearch)`
color: #16b8dd;
`
const TextFieldStyled = styled(TextField) `
flex-grow: 2;
margin: 0 2vw !important;
`
const RadioGroupStyled = styled(RadioGroup) `
display: flex;
flex-direction: row;
flex-grow: 1;
`
const FormControlLabelStyled = styled(FormControlLabel)`
*{
text-transform: uppercase;
color: #ff8a17 !important;
fontWeight: bolder;
} }
`
const RadioStyled = styled(Radio)`
color: #ff8a17;
`
handleChange(event){ const SelectStyled = styled(Select)`
this.setState({content: event.target.value}); margin-right: 2vw;
*{
text-transform: uppercase;
color: #ff8a17 !important;
fontWeight: bolder;
} }
`
const MenuItemStyled = styled(MenuItem)`
text-transform: uppercase;
color: #ff8a17 !important;
fontWeight: bolder;
`
const Bar = styled.div `
display: flex;
align-items: center;
justify-content: space-between;
border-top: 1px rgba(0,0,0,.1) solid;
`
const Flex = styled.span `
display: flex;
align-items: center;
color: #787380;
`
export default function SearchBar() {
const [ query, setQuery ] = useState('')
const [ searchClass, setSearchClass ] = useState('LearningObject')
const { state, dispatch } = useContext(Store)
const [ goSearch, setGoSearch ] = useState(false)
render () { useEffect(()=>{
return ( if(window.location.pathname.includes('busca')){
<form onSubmit={e => e.preventDefault()}> const urlParams = new URLSearchParams(window.location.search)
<Row> const urlQuery = urlParams.get('query')
<Col sm={5} md={6}> const urlSearchClass = urlParams.get('search_class')
<TextField if( searchClass !== urlSearchClass || query !== urlQuery){
type='text' setQuery(urlQuery)
placeholder='O que está buscando?' setSearchClass(urlSearchClass)
value={this.state.content} }
onChange={this.handleChange} }
/> },[])
</Col>
<Col sm={4} md={4}> useEffect(()=>setGoSearch(false),[goSearch])
<Select/>
</Col> const handleChange = ( event ) => {
<Col sm={3} md={2}> setQuery(event.target.value)
<Button }
type='submit'
size="medium" const handleKeyDown = (event) => {
onClick={this.handleSearch.bind(this)}> if(event.key === 'Enter' || event.type === 'click'){
<IoIosSearch size="30px"/> dispatch({
</Button> type: 'SAVE_SEARCH',
</Col> newSearch: {
</Row> query: query!==''?query:'*',
</form> class: searchClass
) }
})
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>
)
} }
export default SearchBar;
import React, {Component} from 'react'; import React, {Component} from 'react';
import '../App.css'; import '../App.css';
import banner from '../img/bannerBusca.jpg'; import banner from '../img/bannerBusca.jpg';
import SearchBar from './SearchBar'; // import SearchBar from './SearchBar';
import {Row, Container} from 'react-grid-system'; import {Row} from 'react-grid-system';
import {MdInfoOutline} from "react-icons/md" import {MdInfoOutline} from "react-icons/md"
import { FaRegPlayCircle} from "react-icons/fa"; import { FaRegPlayCircle} from "react-icons/fa";
...@@ -50,9 +50,9 @@ class SearchSection extends Component{ ...@@ -50,9 +50,9 @@ class SearchSection extends Component{
Encontre e compartilhe vídeos, animações e muitos outros Recursos Encontre e compartilhe vídeos, animações e muitos outros Recursos
</h3> </h3>
</div> </div>
<Container style={{backgroundColor: "white" ,width: "50%" ,float: "center", alignItems: "center", borderRadius: "5px", color: this.state.color}}> {/* <Container style={{backgroundColor: "white" ,width: "50%" ,float: "center", alignItems: "center", borderRadius: "5px", color: this.state.color}}>
<SearchBar/> <SearchBar/>
</Container> </Container> */}
<div style={{paddingBottom: "100px", color: "white"}}> <div style={{paddingBottom: "100px", color: "white"}}>
<a href="#sobre"><MdInfoOutline size="30px"/>SOBRE A PLATAFORMA</a> <a href="#sobre"><MdInfoOutline size="30px"/>SOBRE A PLATAFORMA</a>
<a href="#apresentacao"> <FaRegPlayCircle size="25px"/>VÍDEO DE APRESENTAÇÃO</a> <a href="#apresentacao"> <FaRegPlayCircle size="25px"/>VÍDEO DE APRESENTAÇÃO</a>
......
import React, {Component} from 'react'; import React, {Component} from 'react';
import './Styles/Home.css'; import './Styles/Home.css';
import SearchSection from '../Components/SearchSection'; import SearchSection from '../Components/SearchSection';
import SubPages from '../Components/AreasSubPages'; // import SubPages from '../Components/AreasSubPages';
import StatsBar from '../Components/StatsBar'; import StatsBar from '../Components/StatsBar';
import Funcionalities from '../Components/Funcionalities'; import Funcionalities from '../Components/Funcionalities';
class App extends Component { class App extends Component {
...@@ -23,7 +23,6 @@ class App extends Component { ...@@ -23,7 +23,6 @@ class App extends Component {
return ( return (
<React.Fragment> <React.Fragment>
<SearchSection function={this.changeBanner} banner={this.state.bannerState}/> <SearchSection function={this.changeBanner} banner={this.state.bannerState}/>
<SubPages banner={this.state.bannerState}/>
<StatsBar/> <StatsBar/>
<Funcionalities/> <Funcionalities/>
......
import React, { useEffect, useState, useContext } from 'react';
import axios from 'axios';
// import ResourceCard from '../Components/ResourceCard'
// import CollectionCard from '../Components/CollectionCard'
// import UserCard from '../Components/UserCard'
import {apiUrl} from '../env';
import './Styles/Home.css';
import { Store } from '../Store';
export default function Search(props){
const { state, dispatch } = useContext(Store)
const [ results, setResults ] = useState([])
const [ page, ] = useState(0)
const [ resultsPerPage, ] = useState(12)
const [ order, ] = useState('score')
useEffect(()=>{
dispatch({
type: 'HANDLE_SEARCH_BAR',
opened: true
})
const urlParams = new URLSearchParams(window.location.search)
const query = urlParams.get('query')
const searchClass = urlParams.get('search_class')
if(state.search.query !== query || state.search.class !== searchClass){
dispatch({
type: 'SAVE_SEARCH',
newSearch: {
query: query,
class: searchClass
}
})
}
return () => dispatch({
type: 'HANDLE_SEARCH_BAR',
opened: false
})
},[])
useEffect(()=>{
axios.get(`${apiUrl}/search?page=${page}&results_per_page=${resultsPerPage}&order=${order}&query=${state.search.query}&search_class=${state.search.class}`)
.then( res => {
setResults(res.data)
})
},[state.search])
return (
<React.Fragment>
<h1>Search for {state.search.query!=='*'?state.search.query:'all'} in {state.search.class}</h1>
{
state.search.class === 'LearningObject' &&
<ul>
{results.map((res)=><li key={res.id}> {res.name} </li>)}
</ul>
}
{state.search.class === 'Collection' &&
<ul>
{results.map((res)=><li key={res.id}> {res.name} </li>)}
</ul>
}
{state.search.class === 'User' &&
<ul>
{results.map((res)=><li key={res.id}> {res.name} </li>)}
</ul>
}
</React.Fragment>
)
}
import React, {Component} from 'react';
class UserPage extends Component {
render() {
return (
<h1> Página visulizar usuário</h1>
);
}
}
export default UserPage;
import React from 'react'
export const Store = React.createContext()
const initialState = {
searchOpen: false,
search: {
query: '*',
class: 'LearningObject'
},
windowSize: {
width: 0,
height: 0
}
}
function reducer(state, action) {
switch (action.type){
case 'SAVE_SEARCH':
return {
...state,
search: action.newSearch
}
case 'HANDLE_SEARCH_BAR':
return {
...state,
searchOpen: action.opened
}
case 'WINDOW_SIZE':
return {
...state,
windowSize: action.innerWindow
}
default:
return state
}
}
export function StoreProvider(props) {
const [state, dispatch] = React.useReducer(reducer, initialState);
const value = { state, dispatch };
return (
<Store.Provider value={value}>
{props.children}
</Store.Provider>
)
}
\ No newline at end of file
var apiDomain = 'http://localhost:5000', var apiDomain = 'https://api.portalmec.c3sl.ufpr.br',
apiVersion = 'v1', apiVersion = 'v1',
apiUrl = apiDomain + '/' + apiVersion; apiUrl = apiDomain + '/' + apiVersion;
......
import React from 'react'; import React from 'react';
import ReactDOM from 'react-dom'; import ReactDOM from 'react-dom';
import './index.css';
import Home from './Pages/Home';
import MenuBar from './Components/MenuBar';
import EcFooter from './Components/EcFooter';
import GNUAGPLfooter from './Components/AGPLFooter';
import AcessibilityBar from './Components/AcessibilityBar';
import UserPage from './Pages/UserPage';
import * as serviceWorker from './serviceWorker'; import * as serviceWorker from './serviceWorker';
import {BrowserRouter, Switch, Route} from 'react-router-dom';
import './index.css';
import App from './App.js'
import { StoreProvider } from './Store';
ReactDOM.render( ReactDOM.render(
<BrowserRouter> <StoreProvider>
<AcessibilityBar/> <App />
<MenuBar/> </StoreProvider>
<div style={{backgroundImage: "linear-gradient(to right,#ff7f00,#e81f4f,#673ab7,#00bcd4)", height:"5px"}}></div>
<Switch>
<Route path="/" exact={true} component={Home}/>
<Route path="/usuario" component={UserPage} />
</Switch>
<EcFooter/>
<GNUAGPLfooter/>
</BrowserRouter>
, document.getElementById('root')); , document.getElementById('root'));
// If you want your app to work offline and load faster, you can change // If you want your app to work offline and load faster, you can change
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment