Nós vamos começar pensando agora na renderização condicional. Nós vamos fazer a seguinte lógica: Se o resultado vier com o “.lenght” acima ou igual a 1, nós vamos retonar o map, se não, iremos retornar uma mensagem.
Vamos fazer a verificação do lenght de cursos dentro da verificação.
<main>
<HeaderAuth />
{searchResult.lenght >= 1 ? (
searchResult?.map((course) => (
<div key={course.id}>
<p>{course.name}</p>
</div>
))
) : (
<p className={styles.noSearchText}>Nenhum resultado encontrado!</p>
)}
</main>
Agora, nós iremos fazer uma verificação. Se o “res.data.courses” tiver um lenght igual a 0, nós iremos setar o “searchRender” como falso, para então aparecer a mensagem.
const searchCourses = async () => {
if (typeof searchName === "string") {
const res = await courseService.getSearch(searchName);
setSearchResult(res.data.courses);
if (res.data.courses.length === 0) {
setSearchRender(false);
}
}
};
Podemos então testar, veremos que quando não tem, ele retorna a mensagem certinha. Vamos fazer uma modificação visual simples, para que ele não fique tão pequeno e feio.
.noSearchText {
text-align: center;
padding: 20px;
font-size: 24px;
font-weight: bold;
}
Nós iremos agora lá na pasta “components”, iremos lá criar uma pasta chamada “searchCard”, e dentro dela já colocar um “index.tsx” e um “styles.module.scss”
import styles from "./styles.module.scss";
const SearchCard = function () {
return <></>;
};
export default SearchCard;
Nós iremos criar uma props chamada “course”, faremos algo parecido com o que fizemos em “slideCard”
interface props {
course: CourseType;
}
const SearchCard = function ({ course }: props) {
return <></>;
};
Agora, nós faremos um card que vai armazenar: Thumb, título, descrição e link para ir para o curso. Será muito similar ao que fizemos no slide, o que vai mudar de fato será o visual.
<>
<Link href={`/courses/${course.id}`}>
<div className={styles.searchCard}>
<img src={`${process.env.NEXT_PUBLIC_BASEURL}/${course.thumbnailUrl}`} alt={course.name} className={styles.searchCardImg}/>
<p className={styles.searchCardTitle}>{course.name}</p>
<p className={styles.searchCardDescription}>{course.synopsis}</p>
</div>
</Link>
</>
Agora, nós iremos lá onde estamos fazendo o map para o search, e iremos colocar isso como retorno. Vamos também colocar o nosso map dentro de um container, onde mais para frente iremos colocar um display flex nele.
<main>
<HeaderAuth />
{searchResult.length >= 1 ? (
<Container>
{searchResult?.map((course) => (
<SearchCard key={course.id} course={course} />
))}
</Container>
) : (
<p className={styles.noSearchText}>Nenhum resultado encontrado!</p>
)}
</main>
Podemos testar e ver que está funcionando, vemos que os cursos estão funcionando, só falta ajeitarmos esse visual para ficar 100%. Vamos começar com algo básico, para vermos melhor o retorno que estamos tendo.
@import "../../../styles/colors.module.scss";
.searchCard {
width: 320px;
height: 350px;
border: 1px solid $darkGray;
overflow: hidden;
text-overflow: clip;
cursor: pointer;
}
.searchCardImg {
width: 100%;
height: 190px;
}
Agora no navegador, já temos um belo retorno visual, nós vamos então fazer agora a manipulação dos textos e depois adicionar detalhe aos cards.
.searchCardTitle {
font-size: 20px;
font-weight: bold;
padding: 10px 20px;
}
.searchCardDescription {
color: $lightGray;
padding: 0px 20px;
font-size: 18px;
}
Agora, nós iremos fazer um hover básico nos nossos cards, para que eles tenham um efeito da borda mudando de cor, também aumentando a altura do card, para vermos que tem uma decrição a mais do que vemos.
.searchCard {
width: 320px;
height: 400px;
border: 1px solid $darkGray;
overflow: hidden;
text-overflow: clip;
cursor: pointer;
transition: 0.4s;
&:hover {
border-color: $lightRed;
height: 416px;
}
}
.searchCardTitle {
font-size: 20px;
font-weight: bold;
padding: 10px 20px;
transition: 0.4s;
}
Nós podemos ver no navegador que está funcionando, mas está estranho. Nós iremos então fazer com que o container ganhe um display flex, para que fiquem lado a lado e não fique estranho como está agora.
<Container className="d-flex flex-wrap justify-content-center gap-5 py-4">
{searchResult?.map((course) => (
<SearchCard key={course.id} course={course} />
))}
</Container>
Agora, nós precisamos apenas colocar o footer, e depois disso iremos colocar um background no footer e no header preto, que nem fizemos na página de dados.
<main>
<div className={styles.header}>
<HeaderAuth />
</div>
{searchResult.length >= 1 ? (
<Container className="d-flex flex-wrap justify-content-center gap-5 py-4">
{searchResult?.map((course) => (
<SearchCard key={course.id} course={course} />
))}
</Container>
) : (
<p className={styles.noSearchText}>Nenhum resultado encontrado!</p>
)}
<div className={styles.footer}>
<Footer />
</div>
</main>
Vamos então colocar os backgrounds.
.header {
background-color: black;
}
.footer {
background-color: black;
}
Por último, nós iremos em “search.tsx” para colocarmos um nome dinâmico no nosso head. Nós iremos mudar o “title” para o que o usuário digitar
<Head>
<title>Onebitflix - {searchName}</title>
<link rel="shortcut icon" href="/favicon.svg" type="image/x-icon" />
</Head>
Nossa responsividade será bem básica aqui, nós podemos ver que todos os cards vão se adaptando de acordo com a tela, pois temos o display flex. Mas a partir de “334px”, o nosso texto dentro de card fica estranho, vamos alterar ele.
@media (max-width: 334px) {
.searchCardTitle {
font-size: 16px;
}
.searchCardDescription {
font-size: 14px;
}
}
Agora, uma coisa relacionada a página em si, é que, caso a nossa página retorne o parágrafo informando erro no conteúdo, o footer vai ter um bug e ficar próximo a ele. Nós iremos manipular isso, iremos primeiro colocar um “className” no “main” e também iremos envolver o nosso map com um section, para podermos utilizar o flex para deixarmos o footer sempre colado na parte baixa da nossa página.
<main className={styles.main}>
<div className={styles.header}>
<HeaderAuth />
</div>
<section className={styles.mainContent}>
{searchResult.length >= 1 ? (
<Container className="d-flex flex-wrap justify-content-center gap-5 py-4">
{searchResult?.map((course) => (
<SearchCard key={course.id} course={course} />
))}
</Container>
) : (
<p className={styles.noSearchText}>Nenhum resultado encontrado!</p>
)}
</section>
<div className={styles.footer}>
<Footer />
</div>
</main>