Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
node_modules
dist
6 changes: 6 additions & 0 deletions .prettierrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"trailingComma": "es5",
"tabWidth": 2,
"semi": false,
"singleQuote": true
}
33 changes: 14 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,24 +1,19 @@
# Avaliação Junior
Olá desenvolvedor!\
Tudo bem?! 😊\
\
Seja bem-vindo, o intuito do teste não é reprovar e sim conhecer seu melhor estilo de programar e resolver problemas.
Teste para o processo seletivo da impar para a vaga de front-end junior

## O que fazer
1. Fazer um fork desse repositório e trabalhar no seu ambiente.
2. Replicar o layout do link abaixo, pode usar dados de um JSON local:\
[Link para o layout](https://xd.adobe.com/view/c715f110-fbd4-4323-be0c-0e453c1450db-9246)
2. Fazer a funcionalidade de busca funcionar.
3. Os cliques nos botões de editar/excluir/criar card podem exibir uma mensagem pro usuário de que a funcionalidade não foi implementada.
4. Ao finalizar a avaliação modifique esse README com as instruções de como podemos fazer o seu código rodar na nossa máquina. Ou seja, passo a passo do que instalar e de quais comandos rodar para podermos visualizar o seu trabalho!
5. Realizar um Pull Request para o nosso repositório e mandar um e-mail para [email protected] com o assunto "Avaliação Junior", informando que finalizou a avaliação e colocando o link do Pull Request.
Luan Portugal da Silva

## Dicas
* Não foi definido limite de linhas e colunas, portanto fique à vontade para tal escolha.
* Gostamos de interfaces limpas e elegantes.

## Quais tecnologias usar
* Deixaremos a seu critério qual tecnologia utilizar no entanto você terá mais pontos conosco se utilizar React para criação da interface e também o uso de pré-processadores/styled-components para o CSS.
## Como rodar o projeto
1 - Clone o repositório para sua área de trabalho
2 - yarn install
3 - yarn start

## Desafios se você se sentir confiante
* Usar alguma API na internet, tipo https://pokeapi.co/, para trazer os dados que vão aparecer nos cards da tela.

obs: Caso queira ter um preview do projeto utilize o link, deploy feito na aws
EC2 Ubuntu: http://18.229.142.156:3000/

## Funcionalidade do Projeto
1- Consumo da API https://docs.thecatapi.com/
2- Busca dinamica de Gatos
3- Sidebar
14 changes: 14 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<!DOCTYPE html>
<html lang="pt-br">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/assets/thumb-img.jpg" />
<link rel="stylesheet" href="https://use.typekit.net/ggu8gdd.css" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Teste Ímpar</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>
25 changes: 25 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"name": "vite-project",
"private": true,
"version": "0.0.0",
"scripts": {
"start": "vite",
"build": "tsc && vite build",
"preview": "vite preview"
},
"dependencies": {
"@types/styled-components": "^5.1.25",
"axios": "^0.27.2",
"react": "^18.0.0",
"react-dom": "^18.0.0",
"styled-components": "^5.3.5"
},
"devDependencies": {
"@faker-js/faker": "^7.0.1",
"@types/react": "^18.0.0",
"@types/react-dom": "^18.0.0",
"@vitejs/plugin-react": "^1.3.0",
"typescript": "^4.6.3",
"vite": "^2.9.9"
}
}
1 change: 1 addition & 0 deletions public/assets/Icon-edit.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions public/assets/Icon-trash.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/assets/background.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions public/assets/icon-lupa.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions public/assets/icone.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions public/assets/icone_criar.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/assets/logo-teste.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/assets/thumb-img.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 10 additions & 0 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import Home from './screens/Home'

export default function App() {

return (
<>
<Home />
</>
)
}
14 changes: 14 additions & 0 deletions src/components/Button/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { Container } from "./style"

interface ButtonTypes {
onClick?:any,
children: string,
variant?: 'primary' | 'secondary'
}


export default function Button({onClick, children, variant}:ButtonTypes) {
return(
<Container onClick={onClick} variant={variant}>{children}</Container>
)
}
30 changes: 30 additions & 0 deletions src/components/Button/style.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import styled from 'styled-components'

interface ButtonTypes {
variant?: 'primary' | 'secondary'
}

export const Container = styled.button<ButtonTypes>`

padding: 0 40px;
height: 48px;
text-align: center;
font-size: 23px;

background: ${({variant}) => variant == 'secondary' ? '#fff' : '#e76316' } 0% 0% no-repeat padding-box;
color: ${({variant}) => variant == 'secondary' ? '#e76316' : '#fff' };

font: normal normal 300 18px/23px Muli;

border-radius: 8px;
border: 1px solid #E76316;
box-shadow: 0px 3px 6px #92207242;
cursor: pointer;

@media (max-width: 820px) {
justify-content: center;
p {
padding: 15px;
}
}
`
47 changes: 47 additions & 0 deletions src/components/Card/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { useState, useEffect } from 'react'
import { Box, Img, Name, FooterBox } from './style'
import { RequestApi } from '../../services'

