/*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 ResourceCard from '../Components/ResourceCard' // import CollectionCard from '../Components/CollectionCard' // import UserCard from '../Components/UserCard' // import Select from "react-dropdown-select"; 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' let order = "review_average"; let currFilter = ""; 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); function handleSuccessfulGet (data) { if (option === "LearningObject") setResultsResource(data); else if (option === "Collection") setResultsCollection(data); else if (option === "User") setResultsUser(data); setOptionResult(option); dispatch({ type: "SAVE_SEARCH", newSearch: { query: state.search.query, class: option, }, }); setTotalResults(data.length); 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(() => { 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); setOption(e.value); collectStuff(e.value, ""); }} 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" ? ( <GridBuscaCollection container spacing={2}> <Grid item xs> <Grid container 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> ) : optionResult === "LearningObject" ? ( <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 spacing={2}> {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> ) : optionResult === "User" && ( <GridBuscaUser container spacing={2}> <Grid item xs > <Grid container spacing={2}> {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; `;