Capacitação de Desenvolvimento Web feita por André Cunha 10/05/2023
Com o Next.js configurado em sua máquina e com o projeto criado, execute o servidor de desenvolvimento:
npm run dev
# ou
yarn dev
# ou
pnpm devAbra -> [http://localhost:3000](http://localhost:3000) com seu navegador para ver o resultado.
Você pode começar a editar a página modificando pages/index.tsx que se localiza dentro de src/. A página é atualizada automaticamente conforme você edita o arquivo e sera mostrada no localhost.
No Next.js, os "components" são blocos de código reutilizáveis que encapsulam parte da lógica e da interface do usuário de uma página ou aplicativo.
Depois de criar um componente, você pode importá-lo e usá-lo em outras partes do seu do projeto.
Para adicionar novos componentes ao front end, é necessário trabalhar com as pastas que estão contidas dentro de src/componentes.
- Crie um novo arquivo TypeScript na pasta
src/componentes. -> Ex:componenteX.tsx. - É necessário exportar a função que gera o componente (no mesmo arquivo). -> Ex:
export default function criaComponenteX{... lógica do componente...} - No arquivo
pages/index.tsxdeve importar o componente criado. -> Ex:import { criaComponenteX } from "@/components/componenteX"; - Deve utilizar o componte dentro da função
Home(){..}dopages/index.tsx.
Atualmente temos os seguintes componentes adicionado a tela:
Este é um componente funcional React chamado CardDisplayData, ele contém:
Interface CardDisplayDataProps: Define um tipo de interface para as propriedades que queremos do nosso braco. Essa interface especifica quais propriedades podem ser passadas para o componente, bem como seus tipos.Função CardDisplayData: Renderiza uma representação visual dos dados do barco com cada propriedade contendo um rótulo de unidade de medida associado a ela. As propriedades são inicializadas com valores padrão, caso não sejam fornecidas quando o componente é usado.
Este é um componente funcional React chamado Chart, ele contém a definição de um gráfico de linha usando a biblioteca Carbon Charts e o renderiza com base nos dados fornecidos através das props data. O gráfico é configurado usando o objeto options e é estilizado com classes CSS.
Este é um componente funcional React chamado Chat, ele renderiza uma interface de chat interativo (chat-bot) permitindo que o usuário envie perguntas para um servidor, que processa a pergunta e envia uma resposta de volta. A interface do chat inclui mensagens de perguntas e respostas, um campo de entrada de texto para as perguntas e um botão de envio. Também há um botão de abertura/fechamento do chat quando ele está minimizado. Neste momento essa funcionalidade do componente esta em teste e o nosso objetivo com ele está relacionado a ajudar a equipe de telemetria nas provas do DSB, onde ele irá fornecer informações confiáveis a respeito do estado do barco e com isso, a nossa equipe irá tomar decisões melhores em relação ao estado do barco e do tipo de prova visando o melhor desempenho possível.
Este é um componente funcional React chamado Dropdown, ele cria uma lista suspensa que permite ao usuário selecionar um piloto. Quando uma seleção é feita, a função onChange (fornecida como prop) é chamada com o novo valor selecionado e ao final, teremos os dados (do barco) referente a um específico piloto para futuras análises de dados.
Este é um componente funcional React chamado Dropdown, ele representa uma barra lateral de navegação presente na tela do frontend que pode ser aberta/fechada com um clique em um ícone de menu. Ela inclui opções de navegação, um botão para iniciar/parar a gravação e um botão para deslogar da página.
Este é um componente funcional React chamado Dropdown, ele cria um botão que permite ao usuário alternar entre os modos claro e escuro do tema no canto superior direito da página. Ele verifica se o componente está montado antes de renderizar para evitar possíveis problemas durante a inicialização. Quando o botão é clicado, ele chama a função para trocar o tema, e exibe o ícone correspondente ao tema atual.
Este é um componente funcional React chamado UsersCard, ele representa uma janela de exibição, adição e remoção de usuários autorizados onde cada um deles é representado com seu email e um ícone de lixeira para remoção.
Este arquivo fornece funcionalidades relacionadas à autenticação de usuários usando Firebase Authentication, incluindo o login com uma conta do Google, o registro de novos usuários e a desconexão de usuários autenticados. Nele há três funcões principais:
signInWithPopup: Permite que o usuário faça login usando um provedor de autenticação (neste caso, o provedor Google). Quando o login é bem-sucedido, verifica se o usuário está autorizado verificando se o e-mail está presente na lista de usuários autorizados.GoogleAuthProvider: Cria uma instância do provedor de autenticação do Google.createUserWithEmailAndPassword: Cria um novo usuário com um endereço de e-mail e uma senha.
Este aquivo contém um conjunto de cinco funções que permitem interagir com o Firestore de forma assíncrona, facilitando a leitura, escrita, atualização e remoção de dados na sua aplicação. São elas:
getAllInfoCollection: Esta função busca todos os documentos de uma coleção específica no Firestore. Ela recebe o nome da coleção como argumento (collectionName) onde cada objeto possui os dados do documento e um campo adicional chamado ID, que representa o identificador único do documento.getAllInfoCollectionRealTime: Esta função ativa um ouvinte em tempo real para a coleção especificada no Firestore. Ela também recebe o nome da coleção (collectionName) e uma função setData que será chamada quando os dados mudarem. A função setData recebe um array de objetos, onde cada objeto representa um documento com um campo ID.saveInfoCollection: Esta funçãoadicionaum novo documento à coleção especificada. Ela recebe o nome da coleção (collectionName) e os dados que serão salvos no novo documento (data).updateInfoCollection: Esta funçãoatualizaum documento existente na coleção especificada. Ela recebe o nome da coleção (collectionName), o ID do documento que será atualizado (ID) e os novos dados que serão salvos (data).removeInfoCollection: Esta funçãoremoveum documento da coleção especificada. Ela recebe o nome da coleção (collectionName) e o ID do documento que será removido (ID).
Este aquivo contém um conjunto de cinco funções que fornecem uma interface para manipular arquivos no Firebase Storage, permitindo uploads, downloads, listagem e exclusões de arquivos. São elas:
uploadFile: Esta função é responsável por fazer o upload de um arquivo para o Firebase Storage. Ela recebe um objeto UploadFileProps como argumento, contendo informações sobre o arquivo a ser enviado. Isso inclui o título do arquivo (title), o próprio arquivo (file), um callback opcional para informar o progresso do upload (progressPercentage), um callback opcional para lidar com o sucesso do upload (load), um callback opcional para lidar com erros (errorInfo), e um caminho opcional para onde o arquivo será armazenado (path).getFile: Esta função permite obter a URL de download de um arquivo armazenado no Firebase Storage com base em seu ID. Ela recebe o ID do arquivo (ID) e um caminho opcional (path) que especifica onde o arquivo está armazenado.listFiles: Esta função lista todos os arquivos em um determinado caminho no Firebase Storage e retorna uma array com os nomes dos arquivos.deleteFile: Esta função permite excluir um arquivo do Firebase Storage com base em seu ID. Ela recebe o ID do arquivo (ID) e um caminho opcional (path) que especifica onde o arquivo está armazenado.
Este arquivo é responsável por configurar e inicializar o Firebase em nosso projeto, nele temos:
Importaçõesdo Firebase: Aqui se encontra toda importação necessária para inicializar e utilizar os serviços de autenticação, banco de dados Firestore e armazenamento.firebaseConfig: Aqui está a configuração do Firebase que contém informações específicas do nosso projeto, como apiKey, authDomain, projectId, storageBucket, messagingSenderId e appId. Essas informações são lidas de variáveis de ambiente usando o process.env para manter as credenciais seguras.- Inicialização Firebase e dos Serviços: Aqui temos:
getFirestore: Inicializa o Firestore, o banco de dados em tempo real do Firebase, e retorna uma instância do
Firestore associada à aplicação Firebase app.getAuth: Inicializa o serviço de autenticação do Firebase e retorna uma instância de autenticação associada à aplicação Firebase app.getStorage: Inicializa o serviço de armazenamento do Firebase e retorna uma instância de armazenamento associada à aplicação Firebase app.
Este arquivo exporta um array de dados com vários objetos de propriedades do barco, cada um representando uma leitura de dados em um momento específico para testes.
No Next.js não é preciso realizar nenhum tipo de configuração ou utilizar bibliotecas para fazer o tratamento de rotas, basta criar uma página dentro da pasta "pages" que irá ficar subentendido para a aplicação que os arquivos com extensão ".jsx" é uma rota acessível Ao criar um arquivo dentro da pasta “pages”, o Next.js automaticamente irá assumir que o nome daquele arquivo é um endereço acessível da sua aplicação. Caso seja necessário criar algum arquivo ou alguma pasta dentro dessa pasta que não será vista como um endereço, basta acrescentar o “_” antes do nome do arquivo ou pasta.
No Next.js, o arquivo _app.tsx é usado para fornecer uma estrutura global para sua aplicação. Ele é responsável por fornecer componentes compartilhados, como cabeçalho e rodapé, em todas as páginas da sua aplicação.
Em nosso projeto, declaramos três estados iniciais utilizando Hook useState:
- recordStatus
- isAuthenticated
- erroAutenticacao
Esses estados serão usados para controlar o status de gravação, o estado de autenticação do usuário e qualquer erro de autenticação.
UserEfect:
- É configurado um observador (onAuthStateChanged) para verificar o estado da autenticação do usuário. Quando o estado de autenticação do usuário muda, uma função é executada para verificar se o usuário está autorizado com base em informações obtidas de uma coleção chamada "users" no Firebase Firestore.
- Há um evento de escuta de socket chamado "recordStatus" que atualiza o estado recordStatus quando o status de gravação muda.
Renderização condicional:
- Caso o usuário não esteja autenticado (!isAuthenticated), o código renderiza um botão "Entrar com o Google" que permite ao usuário fazer login com sua conta do Google. Se ocorrer um erro de autenticação (erroAutenticacao for verdadeiro), uma mensagem de erro é exibida.
- Caso o usuário esteja autenticado (isAuthenticated), o código renderiza um componente Sidebar e o conteúdo da página principal, que é controlado pela prop Component. Isso inclui a capacidade de iniciar ou parar uma gravação, dependendo do valor de recordStatus.
O arquivo _document.tsx é usado para controlar o HTML que será renderizado no lado do servidor. É neste arquivo que você pode adicionar meta tags, scripts, estilos e outros elementos que serão compartilhados por todas as páginas da sua aplicação. O componente Head é usado para definir as configurações do cabeçalho HTML, como links para folhas de estilo, links para ícones e meta informações. O componente Html define a estrutura básica do HTML, incluindo a linguagem da página.
(Em nosso projeto utilizamos um modelo básico do _document)
Esse componente trabalha com operações de manipulação de arquivos, incluindo listagem, download e exclusão em um ambiente de armazenamento Firebase. Nele há duas funções assíncronas e ao final, a interface renderizada é uma lista de arquivos, onde cada arquivo tem dois botões: um para baixar (handleDownloadFile) e outro para deletar (handleDeleteFile).
-
handleDownloadFile: É uma função que lida com o
downloadde um arquivo. Ela usa a funçãogetFilepara obter o URL do arquivo e em seguida utiliza ofetchpara baixá-lo. O arquivo é criado como umBlob(objeto binário) e um link é criado para ele noDOM. Por fim, o elemento é adicionado ao corpo do documento e é simulado um clique nele para iniciar o download. -
handleDeleteFile: É uma função que lida com a
exclusãode um arquivo. Usa a funçãodeleteFilepara remover o arquivo do armazenamento e atualiza o estado files para filtrar o arquivo excluído.
O arquivo index.jsx é um arquivo TypeScript que geralmente é usado para representar a página inicial do projeto. O nome index.jsx é uma convenção comum para esse propósito. Para modificar o arquivo index.jsx de um projeto, você deve seguir estas etapas:
- Localize o arquivo index.jsx:
src/pages/index.tsx - Edite o arquivo: Abra o arquivo pages.jsx no seu editor de código preferido. (Eu recomendo o Visual Studio Code)
- Teste a página: Abra o navegador com a url do local host.
Nossa equipe utiliza este arquivo para exibir dados em tempo real de nosso barco POENTE e nele temos:
-
Estado com useState: O nosso componente
Homeutiliza ohookuseState do React para gerenciar o estado local de:dadoAtualBarco: Armazena os dados atuais do barco.dadosBarco: Armazena uma lista de dados do barco.dataForChart: Armazena os dados formatados para serem exibidos em um gráfico.dataForChat: Armazena uma string formatada para ser usada em um chat.speed: Armazena a velocidade do barco.
-
Blocos UserEffect (Existem dois):
-
O
primeiroé usado para seinscrevera eventos do socket. Isso significa que quando os eventosinfo,speedInfoenameInfosão emitidos pelo servidor de socket, as funções fornecidas serão executadas. -
O
segundouseEffect é usado paraatualizaros dados que serão usados no gráfico e no chat. Ele depende do estadodadosBarco, o que significa que sempre que dadosBarco for atualizado, este useEffect será executado.
-
-
Manipulação de eventos: Existe um
dropdownque permite ao usuário selecionar o nome do piloto. Isso altera o estado selectedOption e emite um evento para o servidor de socket e um botão para mudança de tema (dark/light).
Este arquivo cria uma página que exibe informações de usuários, permite a adição de novos usuários através de um alerta e utiliza o Firebase para obter e atualizar os dados em tempo real.
- O componente Users: Define um estado chamado users para armazenar as informações dos usuários e utiliza o hook useEffect para buscar os dados dos usuários em tempo real do Firestore ao montar o componente e ao fim, renderiza um componente
UsersCard, passando a lista de usuários e uma função para adicionar novos usuários.
Este arquivo exporta um menu de navegação que contém os seguintes atributos:
- name: O nome do item de menu.
- href: O destino para onde o item de menu leva.
- icon: Um componente de ícone React que será renderizado junto ao nome do item de menu.
Esse código estabelece uma conexão entre o cliente e o servidor Socket.IO em tempo real hospedado em https://barcos-backend.onrender.com.
Aqui se encontra os estilos que são aplicados em toda a aplicação, afetando todos os componentes e páginas.
Este arquivo contém a interface DadosBarco e ChartData que representa os dados do nosso barco no gráfico.
-
DadosBarco: variáveis do tipo string- temperatura e umidade
- velocidadeBarco e updateAt
- estadoStringSolar1 e estadoStringSolar2
- correnteMotor, correnteBaterias, correnteMPPT
- tensaoSaidaMPPT, tensaoEntradaMPPT e tensaoAlimentacaoPCB]
-
ChartData: grupo de chave e valor.
Neste arquivo, esta presente uma a função transformDataChart que pega um array com os dados originais do tipo DadosBarco que, extrai informações específicas de cada objeto e as
reorganiza em um novo formato onde os pontos de dados são agrupados por tipo de dado e registrados com um carimbo de data/hora específico, que é mais adequado para ser usado em
gráficos.
Neste arquivo, esta presente uma a função formatDataChat pega um array de objetos do tipo DadosBarco e os transforma em uma string formatada no estilo de um arquivo CSV, onde
cada linha representa um objeto e cada coluna é uma propriedade do objeto.
Neste arquivo esta presente algumas funções que trabalham em conjunto para fornecer feedback ao usuário, são elas:
-
ToastSuccess: Esta função utiliza osweetalert2para exibir uma notificação de sucesso no canto superior direito da tela por um curto período de tempo. A notificação inclui um ícone que indica o status (como "sucesso" ou "erro") e uma mensagem -
AlertAddEmail: Utiliza oSwal.firepara exibir uma janela de alerta onde o usuário pode inserir um endereço de e-mail. O valor inserido é armazenado na variável email. Dependendo do resultado dessa operação, uma notificação de sucesso ou erro é exibida usando a função ToastSucces
Esse arquivo é responsável pelo controle do dimensionamento da janela a ser exibida, contém uma função chamada useWindowSize que permite obter o tamanho atual da janela do navegador, e se atualizará automaticamente quando o usuário redimensionar a janela.
🔗 links interessantes:
https://community.revelo.com.br/guia-basico-para-iniciar-com-next-js-parte-i/