Skip to content
Snippets Groups Projects
Commit 0645b4b9 authored by Richard Fernando Heise Ferreira's avatar Richard Fernando Heise Ferreira
Browse files

Merge branch 'issue/31-create-not-found-page' into 'develop'

Issue #31: CREATE not found pages

See merge request !90
parents f73bc1e4 65a4d685
Branches
No related tags found
1 merge request!90Issue #31: CREATE not found pages
Pipeline #37777 passed
Showing
with 183 additions and 112 deletions
export default function ErrorComponent ({ name }) {
return (
<div className="flex flex-col text-center">
<p className="text-text-filter mt-64 font-bold text-2xl">{name} não encontrado!</p>
</div>
)
}
\ No newline at end of file
"use client"
import { useRouter } from "next/navigation";
import Overlay from "./components/Overlay";
export default function Error(){
const router = useRouter()
return (
<Overlay>
<div className="flex justify-center items-center mt-72 flex-col">
<p className="text-8xl text-text-filter font-bold">404</p>
<p className="text-text-filter text-xl font-semibold">Página não encontrada</p>
<button onClick={() => router.push("/")} className="mt-4 bg-secondary text-lg text-white p-2 px-4 rounded-lg hover:bg-secondary-hover">Voltar para página inicial</button>
</div>
</Overlay>
)
}
\ No newline at end of file
// components/Card.js
import { useState } from 'react';
import { useEffect } from 'react';
import KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown';
import KeyboardArrowUpIcon from '@mui/icons-material/KeyboardArrowUp';
import NotFound from './NotFound';
/**
* @param {Object} props
* @param {String} props.title Sobre
* @param {String} props.content Descrição do usuário
* @returns card com a descrição do usuário
*/
const AboutCard = ({ title, content }) => {
const [expanded, setExpanded] = useState(false);
const [showButton, setShowButton] = useState(false);
const AboutCard = ({ content }) => {
/* Verificar se o conteúdo é maior que a altura inicial */
useEffect(() => {
setShowButton(document.getElementById('content').scrollHeight > 50);
}, []);
const toggleContent = () => {
setExpanded(!expanded);
};
return (
<div className="mt-10 min-w-[200px] overflow-hidden transition-height bg-white">
<div className="mt-6 min-w-[200px] overflow-hidden transition-height bg-white">
<div className='p-4 rounded-md min-w-[200px] min-h-[180px] ' >
<h2 className="text-main-text text-2xl font-semibold ">{title}</h2>
<div id="content" className="content pt-2">
<p className={` ${expanded ? '' : 'line-clamp-3'} text-sm text-main-text `}>{content}</p>
</div>
<div className='flex justify-center'>
{/*Verifica se é para o botão aparecer e faz a lógica de Ver mais */}
{showButton && (
<button
onClick={toggleContent}
className="bg-white text-main-text px-4 py-2 rounded transition-colors hover:bg-gray-200 text-base font-medium"
>
{expanded ? 'Ver menos' : 'Ver mais'}
{expanded ? <KeyboardArrowUpIcon /> : <KeyboardArrowDownIcon />}
</button>
)}
</div>
<h2 className="text-main-text text-2xl font-semibold ">Sobre</h2>
{content ? <div id="content" className="content pt-2">
<p className={` text-sm text-main-text `}>{content}</p>
</div> :
<NotFound name="descrição" />
}
</div>
</div>
);
......
......@@ -3,6 +3,7 @@ import mecredApi from "@/axiosConfig"
import { getStoredValue } from "@/app/handlers/localStorageHandler"
import UsersPageCard from "@/app/components/UsersPageCard"
import { Button } from "@mui/material"
import NotFound from "./NotFound"
/**
*
......@@ -49,6 +50,8 @@ export default function FollowersCards({ id, count }) {
<div className="flex justify-between pt-10">
<div className="text-main-text text-2xl font-semibold inline-block ">Seguidores</div>
</div>
{count === 0 ?
<NotFound name="seguidores" /> :
<div className='p-3 my-5 rounded-md min-w-[200px] min-h-[180px] ' >
<div className="flex flex-wrap justify-center">
{followers.map((item, i) => {
......@@ -64,6 +67,7 @@ export default function FollowersCards({ id, count }) {
</div>
</div>
}
{numberCards+12 < count ?
<Button
fullWidth
......
......@@ -3,6 +3,7 @@ import mecredApi from "@/axiosConfig"
import { getStoredValue } from "@/app/handlers/localStorageHandler"
import UsersPageCard from "@/app/components/UsersPageCard"
import { Button } from "@mui/material"
import NotFound from "./NotFound"
/**
*
......@@ -49,6 +50,8 @@ export default function FollowingCards({ id, count }) {
<div className="flex justify-between pt-10">
<div className="text-main-text text-2xl font-semibold inline-block ">Seguindo</div>
</div>
{count === 0 ?
<NotFound name="Seguindo" /> :
<div className='p-3 my-5 rounded-md min-w-[200px] min-h-[180px] ' >
<div className="flex flex-wrap justify-center">
{following.map((item, i) => {
......@@ -64,6 +67,7 @@ export default function FollowingCards({ id, count }) {
</div>
</div>
}
{numberCards + 12 < count ?
<Button
fullWidth
......
export default function NotFound({ name }) {
return (
<div className="flex justify-center">
<p className="pt-12 text-text-filter text-lg">{name === "Seguindo" ? `O usuário não segue ninguém ainda.` : `O usuário não possui ${name}`}</p>
</div>
)
}
\ No newline at end of file
......@@ -6,6 +6,7 @@ import DownloadButton from "@/app/components/DownloadButton";
import GroupCardsCollections from "@/app/components/GroupCardsCollections";
import Link from "next/link";
import mecredApi from "@/axiosConfig";
import NotFound from "./NotFound";
/**
* @returns Coleçoes dos usuários
......@@ -84,6 +85,8 @@ export default function ProfileCollections({ id, idLogin }) {
Criar Nova Coleção
</button>}
</div>
{collections.length === 0 ?
<NotFound name="coleções" /> :
<div className="justify-center mt-5">
{collections.map((item, index) => {
......@@ -107,6 +110,7 @@ export default function ProfileCollections({ id, idLogin }) {
);
})}
</div>
}
{/**
* verifica se o número de coleções é menor que o total de coleções
* se sim, aparece o botão de ver mais
......
......@@ -11,8 +11,8 @@ import CardsHomologation from "./CardsHomologation";
*/
export default function ProfileHomologation({ id }) {
const [homologated, setHomologated] = useState([])
const [expanded, setExpanded] = useState(false);
const [numberCards, setNumberCards] = useState(0)
const [totalCount, setTotalCount] = useState(0)
const token = getStoredValue("access_token")
const client = getStoredValue("client")
const uid = getStoredValue("uid")
......@@ -29,43 +29,46 @@ export default function ProfileHomologation({ id }) {
'Expires': 0
}
})
.then(({ data }) => {
.then(({ data, headers }) => {
setHomologated(prevData => [...prevData, ...data]);
setTotalCount(Number(headers["x-total-count"]))
});
}
fetchHomologation(id);
}, [client, id, token, numberCards, uid]);
}, [id, numberCards]);
/**
* Aumenta de 12 em 12 o número de recursos à serem homologados
*/
const toggleContent = () => {
setNumberCards(numberCards + 12)
setExpanded(!expanded);
};
return (
<Card className='p-3 my-10 rounded-md min-w-[200px] min-h-[180px] ' >
<div className="text-main-text text-2xl font-semibold ">Homologação</div>
<div className={`flex content flex-wrap justify-center ${expanded ? "" : "overflow-y-hidden"}`}>
<div className={`flex content flex-wrap justify-center `}>
{homologated.map((item, i) => {
return <CardsHomologation item={item} key={i} />
})}
</div>
<Divider className="mr-8 max-md:mr-0 mb-8">
{numberCards + 12 < totalCount ?
<Button
fullWidth
disableElevation
variant="outlined"
className="mt-2 border-secondary rounded-xl hover:border-secondary-hover text-gray-700 normal-case flex gap-2"
className="my-4 border-hidden hover:bg-transparent rounded-xl normal-case "
onClick={() => toggleContent()}
alt="Carregar mais"
>
{"Carregar mais"}
<p className="hover:bg-main px-4 text-gray-600 text-lg rounded-md">
{"Ver mais..."}
</p>
</Button>
</Divider>
: <></>}
</Card>
);
}
\ No newline at end of file
......@@ -8,19 +8,17 @@ import FollowersCards from "./FollowersCards";
/**
* @returns Retorna para o usuário qual dos botões em SelectionButtons que ele solicitou
* @param {Object} props
* @param {string} props.title Sobre
* @param {string} props.content Descrição do usuário
* @param {Number} props.optButton Qual dos botões foi selecionado pelo usuário (Sobre, Recursos, Coelções ou Homologação)
* @param {Number} props.id id do usuário acessado
* @param {Number} props.idLogin id do usuário logado
*/
export default function ProfileOptions({ title, content, optButton, id, idLogin, followingCount, followersCount }) {
export default function ProfileOptions({ content, optButton, id, idLogin, followingCount, followersCount }) {
const opts = (op) => {
switch (op) {
case 0:
return <AboutCard title={title} content={content} />
return <AboutCard content={content} />
case 1:
return <ProfileResources id={id} idLogin={idLogin} />
case 2:
......@@ -32,7 +30,7 @@ export default function ProfileOptions({ title, content, optButton, id, idLogin,
case 5:
return <ProfileHomologation id={id} />
default:
return <AboutCard title={title} content={content} />
return <AboutCard content={content} />
}
}
......
......@@ -4,6 +4,7 @@ import { useState, useEffect } from "react";
import mecredApi from "@/axiosConfig";
import { getStoredValue } from "@/app/handlers/localStorageHandler";
import { Button } from "@mui/material";
import NotFound from "./NotFound";
/**
* @returns Recursos do usuário
......@@ -65,6 +66,9 @@ export default function ProfileResources({ id, idLogin }) {
</button>
</Link>}
</div>
{totalCount === 0 ?
<NotFound name="recursos" /> :
<div className='p-3 my-5 rounded-md min-w-[200px] min-h-[180px] bg-white ' >
<div className="flex flex-wrap justify-center">
{resources.map((resource, index) => {
......@@ -82,6 +86,7 @@ export default function ProfileResources({ id, idLogin }) {
})}
</div>
</div>
}
{numberCards + 12 < totalCount ?
<Button
fullWidth
......
import Grid from "@mui/material/Grid"
import { isLoggedIn } from '@/app/handlers/loginHandler';
import { Tab, Tabs } from "@mui/material";
import { useState } from "react";
/**
* @return Botões de informações que o usuário pode acessar
......@@ -10,6 +12,11 @@ import { isLoggedIn } from '@/app/handlers/loginHandler';
* @param {Number} props.idLogin
*/
export default function SelectionButtons({ setOptButton, verifyCurator, idProfile, idLogin }) {
const [value, setValue] = useState(0)
const handleChange = (e, newValue) => {
setValue(newValue)
setOptButton(newValue)
}
/**
* Se o usuário estiver logado, vendo seu próprio perfil e for curador tem todas as opções disponíveis.
......@@ -22,22 +29,46 @@ export default function SelectionButtons({ setOptButton, verifyCurator, idProfil
["Sobre", "Meus Recursos", "Minhas Coleções", "Seguidores", "Seguindo"]) :
["Sobre", "Recursos", "Coleções", "Seguidores", "Seguindo"]
return (
<Grid container className='' >
{
buttons.map((item, index) => {
<div>
<div className="max-lg:hidden">
<Tabs
value={value}
onChange={handleChange}
variant="fullWidth"
>
{buttons.map((item, index) => {
return (
<Grid item key={index} xs={6} sm={12 / buttons.length} lg={12 / buttons.length}>
<button
className="h-12 text-main-text text-base normal-case font-bold w-[100%] hover:bg-gray-100 hover:text-secondary hover:border-b-2 hover:border-secondary focus:text-secondary focus:border-b-2 focus:border-secondary"
onClick={() => setOptButton(index)}
// title={item}
alt={item}
<Tab key={index} value={index} label={item} />
)
})}
</Tabs>
</div>
<div className="lg:hidden">
<Tabs
value={value}
onChange={handleChange}
variant="scrollable"
scrollButtons="auto"
allowScrollButtonsMobile
>
{item}
</button>
</Grid>
{buttons.map((item, index) => {
return (
<Tab key={index} value={index} label={item} />
)
})}
</Grid>
</Tabs>
</div>
</div>
);
};
\ No newline at end of file
......@@ -188,7 +188,7 @@ export default function UserCard({ profileData, idLogin}) {
{<SelectionButtons setOptButton={setOptButton} verifyCurator={verifyCurator} idLogin={idLogin} idProfile={profileData["id"]} />}
</div>
{/* Faz a escolha correta de qual botão o usuário clicou */}
<ProfileOptions title="Sobre" content={profileData["description"]} optButton={optButton} id={profileData["id"]} idLogin={idLogin} followersCount={followers} followingCount={following} />
<ProfileOptions content={profileData["description"]} optButton={optButton} id={profileData["id"]} idLogin={idLogin} followersCount={followers} followingCount={following} />
</div>
</>
);
......
......@@ -5,9 +5,11 @@ import { useEffect, useState } from "react";
import Overlay from "../../components/Overlay";
import mecredApi from "@/axiosConfig";
import { isLoggedIn } from "@/app/handlers/loginHandler";
import ErrorComponent from "@/app/components/ErrorComponent";
export default function Perfil({ params }) {
const [profileData, setProfileData] = useState(null);
const [error, setError] = useState(false)
const [idLogin, setIdLogin] = useState(0)
const token = getStoredValue("access_token")
const client = getStoredValue("client")
......@@ -41,7 +43,8 @@ export default function Perfil({ params }) {
})
.then(({ data }) => {
setProfileData(data);
});
})
.catch(() => setError(true))
}
fetchUser(params.id)
......@@ -54,7 +57,8 @@ export default function Perfil({ params }) {
.get(`/users/${id}`)
.then(({ data }) => {
setProfileData(data);
});
})
.catch(() => setError(true))
}
fetchUser(params.id)
......@@ -62,10 +66,13 @@ export default function Perfil({ params }) {
}, [params.id, client, token, uid])
return (
<>
<Overlay>
{profileData && <UserCard profileData={profileData} idLogin={idLogin} tab={optTab} />}
{error ? <ErrorComponent name="Usuário" /> :
( profileData && <UserCard profileData={profileData} idLogin={idLogin} tab={optTab} />)}
</Overlay>
</>
);
......
......@@ -12,10 +12,12 @@ import { getStoredValue } from "@/app/handlers/localStorageHandler";
import Loading from "@/app/components/Loading";
import ResourcePreview from "./components/resourcePreview";
import NeedLoginModal from "./components/needLoginModal";
import ErrorComponent from "@/app/components/ErrorComponent";
export default function Recurso({ params }) {
const [learningObject, setLearningObject] = useState(undefined);
const [needLoginOpen, setNeedLoginOpen] = useState(false);
const [error, setError] = useState(false)
const token = getStoredValue("access_token");
const client = getStoredValue("client");
......@@ -40,13 +42,17 @@ export default function Recurso({ params }) {
})
.then((response) => {
setLearningObject(response.data);
});
})
.catch(() => {setError(true);})
}, [params.id, client, token, uid]);
return (
<>
<Overlay>
{!learningObject ? (
{!learningObject ? ( error ?
<ErrorComponent name="Recurso" /> :
<Loading scroll />
) : (
<>
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment