Introdução A web está evoluindo, e as tecnologias Web3 estão revolucionando as indústrias tradicionais, incluindo streaming de vídeo. Plataformas como estão liderando a mudança, oferecendo alternativas descentralizadas ao YouTube e Rumble. Da mesma forma, diferentemente de provedores legados como Google Drive e Dropbox, está transformando o armazenamento de dados, fornecendo uma abordagem focada na privacidade e centrada no usuário. Odysee a Sia usando NextJs, TypeScript, Tailwind CSS e Sia Renterd. Esta série de tutoriais guiará você na criação de um aplicativo descentralizado que aproveita a tecnologia blockchain da Sia para garantir a propriedade e a privacidade dos dados do usuário. Junte-se a nós em uma jornada para construir um dApp de streaming de filmes Web3 de ponta Ao final deste tutorial, você adquirirá experiência para: Crie uma plataforma de streaming de filmes totalmente funcional para compartilhar com amigos ou usar como um projeto escolar Inicie seu próprio aplicativo SaaS (Software como Serviço) Desbloqueie o potencial das tecnologias Web3 na indústria de streaming de vídeo para ver o projeto em ação e para mais conteúdo inovador como este! Assista ao vídeo de demonstração abaixo inscreva-se em nosso canal https://www.youtube.com/watch?v=Hgfdesry8Ss&embedable=true Pré-requisitos Para acompanhar, certifique-se de ter as seguintes ferramentas instaladas. A familiaridade com as pilhas também aumentará sua compreensão: NodeJS PróximoJs CSS do vento de cauda TypeScript Docker (obrigatório) Esta série de três partes abordará: - Rede de teste Renterd Zen, instalações de pacotes e variáveis de ambiente. Parte 1: Configuração do projeto - Construindo o Serviço de Backend Parte 2: Desenvolvimento de Backend - Integrando o Frontend com o serviço Backend. Parte 3: Desenvolvimento Frontend Se você preferir assistir a todo o processo de desenvolvimento, , na playlist, tudo o que está escrito aqui e muito mais está capturado nos vídeos. recomendo assistir a esta playlist Dito isso, vamos começar a configurar este projeto. Configuração do projeto – Parte 1 Começaremos clonando um repositório preparado que inclui o script docker compose do Sia Renterd e os serviços de backend e frontend. Execute os seguintes comandos: $ git clone https://github.com/Daltonic/sia_vid_tv $ cd sia_vid_tv Agora, é crucial que mudemos para nossa ramificação inicial neste projeto GitHub recém-clonado e executemos o comando abaixo para concluí-lo. $ git checkout 01_starter_branch Em seguida, vamos configurar a variável de ambiente associada para este serviço Renterd. Crie um arquivo na raiz deste projeto e aplique as chaves abaixo: .env RENTERD_SEED=<RENTERD_SEED_PHRASE> RENTERD_API_PASSWORD=<YOUR_PREFERED_PASSWORD> RENTERD_LOG_LEVEL=debug RENTERD_LOG_DATABASE_LEVEL=error Para obter essas chaves de API, você precisará ter o Sia Renterd instalado em sua máquina; assista ao breve vídeo abaixo, que resume tudo. https://www.youtube.com/watch?v=78XCHGWZwhA&embedable=true Gere uma frase semente com o aplicativo Renterd como visto no vídeo acima, e inclua-a dentro da sua variável de ambiente como instruído no vídeo acima. Substitua a senha por algo que você possa lembrar facilmente. Em seguida, precisamos instalar o Docker caso ainda não tenha feito isso. Como alternativa, use uma plataforma online gratuita como ou um VPS para executar uma instância do Docker, se possível. Caso contrário, instale-o no seu computador local. baixando-o do site oficial, o Gitpod Por fim, podemos girar um contêiner docker executando o seguinte comando docker na raiz deste projeto. Certifique-se de que o terminal esteja no mesmo local de diretório que este arquivo . docker-compose.yml $ docker compose -f "docker-compose.yml" up -d --build Observe o comando para puxar o contêiner para baixo: . Execute isso quando quiser desligar sua instância do Docker (mas não agora). $ docker compose -f "docker-compose.yml" down Se você seguiu as instruções acima corretamente, deverá ver a interface abaixo quando visitar seu navegador em . http://localhost:9880 Digite sua senha (da sua variável de ambiente) para efetuar login. Em seguida, siga o procedimento de configuração no vídeo abaixo para configurar sua instância do Sia Renterd para uploads, downloads e streaming de arquivos. https://www.youtube.com/watch?v=ZJ8YWdVTWUA&t=401s&embedable=true O vídeo acima começa na marca de minutos, pare na marca de , esta parte guiará você visualmente pelo processo de configuração do Renterd. 6:41 20:01 Observe que o processo de sincronização do blockchain, juntamente com a correspondência do host, leva até para ficar pronto, então você terá que ser paciente com todo o processo. 25 min Crie um novo bucket no Renterd chamado , onde todos os nossos arquivos para este projeto serão armazenados. Se você executou as instruções acima com sucesso, seu nó Renterd deve estar pronto para upload e download. Veja a imagem abaixo. vidtv Incrível. Neste ponto, nosso serviço Renterd está pronto para começar a receber arquivos, mas precisamos nos comunicar com ele programaticamente. Vamos encerrar esta primeira parte deste tutorial configurando os pacotes e as variáveis de ambiente para o backend e o frontend. Siga as instruções a seguir para ter os pacotes de serviço de backend instalados e prontos para desenvolvimento posterior. Configuração do projeto de backend Navegue até o diretório de backend a partir de uma nova instância de terminal usando os seguintes comandos: $ cd backend $ yarn install #you can also use npm install $ touch .env #or mannually create it at the root of the backend directory Em seguida, forneça as seguintes informações nas variáveis de ambiente. SIA_API_BUCKET=vidtv SIA_API_PASSWORD=<YOUR_PREFERED_PASSWORD> SIA_API_BASE_URL=http://localhost:9880 ORIGIN=http://localhost:9000 PORT=9000 E agora, execute para iniciar o backend e também confirmar se ele está livre de bugs. $ yarn build && yarn start Por fim, execute os seguintes comandos para instalar os pacotes associados ao frontend. Depois, vamos executá-lo. Configuração do Projeto Frontend Navegue até o diretório de backend a partir de uma nova instância de terminal usando os seguintes comandos: $ cd frontend $ yarn install #you can also use npm install $ touch .env #or mannually create it at the root of the backend directory Em seguida, forneça as seguintes informações nas variáveis de ambiente. NEXT_PUBLIC_PROJECT_ID=<YOUR_WALLET_CONNECT_ID> NEXT_PUBLIC_FILE_SERVICE_URL=http://localhost:9000 Cadastre-se e crie um projeto com para obter seu ID de projeto. Após fornecer o ID do projeto para a variável de ambiente, execute para ativar o backend e também confirmar que ele está livre de qualquer bug. o Walletconnect $ yarn build && yarn start Neste ponto, você verá a interface abaixo ao visitar o navegador em . http://localhost:3000 Parabéns por atingir esse marco! para concluir o desenvolvimento do serviço de backend. Próximo passo Prossiga para a Parte 2 O Serviço Backend – Parte 2 Por favor, leia a Parte 1 se ainda não leu. Agora, vamos mergulhar na Parte 2: Construindo o serviço de backend para nossa plataforma de streaming de filmes web3. Bem-vindo de volta! Fornecemos um código inicial para o backend, que atualmente exibe uma mensagem de "Boas-vindas" quando você inicia o servidor e visita no seu navegador. Vamos construir sobre essa base. http://localhost:9000 Atualmente, temos esses códigos no diretório de origem do backend. Deixe-me explicá-los brevemente para você. Esta pasta, que pode ser totalmente endereçada a contém dois arquivos essenciais: uma função de manipulador de exceções HTTP e uma interface para manipular informações de upload de arquivos. Arquivos de utilitários backend/src/utils Este código define uma classe personalizada que estende a classe do JavaScript integrada, permitindo a criação de instâncias de erro com códigos de status HTTP e mensagens específicas. HttpException Error https://gist.github.com/Daltonic/bb37e1d4c5f84bc9c10fcbb8c3e19621 Este código define uma interface que representa um arquivo carregado, especificando suas propriedades, como nome, dados, tamanho, codificação e muito mais, fornecendo uma maneira estruturada de lidar com uploads de arquivos neste aplicativo de backend. FileUpload https://gist.github.com/Daltonic/64fb31bf3b19668a17d14f59e087a77e E então, na pasta raiz , temos este arquivo que configura um servidor Express.js com CORS e suporte para upload de arquivos, define uma única rota GET que retorna uma mensagem de "Boas-vindas" e manipula erros capturando-os e lançando-os novamente como HttpExceptions personalizadas, e então inicia o servidor na porta 9000, conforme especificado nas variáveis de ambiente. backend/src index.ts https://gist.github.com/Daltonic/8d76c3a212681d7bfe89b0792b0e707f Agora que cobrimos os arquivos principais, vamos criar dois novos arquivos em uma pasta , cada um servindo a um propósito distinto em nosso aplicativo. services Arquivos de serviço Na pasta , crie uma nova pasta chamada neste local, é aqui que criaremos dois serviços: backend/src services : lida com uploads, downloads, streaming e armazenamento em cache de arquivos, comunicando-se com o serviço Renterd. Serviço Sia : gerencia arquivos em cache, removendo-os automaticamente após 7 dias, à meia-noite, diariamente. Serviço em segundo plano O Serviço Sia Vamos criar um arquivo chamado na pasta e seguir os passos abaixo para formular este serviço. sia.service.ts backend/src/services https://gist.github.com/Daltonic/a82a0c1cf8d3e7b31702b66eeead3718?embedable=true Este código define uma classe que inicializa com variáveis de ambiente para configurações da API Sia e uma URL de origem, fornecendo uma base para gerenciar interações com o serviço Sia. Agora, vamos fornecer o restante dos códigos para este serviço. SiaService Para enviar arquivos para a Sia Network, precisaremos adicionar esses três métodos à classe: dois serão privados e um será público. Enviando arquivos para o Sia Renterd https://gist.github.com/Daltonic/ddf74dffc5ac1005585f7ae3ad55c286?embedable=true Este código define um método privado que gera uma string aleatória de um comprimento especificado, composta de letras maiúsculas e minúsculas e números, usando um loop para selecionar caracteres aleatoriamente de uma string predefinida. Usaremos isso para renomear cada arquivo exclusivamente antes de enviar um arquivo para Renterd. generateRandomString https://gist.github.com/Daltonic/e6a82ac4af9eca9c881f4e0bdd1d682b?embedable=true O código acima define um método privado que carrega um arquivo para o Sia Renterd usando o Axios, manipulando o progresso e os erros do upload e retornando a resposta do Axios ou gerando um erro se o upload falhar. uploadToSiaService Os endpoints do Renterd estão escritos na documentação da API, que você pode conferir ou assistir ao vídeo abaixo, onde expliquei como funciona a documentação da API do Sia Renterd. https://www.youtube.com/watch?v=zOmUMz0DBQM&embedable=true Agora vamos incluir o método público que mais tarde exporemos como um endpoint em nosso aplicativo. https://gist.github.com/Daltonic/ce565350160a39c4d9f0abc0b7e7dc26?embedable=true Este código define um método público que carrega um arquivo gerando um identificador exclusivo, salvando o arquivo em um cache local e, em seguida, carregando-o no Sia Renterd, retornando a URL do arquivo e uma mensagem de sucesso ou gerando um erro se o upload falhar. uploadFile Para baixar arquivos para a Sia Network, precisaremos adicionar esses dois métodos na classe, um será privado e o outro será público. Baixando arquivos para o Sia Renterd https://gist.github.com/Daltonic/b401e92d510ffddc8a0b7301d526f702?embedable=true Este código define um método privado que recupera um arquivo do serviço Sia, armazena-o em cache localmente e retorna um fluxo legível do arquivo, manipulando erros e retornando uma imagem 404 se o arquivo não for encontrado. downloadFromSiaService Vamos ter esses response_files disponíveis no diretório backend, senão teremos um erro ao chamar o arquivo . No diretório , crie outra pasta chamada e copie as seguintes imagens para ela. 404.png backend response_files Perfeito, agora vamos completar esse serviço de download de arquivo. Adicione também o método abaixo na classe . SiaService https://gist.github.com/Daltonic/1f1a99c82d5b15693eaa2d8d2482f6c2?embedable=true Este código define um método público que chama o método privado para recuperar um arquivo do Sia Renterd e retorna o fluxo legível do arquivo recuperado. downloadFile downloadFromSiaService Pontos de extremidade de serviço É hora de acoplar esses vários métodos aos seus respectivos endpoints, atualmente, temos apenas um, mas precisaremos de dois adicionais para upload e download de arquivos. O streaming de arquivos também utilizará o endpoint de download. Vá até o arquivo e atualize seu conteúdo com esses códigos. backend/src/index.ts https://gist.github.com/Daltonic/c8dec40acbc47b2582c651e04fae432f?embedable=true Este código configura um servidor Express.js com CORS e suporte para upload de arquivos, definindo três pontos de extremidade: uma mensagem de boas-vindas, upload de arquivo para a Sia Network e download de arquivo da Sia Network, usando a classe SiaService para manipular operações de arquivo e HttpException para tratamento de erros. Assista a esta seção do vídeo abaixo se precisar de algum auxílio visual. Pare no horário . 01:50:44 https://www.youtube.com/watch?v=ZJ8YWdVTWUA&t=3795&si=A6fF8n8Pd92i6weM&embedable=true Precisamos criar um serviço de gerenciamento de cache para garantir que nosso servidor não fique cheio de arquivos não utilizados, controlando por quanto tempo os arquivos permanecem no cache. É importante saber que a única razão pela qual precisamos desse serviço é para reduzir . a latência de dados O serviço de fundo Vá para a pasta e crie um arquivo chamado e adicione essas sequências de código a ele. backend/src/services background.service.ts https://gist.github.com/Daltonic/bc62ccefd72cec85772dedd311afbffd?embedable=true Este código define uma classe que configura um diretório de cache e agenda jobs diários usando a biblioteca , inicializando os jobs em background e registrando uma mensagem de confirmação. Vamos criar um método que será responsável por excluir arquivos com mais de 7 dias no cache. BackgroundService node-cron Adicione este método à classe . Excluindo arquivo antigo BackgroundService https://gist.github.com/Daltonic/43da392512b88b6abf068be62d14eb7e?embedable=true Este código define um método chamado que remove arquivos de um diretório de cache com mais de 7 dias, lendo o diretório, verificando o tempo de criação de cada arquivo, removendo arquivos que excedem o tempo alvo, registrando o início e o fim do trabalho e quaisquer erros ou exclusões bem-sucedidas. deleteOldFiles Agora, vamos escrever uma função que utilizará o pacote node-cron para agendar quando executar a exclusão do arquivo. https://gist.github.com/Daltonic/18b60b0bc1f7414a306f01f9087db435?embedable=true Este código configura uma tarefa cron diária para executar o método todos os dias à meia-noite (00:00) para realizar a limpeza automática de arquivos. deleteOldFiles Também precisamos atualizar a função construtora para agendar os trabalhos diários na instanciação da classe de serviço em segundo plano. https://gist.github.com/Daltonic/5f608cd3793ff6deea56c262bdfbc395?embedable=true Perfeito, por fim, vamos adicionar essa operação em segundo plano como parte do processo do servidor na inicialização. Vá para o arquivo e atualize o método app listener para importar o arquivo de serviço em segundo plano. backend/src/index.ts https://gist.github.com/Daltonic/7966a7b27fa7eade2c6d1a7e60b2e530?embedable=true Você deve executar novamente o comando de serviço de backend usando e ver uma impressão de terminal como a da imagem abaixo. $ yarn build && yarn start Se você preferir assistir como eu codifiquei todo o serviço em segundo plano, o vídeo abaixo é para você; apenas certifique-se de parar no registro de data e . hora 02:16:07 https://www.youtube.com/watch?v=ZJ8YWdVTWUA&t=8167&si=4DZ27j0lqwufUgRf&embedable=true Parabéns, agora você está pronto para a parte final deste tutorial, que é . Próximo passo a Parte 3 Vamos mergulhar na parte final desta série de tutoriais, onde integraremos o backend com o Frontend, conectando as peças para concluir o aplicativo de upload de arquivo. Começaremos garantindo que as autenticações no Frontend estejam ativas e funcionando. Autenticação Modal Web3 – Parte 3 Crie uma nova pasta chamada 'config' no diretório Frontend e adicione um arquivo index, resultando no caminho . Agora, vamos adicionar os seguintes códigos a ele. /frontend/config/index.tsx https://gist.github.com/Daltonic/38bbe9fa325fb793dd59136ebdea8b43?embedable=true Este código configura uma configuração Wagmi para nosso aplicativo Web3, definindo metadados, cadeias suportadas e configurações de autenticação, incluindo opções de carteira e login social, e armazena-as na exportação . Também precisamos criar uma API de contexto para manter o controle do estado de autenticação. config Em seguida, crie uma nova pasta chamada 'context' ainda no diretório Frontend e adicione um arquivo de índice, resultando no caminho . Adicione os seguintes códigos a ela. A API de contexto /frontend/context/index.tsx https://gist.github.com/Daltonic/db7330a9159ff83727cda0a384fd907e?embedable=true Este código configura um provedor Web3Modal usando Wagmi e React Query, configurando o modal Web3 com o ID do projeto e variáveis de tema e encapsulando o aplicativo em um WagmiProvider e QueryClientProvider. : Vamos atualizar o layout do nosso aplicativo para incluir as configurações acima. Vá para e substitua seus códigos pelo abaixo. Atualizando Layout /frontend/app/layout.tsx https://gist.github.com/Daltonic/2b54f191d56fa02f0ae3974bd8ffd11b?embedable=true O código acima configura o layout raiz para um aplicativo Next.js, incluindo metadados, fontes, estilos e provedores para modal Web3, notificações do sistema e componentes de layout como cabeçalho e rodapé. Agora, precisamos habilitar os botões de login nos componentes e e atualizar seus códigos usando as informações abaixo. O botão de login /frontend/app/components/layout/Header.tsx /frontend/app/components/shared/Menu.tsx https://gist.github.com/Daltonic/f9f60e85c18da94a5bbc97d1acb3d423?embedable=true Este código define um componente React para uma barra de navegação que inclui um logotipo, links de navegação, um menu personalizado e um botão de login que inicia um Modal Web3 com um design responsivo para diferentes tamanhos de tela. As imagens a seguir devem aparecer como prova de que o que fizemos funciona quando você clica no botão de login e prossegue com seu provedor preferido, X, Facebook, Google, Discord ou Ethereum. Ótimo, vamos nos aprofundar e configurar nosso banco de dados e o sistema baseado em API NextJs. Para qualquer confusão sobre o processo, assista à seção de vídeo abaixo; apenas certifique-se de parar na marca de . 02:57:59 https://www.youtube.com/watch?v=ZJ8YWdVTWUA&t=9305&si=OadhxKlut7o3iLl5&embedable=true Scripts de banco de dados Primeiro, vamos atualizar o script de configuração do NextJs para endereçar corretamente nossas páginas e endpoints e liberar nossas imagens remotas de avisos e escrutínio. https://gist.github.com/Daltonic/a4ecb4d168f8bb01cb8abb600653c4cf?embedable=true Este código define um objeto de configuração Next.js que configura reescritas de rotas de API e otimização de imagens, permitindo imagens remotas de qualquer nome de host HTTPS e imagens locais do domínio localhost. Usaremos SQLite para esta aplicação, mas você está livre para usar uma solução mais robusta, como provedores MYSQL ou NOSQL. Para simplificar, vamos trabalhar com um arquivo simples SQLite. Script de configuração do banco de dados Crie o caminho do arquivo e adicione os códigos abaixo a ele. /frontend/app/api/database.ts https://gist.github.com/Daltonic/b699c52587b28c2d9435827837019633?embedable=true Este código configura uma conexão de banco de dados SQLite, define duas funções de API, e , para executar solicitações GET e POST no banco de dados, com tratamento de erros e execução assíncrona baseada em promessas. Usaremos esses códigos sempre que desejarmos enviar ou recuperar dados do banco de dados. apiGet apiPost Precisamos criar um arquivo simples de banco de dados e uma tabela para armazenar todo o nosso conteúdo. Crie o caminho do arquivo e adicione os códigos abaixo a ele. Script de migração de banco de dados /frontend/app/api/migrations.ts https://gist.github.com/Daltonic/4c213153fe53334fcf8444666587d6a5?embedable=true Este código define uma função de migração de banco de dados que cria uma tabela 'movies' com colunas especificadas se ela não existir, usando SQLite, e registra o resultado da operação. Agora execute o comando abaixo em um terminal apontado para o diretório . /frontend $ cd frontend $ npx esrun app/api/migrations.ts Deve-se notar que esse processo também criará um arquivo plano de banco de dados chamado na raiz do diretório frontend. Também adicionamos esse comando ao script package.json, então executar no diretório frontend deve funcionar da mesma forma. movies.db $ yarn migrate Para assistência visual, assista ao vídeo abaixo, basta pará-lo na marca de . 03:10:54 https://www.youtube.com/watch?v=ZJ8YWdVTWUA&t=10679&si=-uhv8Zw0T3Gx0XgQ&embedable=true Pontos de extremidade do aplicativo Agora, vamos definir alguns endpoints para criar, ler, atualizar e excluir filmes. Usaremos a provisão da API NextJs para fazer esses endpoints. Para criar um filme, as informações necessárias incluem o ID do usuário, nome do filme, imagem, URL do vídeo, data de lançamento, gênero, classificação, idioma, duração e descrição do plano de fundo. Crie o caminho do arquivo e adicione os códigos abaixo a ele. Criar ponto final do filme /frontend/app/api/movies/create/route.ts https://gist.github.com/Daltonic/bf8a431ec00aa71491ae71781fb99278?embedable=true Este código define um ponto de extremidade para manipular solicitações POST, validar e processar dados de filmes, gerar um slug exclusivo e inserir os dados em um banco de dados usando uma função apiPost enquanto manipula erros e retorna respostas JSON. Para atualizar um filme, as informações necessárias incluem o ID do usuário, slug e outras informações fornecidas ao criar um filme. Crie o caminho do arquivo e adicione os códigos abaixo a ele. Atualizar ponto final do filme /frontend/app/api/movies/update/route.ts https://gist.github.com/Daltonic/2ed7d44cb8efe091675ebc0fc1bdf27c?embedable=true Este código define um ponto de extremidade para manipular solicitações POST para atualizar um filme, validar propriedades necessárias e executar uma consulta SQL para atualizar os dados do filme no banco de dados usando a função apiPost. Para excluir um filme, as informações necessárias incluem o ID do usuário e o slug de um filme. Crie o caminho do arquivo e adicione os códigos abaixo nele. Excluir ponto final do filme /frontend/app/api/movies/delete/route.ts https://gist.github.com/Daltonic/aa7ab36b982ad1f377b2a4d26930dd8d?embedable=true Este código define um ponto de extremidade para manipular solicitações POST para excluir um filme, validar as propriedades necessárias (userId e slug) e executar uma consulta SQL para excluir o filme do banco de dados usando a função apiPost. Os dados opcionais necessários para obter filmes são pageSize e userId, que podem ser passados como parâmetros de consulta para filtrar e paginar os resultados. Crie o caminho do arquivo e adicione os códigos abaixo a ele. Todos os filmes Endpoint /frontend/app/api/movies/all/route.ts https://gist.github.com/Daltonic/23bb2aa55446995dad87084bb7968c3e?embedable=true O código acima define um ponto de extremidade para manipular solicitações GET para recuperar filmes, permitindo filtragem opcional por userId e paginação por pageSize, e retorna os resultados no formato JSON. Para recuperar um único filme, os dados necessários são o slug de um filme. Crie o caminho do arquivo e adicione os códigos abaixo a ele. Single Movie Endpoint /frontend/app/api/movies/[slug]/route.ts https://gist.github.com/Daltonic/64e069e9bafd026a83796eaa95334ac8?embedable=true Este código define um ponto de extremidade para manipular solicitações GET para recuperar um filme por seu slug, validar o parâmetro slug e executar uma consulta SQL para recuperar os dados do filme do banco de dados usando a função apiGet. Isso marca todos os endpoints que precisaremos para esta aplicação. Se você precisar de um auxílio visual para entender melhor esses endpoints, assista ao vídeo abaixo, apenas certifique-se de parar no timestamp . 03:48:22 https://www.youtube.com/watch?v=ZJ8YWdVTWUA&t=10679&si=3Ynq9tNLx5SZXHBE&embedable=true Integração de endpoint Nossa tarefa é revisar e atualizar componentes e páginas pré-codificados, explicando o propósito e a funcionalidade de cada um e documentando as alterações que fazemos no código existente. Começaremos criando um serviço para interagir com os endpoints que criamos anteriormente no diretório . api Crie o caminho do arquivo e adicione os códigos abaixo a ele. /frontend/app/services/api.service.ts https://gist.github.com/Daltonic/fdf65c7ffaf3ea8219c617cdb7c96375?embedable=true Este serviço fornece um conjunto de funções para interagir com um banco de dados de filmes, permitindo que o aplicativo busque filmes, busque um único filme por slug, crie um novo filme, atualize um filme existente, exclua um filme e carregue arquivos usando solicitações de API e tratamento de erros. Páginas de aplicação Vamos revisar e atualizar as várias páginas associadas ao nosso aplicativo. Você não precisaria mudar muitas coisas, apenas as destacadas aqui. Criar página de filme Esta página é um formulário de publicação de filmes que permite aos usuários carregar arquivos de vídeo e imagem, inserir detalhes do filme e enviar o formulário para publicar o filme, com validação e tratamento de erros, usando as bibliotecas React e Wagmi. Agora, atualize o arquivo encontrado em com os códigos abaixo. /frontend/app/pages/create/page.tsx https://gist.github.com/Daltonic/0ec440d6dfc2b46e07ecec3e81f532c6?embedable=true As alterações feitas neste código em comparação ao original são: Importei a função de e a usei na função para criar um novo filme. createMovie api.service handleSubmit Adicionado o parâmetro à chamada da função , passando o endereço do usuário do hook . userId createMovie useAccount A função foi atualizada para usar para manipular a promessa retornada por . handleSubmit toast.promise createMovie Adicionado tratamento de erros à chamada da função na função . createMovie handleSubmit Essas alterações permitem que o formulário envie dados do filme para a API e crie uma nova entrada de filme, ao mesmo tempo em que manipula erros e exibe uma mensagem de sucesso. Editar página do filme Esta página de edição de filmes permite que usuários autorizados atualizem detalhes do filme, carreguem pôsteres e vídeos e salvem alterações, com validação e tratamento de erros, utilizando React, Wagmi e Next.js, projetados especificamente para usuários editarem seus filmes. Agora, atualize o arquivo encontrado em com os códigos abaixo. /frontend/app/pages/movies/edit/[slug]/page.tsx https://gist.github.com/Daltonic/63ddb6e3c65e3bcd2665ab0e3ffb6205?embedable=true As atualizações feitas no código que são diferentes do original são: Importou as funções e de e as usou no gancho e na função , respectivamente. fetchMovie updateMovie @/app/services/api.service useEffect handleSubmit Substituiu o método pela função para recuperar dados do filme. posters.find() fetchMovie A função foi atualizada para chamar a função com os detalhes atualizados do filme. handleSubmit updateMovie Adicionado tratamento de erros à chamada da função na função . updateMovie handleSubmit Essas alterações permitem que nosso aplicativo interaja com nossos endpoints de API para recuperar e atualizar dados de filmes, enquanto o código original dependia de nossa matriz locais. posters Página inicial Esta página inicial renderiza o componente de banners, uma lista de filmes (de uma fonte de API ou de uma interface de usuário de carregamento) e opções de assinatura, utilizando React e Next.js, para fornecer uma página de destino envolvente e informativa para os usuários. Atualize o arquivo encontrado em com os seguintes códigos. /frontend/app/pages/page.tsx https://gist.github.com/Daltonic/97cb49662ed70be9b183b4f601b529d6?embedable=true As alterações que fizemos na página inicial são: Importamos a função de e a usamos no hook para recuperar dados de filmes da nossa API. fetchMovies ./services/api.service useEffect Substituímos os dados locais pela chamada de função , que busca dados da nossa API. posters fetchMovies Adicionada a palavra-chave para aguardar a resolução da promessa retornada por antes de definir o estado . await fetchMovies movies Essas mudanças ajudam nosso aplicativo a recuperar dados de filmes de nossa API em vez de depender de dados locais, tornando o aplicativo mais dinâmico e orientado a dados. Página da conta do usuário Esta página exibe uma lista de filmes postados pelo usuário conectado no momento, com um espaço reservado para esqueleto de carregamento enquanto os dados estão sendo buscados e uma mensagem solicitando que o usuário conecte sua conta, caso ainda não tenha feito isso, utilizando Wagmi e react-loading-skeleton. Atualize o arquivo encontrado em com os seguintes códigos. /frontend/app/pages/account/page.tsx https://gist.github.com/Daltonic/ba714bfa557f10aebacfa8b5ac3d7111?embedable=true As alterações feitas na página são: Importamos a função de e a usamos no gancho para recuperar dados de filmes da nossa API. fetchMovies @/app/services/api.service useEffect Substituímos os dados locais pela chamada de função , que busca dados da nossa API. posters fetchMovies passado como argumento para a função para recuperar dados de filmes específicos do usuário. address fetchMovies Foi removida a verificação condicional de antes de renderizar a lista de filmes, pois a função agora lida com essa lógica. address fetchMovies Simplificou a declaração condicional para exibir o esqueleto de carregamento, pois agora depende apenas do estado . loaded Essas alterações recuperam dados do filme da nossa API, específicos para o usuário conectado, e exibem um esqueleto de carregamento enquanto os dados estão sendo buscados. Página de detalhes dos filmes Esta página exibe os detalhes de um único filme, incluindo seu nome, ano de lançamento, classificação, duração, gênero e informações básicas, juntamente com um reprodutor de vídeo e filmes relacionados, e fornece opções para editar ou excluir o filme se o usuário for o proprietário, utilizando Next.js e Wagmi. Atualize o arquivo encontrado em com os seguintes códigos. /frontend/app/pages/movies/[slug]/page.tsx https://gist.github.com/Daltonic/5e37c94db3d73005a481ffd0cd141140?embedable=true Fizemos algumas mudanças enormes aqui! Aqui está um resumo do que fizemos: Importamos as funções , e de e as usamos para interagir com nossos endpoints de API. deleteMovie fetchMovie fetchMovies @/app/services/api.service Dados locais substituídos por chamadas de API para recuperar dados do filme. Implementou a funcionalidade de exclusão de filme usando a função . deleteMovie Use para exibir uma notificação ao excluir um filme. toast.promise Os dados locais dos foram removidos e substituídos por chamadas de API. posters A função foi atualizada para chamar a função e manipular a resposta. handleSubmit deleteMovie Atualizado o gancho para chamar as funções e . useEffect fetchMovie fetchMovies Essas alterações fazem com que nosso aplicativo interaja com nossa API para recuperar e excluir dados de filmes e exibir notificações ao usuário durante o processo de exclusão. Esta parte do vídeo abaixo mostrará a você na prática como integramos essas páginas com o endpoint, sinta-se à vontade para assistir a essa parte se tiver algum problema. Apenas certifique-se de parar no timestamp . 04:57:41 https://www.youtube.com/watch?v=ZJ8YWdVTWUA&t=14070&si=XCKxX3HvX3RjtNHY&embedable=true Componentes do aplicativo Vamos discutir o propósito de cada componente em nossa aplicação. Atualizaremos qualquer componente que precise ser modificado. Componente de banner Este componente exibe uma imagem de fundo rotativa de banners de filmes, passando por uma matriz de imagens de filmes a cada 5 segundos, criando um efeito de apresentação de slides simples e automático. O código deste componente pode ser acessado em . /frontend/app/components/home/Banner.tsx Componente de pôsteres Este componente exibe um carrossel interativo e responsivo de pôsteres de filmes usando a biblioteca Swiper, com recursos como reprodução automática, paginação e navegação, exibindo uma lista de filmes passados como prop, com um layout dinâmico que se adapta a diferentes tamanhos de tela. O código deste componente pode ser acessado em . /frontend/app/components/home/Posters.tsx Componente de IU do pôster Este componente exibe um layout de esqueleto de espaço reservado para uma seção de pôsteres de filmes, usando a biblioteca react-loading-skeleton, mostrando um número dinâmico de pôsteres de esqueleto com base na prop "posters", com um design responsivo que se adapta a diferentes tamanhos de tela, indicando um estado de carregamento até que os dados reais dos pôsteres sejam buscados e exibidos. Este código de componente pode ser acessado em . /frontend/app/components/home/PosterUI.tsx Componente de Assinaturas Este componente exibe uma seção de planos de assinatura, mostrando vários planos fictícios com seus detalhes, preços e benefícios. Ele permite que os usuários escolham um plano que atenda às suas necessidades, utilizando um layout de grade responsivo e efeitos de foco interativos para aprimorar a experiência do usuário. Este código de componente pode ser acessado em . /frontend/app/components/home/Subscription.tsx Componente de Cabeçalho Este componente renderiza uma barra de navegação fixa no topo da página, apresentando um logotipo, um menu de navegação com links para várias seções, um botão de alternância de menu para design responsivo e um botão de login, fornecendo uma seção de cabeçalho consistente e acessível em todo o aplicativo. Este código de componente pode ser acessado em . /frontend/app/components/layout/Header.tsx Componente de rodapé Este componente renderiza uma seção de rodapé na parte inferior da página, apresentando o logotipo do aplicativo, uma breve descrição, links de navegação, informações de contato e um crédito mencionando a solução de armazenamento descentralizada fornecida pela Sia Foundation, fornecendo uma seção de rodapé clara e organizada com informações e links relevantes. Este código de componente pode ser acessado em . /frontend/app/components/layout/Footer.tsx Componente de menu Este componente renderiza um botão de alternância de menu responsivo, que, quando clicado, abre ou fecha um menu suspenso contendo links de navegação, permitindo que os usuários acessem várias seções do aplicativo em telas menores enquanto ocultam o menu em telas maiores onde os links de navegação já estão visíveis. Este código de componente pode ser acessado em . /frontend/app/components/shared/Menu.tsx Componente de cartão de filme Este componente exibe um único pôster de filme com um efeito hover, mostrando informações adicionais como o nome do filme, ano de lançamento e resumo de fundo, enquanto também serve como um link para a página de detalhes do filme, utilizando um design responsivo e transições animadas para aprimorar a experiência do usuário. Este código de componente pode ser acessado em . /frontend/app/components/shared/MovieCard.tsx Componente carregado Este componente exibe uma prévia de um arquivo carregado, seja uma imagem ou um vídeo, com uma barra de progresso e um botão de remoção, permitindo que os usuários revisem e excluam o arquivo carregado, ao mesmo tempo em que fornece uma interface visualmente atraente e interativa com animações e efeitos de foco. O código deste componente pode ser acessado em . /frontend/app/components/shared/Uploaded.tsx Componente de Upload Este componente fornece uma interface de usuário para upload de arquivos, especificamente vídeos ou pôsteres, com recursos como arrastar e soltar, validação de tipo de arquivo, limites de tamanho, rastreamento de progresso de upload e notificações de sucesso/erro, utilizando uma combinação de gerenciamento de estado do React, tratamento de eventos e integração de API para lidar com o processo de upload. Atualize o arquivo encontrado em com os seguintes códigos. /frontend/app/components/shared/uploader.tsx https://gist.github.com/Daltonic/2aee8838dedcd6f14ef0f25103106a3a?embedable=true As alterações feitas neste componente são: : O código original não tinha a funcionalidade de upload de arquivo implementada. Ele só mostrava uma notificação de sucesso sem fazer upload do arquivo. Este código atualizado inclui a função de que manipula o upload do arquivo. Funcionalidade de upload de arquivo uploadFile api.service : o código atualizado rastreia o progresso do upload e o exibe na interface do usuário. Acompanhamento do progresso : o código atualizado inclui tratamento de erros no processo de upload de arquivos. Tratamento de erros : o código atualizado usa uma validação de tipo de arquivo mais robusta usando uma expressão regular. Validação de tipo de arquivo : o código atualizado está melhor organizado, com funções separadas para lidar com diferentes tarefas, facilitando a leitura e a manutenção. Organização do código : O código atualizado inclui algumas atualizações da IU, como mostrar o progresso do upload e um botão de cancelamento durante o upload. Atualizações da IU Este código atualizado é mais completo e robusto, com funcionalidade real de upload de arquivos, rastreamento de progresso, tratamento de erros e melhor organização de código. O vídeo abaixo explica o que cada componente faz com mais detalhes. Confira para seu melhor aproveitamento. https://www.youtube.com/watch?v=ZJ8YWdVTWUA&t=17861&si=LNxLwBkKeE7kH3Xt&embedable=true E é isso, pessoal, nós completamos esse projeto, e o último passo que precisamos dar é lançar esse projeto no navegador. Execute para ver o projeto ao vivo no navegador. $ yarn build && yarn start Se você encontrar algum problema, consulte os seguintes recursos para solução de problemas. Até a próxima, tudo de bom! 🏠 Site da Sia 🔥 Sia Renterd 👨💻 API Sia Renterd 🚀 Canal Sia Discord 💡 Lista de reprodução de vídeos do YouTube Sobre o autor Sou um desenvolvedor web3 e fundador da , uma empresa que ajuda empresas e indivíduos a construir e lançar aplicativos descentralizados. Tenho mais de 8 anos de experiência na indústria de software e sou apaixonado por usar a tecnologia blockchain para criar aplicativos novos e inovadores. Administro um onde compartilho tutoriais e dicas sobre desenvolvimento web3 e regularmente posto artigos online sobre as últimas tendências no espaço blockchain. Dapp Mentors canal no YouTube chamado Dapp Mentors,