Cursos / Informática para Internet / Plataformas de aplicações Web / Aula

arrow_back Aula 12 - PetTopStore - PDV - Parte 1

Componente src/App.js

É o componente será responsável por determinar se o usuário está logado ou não e dependendo do caso ele vai renderizar o componente src/Login.js ou src/Sale.js

Vamos ver o código completo comentado do src/App.js:

import './App.css'; // Importando um CSS para estilizar o App
import Sale from './Sale'; // Importando o componente de venda
import Login from './Login'; // Importando o componente de login
import { useState, useEffect } from 'react'; // React Hooks useState e useEffect

// função auxiliar que determina se um token JWT está próximo de expirar (falta 1 hora ou menos)
function isTokenOld(jwt) {

  // converte o payload do JWT para um objeto Javascript
  const payload = JSON.parse(Buffer.from(jwt.split(".")[1], 'base64').toString('binary'));

  // Calcula a expiração baseado no atributo "exp" o token. Esse foi seratado quando se assinou o token com a expiração de 2 dias(se assim você fez)
  const expiration = new Date(payload.exp * 1000);
  const now = new Date();
  const oneHour = 1000 * 60 * 60;

  // verifica se o token está próximo de expirar(menos de 1 hora), baseado na sua expiração e na data atual
  if( expiration.getTime() - now.getTime() < oneHour ){
    return true;
  } else {
    return false;
  }
}

// Componente principal App
function App() {

  // Estamos criando a variável de estado "employee" usando o useState de forma especial
  // Aqui o useState recebe uma função como valor inicial.
  // isso siginifica que o retorno dessa função será o valor inicial de employee.
  const [employee, setEmployee] = useState(() => {
    // O que essa função faz é verificar se "employee" está no localStorage do navegador
    const saved = localStorage.getItem("employee");
    const employeeJSON = JSON.parse(saved);

    // se ele estiver no localStorage, então vamos verificar se o token desse employee está perto de expirar
    if (employeeJSON) {
      if (isTokenOld(employeeJSON.token)){
        // se o token é antivo (está perto de expirar), retornamos um valor inicial fazio '' para o estado inicial de employee
        return '';
      }
    }

    // caso contrário retornamos o employeeJSON que contém o funcionário salvo no localStorage, ou em branco se ele não existir no localStorage ainda (nunca foi feito login nesse navegador)
    return employeeJSON;
  });

  // Estamos agora usando o useEffect da seguitne maneira:
  // Se employee mudar, ou seja, o login for realizado pela API e ele receber o valor de retorno
  // então essa função abaixo passada ao useEffect será executara
  // e ela seta a chave 'employee' no localStorage do navegador para o valor que a variável employee tem.
  // Essa estratégia, junto ao useState do employee, faz com que seu valor fique sempre sincronizado com o que está salvo no localStorage.
  useEffect(() => {
    localStorage.setItem("employee", JSON.stringify(employee));
  }, [employee]);

  // Finalmente verificamos se employee existe. 
  if (employee) {
    //Se for o caso ele já está logado e o token não está próximo de expirar()
    // retornar o componente de realizar venda (Sale)
    // Repare que passamos tanto a variável de estaod "employee" como o setEmployee para o componente Sale, permitindo que ele tenha acesso a esses dados que são de responsabilidade desse componente.
    return <Sale employee={employee} setEmployee={setEmployee} />
  } else {
    // Se não for o caso, o funcionário não está logado ou seu token está próximo de expirar.
    // Retornar o Login.js euq tem o formulário de login.
    // Repare que passamos tanto a variável de estaod "employee" como o setEmployee para o componente Login, permitindo que ele tenha acesso a esses dados que são de responsabilidade desse componente.
    return <Login employee={employee} setEmployee={setEmployee} />
  }

}

export default App;

Como visto nos comentários do código, o src/App.js é o componente principal do PDV, ele verifica se o employee (funcionário) está logado com uma estratégia que mistura o gerenciamento de estados do React com uma variável "employee" criada com o useState, mas utiliza localStorage para manter essa variável salva no armazenamento do navegador. Isso faz com que, mesmo que você recarregue a página, o funcionário se mantenha logado.

Foi necessário criar uma função que verifica se o token expirou (está próximo de expirar, na verdade) para evitar exibir o sistema para um token que não tem muito tempo de vida ainda. Nesse caso é preferencial mostrar o componente de Login.

No final o src/App.js verifica se, depois de todas as verificações, o employee existe é porque o funcionário logou no sistema. Se não existe , não logou. Para cada caso ele msotra um componente diferente (Sale ou Login).

Repare que passamos tanto para o componente Sale como para o Login o employee e o setEmployee. Isso faz com que dentro deles esses atributos possam ser acessados através dos "props" e a variável employee possa ser mudada pelos por esses componentes. Caso, por exemplo, o componente Login execute setEmployee (que foi passado pra ele), o efeito é o mesmo que isso tivesse sido feito dentro de src/App.js e uma reatividade irá acontecer, salvando o employee no localStorage e alterando o retorno do componente, fazendo com que o componente Sale aparece (se o login aconteceu com sucesso).

Segue também o conteúdo do arquivo App.css, que tem um estilo básico para o PDV:

.App {
  text-align: center;
}

.App-logo {
  height: 40vmin;
  pointer-events: none;
}

@media (prefers-reduced-motion: no-preference) {
  .App-logo {
    animation: App-logo-spin infinite 20s linear;
  }
}

.App-header {
  background-color: #282c34;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  font-size: calc(10px + 2vmin);
  color: white;
}

.App-link {
  color: #61dafb;
}

@keyframes App-logo-spin {
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(360deg);
  }
}

Para mais informações sobre o localStorage visite: https://www.w3schools.com/html/html5_webstorage.asp


Versão 5.3 - Todos os Direitos reservados