diff --git a/next.config.mjs b/next.config.mjs index 4678774e6d606704bce1897a5dab960cd798bf66..c58c974979f7eaa23dafb116081e37cfb55a25a8 100644 --- a/next.config.mjs +++ b/next.config.mjs @@ -1,4 +1,6 @@ /** @type {import('next').NextConfig} */ -const nextConfig = {}; +const nextConfig = { + reactStrictMode: false, +}; export default nextConfig; diff --git a/src/app/collections/page.js b/src/app/collections/page.js new file mode 100644 index 0000000000000000000000000000000000000000..218f70496dd582af31eed03cfaeba920cfc7c15d --- /dev/null +++ b/src/app/collections/page.js @@ -0,0 +1,11 @@ + + +export default function Collections(){ + return ( + <div> + <h1>Collections</h1> + </div> + ) + + +}; \ No newline at end of file diff --git a/src/app/components/Cards.js b/src/app/components/Cards.js index 9c4105d4313941d93aa7d99135eb78bbfa3a13a1..1c33e70c9836465e0be61ee7958673a7e375d97d 100644 --- a/src/app/components/Cards.js +++ b/src/app/components/Cards.js @@ -6,8 +6,14 @@ import CardMedia from "@mui/material/CardMedia"; import Avatar from "@mui/material/Avatar"; import Typography from "@mui/material/Typography"; import Link from "next/link"; +import { useEffect } from "react"; +import { useRef } from "react"; + export default function Cards(props) { + + const cardRef = useRef(false); + const defaultImgCards = "https://plataformaintegrada.mec.gov.br/static/media/VIDEO.69a83499.webp"; @@ -70,7 +76,7 @@ export default function Cards(props) { image={ props["image"] === null ? getDefaultThumbnail(props["type"]) - : `http://portalmec.c3sl.ufpr.br${props["image"]}` + : `https://api.portalmec.c3sl.ufpr.br${props["image"]}` } alt="img" /> @@ -79,7 +85,7 @@ export default function Cards(props) { avatar={ <Link href="/perfil"> <Avatar - src={`http://api.portalmec.c3sl.ufpr.br/${props["avatar"]}`} + src={`https://api.portalmec.c3sl.ufpr.br/${props["avatar"]}`} alt={props["author"]} sx={{ width: 28, diff --git a/src/app/components/GroupCardsCollections.js b/src/app/components/GroupCardsCollections.js index 6fb0b92656626b09cdd1b4915d095f6a1ef25471..72f7b5f6d0f1106ffd6ad69479c15b7500f347ff 100644 --- a/src/app/components/GroupCardsCollections.js +++ b/src/app/components/GroupCardsCollections.js @@ -30,6 +30,7 @@ export default function GroupCardsCollections({ id, title, cardsPerRow }) { .then(({ data }) => { setCollections(data); handleResize(data); + console.log(data); }); }; @@ -44,7 +45,6 @@ export default function GroupCardsCollections({ id, title, cardsPerRow }) { <div className="mx-1 flex flex-col"> <div className="ml-6 inline-block"> <h1 className="text-xl font-bold mb-4 text-gray-600"> - Coleções oficiais do <Link href="/perfil" className="pl-1"> {title} </Link> @@ -52,6 +52,7 @@ export default function GroupCardsCollections({ id, title, cardsPerRow }) { </div> <div className={`flex content flex-wrap justify-center ${expanded ? "" : "overflow-y-hidden h-[300px]"}`}> {collections.map((item, index) => { + return ( <Cards key={index} diff --git a/src/app/components/HomePage.js b/src/app/components/HomePage.js index dfbbf17c1bf982672a183cc10bc41648b840281d..4564f57e3a8a1ed08398669b72fc8477b8c92d6e 100644 --- a/src/app/components/HomePage.js +++ b/src/app/components/HomePage.js @@ -1,36 +1,107 @@ "use client" - import Overlay from "./Overlay"; import GroupCardsCollections from "./GroupCardsCollections"; -import { useEffect, useState } from "react"; +import { useEffect, useState, useCallback } from "react"; import GroupCardsLearningObjects from "./GroupCardsLearningObjects"; +import InfiniteScrollCards from "./InfiniteScrollCards"; +import mecredApi from "@/axiosConfig"; + export default function HomePage() { + + const [selectedTab, setSelectedTab] = useState("Coleções"); const [cardsPerRow, setCardsPerRow] = useState(0); const rowsPerBlock = 3; + const [collections, setCollections] = useState(true); + const [learningObjects, setLearningObjects] = useState([]); + const [isLoading, setIsLoading] = useState(false); + const [page, setPage] = useState(0); + const orderScore = `/search?page=0&results_per_page=${cardsPerRow * rowsPerBlock}&order=score&query=*&search_class=LearningObject`; const orderPublication = `/search?page=0&results_per_page=${cardsPerRow * rowsPerBlock}&order=publicationdesc&query=*&search_class=LearningObject`; const orderLikes = `/search?page=0&results_per_page=${cardsPerRow * rowsPerBlock}&order=likes&query=*&search_class=LearningObject`; const orderReview = `/search?page=0&results_per_page=${cardsPerRow * rowsPerBlock}&order=review_average&query=*&search_class=LearningObject`; const orderDownloads = `/search?page=0&results_per_page=${cardsPerRow * rowsPerBlock}&order=downloads&query=*&search_class=LearningObject`; + const fetchLearningObjects = async () => { + setIsLoading(true); + mecredApi + .get(`/search?page=${page}&results_per_page=20&order=likes&query=*&search_class=LearningObject`) + .then(({ data }) => { + setLearningObjects(prev => [...prev, ...data]); + setPage(page + 1); + }) + .catch((error) => { + console.log(error); + }); + + setIsLoading(false); + }; + + const onScroll = useCallback(async () => { + if (window.innerHeight + window.scrollY >= document.body.offsetHeight - 100 && !isLoading) + await fetchLearningObjects(); + }, [page, isLoading]) + + + const calc = () => { + const tamWidth = window.innerWidth; + return (Math.floor(tamWidth / 280)); + } + useEffect(() => { - const tamWidth = document.getElementById('content').scrollWidth; - setCardsPerRow(Math.floor(tamWidth / 280)); + setLearningObjects([]); + setCardsPerRow(calc()); + fetchLearningObjects(); }, []); + useEffect(() => { + window.addEventListener('scroll', onScroll); + return () => window.removeEventListener('scroll', onScroll); + }, [onScroll]); + + const tabSwitch = (index) => { + + switch (index) { + case "Coleções": + return ( + <div id="content" className="mb-28 mt-8"> + {cardsCollections.map((item, index) => { + return item + })} + </div> + ); + break; + case "Recursos": + return ( + <div id="content" className="mb-28 mt-8"> + <InfiniteScrollCards learningObjects={learningObjects} /> + {isLoading && <div className="text-center">Loading...</div>} + </div> + ); + break; + } + } + + const cardsLearning = [ + <GroupCardsLearningObjects title="Relevantes" cardsPerRow={cardsPerRow} url={orderScore} />, + <GroupCardsLearningObjects title="Recentes" cardsPerRow={cardsPerRow} url={orderPublication} />, + <GroupCardsLearningObjects title="Favoritados" cardsPerRow={cardsPerRow} url={orderLikes} />, + <GroupCardsLearningObjects title="Avaliados" cardsPerRow={cardsPerRow} url={orderReview} />, + <GroupCardsLearningObjects title="Baixados" cardsPerRow={cardsPerRow} url={orderDownloads} /> + + ] + + const cardsCollections = [ + <GroupCardsCollections id="35342" title="Coleções oficiais do MEC" cardsPerRow={cardsPerRow} /> + + ] + return ( - <Overlay> - <div id="content" className="mb-28 mt-8"> - <GroupCardsCollections id="35342" title="MEC" cardsPerRow={cardsPerRow} /> - <GroupCardsLearningObjects title="Relevantes" cardsPerRow={cardsPerRow} url={orderScore} /> - <GroupCardsLearningObjects title="Recentes" cardsPerRow={cardsPerRow} url={orderPublication} /> - <GroupCardsLearningObjects title="Favoritados" cardsPerRow={cardsPerRow} url={orderLikes} /> - <GroupCardsLearningObjects title="Avaliados" cardsPerRow={cardsPerRow} url={orderReview} /> - <GroupCardsLearningObjects title="Baixados" cardsPerRow={cardsPerRow} url={orderDownloads} /> - </div> + <Overlay setSelectedTab={setSelectedTab}> + {tabSwitch(selectedTab)} </Overlay> - ); + ) } diff --git a/src/app/components/InfiniteScrollCards.js b/src/app/components/InfiniteScrollCards.js new file mode 100644 index 0000000000000000000000000000000000000000..fa886acc450b9dde4f070a26b620de165b4495f2 --- /dev/null +++ b/src/app/components/InfiniteScrollCards.js @@ -0,0 +1,21 @@ +import React, { useState, useEffect } from "react"; +import Cards from "./Cards"; + +export default function InfiniteScrollCards({ learningObjects, page, setPage }) { + + return ( + <div className="flex flex-wrap justify-center"> + {learningObjects.map((item, index) => ( + <Cards + id={item['id']} + key={index} + title={item["name"]} + author={item["publisher"]["name"]} + avatar={item["publisher"]["avatar"]} + image={item["thumbnail"]} + type={item["object_type"]} + /> + ))} + </div> + ) +}; \ No newline at end of file diff --git a/src/app/components/Overlay.js b/src/app/components/Overlay.js index fd1b47df1ae8d010ca12e527e286b2d1baf019fe..30bc0ef7f6624bf093e7261c7e5115596e5207ee 100644 --- a/src/app/components/Overlay.js +++ b/src/app/components/Overlay.js @@ -6,7 +6,7 @@ import { useState } from "react"; import theme from "@/app/theme"; import { ThemeProvider } from "@emotion/react"; -export default function Overlay({ children }) { +export default function Overlay({ children, setSelectedTab }) { const [openMenu, setOpenMenu] = useState(false); const handleOpenMenu = () => { setOpenMenu(!openMenu); @@ -16,7 +16,7 @@ export default function Overlay({ children }) { <ThemeProvider theme={theme}> <main className="flex min-h-screen bg-main flex-col"> <Header handleOpenMenu={handleOpenMenu} /> - <SideBar openMenu={openMenu} /> + <SideBar setSelectedTab={setSelectedTab} openMenu={openMenu} /> <div className={`flex flex-col ml-0 ${ diff --git a/src/app/components/SideBar.js b/src/app/components/SideBar.js index bd9f3e7946b5cc1e4d7d28a1aaf161747b5ed1f1..18b9eb7fb084e57a958d2ef9b496c30b6b9e2531 100644 --- a/src/app/components/SideBar.js +++ b/src/app/components/SideBar.js @@ -2,26 +2,28 @@ import Link from 'next/link'; import CollectionsBookmarkIcon from '@mui/icons-material/CollectionsBookmark'; +import SubjectIcon from '@mui/icons-material/Subject'; import LocalLibraryIcon from '@mui/icons-material/LocalLibrary'; import PeopleAltIcon from '@mui/icons-material/PeopleAlt'; -import HomeIcon from '@mui/icons-material/Home'; import { useEffect, useState } from 'react'; +import { Button } from '@mui/material'; const acessoRapido = [ - { - title: 'Início', - icon: HomeIcon, - href: '/', - }, + { title: 'Coleções', icon: CollectionsBookmarkIcon, - href: '/colecoes' + href: '/collections' + }, + { + title: 'Recursos', + icon: SubjectIcon, + href: '/recursos' }, { title: 'Seguindo', icon: PeopleAltIcon, - href: '/seguindo' + href: '/colections' } ] @@ -48,11 +50,15 @@ const atalhos = [ } ] -export default function SideBar({ openMenu }) { +export default function SideBar({ openMenu, setSelectedTab }) { // {` bg-main inset-y-0 top-16 left-0 max-w-64 pl-16 fixed left-0 w-64 h-full`}> const [subjects, setSubjects] = useState([]); + const action = (index) => { + setSelectedTab(index); + } + useEffect(() => { fetch('https://api.portalmec.c3sl.ufpr.br/v1/subjects') .then(response => response.json()) @@ -67,7 +73,11 @@ export default function SideBar({ openMenu }) { <a className='text-xl font-bold text-gray-500 '>Acesso Rápido</a> <div className='flex flex-col text-gray-500 mt-2'> {acessoRapido.map((item, index) => { - return <Link href={item.href} key={index} className='cursor-pointer rounded hover:bg-slate-300 pr-8 pt-x pt-0 mb-2 max-w-max '> < item.icon className='text-secondary cursor-pointer' /> {item.title} </Link> + return ( + <Link href={item.href} key={index} className='cursor-pointer rounded hover:bg-slate-300 pr-8 pt-x pt-0 mb-2 max-w-max' > + <item.icon className='text-secondary cursor-pointer' /> {item.title} + </Link> + ) })} </div> </div> @@ -91,12 +101,12 @@ export default function SideBar({ openMenu }) { </div> </div> {!openMenu && <div className='max-md:hidden '> - <div className='flex flex-col pt-2 items-center pl-6 top-16 sm:top-[60px] start-0 overflow-y-auto pb-24 bg-main w-20 text-white fixed h-full z-40 ease-in-out duration-300 '> - {acessoRapido.map((item, index) => { - return <Link href={item.href} key={index} className='cursor-pointer text-center text-secondary text-xs rounded hover:bg-slate-300 pt-x pt-0 mb-4 max-w-max '> < item.icon className='text-secondary text-3xl cursor-pointer' /> </Link> - })} - </div> - + <div className='flex flex-col pt-2 items-center pl-6 top-16 sm:top-[60px] start-0 overflow-y-auto pb-24 bg-main w-20 text-white fixed h-full z-40 ease-in-out duration-300 '> + {acessoRapido.map((item, index) => { + return <Link href={item.href} key={index} className='cursor-pointer text-center text-secondary text-xs rounded hover:bg-slate-300 pt-x pt-0 mb-4 max-w-max '> < item.icon className='text-secondary text-3xl cursor-pointer' /> </Link> + })} + </div> + </div>} </> );