Aula 2: Front-end com React (parte 1) – SpotCode | OneBitCode
• Incluindo o React no Projeto – 00:01:05
• Preparando a estrutura do projeto – 00:07:24
• Incluindo o Bulma – 00:16:10
• Incluindo as Rotas – 00:26:28
• Incluindo o Styled Components e os Icons – 00:37:56
• Criando o menu superior – 00:40:20
• Criando o menu Superior Logado – 00:53:56
• Criando a Página Home – 01:01:33
• Incluindo a barra de navegação – 01:14:33
• Criando a página Discovery – 01:25:14
• Criando a conexão com o Back-end – 01:40:53
Incluindo o React no Projeto
1 – Instale o webpacker e o react rodando:
1 |
rails webpacker:install:react |
2 – Renomeie o arquivo gerado (hello_react.jsx) para spotcode.jsx e coloque nele
1 2 3 4 5 6 7 8 9 |
import * as React from 'react'; import * as ReactDOM from 'react-dom'; document.addEventListener('DOMContentLoaded', () => { ReactDOM.render( <div>Hello</div>, document.getElementById('root'), ) }) |
3 – Coloque no head do application.html.erb
1 |
<%= javascript_pack_tag 'spotcode' %> |
4 – Na View Home Index limpe o conteúdo atual e coloque
1 |
<div id="root"></div> |
5 – Suba o servidor (rails s) e verifique que o component apareceu na tela
Preparando a estrutura do projeto
1 – Dentro de javascript crie as seguintes pastas:
– components
– screens
– services
2 – Dentro da pasta Screens crie as seguintes pastas e arquivos
– /home
– index.js
1 2 3 4 5 6 7 8 9 10 |
import React, { Fragment, useState } from 'react'; const HomeScreen = () => { return( <Fragment> <div>Home Screen</div> </Fragment> ); } export default HomeScreen; |
– /discovery
– index.js
1 2 3 4 5 6 7 8 9 10 |
import React, { Fragment, useState } from 'react'; const DiscoveryScreen = () => { return( <Fragment> <div>Discovery Screen</div> </Fragment> ); } export default DiscoveryScreen; |
– /search
– index.js
1 2 3 4 5 6 7 8 9 10 |
import React, { Fragment, useState } from 'react'; const SearchScreen = () => { return( <Fragment> <div>Search Screen</div> </Fragment> ); } export default SearchScreen; |
– /album
– index.js
1 2 3 4 5 6 7 8 9 10 |
import React, { Fragment, useState } from 'react'; const AlbumScreen = () => { return( <Fragment> <div>Album Screen</div> </Fragment> ); } export default AlbumScreen; |
– /favorites
– index.js
1 2 3 4 5 6 7 8 9 10 |
import React, { Fragment, useState } from 'react'; const FavoritesScreen = () => { return( <Fragment> <div>Favorites Screen</div> </Fragment> ); } export default FavoritesScreen; |
3 – Ainda na pasta javascript crie o arquivo app.scss e o arquivo app.js
4 – No arquivo App.js coloque
1 2 3 4 5 6 7 8 9 10 |
import React, { Fragment } from 'react'; const App = () => { return( <Fragment> Hello </Fragment> ); } export default App; |
5 – No arquivo spotcode.jsx coloque
1 2 3 4 5 6 7 8 9 10 |
import * as React from 'react'; import * as ReactDOM from 'react-dom'; import App from '../app'; document.addEventListener('turbolinks:load', function() { ReactDOM.render( <App/>, document.getElementById('root'), ) }) |
Incluindo o Bulma
1 – Instale a biblioteca react-bulma-components rodando
1 |
yarn add react-bulma-components |
2 – Coloque em App.js
1 2 3 4 5 6 7 8 9 10 11 12 |
import * as React, { Fragment } from 'react'; import 'react-bulma-components/dist/react-bulma-components.min.css'; import { Button } from 'react-bulma-components'; const App = () => { return( <Fragment> <Button color="primary">Testando o Bulma</Button> </Fragment> ); } export default App; |
3 – Suba o servidor (rails s) e verifique que o component Bulma apareceu na tela
4 – No header do application.html.erb inclua
1 |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
5 – No arquivo app.scss coloque:
1 2 3 4 5 6 7 8 |
@import "~react-bulma-components/src/index.sass"; html, body, #root { margin: 0; padding: 0; height: 100%; background-color: $dark; } |
Incluindo as Rotas
1 – Instale a biblioteca de rotas rodando
1 |
yarn add react-router-dom |
2 – Crie um arquivo chamado routes.js (em /javascript) e coloque nele
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
// Importantando o React import React from "react"; // Importantando o component Home import HomeScreen from "./screens/home"; // Importanto o component <Switch /> e <Route /> da nossa Lib de rotas import { Switch, Route } from 'react-router-dom' const Routes = () => ( <Switch> <Route exact path='/' component={HomeScreen}/> </Switch> ); export default Routes; |
3 – Atualize o App.js colocando
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
import React, { Fragment } from 'react'; import 'react-bulma-components/dist/react-bulma-components.min.css'; import Routes from './routes'; import { BrowserRouter } from 'react-router-dom' const App = () => { return( <Fragment> <BrowserRouter> <Routes/> </BrowserRouter> </Fragment> ); } export default App; |
4 – Complete as views no routes
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
import React from "react"; import HomeScreen from "./screens/home"; import DiscoveryScreen from "./screens/discovery"; import SearchScreen from "./screens/search"; import AlbumScreen from "./screens/album"; import FavoritesScreen from "./screens/favorites"; import { Switch, Route } from 'react-router-dom' const Routes = (props) => ( <Switch> <Route exact path='/' component={HomeScreen} /> <Route exact path='/discovery' component={DiscoveryScreen} /> <Route exact path='/search' component={SearchScreen} /> <Route exact path='/album/:id' component={AlbumScreen} /> <Route exact path='/favorites' component={FavoritesScreen} /> </Switch> ); export default Routes; |
5 – No arquivo routes coloque por último
1 |
get "*path", to: "home#index", :constraints => lambda{|req| req.path !~ /\.(png|jpg|js|css|json)$/ } |
6 – Atualize no App Controller
De:
1 |
before_action :authenticate_user! |
Para:
1 |
before_action :authenticate_user!, unless: -> { request.env['PATH_INFO'] == '/' } |
Incluindo o Styled Components e os Icons
1 – Para conhecer o StyledComponents visite: https://styled-components.com
2 – Para instalar rode
1 |
yarn add styled-components |
3 – Para conhecer os Icons: https://react-icons.netlify.com
4 – Para instalar os Icons rode
1 |
yarn add react-icons |
Criando o menu superior
1 – Em components crie uma pasta assets e dentro dela a pasta images
2 – Baixe o logo (https://onebitcode.com/wp-content/uploads/2020/04/logo.png) e coloque dentro da pasta images criada anteriormente
3 – Em components crie a pasta common
4 – Dentro da pasta common crie a pasta menu com um arquivo index.js e coloque nele
1 2 3 4 5 6 7 8 9 10 11 |
import React, { Fragment } from 'react'; const Menu = () => { return ( <Fragment> Menu </Fragment> ); } export default Menu; |
5 – Em app.js coloque:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
import React, { Fragment } from 'react'; import 'react-bulma-components/dist/react-bulma-components.min.css'; import Routes from './routes'; import { BrowserRouter } from 'react-router-dom' import Menu from './components/common/menu' const App = () => { return( <Fragment> <BrowserRouter> <Menu/> <Routes/> </BrowserRouter> </Fragment> ); } export default App; |
6 – Para incluirmos a navbar, container e columns (estrutura), atualize o menu para:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
import React, { Fragment } from 'react'; import { Navbar, Container, Columns } from 'react-bulma-components'; const Menu = () => { return ( <Fragment> <Navbar color="dark"> <Container> <Columns className='is-mobile'> <Columns.Column desktop={{size: 2}} mobile={{size: 5}}> </Columns.Column> <Columns.Column> </Columns.Column> </Columns> </Container> </Navbar> </Fragment> ); } export default Menu; |
7 – Para incluirmos o logo coloque:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
import React, { Fragment } from 'react'; import { Navbar, Container, Columns } from 'react-bulma-components'; import logoImage from '../../../assets/images/logo.png' const Menu = () => { return ( <Fragment> <Navbar color="dark"> <Container> <Columns className='is-mobile'> <Columns.Column desktop={{size: 2}} mobile={{size: 5}}> <img src={logoImage}/> </Columns.Column> <Columns.Column> </Columns.Column> </Columns> </Container> </Navbar> </Fragment> ); } export default Menu; |
8 – Agora para ajustarmos o estilo da apresentação dos elementos vamos usar o StyledComponents, adicione:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
import React, { Fragment } from 'react'; import { Navbar, Container, Columns } from 'react-bulma-components'; import logoImage from '../../../assets/images/logo.png' import styled from 'styled-components' const ColumnsFullWidth = styled(Columns)` width: 100%; padding-top: 20px; padding-left: 10px; padding-bottom: 10px; ` const Menu = () => { return ( <Fragment> <Navbar color="dark"> <Container> <ColumnsFullWidth className='is-mobile'> <Columns.Column desktop={{size: 2}} mobile={{size: 5}}> <img src={logoImage} className='image'/> </Columns.Column> <Columns.Column> </Columns.Column> </ColumnsFullWidth> </Container> </Navbar> </Fragment> ); } export default Menu; |
9 – Agora vamos incluir o botão ENTRAR
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
import React, { Fragment } from 'react'; import { Navbar, Container, Columns, Button } from 'react-bulma-components'; import logoImage from '../../../assets/images/logo.png' import styled from 'styled-components' const ColumnsFullWidth = styled(Columns)` width: 100%; padding-top: 20px; padding-left: 10px; padding-bottom: 10px; padding-right: 10px; ` const Menu = () => { return ( <Fragment> <Navbar color="dark"> <Container> <ColumnsFullWidth className='is-mobile'> <Columns.Column desktop={{size: 2}} mobile={{size: 5}}> <img src={logoImage} className='image'/> </Columns.Column> <Columns.Column> <a href='/users/sign_in' className="is-pulled-right is-right"> <Button outlined={true} color="white">ENTRAR</Button> </a> </Columns.Column> </ColumnsFullWidth> </Container> </Navbar> </Fragment> ); } export default Menu; |
Obs: Para que o APP seja atualizado browser quando você atualizar os códigos, rode em um novo terminal:
Criando o menu Superior Logado
1 – No mesmo arquivo de menu que estavamos trabalhando nós vamos adicionar o link de edição de perfil e logout baseado na rota atual do usuário (ou seja, quando ele estiver na home vamos mostrar o botão ENTRAR quando ele não estiver vamos mostrar o link de edição do perfil e logout), no component menu improte:
1 |
import { useLocation } from 'react-router-dom' |
2 – Vamos incluir dentro do component uma condição para devolver o botão ENTRAR quando estiver logado e devolver os links de edição e logout quando não estiver logado:
1 2 3 4 5 6 7 8 9 10 11 12 |
const Menu = () => { let actionButton; if (useLocation().pathname == '/') { } else { } ... } |
3 – Dentro do primeiro, vamos colocar o botão que já criamos:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
const Menu = () => { let actionButton; if (useLocation().pathname == '/') { actionButton = <a href='/users/sign_in' className="is-pulled-right is-right"> <Button outlined={true} color="white">ENTRAR</Button> </a> } else { } ... } |
4 – Onde tinhamos o botão vamos colocar:
1 2 3 4 5 |
... <Columns.Column> {actionButton} </Columns.Column> ... |
5 – Vamos importar o component Dropdown para o segundo caso:
1 |
import { Navbar, Button, Container, Columns, Dropdown } from 'react-bulma-components'; |
6 – Agora no else, coloque:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
actionButton = <Dropdown className='is-pulled-right is-right' color='dark' label= {<FaUserCircle size="2em" />}> <Dropdown.Item value="other"> <a href='/users/edit'> Edit User </a> </Dropdown.Item> <Dropdown.Item value="other"> <a href='/users/sign_out'> LogOut </a> </Dropdown.Item> </Dropdown> |
7 – Seu arquivo final deve ter ficado desta forma:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
import React, { Fragment } from 'react'; import { Navbar, Button, Container, Columns, Dropdown } from 'react-bulma-components'; import logoImage from '../../../assets/images/logo.png' import styled from 'styled-components' import { useLocation } from 'react-router-dom' import { FaUserCircle } from "react-icons/fa"; const ColumnsFullWidth = styled(Columns)` width: 100%; padding-top: 20px; padding-left: 10px; padding-bottom: 10px; padding-right: 10px; ` const Menu = () => { let actionButton; if (useLocation().pathname == '/') { actionButton = <a href='/users/sign_in' className="is-pulled-right is-right"> <Button outlined={true} color="white">ENTRAR</Button> </a> } else { actionButton = <Dropdown className='is-pulled-right is-right' color='dark' label={<FaUserCircle size="2em" />}> <Dropdown.Item value="other"> <a href='/users/edit'> Edit User </a> </Dropdown.Item> <Dropdown.Item value="other"> <a href='/users/sign_out'> LogOut </a> </Dropdown.Item> </Dropdown> } return ( <Fragment> <Navbar color="dark"> <Container> <ColumnsFullWidth className='is-mobile'> <Columns.Column desktop={{size: 2}} mobile={{size: 5}}> <img src={logoImage}/> </Columns.Column> <Columns.Column> {actionButton} </Columns.Column> </ColumnsFullWidth> </Container> </Navbar> </Fragment> ); } export default Menu; |
8 – Para finalizar, vamos mudar no arquivo devise o método de logout:
de:
1 |
config.sign_out_via = :delete |
para:
1 |
config.sign_out_via = :get |
Criando a Página Home
1 – Dentro de components/common vamos criar um container para envolver nossas telas, crie um arquivo chamado section_wrapper e coloque nele:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
import React from 'react'; import { Container, Section } from 'react-bulma-components'; const SectionWrapper = (props) => { return( <Section> <Container> {props.children} </Container> </Section> ); } export default SectionWrapper; |
2 – Na Screen Home coloque a estrutura:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
import React, { Fragment } from 'react'; import SectionWrapper from '../../components/common/section_wrapper' import { Columns } from 'react-bulma-components'; const HomeScreen = () => { return ( <SectionWrapper> <Columns> <Columns.Column> </Columns.Column> </Columns> <Columns className="is-centered is-mobile"> <Columns.Column mobile={{ size: 8, offset: 1 }} desktop={{ size: 4, offset: 2 }}> </Columns.Column> </Columns> <Columns className="has-text-centered"> </Columns> </SectionWrapper> ); } export default HomeScreen; |
3 – Agora vamos colocar a primeira frase, adicione:
1 2 3 4 5 6 7 8 9 10 11 12 |
import { Columns, Heading } from 'react-bulma-components'; ... <SectionWrapper> <Columns className="is-centered is-vcentered has-text-centered"> <Columns.Column> <Heading className='has-text-weight-light has-text-centered has-text-white' size={1}> SEU APP DE <br /><span className='has-text-success'>MÚSICA</span> </Heading> </Columns.Column> </Columns> ... |
4 – Vamos colocar um espaço superior estilizando o component Heading
1 2 3 4 5 6 7 8 9 10 11 12 |
... import styled from 'styled-components' const MainHeading = styled(Heading)` margin-top: 50px; ` ... <MainHeading className='has-text-weight-light has-text-centered has-text-white' size={1}> SEU APP DE <br /><span className='has-text-success'>MÚSICA</span> </MainHeading> ... |
5 – Agora vamos incluir a listagem no meio
1 2 3 4 5 6 7 8 |
... <ul className='has-text-white'> <li>Suas músicas <b>Favoritas</b></li> <li>Seus <b>Podcasts</b></li> <li>Os <b>Lançamentos</b></li> <li>As novas <b>Descobertas</b></li> </ul> ... |
6 – Agora vamos colocar estilo nele
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
... const DescriptionList = styled.ul` margin-top: 50px; font-size: 20px; list-style-type: square; ` ... <DescriptionList className='has-text-white'> <li>Suas músicas <b>Favoritas</b></li> <li>Seus <b>Podcasts</b></li> <li>Os <b>Lançamentos</b></li> <li>As novas <b>Descobertas</b></li> </DescriptionList> ... |
7 – Vamos incluir o botão de cadastro
1 2 3 4 5 6 |
... import { Button, Columns, Heading } from 'react-bulma-components'; ... <Button className='is-success is-outlined is-large has-text-white'>CADASTRAR AGORA</Button> ... |
8 – Agora vamos colocar um pouco de estilo nele
1 2 3 4 5 6 7 8 9 |
... const ButtonSubscribe = styled(Button)` border-width: 2px; margin-top: 50px; ` ... <ButtonSubscribe className='is-success is-outlined is-large has-text-white'>CADASTRAR AGORA</ButtonSubscribe> ... |
9 – Pronto, nosso arquivo ficou assim
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
import React, { Fragment } from 'react'; import { Button, Columns, Heading } from 'react-bulma-components'; import styled from 'styled-components' import SectionWrapper from '../../components/common/section_wrapper' const MainHeading = styled(Heading)` margin-top: 50px; ` const ButtonSubscribe = styled(Button)` border-width: 2px; margin-top: 50px; ` const DescriptionList = styled.ul` margin-top: 50px; font-size: 20px; list-style-type: square; ` const HomeScreen = () => { return ( <SectionWrapper> <Columns> <Columns.Column> <MainHeading className='has-text-weight-light has-text-centered has-text-white' size={1}> SEU APP DE <br /><span className='has-text-success'>MÚSICA</span> </MainHeading> </Columns.Column> </Columns> <Columns className="is-centered is-mobile"> <Columns.Column mobile={{ size: 8, offset: 1 }} desktop={{ size: 4, offset: 2 }}> <DescriptionList className='has-text-white'> <li>Suas músicas <b>Favoritas</b></li> <li>Seus <b>Podcasts</b></li> <li>Os <b>Lançamentos</b></li> <li>As novas <b>Descobertas</b></li> </DescriptionList> </Columns.Column> </Columns> <Columns className="has-text-centered"> <Columns.Column> <ButtonSubscribe className='is-success is-outlined is-large has-text-white'>CADASTRAR AGORA</ButtonSubscribe> </Columns.Column> </Columns> </SectionWrapper> ); } export default HomeScreen; |
Incluindo a barra de navegação
1 – Crie um arquivo chamado navbar_footer dentro de components/common e coloque nele:
1 2 3 4 5 6 7 8 9 10 11 |
import React, { Fragment } from 'react'; const NavbarFooter = () => { return ( <Fragment> </Fragment> ); } export default NavbarFooter; |
2 – Vamos incluir a estrutura da navbar
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
... import { Navbar, Container, Columns } from 'react-bulma-components'; ... const NavbarFooter = () => { ... <Fragment> <Navbar fixed='bottom' color='dark'> <Container> <ColumnsCustom className='is-mobile is-vcentered'> <Columns.Column className='has-text-centered'> </Columns.Column> <Columns.Column className='has-text-centered'> </Columns.Column> <Columns.Column className='has-text-centered'> </Columns.Column> </ColumnsCustom> </Container> </Navbar> ... |
3 – Vamos criar as customizações de estilo para a Navbar e para a Columns
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
... import styled from 'styled-components' ... const NavbarWithBorder = styled(Navbar)` border-top-color: white !important; border-top-style: solid; border-top-width: 1px; ` const ColumnsFullWidth = styled(Columns)` width: 100%; padding-top: 10px; ` ... <Fragment> <NavbarWithBorder fixed='bottom' color='dark'> ... <ColumnsFullWidth className='is-mobile is-vcentered'> ... </ColumnsFullWidth> ... </NavbarWithBorder> ... |
4 – Vamos incluir os links dentro das columns
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
... import { Link } from 'react-router-dom' ... <ColumnsFullWidth className='is-mobile is-vcentered'> <Columns.Column className='has-text-centered'> <Link to='/' className='has-text-white'> </Link> </Columns.Column> <Columns.Column className='has-text-centered'> <Link to='/search' className='has-text-white'> </Link> </Columns.Column> <Columns.Column className='has-text-centered'> <Link to='/favorites' className='has-text-white'> </Link> </Columns.Column> </ColumnsFullWidth> ... |
5 – Agora vamos incluir os icones
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
... import { FaSearch, FaHome, FaHeart } from "react-icons/fa"; ... <ColumnsFullWidth className='is-mobile is-vcentered'> <Columns.Column className='has-text-centered'> <Link to='/discovery' className='has-text-white'> <FaHome size='25px'/> </Link> </Columns.Column> <Columns.Column className='has-text-centered'> <Link to='/search' className='has-text-white'> <FaSearch size='25px'/> </Link> </Columns.Column> <Columns.Column className='has-text-centered'> <Link to='/favorites' className='has-text-white'> <FaHeart size='25px'/> </Link> </Columns.Column> </ColumnsFullWidth> ... |
6 – No Discovery Screen coloque
1 2 3 4 5 6 7 8 9 10 11 12 |
import React, { Fragment } from 'react'; import NavbarFooter from '../../components/common/navbar_footer'; const DiscoveryScreen = () => { return ( <Fragment> <NavbarFooter /> </Fragment> ); } export default DiscoveryScreen; |
7 – No Search Screen coloque
1 2 3 4 5 6 7 8 9 10 11 12 |
import React, { Fragment } from 'react'; ... import NavbarFooter from '../../components/common/navbar_footer'; const SearchScreen = () => { return ( <Fragment> ... <NavbarFooter/> </Fragment> ); } |
8 – No Favorites Screen coloque
1 2 3 4 5 6 7 8 9 10 11 12 |
import React, { Fragment } from 'react'; ... import NavbarFooter from '../../components/common/navbar_footer'; const FavoritesScreen = () => { return ( <Fragment> ... <NavbarFooter/> </Fragment> ); } |
9 – No Album Screen coloque
1 2 3 4 5 6 7 8 9 10 11 12 |
import React, { Fragment } from 'react'; ... import NavbarFooter from '../../components/common/navbar_footer'; const AlbumScreen = () => { return ( <Fragment> ... <NavbarFooter/> </Fragment> ); } |
10 – Em application_controller.rb adicione:
1 2 3 |
def after_sign_in_path_for(resource) '/discovery' end |
Criando a página Discovery
1 – Crie um component chamado discovery e coloque nele
1 2 3 4 5 6 7 8 9 10 |
import React, { Fragment } from 'react'; const Discovery = () => { return ( <Fragment> </Fragment> ); } export default Discovery; |
2 – Importe ele em DiscoveryScreen
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
import React from 'react'; import SectionWrapper from '../../components/common/section_wrapper' import Discovery from '../../components/discovery'; import NavbarFooter from '../../components/common/navbar_footer'; const DiscoveryScreen = () => { return( <Fragment> <SectionWrapper> <Discovery /> </SectionWrapper> <NavbarFooter /> </Fragment> ); } export default DiscoveryScreen; |
3 – Crie um component Album e coloque nele
1 2 3 4 5 6 7 8 9 10 |
import React, {Fragment} from 'react'; const Album = (props) => { return( <Fragment> </Fragment> ); } export default Album; |
4 – Importe ele no component Discovery
1 2 3 |
... import Album from '../album'; ... |
5 – Crie uma div com espaços especiais
1 2 3 4 5 6 7 |
... import styled from 'styled-components'; const DivVSpaced = styled.div` margin-top: 50px; ` ... |
6 – Crie a estrutura da página
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
... import { Columns, Heading } from 'react-bulma-components'; <Fragment> <div> <Heading className='has-text-white' size={4}> Tocadas recentemente </Heading> <Columns className='is-mobile'> </Columns> </div> <DivVSpaced> <Heading className='has-text-white' size={4}> Recomendadas </Heading> <Columns className='is-mobile'> </Columns> </DivVSpaced> </Fragment> ... |
7 – Vamos criar alguns dados fake para preencher os albums
1 2 3 4 5 6 7 8 9 |
... const Discovery = () => { const albums_mock = [ { id: 1, artist_name: 'Andrew Howes', title: 'Gubernator', cover_url: '/rails/active_storage/blobs/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBDdz09IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--2f248b465e87a8800d0362b55a3b16f9d7173888/gubernator.jpg' }, { id: 2, artist_name: 'Andrew Howes', title: 'The Great Bear', cover_url: '/rails/active_storage/blobs/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBFQT09IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--ffbb0eea38171a0cd8c85f977e3bf2e4f9996775/the_great_bear.jpg' }, { id: 3, artist_name: 'Yellow Chair', title: 'Barcelona', cover_url: '/rails/active_storage/blobs/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBGUT09IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--b56f4c80ed66afda06173d0530bbf8c720ad7ae0/barcelona.jpg' }, { id: 4, artist_name: 'Andrew Howes', title: 'Gubernator', cover_url: '/rails/active_storage/blobs/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBDdz09IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--2f248b465e87a8800d0362b55a3b16f9d7173888/gubernator.jpg' }, ] ... |
8 – Em album, vamos criar um component especial de espaçamento e importar os components bulma
1 2 3 4 5 6 7 8 9 |
... import { Heading, Image } from 'react-bulma-components'; import styled from 'styled-components' const DivVSpaced = styled.div` margin-top: 10px; ` ... |
9 – Vamos criar a estrutura agora
1 2 3 4 5 6 7 8 9 10 11 12 13 |
... const Album = (props) => { return( <Fragment> <Image src={props.cover_url}/> <DivVSpaced> <Heading size={6} className='has-text-white'>{props.title}</Heading> <Heading size={6} className='has-text-white' subtitle>{props.artist_name}</Heading> </DivVSpaced> </Fragment> ); } ... |
10 – Vamos incluir um link para a página de album (mudando fragment para link)
1 2 3 4 5 6 7 |
... import { Link } from "react-router-dom"; <Link to={`/album/${props.id}`}> ... </Link> |
11 – Voltando ao discovery vamos criar N components Album baseado nos dados fake que criamos
1 2 3 4 5 |
const albums = albums_mock.map((album, key) => <Columns.Column desktop={{ size: 3 }} mobile={{ size: 6 }} key={key}> <Album artist_name={album.artist_name} title={album.title} cover_url={album.cover_url} id={key}/> </Columns.Column> ); |
12 – Agora vamos injetar o resultado no component
1 2 3 4 5 6 7 8 9 10 11 |
... <Columns className='is-mobile'> {albums} </Columns> ... ... <Columns className='is-mobile'> {albums} </Columns> ... |
Criando a conexão com o Back-end
1 – Instale o axios para fazer chamadas web através do javascript rodando
1 |
yarn add axios |
1 – Em javascript crie uma pasta chamada services
2 – Dentro dela crie um arquivo chamado api.js e coloque nele:
1 2 3 |
import axios from 'axios'; const Api = axios.create({baseURL: 'http://localhost:3000'}); export default Api; |
3 – Crie um arquivo chamado discovery.js e coloque nele
1 2 3 4 5 6 7 |
import Api from './api'; const AlbumsService = { index: () => Api.get('/dashboard') } export default AlbumsService; |