interface CardsProps {
filterQuery: any
actions: any
}

export default function Cards({ actions, filterQuery }: CardsProps) {
const [data, setData] = useState<any>([])

useEffect(() => {
RequestApi().then((data: any) => {
const cats = data.filter((cat: any) => cat.name.includes(filterQuery))
setData(cats)
})
}, [filterQuery])

return (
<Box>
{data.map((p: any, index: number) => (
<div className="container-box" key={index}>
<Img src={p.url} alt={p.name} />

<Name>{p.name}</Name>

<FooterBox>
<div>
<img src="/assets/icon-trash.svg" alt="Ícone de lixo"></img>
<button onClick={() => actions.setDeleteSidebar(true)}>
Excluir
</button>
</div>
<div className="div-button"></div>
<div>
<img src="/assets/icon-edit.svg" alt="Ícone para editar"></img>
<button onClick={() => actions.setShowSidebar(true)}>
Editar
</button>
</div>
</FooterBox>
</div>
))}
</Box>
)
}
80 changes: 80 additions & 0 deletions src/components/Card/style.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import styled from 'styled-components'

export const Box = styled.div`
text-align: center;
margin-top: 20px;
display: flex;
justify-content: center;
flex-direction: row;
flex-wrap: wrap;
gap: 50px;
padding: 0px 10vh;

.container-box {
border: 1px solid #e4e4e4;
border-radius: 8px;
box-shadow: 0px 3px 6px #e5e5e5;
}
`

export const Name = styled.p`
max-width: 65%;
margin: 0 auto;
margin-bottom: auto;
text-align: center;
padding: 10px;
border-top: 1px solid #0000000f;
font: normal normal normal 16px/20px Muli;
color: #263238;
text-transform: capitalize;
`

export const Img = styled.img`
width: 100px;
height: 100px;
margin: 20px auto;
border-radius: 50%;
border: solid 3px #e4e4e4;
`

export const FooterBox = styled.div`
display: flex;
justify-content: space-evenly;
padding: 15px;
box-shadow: inset 0px 3px 6px #0000000f;
font: normal normal normal 15px/19px Muli;
width: 200px;
gap: 20px;

div {
display: flex;
justify-content: space-evenly;
align-items: center;
}

.div-button {
width: .5px;
border-right: 1px solid #e5e5e5;
height: 20px;
float: left;
}

div > button {
display: flex;
justify-content: space-evenly;
align-items: center;
border: 0px;
margin-top: 5px;
color: #263238;
background-color: white;
}

div :hover {
color: #e76316;
transition: all 0.3s;
}
div:first-child :hover {
color: #db2525;
transition: all 0.3s;
}
`
12 changes: 12 additions & 0 deletions src/main.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App'

import { GlobalStyle } from './styles/globalStyle'

ReactDOM.createRoot(document.getElementById('root')!).render(
<React.StrictMode>
<GlobalStyle />
<App />
</React.StrictMode>
)
45 changes: 45 additions & 0 deletions src/screens/Home/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { useState, useEffect } from 'react'
import Cards from '../../components/Card'
import CreateCards from '../../templates/CreateCard'
import DeleteCard from '../../templates/DeleteCard'
import Button from '../../components/Button'

import {
ContainerCards,
InputSearch,
Header,
} from './style'

export default function Home() {

const [showSidebar, setShowSidebar] = useState<boolean>(false)
const [deleteSidebar, setDeleteSidebar] = useState<boolean>(false)

const [filterQuery, setFilterQuery] = useState<string>('')

function queryHandler(e: any){
setFilterQuery(e.target.value)
}

return (
<>
{showSidebar && <CreateCards onClick={() => setShowSidebar(false)} />}
{deleteSidebar && <DeleteCard onClick={() => setDeleteSidebar(false)} />}
<Header>
<img src="/assets/logo-teste.png" alt="logo" />
</Header>

<InputSearch>
<input type="text" placeholder="Digite aqui sua busca..." onChange={queryHandler}/>
</InputSearch>

<ContainerCards>
<p>Resultado de Busca</p>
{/*<button onClick={() => setShowSidebar(!showSidebar)}>Novo Card</button>*/}
<Button onClick={() => setShowSidebar(!showSidebar)}>Novo Card</Button>
</ContainerCards>

<Cards actions={{setShowSidebar, setDeleteSidebar}} filterQuery={filterQuery}/>
</>
)
}
Loading