segunda-feira, 13 de julho de 2020

TypeScript #2: Melhorias no projeto EColeta

Pessoal, hoje vou comentar sobre o projeto que desenvolvi no post anterior sobre a criação de um marketplace de coleta de resíduos.No post anterior expliquei um pouco sobre a criação do backend desenvolvendo uma API (link) para ser consumida tanto Web como Mobile.
Neste post vou comentar sobre as novas funcionalidades desenvolvidas por mim dentro desse projeto, mostrando que com os conhecimentos obtidos da semana Next Level Week, foram desenvolvidas novas features:
  • Pesquisa de pontos de coleta (onde o usuário poderá pesquisar quais são os pontos disponíveis na sua cidade/cidade vizinha, e obter as informações sobre endereço do local);
  • Entrega de resíduos (onde o usuário poderá informar que entregou algum ítem de coleta em um determinado ponto de uma cidade).
A análise da feature de pesquisa foi:

O cliente informa o estado e cidade, e o sistema realiza uma pesquisa retornado todos os pontos localizados da localidade informada, atualizando o maps (LeafLeat), anexando o marcador nos pontos encontrados.
Logo abaixo, será retornado a imagem do ponto, junto com as suas informações do nome, email e telefone, para que o cliente consiga localizar/entrar em contato com o ponto que deseja entregar o ítem.

Para começar, eu comecei criando um arquivo .tsx (Nesse projeto foi usado TypeScrpit), onde será o index da Pesquisa do ponto de coleta. 

A primeira questão interessante que serviu como aprendizado nesse projeto foi que utilizamos a API do IBGE para nos retornarmos os estados e cidades do Brasil, assim evitamos possíveis inconsistências de informações como cidade/estado inexistente, e o cliente final ganha agilidade no processo de preenchimento do formulário, seja para pesquisa ou para cadastro.
Quando o cliente informa o estado é acionado o evento onChange, para obter o estado informado e pesquisar a cidade conforme o trecho de código abaixo:

<div className="field">
      <label htmlFor="uf">UF:</label>
        <select name="uf" id="uf" onChange={handleSelectUF}>
       <option value="0">Selecione uma UF</option>
           {ufs.map(uf=>(
             <option key={ufvalue={uf}>{uf}</option>
            ))}
         </select>
</div>

<div className="field">
        <label htmlFor="cidade">Cidade:</label>
          <select 
          name="cidade" 
          id="cidade" 
          value={selectedCity}
          onChange={handleSelectCidade}>
        <option value="0">Selecione uma Cidade</option>
               {cidades.map(cidade=>(
                   <option key={cidadevalue={cidade}>{cidade}</option>
                ))}
            </select>
           </div>
</div>
       <span>Foram localizados 
{quantidadeLocalizados < 1 ? '0' : quantidadeLocalizados} ponto(s)</span>                            
  <button type='submit'>Pesquisar</button>

E foi utilizado o useEffect para realizar as requisições para a API do IBGE, conforme o trecho de código abaixo:

    useEffect(()=>{
       axios.get<IBGEUFReponse[]>
('https://servicodados.ibge.gov.br/api/v1/localidades/estados')
       .then(response =>{
           const ufInitials = response.data.map(uf=> uf.sigla);
            setUFs(ufInitials);
           
       })
       
    }, [])
    //Carrega as cidades sempre que a UF mudar
    useEffect(()=>{
       if(selectedUF==='0'return;

       axios.get<IBGECidadeReponse[]>
(`https://servicodados.ibge.gov.br/api/v1/localidades/estados/
${selectedUF}/municipios`)
       .then(response =>{
           const cidades = response.data.map(cidade=> cidade.nome);
            setCidades(cidades);
           
       })

    }, [selectedUF]);

Após clicar no botão Pesquisar e for encontrado algum ponto com a localidade informada, o sistema populará o maps com a localidade (longitude,latitude) salvas no banco, usando o useEffect abaixo:
    
    useEffect(()=>{
        coordenadas.map(coordenada =>(
            setInitialPosition([coordenada.latitude, coordenada.longitude])
        ))
      
    }, [coordenadas])


Para mostrar as informações dos pontos localizados foi definida uma lista e dentro dela, será lido a lista de pontos, usando a função map, conforme o trecho de código abaixo:

<ul className='pontosLocalizados'>
        {pontos.map(ponto=> (
             <li key={ponto.id}>
              <img src={ponto.image} alt={ponto.name} 
className='pontosLocalizados'/>
             <br></br>

      <p className='pontosLocalizados'><b>{ponto.name}</b><br></br>
               {ponto.email}<br></br>
               {ponto.whatsapp}<br></br>
                                    
               </p>
              </li>
            ))}
</ul>


Desenvolvendo esses passos, consegui cumprir o que foi solicitado na análise comentada acima. Irei detalhar sobre a feature Entrega de resíduos no próximo post. Para mais detalhes do código, o repositório está disponível em:

Github: https://github.com/hiranneri/ecoleta-rocketseat
Linkedin: https://linkedin.com/in/hiranneri