Eu e meus colegas, Rodolfo Braga, Vitor Lima, Natalia Martins e Elton Rodrigues, desenvolvemos um app de receitas, utilizando Hooks e Context API!
Nele é possível ver, buscar, filtrar, favoritar e acompanhar o processo de preparação de receitas e drinks.
A base de dados são de 2 APIs distintas, uma para comidas e outra para bebidas.
O layout tem como foco dispositivos móveis.
Após cada um dos passos, haverá um exemplo do comando a ser digitado para fazer o que está sendo pedido, caso tenha dificuldades, mande mensagem para o meu e-mail humberto_bonadiman@hotmail.com.
- Abra o terminal e crie um diretório no local de sua preferência com o comando mkdir:
mkdir projetos-humberto
- Entre no diretório que acabou de criar e depois clone o projeto:
cd projetos-humberto
git clone git@github.com:Humberto-Bonadiman/Project-recipes-app.git
- Acesse o diretório do projeto e depois utilize o comando npm i para instalar todas as dependências necessárias:
cd Project-recipes-app
npm i
- Por último, rode o comando npm start e acesse o projeto via browser, no caminho
http://localhost:3000/Project-recipes-app
.
2 - Crie todos os elementos que devem respeitar os atributos descritos no protótipo para a tela de login
Observações técnicas
- O input de email deve possuir o atributo
data-testid="email-input"
; - O input de senha deve possuir o atributo
data-testid="password-input"
; - O botão "Entrar" deve possuir o atributo
data-testid="login-submit-btn"
.
5 - Desenvolva a tela de maneira que o formulário só seja válido após um email válido e uma senha de mais de 6 caracteres serem preenchidos
O formulário só fica válido após um email válido e uma senha de mais de 6 caracteres serem preenchidos. Caso o formulário esteja inválido, o botão de submeter deve estar desativado, contendo a propriedade disabled
. Caso contrário, deve estar ativado, não contendo a propriedade disabled
.
6 - Salve 2 tokens no localStorage após a submissão, identificados pelas chaves mealsToken e cocktailsToken
Observações técnicas
- O token de teste é sempre
1
.
Observações técnicas
- Após a submissão, o e-mail de pessoa usuária deve ser salvo em
localStorage
na chaveuser
no formato{ email: email-da-pessoa }
.
8 - Redirecione a pessoa usuária para a tela principal de receitas de comidas após a submissão e validação com sucesso do login
9 - Implemente os elementos do header na tela principal de receitas, respeitando os atributos descritos no protótipo
10 - Implemente um ícone para a tela de perfil, um título e um ícone para a busca, caso exista no protótipo
Todas as rotas serão verificadas. Os ícones podem ser encontrados em src/images/profileIcon.svg
e em src/images/searchIcon.svg
.
12 - Desenvolva o botão de busca que, ao ser clicado, a barra de busca deve aparecer. O mesmo serve para escondê-la
- O input de busca deve possuir o atributo
data-testid="search-input"
Deve existir os data-testids tanto da barra de busca quanto de todos os radio-buttons.
Observações técnicas
- O radio button de busca de ingrediente deve possuir o atributo
data-testid="ingredient-search-radio"
; - O radio button de busca por nome deve possuir o atributo
data-testid="name-search-radio"
; - O radio button de busca da primeira letra deve possuir o atributo
data-testid="first-letter-search-radio"
. - O botão de busca deve possuir o atributo
data-testid="exec-search-btn"
14 - Posicione a barra logo abaixo do header e implemente 3 radio buttons: Ingrediente, Nome e Primeira letra
A barra de busca deve ficar logo abaixo do header e deve possuir 3 radio buttons: Ingrediente
, Nome
e Primeira letra
. Eles, em conjunto com a search-input
, devem mudar a forma como serão filtradas as receitas após clicar no botão Buscar
. Os endpoints da API que você deve usar podem ser consultados aqui para a API de comidas e aqui para a API de bebidas.
Observações técnicas
- Se o radio selecionado for
Ingrediente
, a busca na API é feita corretamente pelo ingrediente. O endpoint utilizado deve serhttps://www.themealdb.com/api/json/v1/1/filter.php?i={ingrediente}
; - Se o radio selecionado for
Nome
, a busca na API é feita corretamente pelo nome. O endpoint utilizado deve serhttps://www.themealdb.com/api/json/v1/1/search.php?s={nome}
; - Se o radio selecionado for
Primeira letra
, a busca na API é feita corretamente pela primeira letra. O endpoint utilizado deve serhttps://www.themealdb.com/api/json/v1/1/search.php?f={primeira-letra}
; - Se o radio selecionado for
Primeira letra
e a busca na API for feita com mais de uma letra, deve-se exibir umalert
com a mensgem "Sua busca deve conter somente 1 (um) caracter".
Atenção: Utilize global.alert
para evitar os warnings
do eslint sobre o uso de alert
no código.
Exemplo: Ao selecionar Ingrediente
e buscar por chicken
, deve-se utilizar o endpoint https://www.themealdb.com/api/json/v1/1/filter.php?i=chicken
.
15 - Busque na API de comidas caso a pessoa esteja na página de comidas e na de bebidas caso esteja na de bebidas
Observações técnicas
- Na tela de bebidas, se o radio selecionado for
Ingrediente
, a busca na API é feita corretamente pelo ingrediente. O endpoint utilizado deve serhttps://www.thecocktaildb.com/api/json/v1/1/filter.php?i={ingrediente}
; - Na tela de bebidas, se o radio selecionado for
Nome
, a busca na API é feita corretamente pelo nome. O endpoint utilizado deve serhttps://www.thecocktaildb.com/api/json/v1/1/search.php?s={nome}
; - Na tela de bebidas, se o radio selecionado for Primeira letra, a busca na API é feita corretamente pela primeira letra. O endpoint utilizado deve ser
https://www.thecocktaildb.com/api/json/v1/1/search.php?f={primeira-letra}
; - Na tela de bebidas, se o radio selecionado for
Primeira letra
e a busca na API for feita com mais de uma letra, deve-se exibir umalert
com a mensgem "Sua busca deve conter somente 1 (um) caracter".
Observação: Para esse requisito será verificada apenas a tela principal de receitas de bebidas, já que a de comidas já foi verificada no requisito 15.
16 - Redirecione para a tela de detalhes da receita caso apenas uma receita seja encontrada, com o ID da mesma na URL
Observações técnicas
- Caso apenas uma comida seja encontrada, deve-se ir para sua rota de detalhes (
/comidas/{id-da-receita}
); - Caso apenas uma bebida seja encontrada, deve-se ir para sua rota de detalhes (
/bebidas/{id-da-receita}
).
Mostre as receitas em cards como as da tela principal, caso mais de uma receita seja encontrada.
Observações técnicas
- Cada card deve conter o
data-testid="${index}-recipe-card"
. - Cada imagem deve conter o
data-testid="${index}-card-img"
. - Cada tag com o nome da receita deve ter o
data-testid="${index}-card-name"
. - Caso mais de uma bebida seja encontrada, mostrar as 12 primeiras (ou menos, se não hoverem 12).
O alert deve contendo o texto "Sinto muito, não encontramos nenhuma receita para esses filtros."
Todos os elementos devem respeitar os atributos descritos no protótipo para o menu inferior disponível na tela principal de receitas
Observações técnicas
- O menu inferior deve ter possuir o atributo
data-testid="footer"
; - O elemento que leva para a página de drinks deve possuir o atributo
data-testid="drinks-bottom-btn"
; - O elemento que leva para a página de explorar deve possuir o atributo
data-testid="explore-bottom-btn"
; - O elemento que leva para a página de comidas deve possuir o atributo
data-testid="food-bottom-btn"
.
20 - Posicione o menu inferior de forma fixa e apresente 3 ícones: um para comidas, um para bebidas e outro para exploração
Observações técnicas
- O menu inferior deve ficar fixado sempre ao final da página;
- Apresenta os ícones corretos (drinkIcon.svg, exploreIcon.svg e mealIcon.svg, disponíveis na pasta
src/images/
).
O menu inferior deve aparecer somente nas telas indicas no protótipo, como a de comida, de explorar e de perfil.
- Observação: lembre de componentizar muito bem os elementos em React nessa tela para evitar problemas de lógica e de complexidade ;).
25 - Implemente os elementos da tela principal de receitas respeitando os atributos descritos no protótipo
O Card de receita deve conter sua foto (strMealThumb
ou strDrinkThumb
) e seu nome (strMeal
ou strDrink
).
Observações técnicas
- Caso as receitas sejam de comida, deve-se carregar as 12 primeiras receitas obtidas através do endpoint
https://www.themealdb.com/api/json/v1/1/search.php?s=
; - Caso as receitas sejam de bebida, deve-se carregar as 12 primeiras receitas obtidas através do endpoint
https://www.thecocktaildb.com/api/json/v1/1/search.php?s=
.
Cada botão deve conter o atributo prefixado data-testid=${categoryName}-category-filter
e devem ser exibidas apenas as 5 primeiras categorias retornadas da API.
Observações técnicas
- Caso as receitas sejam de comida, deve-se exibir as 5 primeiras categorias de comida obtidas através do endpoint
https://www.themealdb.com/api/json/v1/1/list.php?c=list
; - Caso as receitas sejam de bebida, deve-se exibir as 5 primeiras categorias de bebida obtidas através do endpoint
https://www.thecocktaildb.com/api/json/v1/1/list.php?c=list
.
As categorias disponíveis devem ser obtidas através da API de comidas ou bebidas.
Atenção: Caso a categoria retorne apenas um resultado, NÃO deve redirecionar para a página de detalhes.
29 - Implemente o filtro como um toggle, que se for selecionado de novo, o app deve retornar as receitas sem nenhum filtro
Ou seja, se outro filtro de categoria for selecionado, ele deve substituir o anterior.
Ou seja, retornando novamente todas as receitas. O nome do filtro deve ser "All".
32 - Redirecione a pessoa usuária, ao clicar no card, para a tela de detalhes, que deve mudar a rota e conter o id da receita na URL
Além de dizer se a pessoa veio da tela de comidas ou de bebidas. Exemplo: /comidas/{id-da-receita}
.
- Observação: lembre de componentizar muito bem os elementos em React nessa tela para evitar problemas de lógica e de complexidade ;).
33 - Implemente os elementos da tela de detalhes de uma receita respeitando os atributos descritos no protótipo
A verificação será feita a partir dos atributos data-testids:
- A foto deve possuir o atributo
data-testid="recipe-photo"
; - O título deve possuir o atributo
data-testid="recipe-title"
; - O botão de compartilhar deve possuir o atributo
data-testid="share-btn"
; - O botão de favoritar deve possuir o atributo
data-testid="favorite-btn"
; - O texto da categoria deve possuir o atributo
data-testid="recipe-category"
; - Os ingredientes devem possuir o atributo
data-testid="${index}-ingredient-name-and-measure"
; - O texto de instruções deve possuir o atributo
data-testid="instructions"
; - O vídeo, presente somente na tela de comidas, deve possuir o atributo
data-testid="video"
; - O card de receitas recomendadas deve possuir o atributo
data-testid="${index}-recomendation-card"
; - O botão de iniciar receita deve possuir o atributo
data-testid="start-recipe-btn"
;
34 - Realize uma request para a API passando o id
da receita que deve estar disponível nos parâmetros da URL
Observações técnicas
- Verifica se a requisição para a API de comidas foi realizada. O endpoint utilizado deve ser
https://www.themealdb.com/api/json/v1/1/lookup.php?i={id-da-receita}
; - Verifica se a requisição para a API de bebidas foi realizada. O endpoint utilizado deve ser
https://www.thecocktaildb.com/api/json/v1/1/lookup.php?i={id-da-receita}
.
35 - Desenvolva a tela de forma que contenha uma imagem da receita, o título, a categoria (ou se é ou não alcoólico), uma lista de ingredientes seguidos pelas quantidades, instruções, um vídeo do youtube "embedado" e recomendações
A verificação será feita através das receitas retornadas pela API, como por exemplo, o texto dos ingredientes e das instruções.
Lembre-se: O vídeo do youtube só deve estar disponível para receitas de comida, já que não é retornado pela API de bebidas.
36 - Implemente as recomendações, para receitas de comida, a recomendação deverá ser bebida e vice-versa
Observações técnicas
- Verifica se a requisição para a API de bebidas foi realizada. O endpoint utilizado deve ser
https://www.thecocktaildb.com/api/json/v1/1/search.php?s=
; - Verifica se a requisição para a API de comidas foi realizada. O endpoint utilizado deve ser
https://www.themealdb.com/api/json/v1/1/search.php?s=
.
37 - Implemente os cards de recomendação, onde serão 6 cards, mas mostrando apenas 2 e o scroll é horizontal, similar a um carousel
Observações técnicas
- Verifica se existem todas as recomendações na tela de detalhes de uma comida. Apenas as 6 primeiras bebidas devem ser exibidas;
- Verifica se existem todas as recomendações na tela de detalhes de uma bebida. Apenas as 6 primeiras comidas devem ser exibidas.
38 - Desenvolva um botão de nome "Iniciar Receita" que deve ficar fixo na parte de baixo da tela o tempo todo
39 - Implemente a solução de forma que caso a receita já tenha sido feita, o botão "Iniciar Receita" deve sumir
40 - Implemente a solução de modo que caso a receita tenha sido iniciada mas não finalizada, o texto do botão deve ser "Continuar Receita"
41 - Redirecione a pessoa usuário caso o botão "Iniciar Receita" seja clicado, a rota deve mudar para a tela de receita em processo
43 - Implemente a solução de forma que, ao clicar no botão de compartilhar, o link da receita dentro do app deve ser copiado para o clipboard e uma mensagem avisando que o link foi copiado deve aparecer
O ícone do botão de compartilhar pode ser encontrado em src/images/shareIcon.svg
.
44 - Implemente o ícone do coração (favorito) de maneira que, deve vir preenchido caso a receita esteja favoritada e "despreenchido" caso contrário
Os ícones dos botões podem ser encontrados em src/images/whiteHeartIcon.svg
e em src/images/blackHeartIcon.svg
, respectivamente.
45 - Implemente a lógica no botão de favoritar, caso seja clicado, o ícone do coração deve mudar seu estado atual, caso esteja preenchido deve mudar para "despreenchido" e vice-versa
- O formato deve ser
[{ id, type, area, category, alcoholicOrNot, name, image }]
. - As receitas favoritas devem ser salvas no
localStorage
na chavefavoriteRecipes
no formato[{ id, type, area, category, alcoholicOrNot, name, image }]
.
- Observação: lembre de componentizar muito bem os elementos em React nessa tela para evitar problemas de lógica e de complexidade ;).
47 - Desenvolva a tela de maneira que contenha uma imagem da receita, seu titulo, sua categoria (ou se a bebida é alcoólica ou não) uma lista de ingredientes com suas respectivas quantidade e suas instruções
Verifica se os atributos data-testid estão presentes na tela com suas respectivas quantidades:
- A foto deve possuir o atributo
data-testid="recipe-photo"
; - O título deve possuir o atributo
data-testid="recipe-title"
; - O botão de compartilhar deve possuir o atributo
data-testid="share-btn"
; - O botão de favoritar deve possuir o atributo
data-testid="favorite-btn"
; - O texto da categoria deve possuir o atributo
data-testid="recipe-category"
; - Os ingredientes devem possuir o atributo
data-testid=${index}-ingredient-step
, a verificação será feita pelo length do atributo. - O elemento de instruções deve possuir o atributo
data-testid="instructions"
; - O botão para finalizar a receita deve possuir o atributo
data-testid="finish-recipe-btn"
.
49 - Implemente uma lógica que, ao clicar no checkbox de um ingrediente, o nome dele deve ser "riscado" da lista
Ao clicar no checkbox, o item deve ser riscado, mostrando que esse passo foi finalizado
50 - Salve o estado do progresso, que deve ser mantido caso a pessoa atualize a página ou volte para a mesma receita
O progresso das receitas devem ser salvos em localStorage
na chave inProgressRecipes
no formato especificado na seção localStorage
;
51 - Desenvolva a lógica de favoritar e compartilhar, a lógica da tela de detalhes de uma receita se aplica aqui
52 - Implemente a solução de maneira que o botão de finalizar receita só pode estar habilitado quando todos os ingredientes estiverem "checkados" (marcados)
O botão deve ficar desabilitado em quanto todos os checkboxs não forem marcados. O botão deve ficar fixo na parte de baixo da tela o tempo todo, semelhante ao botão de "Iniciar Receita"
53 - Redirecione a pessoa usuária após clicar no botão "Finalizar receita", para a página de receitas feitas, cuja rota deve ser /receitas-feitas
54 - Implemente os elementos da tela de receitas feitas respeitando os atributos descritos no protótipo
Observações técnicas
- Todos os data-testids estão presentes:
- O botão de filtro
All
deve ter o atributodata-testid="filter-by-all-btn"
; - O botão de filtro
Food
deve ter o atributodata-testid="filter-by-food-btn"
; - O botão de
Drinks
deve ter o atributodata-testid="filter-by-drink-btn"
; - O imagem do card de receita deve ter o atributo
data-testid="${index}-horizontal-image"
; - O texto da categoria da receita deve ter o atributo
data-testid="${index}-horizontal-top-text"
; - O texto do nome da receita deve ter o atributo
data-testid="${index}-horizontal-name"
; - O texto da data que a receita foi feita deve ter o atributo
data-testid="${index}-horizontal-done-date"
; - O elemento de compartilhar a receita deve ter o atributo
data-testid="${index}-horizontal-share-btn"
; - As
tags
da receita devem possuir o atributodata-testid=${index}-${tagName}-horizontal-tag
;
- O botão de filtro
55 - Desenvolva a tela de maneira que, caso a receita do card seja uma comida, ela deve possuir: a foto da receita, o nome, a categoria, a area, a data em que a pessoa fez a receita, as 2 primeiras tags retornadas pela API e um botão de compartilhar
O ícone do botão de compartilhar pode ser encontrado em src/images/shareIcon.svg
.
ObservaçÕes técnicas
- O card possui os atributos corretos de uma comida
56 - Desenvolva a tela de maneira que, caso a receita do card seja uma bebida, ela deve possuir: a foto da receita, o nome, se é alcoólica, a data em que a pessoa fez a receita e um botão de compartilhar
O ícone do botão de compartilhar pode ser encontrado em src/images/shareIcon.svg
.
57 - Desenvolva a solução de maneira que o botão de compartilhar deve copiar a URL da tela de detalhes da receita para o clipboard
58 - Implemente 2 botões que filtram as receitas por comida ou bebida e um terceiro que remove todos os filtros
Os nomes dos botões devem ser "Food", "Drinks" e "All", respectivamente.
Observações técnicas
- Ao clicar no botão "Food" as receitas devem ser filtradas por comidas;
- Ao clicar no botão "Drinks" as receitas devem ser filtradas por bebidas;
- Ao clicar no botão "All" o filtro deve ser removido.
60 - Implemente os elementos da tela de receitas favoritas (cumulativo com os atributos em comum com a tela de receitas feitas) respeitando os atributos descritos no protótipo
61 - Desenvolva a tela de maneira que, caso a receita do card seja uma comida, ela deve possuir: a foto da receita, o nome, a categoria, a area, um botão de compartilhar e um de "desfavoritar"
Os ícones dos botões podem ser encontrados em src/images/shareIcon.svg
e em src/images/blackHeartIcon.svg
, respectivamente.
62 - Desenvolva a tela de maneira que, caso a receita do card seja uma bebida, ela deve possuir: a foto da receita, o nome, se é alcoólica ou não, um botão de compartilhar e um de "desfavoritar"
Os ícones dos botões podem ser encontrados em src/images/shareIcon.svg
e em src/images/blackHeartIcon.svg
, respectivamente.
63 - Desenvolva a solução de maneira que o botão de compartilhar deve copiar a URL da tela de detalhes da receita para o clipboard
64 - Desenvolva a solução de maneira que o botão de "desfavoritar" deve remover a receita da lista de receitas favoritas do localStorage
e da tela
65 - Implemente 2 botões que filtram as receitas por comida ou bebida e um terceiro que remove todos os filtros
Os nomes dos botões devem ser "Food", "Drinks" e "All", respectivamente
66 - Redirecione a pessoa usuária ao clicar na foto ou no nome da receita, a rota deve mudar para a tela de detalhes daquela receita
68 - Desenvolva a tela de maneira que tenha 2 botões: um para explorar comidas e o outro para explorar bebidas
Verifica se o atributo data-testid="explore-food"
possui o texto "Explorar Comidas" e se o data-testid="explore-drinks"
possui o texto "Explorar Bebidas".
69 - Redirecione a pessoa usuária ao clicar em um dos botões, a rota deve mudar para a página de explorar comidas ou de explorar bebidas
70 - Implemente os elementos da tela de explorar bebidas ou comidas respeitando os atributos descritos no protótipo
71 - Desenvolva 3 botões: um para explorar por ingrediente, um para explorar por local de origem e um para pegar uma receita aleatória
O nomes dos botões devem ser "Por Ingredientes" com o atributo data-testid="explore-by-ingredient"
, "Por Local de Origem" com o atributo data-testid="explore-by-area"
e "Me Surpreenda!" com o atributo data-testid="explore-surprise"
, respectivamente.
Obs: se a opção escolhida for explorar bebidas, o botão para explorar por local de origem não deve estar disponível.
72 - Redirecione a pessoa usuária ao clicar em "Por Ingredientes", para a tela de explorar por ingredientes
73 - Redirecione a pessoa usuária ao clicar em "Por Local de Origem", a rota deve mudar para tela de explorar por local de origem
74 - Redirecione a pessoa usuária ao clicar em "Me Surpreenda!", a rota deve mudar para a tela de detalhes de uma receita, que deve ser escolhida de forma aleatória através da API
Observações técnicas
- Ao clicar no botão "Me Surpreenda!" da tela de explorar comidas a rota muda para a página de detalhes de uma comida aleatória obtida através do endpoint
https://www.themealdb.com/api/json/v1/1/random.php
; - Ao clicar no botão "Me Surpreenda!" da tela de explorar bebidas a rota muda para a página de detalhes de uma bebida aleatória obtida através do endpoint
https://www.thecocktaildb.com/api/json/v1/1/random.php
.
75 - Implemente os elementos da tela de explorar ingredientes respeitando os atributos descritos no protótipo
A tela deve possuir os atributos data-testid="${index}-ingredient-card"
, data-testid="${index}-card-img"
e data-testid="${index}-card-name"
, que estão relacionados ao card, imagem e nome do ingrediente respectivamente.
76 - Desenvolva cards para os 12 primeiros ingredientes, de forma que cada card contenha o nome do ingrediente e uma foto
77 - Redireciona a pessoa usuária ao clicar no card do ingrediente, a rota deve mudar para tela principal de receitas mas mostrando apenas as receitas que contém o ingrediente escolhido
78 - Implemente os elementos da tela de explorar por local de origem respeitando os atributos descritos no protótipo
O elemento de dropdown deve possuir o atributo data-testid="explore-by-area-dropdown"
e suas opções devem possuir o atributo [data-testid="${area}-option"]
.
79 - Desenvolva as mesmas especificações da tela de receitas principal, com a diferença de que os filtros de categoria são substituídos por um dropdown
O elemento de dropdown deve possuir o atributo data-testid="explore-by-area-dropdown"
.
80 - Implemente o dropdown de maneira que devem estar disponíveis todas as áreas retornadas da API, incluindo a opção "All", que retorna as receitas sem nenhum filtro
A rota /explorar/bebidas/area
não deve estar disponível, retornando um erro de "Not Found".
Observações técnicas
- Todos o data-testid do email e de todos os botões
- O elemento de email deve possuir o atributo
data-testid="profile-email"
; - O botão com as "Receitas Feitas" deve possuir o atributo
data-testid="profile-done-btn"
; - O botão com as "Receitas Favoritas" deve possuir o atributo
data-testid="profile-favorite-btn"
; - O botão de sair deve possuir o atributo
data-testid="profile-logout-btn"
.
- O elemento de email deve possuir o atributo
84 - Implemente 3 botões: um de nome "Receitas Feitas", um de nome "Receitas Favoritas" e um de nome "Sair"
85 - Redirecione a pessoa usuária que, ao clicar no botão de "Receitas Favoritas", a rota deve mudar para a tela de receitas favoritas
86 - Redirecione a pessoa usuária que, ao clicar no botão de "Receitas Feitas", a rota deve mudar para a tela de receitas feitas
87 - Redirecione a pessoa usuária que, ao clicar no botão de "Sair", o localStorage
deve ser limpo e a rota deve mudar para a tela de login
Obs: A maneira como as APIs devem ser estruturadas segue os seguintes modelos: https://www.themealdb.com/api.php e https://www.thecocktaildb.com/api.php
Requisito 1 não finalizado, mas quero finaliza-ló em algum momento no futuro.