Select Git revision
-
Lucas Eduardo Schoenfelder authoredLucas Eduardo Schoenfelder authored
Search.js 23.26 KiB
/*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, { useEffect, useState, useContext } from "react";
import { apiDomain } from '../env';
import { Link } from "react-router-dom";
import styled from "styled-components";
import Paper from "@material-ui/core/Paper";
import LoadingSpinner from '../Components/LoadingSpinner';
import Breadcrumbs from "@material-ui/core/Breadcrumbs";
import "./Styles/Home.css";
import { Store } from "../Store";
import { Grid } from "@material-ui/core";
import Dropdown from "react-dropdown";
import "react-dropdown/style.css";
import SearchExpansionPanel from "../Components/SearchExpansionPanel/SearchExpansionPanel";
import ResourceCardFunction from "../Components/ResourceCardFunction";
import CollectionCardFunction from "../Components/CollectionCardFunction";
import ContactCard from "../Components/ContactCard";
import CircularProgress from '@material-ui/core/CircularProgress';
import { getRequest } from '../Components/HelperFunctions/getAxiosConfig'
import ColecaoVazia from '../img/Pagina_vazia_colecao.png'
import RecursoVazio from '../img/Pagina_vazia_Sem_publicar.png'
let order = "review_average";
let currFilter = "";
let currOption;
export default function Search(props) {
const { state, dispatch } = useContext(Store);
const [resultsResource, setResultsResource] = useState([]);
const [resultsCollection, setResultsCollection] = useState([]);
const [resultsUser, setResultsUser] = useState([]);
const [currOrder, setCurrOrder] = useState(order);
const [page] = useState(0);
const [isloading, setIsLoading] = useState(false);
const [loadingMoreData, setLoadingMoreData] = useState(false);
const [isFiltering, setIsFiltering] = useState(false);
const [resultsPerPage, setResultsPerPage] = useState(12);
const [totalResults, setTotalResults] = useState(0);
const [options] = React.useState([
{ label: "Recursos", value: "LearningObject" },
{ label: "Coleções", value: "Collection" },
{ label: "Usuários", value: "User" },
]);
const [ordenar] = useState([
{ label: "Mais Estrelas", value: "review_average" },
{ label: "Mais Relevante", value: "score" },
{ label: "Mais Baixados", value: "downloads" },
{ label: "Mais Favoritados", value: "likes" },
{ label: "Mais Recentes", value: "publicationdesc" },
{ label: "Ordem Alfabética", value: "title" },
]);
const [option, setOption] = useState(
new URLSearchParams(window.location.search).get("search_class")
);
const [optionResult, setOptionResult] = useState(option);
currOption = option;
function handleSuccessfulGet(data, headers) {
if (currOption === "LearningObject") setResultsResource(data);
else if (currOption === "Collection") setResultsCollection(data);
else if (currOption === "User") setResultsUser(data);
setOptionResult(option);
dispatch({
type: "SAVE_SEARCH",
newSearch: {
query: state.search.query,
class: currOption,
},
});
console.log(data);
if (headers.has('X-Total-Count')) {
setTotalResults(headers.get('X-Total-Count'));
}
else {
setTotalResults(data.length);
}
setOptionResult(currOption);
setIsLoading(false);
setIsFiltering(false);
setLoadingMoreData(false);
}
const collectStuff = (tipoBusca, filtro) => {
if (!loadingMoreData) // this line prevents resetting filter when loading more data
currFilter = filtro;
if (filtro)
setIsFiltering(true);
const url = `/search?page=${page}&results_per_page=${resultsPerPage}&order=${order}&query=${state.search.query}${currFilter ? currFilter : ""}&search_class=${tipoBusca}`
getRequest(url, handleSuccessfulGet, (error) => { console.log(error) })
};
useEffect(() => {
dispatch({
type: "HANDLE_SEARCH_BAR",
opened: false,
});
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(() => {
setIsLoading(true);
collectStuff(option);
}, [resultsPerPage]);
return (
<div style={{ backgroundColor: "#f4f4f4" }}>
<Principal>
<BreadCrumbsDiv style={{ margin: "15px 2%", }}>
<StyledBreadCrumbs>
<Link to="/">Página Inicial</Link>
<span>Busca</span>
</StyledBreadCrumbs>
</BreadCrumbsDiv>
<div style={{ margin: "15px 2%", }}>
<HeaderFilters elevation={4} square>
<Grid container spacing={0} style={{ height: "100%" }}>
<Grid item xs style={{ display: "flex", flexDirection: "column", justifyContent: "center", paddingLeft: 20 }}>
<div style={{ marginRight: 5, marginTop: 15 }}>
<div className="textInfo">
<span style={{ fontWeight: "bold" }}>
MOSTRAR
</span>
</div>
<Dropdown options={options} value={optionResult}
onChange={(e) => {
setIsLoading(true);
currOption = e.value;
setOption(currOption);
collectStuff(currOption, "");
}}
placeholder="Selecione um tipo"
/>
</div>
</Grid>
{
optionResult === "User" ? null :
<Grid item xs style={{ display: "flex", flexDirection: "column", justifyContent: "center", paddingRight: 20, }}>
<div style={{ marginLeft: 5, marginTop: 15 }}>
<div className="textInfo">
<span style={{ fontWeight: "bold" }}>
ORDENAR POR
</span>
</div>
<Dropdown options={ordenar} value={currOrder} onChange={(e) => {
order = e.value;
setCurrOrder(e.label)
collectStuff(optionResult, currFilter);
}}
placeholder="Selecione uma opção"
/>
</div>
</Grid>
}
<Grid item xs={12}>
<div style={{ display: "flex", flexDirection: "column", justifyContent: "center" }}>
<div style={{ textAlign: "center", paddingTop: 10, fontWeight: "bolder" }}>
Exibindo {totalResults === 0 ? 0 : resultsPerPage} resultados de {totalResults} encontrados
{/*Exibindo {totalResults === 0 ? 0 : resultsPerPage} resultados*/}
</div>
</div>
</Grid>
</Grid>
</HeaderFilters>
{
isloading ? <LoadingSpinner text="Carregando..." /> :
optionResult === "Collection" ? (
resultsCollection.length >= 1 ?
<GridBuscaCollection container direction="row" spacing={2}>
<Grid item xs>
<Grid container justify="center" alignItems="center" spacing={2}>
{resultsCollection.map((card) => (
<Grid item xs key={card.id}>
<CollectionCardFunction
name={card.name}
tags={card.tags}
rating={card.review_average}
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}
/>
</Grid>
))}
</Grid>
<div style={{ display: "flex", flexDirection: "row", justifyContent: "center", }}>
<button
style={{
height: 36, backgroundColor: "#ff7f00", marginBottom: 50, marginTop: 50, fontSize: 14,
color: "white", borderRadius: 4, border: "none",
}}
onClick={() => {
setLoadingMoreData(true);
setResultsPerPage(resultsPerPage + 12)
// collectStuff("Collection", "");
}}
>
{
loadingMoreData ? <CircularProgress size={24} color="inherit" /> : "Carregar mais 12"
}
</button>
</div>
</Grid>
</GridBuscaCollection> :
<Grid container direction="row" justify="center" alignItems="center">
<Grid item>
<img src={ColecaoVazia} alt="coleção vazia"/>
</Grid>
</Grid>
) :
optionResult === "LearningObject" ? (
resultsResource.length >= 1 ?
<GridBuscaResource container spacing={2}>
<Grid item xs={12} md={2}>
<Grid container >
<Grid item xs={12}>
<Paper elevation={4} square>
<SearchExpansionPanel onChange={collectStuff} onFiltering={isFiltering} />
</Paper>
</Grid>
</Grid>
</Grid>
<Grid item xs>
<Grid container justify="center" spacing={3} alignItems="center" >
{resultsResource.map((card) => (
<Grid item xs={12} sm={6} md={4} lg={3} key={card.id}>
<ResourceCardFunction
avatar={card.publisher.avatar}
id={card.id}
thumbnail={card.thumbnail}
type={card.object_type ? card.object_type : "Outros"}
title={card.name}
published={card.state === "published" ? true : false}
likeCount={card.likes_count}
liked={card.liked}
rating={card.review_average}
author={card.author}
tags={card.educational_stages}
href={"/recurso/" + card.id}
downloadableLink={card.default_attachment_location}
/>
</Grid>
))}
</Grid>
<div
style={{
display: "flex",
flexDirection: "row",
justifyContent: "center",
}}
>
<button
style={{
height: 36,
backgroundColor: "#ff7f00",
marginBottom: 50,
marginTop: 50,
fontSize: 14,
color: "white",
borderRadius: 4,
border: "none",
}}
onClick={() => {
setLoadingMoreData(true);
setResultsPerPage(resultsPerPage + 12)
// collectStuff("LearningObject", "");
}}
>
{
loadingMoreData ? <CircularProgress size={24} color="inherit" /> : "Carregar mais 12"
}
</button>
</div>
</Grid>
</GridBuscaResource> :
<Grid container direction="row" justify="center" alignItems="center">
<Grid item>
<img src={RecursoVazio} alt="recurso vazio" />
</Grid>
</Grid>
) :
optionResult === "User" && (
<GridBuscaUser container spacing={2}>
<Grid item xs >
<Grid container spacing={2} justify="center" alignItems="center">
{resultsUser.map((card) => (
<Grid item xs key={card.id}>
<ContactCard
name={card.name}
avatar={card.avatar ? apiDomain + card.avatar : null}
cover={card.cover ? apiDomain + card.cover : null}
numCollections={card.collections_count}
numLearningObjects={card.learning_objects_count}
follow_count={card.follows_count}
followed={card.followed || null}
followerID={card.id}
href={'/usuario-publico/' + card.id}
/>
</Grid>
))}
</Grid>
<div
style={{
display: "flex",
flexDirection: "row",
justifyContent: "center",
}}
>
<button
style={{
height: 36,
backgroundColor: "#ff7f00",
marginBottom: 50,
marginTop: 50,
fontSize: 14,
color: "white",
borderRadius: 4,
border: "none",
}}
onClick={() => {
setLoadingMoreData(true);
setResultsPerPage(resultsPerPage + 12)
// collectStuff("User", "");
}}
>
{
loadingMoreData ? <CircularProgress color="inherit" size={24} /> : "Carregar mais 12"
}
</button>
</div>
</Grid>
</GridBuscaUser>
)
}
</div>
</Principal>
</div>
);
}
const GridBuscaCollection = styled(Grid)`
color: #666;
${'' /* background-color: green; */}
h4 {
padding: 0 15px;
font-size: 18px;
margin-block: 10px;
text-transform: uppercase;
}
`;
const GridBuscaResource = styled(Grid)`
color: #666;
${'' /* background-color: red; */}
h4 {
padding: 0 15px;
font-size: 18px;
margin-block: 10px;
text-transform: uppercase;
}
`;
const GridBuscaUser = styled(Grid)`
color: #666;
${'' /* background-color: blue; */}
h4 {
padding: 0 15px;
font-size: 18px;
margin-block: 10px;
text-transform: uppercase;
}
`;
const HeaderFilters = styled(Paper)`
height: 150px;
text-align: center;
background-color: #fff;
margin-bottom: 30px;
color: #666;
.textInfo{
text-align: start;
}
`;
const StyledBreadCrumbs = styled(Breadcrumbs)`
display: flex;
justify-content: flex-start;
max-width: 1170px;
span {
color: #a5a5a5;
}
a {
color: #00bcd4;
text-decoration: none;
}
`;
const BreadCrumbsDiv = styled.div`
padding: 10px;
display: flex;
`;
const Principal = styled.div`
margin-inline: auto;
`;