App Studios Ghibli - Pt.1

App Studios Ghibli - Pt.1

Criando uma aplicação de busca utilizando a API dos Studios Ghibli, React.js e o Code Server em um dispositivo Android.

Uma boa forma de praticar os conhecimentos em um determinado framework ou biblioteca, é criando aplicações divertidas de estudo, que irão realizar os mesmos tipos de operações que sistemas maiores costumam executar. Nessa série de artigos nós vamos criar uma aplicação que vai executar a operação de leitura da API dos Studios Ghibli e permitir que criemos filtros buscas. Este app vai seguir o design abaixo (Link para o design).

SmartSelect_20221021_110038_Chrome.jpg

Então vamos começar com o basico, criando o nosso projeto e criando a estrutura básica dele.

npx cretae-react-app studios-ghibli-app

Depois de executarmos esse comando o React vai criar a estrutura básica do nosso projeto. Se você quiser conhecer mais sobre a estruturade um projeto React.js você pode dar uma olhadinha neste Link. Agora vamos focar dentro na pasta ./src.

A primeira coisa que vamos fazer é instalar a biblioteca de icones chamada React Icons

npm install react-icons --save

E depois criar o nosso arquivo reset.css, para evitar algumas margens indesejadas no projeto. Para criar esse arquivo eu sugiro que você utilize um arquivo de reset.css já pronto e aqui no projeto nós vamos utilizar o arquivo deste Site e o nosso ./src/reset.css vai ficar desta forma:

/* http://meyerweb.com/eric/tools/css/reset/ 
   v2.0 | 20110126
   License: none (public domain)
*/

html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed, 
figure, figcaption, footer, header, hgroup, 
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
    margin: 0;
    padding: 0;
    border: 0;
    font-size: 100%;
    font: inherit;
    vertical-align: baseline;
}
/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure, 
footer, header, hgroup, menu, nav, section {
    display: block;
}
body {
    line-height: 1;
}
ol, ul {
    list-style: none;
}
blockquote, q {
    quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {
    content: '';
    content: none;
}
table {
    border-collapse: collapse;
    border-spacing: 0;
}

Com o reset.css criado vamos importar ele no nosso .src/index.js, para ele ser utilzado por todo o projeto. Seu index.js vai ficar desta forma:

import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import './reset.css';
import App from './App';
import reportWebVitals from './reportWebVitals';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
    <React.StrictMode>
      <App />
    </React.StrictMode>
);

reportWebVitals();

Agora vamos começar a limpar o nosso projeto, removendo coisas que não iremos utilizar e adicionar alguns recursos para essa primeira etapa. Então dentro da pasta src execute o comando abaixo:

rm logo.svg

Depois vamos abrir o arquivo App.js e remover o conteúdo de dentro do return e remover o import da logo também. Seu arquivo ./src/App.js vai ficar parecido com esse:

import './App.css';

  function App() {
    return (

    );
  }

export default App;

Ainda dentro da pasta ./src, vamos criar uma pasta chamada generals e dentro de genrals uma chamada images e colocar a logo dos Studios Ghibli (link para download). Com a imagem criada vamos começar criando o cabeçalho do nosso app (neste momento ainda não vamos organizar os componentes, isso será feito mais para frente). Em ./src/App.css cole o trecho de código abaixo:

.header-container {
    background-color: var(--background-header);
    padding: 10px;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: left;
    text-align: left;
}

.header-logo {
    width: 167px;
    height: 87px;
    margin-right: 15px;
}

.header-link {
    color: white;
    font-size: 25px;
    margin-right: 25px;
}

.hamburguer-icon {
    border: 0;
    height: 40px;
    padding: 0.5rem;
    border-radius: 50%;
    cursor: pointer;
    background-color: transparent;
    right: 25px;
    display: none;
    font-size: 35px;
    color: white;
}

.hamburguer-icon:hover {
    opacity: 0.5;
}

@media screen and (max-width: 768px) {
    .header-container {
        justify-content: space-between;
    }

    .hamburguer-icon {
        display: block;
    }

    .header-container__menu-content {
        display: none;
        position: absolute;
        top: 107px;
        left: 0;
        flex-direction: column;
        width: 100%;
        height: calc(100vh - 685px);
        background-color: var(--background-header);
        text-align: center;
    }

    .header-container__menu-content a {
        color: white;
        width: 100%;
        padding: 1.5rem 0;
    }

    .header-container__menu-content a:hover {
        background-color: rgb(245, 153, 160, 0.6);
    }

    .header-container__menu-content a:focus {
        background-color: rgb(245, 153, 160, 0.6);
    }

    .header-container__menu-content.expanded {
        display: inline-flex;
        justify-content: center;
    }
}

Agora em ./src/App.js vamos criar a estrutura do nosso header. O arquivo App.js vai ficar desta forma:

import './App.css';
import logo from "../../general/images/Studio_Ghibli_logo.png";
import { FaBars } from "react-icons/fa";

function App() {
  return (
     <header className="header-container">
        <img src={logo} className="header-logo" alt="Studios Ghibli Logo" />
        <div id="menu" className={`header-container__menu-content ${(isOpen ? 'expanded' :  '')}`}>
            <a className="header-link" href="/">
              Filmes
            </a>
            <a className="header-link" href="/atores">
              Atores
            </a>
            <a className="header-link" href="/locais">
              Locais
            </a>
        </div>
        <button className="hamburguer-icon" onClick={() => setHamburguerOpen(!isHamburguerOpen)}>
          <FaBars />
        </button>

      </header>
  );
}

export default App;

Se rodarmos o projeto ele vai estar parecido com a imagem abaixo:

Untitled (500 × 317 px).png

E se redimensionarmos a tela para uma tela menor, teremos o nosso menu hamburguer.

Untitled (400 × 642 px).png

Mas ele ainda não está 100%, pois quando clicamos ele ainda não funciona. O nosso css já possui uma classe para exibir e esconder o menu chamada ".expanded". Mas para o navegador saber quando essa classe deve ser ativada, precisamos informar quando querermos que ele ative. No nosso caso o melhor candidato para nos trazer essa informação é o botão do menu hamburguer, então quando o usuário clicar no icone do menu queremos que ele seja aberto e se clicar novamente queremos que ele feche.

O React nos permite controlar o status de um item utilizando o hook useState e é exatamente o que vamos fazer agora. Então vamos começar importando esse hook e criando a constante que vai controlar o status do botão e permitir que o React controle o css do nosso header.

 import { useState } from "react";
const [isOpen, setOpen] = useState(false);

Agora é a hora em que a mágica do React vai nos permitir manipular o CSS com poucos caracteres de código. Vamos adicionar um ternário no nome da nossa classe css que irá variar de acordo com o estado do nosso botão.

className={`header-container__menu-content ${(isOpen ? 'expanded' : '')}`}

E essa foi a primeira etapa da construção do nosso projeto, o link do repositório com o código que foi feito nesta primeira etapa esta disponível no link abaixo.