Untitled

mail@pastecode.io avatar
unknown
plain_text
a year ago
7.5 kB
4
Indexable
Never
import { useContext, useEffect, useState } from 'react';
import PlanetContext from '../context/planet-context';
import { OpcoesOrdenacaoType, TipoInfoForm } from '../types/types';

export default function Table() {
  const { resultadoApi } = useContext(PlanetContext);
  const [apiFiltrada, setApiFiltrada] = useState(resultadoApi);
  const [dadosForm, setDadosForm] = useState<TipoInfoForm[]>([]);
  const todosFiltros = [
    'population', 'orbital_period', 'diameter', 'rotation_period', 'surface_water',
  ];
  const [filtros, setFiltros] = useState(todosFiltros);
  const [filtrosCopia, setFiltrosCopia] = useState(todosFiltros);
  const [ordenacao, setOrdenacao] = useState<OpcoesOrdenacaoType>({
    ordem: 'population',
    ascendente: 'ASC',
  });
  const [infoForm, setInfoForm] = useState<TipoInfoForm>({
    nome: '',
    filtro: 'population',
    operador: 'maior que',
    valor: '0',
  });

  useEffect(() => {
    function buscaPlaneta() {
      const busca = resultadoApi
        .filter((planeta) => planeta.name.toLowerCase()
          .includes(infoForm.nome.toLowerCase()));
      setApiFiltrada(busca);
    }
    buscaPlaneta();
  }, [resultadoApi, infoForm]);

  function removeTudo() {
    setFiltros(filtrosCopia);
    setDadosForm([]);
  }

  const inputOrdenacao = (arr:any, filtro:string, sentido:string) => {
    const alteracaoOrdem = sentido === 'ASC' ? 1 : -1;
    return [...arr].sort((a, b) => {
      if (a[filtro] === 'unknown') return 1;
      if (b[filtro] === 'unknown') return -1;
      return (Number(a[filtro]) > Number(b[filtro]) ? 1 : -1) * alteracaoOrdem;
    });
  };

  function ordemDaLista() {
    console.log('CLIQUEI');
    setApiFiltrada(inputOrdenacao(apiFiltrada, ordenacao.ordem, ordenacao.ascendente));
  }

  function removerFiltroAplicado(filtro:string) {
    setDadosForm(dadosForm.filter((filtroAplicado) => filtroAplicado.filtro !== filtro));
  }

  function handleClickAddFiltro() {
    botaoFiltragem(infoForm);
  }

  function botaoFiltragem(formulario:TipoInfoForm) {
    setDadosForm([...dadosForm, formulario]);
  }

  function handleBusca(e: React.ChangeEvent<HTMLInputElement | HTMLSelectElement>) {
    const { name, value } = e.target;
    setInfoForm({ ...infoForm, [name]: value });
  }
  const filtrarColunas = dadosForm.map((filtrando:any) => filtrando.filtro);
  const meuArrayComparacao = [
    'population',
    'orbital_period',
    'diameter',
    'rotation_period',
    'surface_water',
  ];
  const arrayOriginal = meuArrayComparacao
    .filter((elemento:any) => !filtrarColunas.includes(elemento));

  const limpaResultados = apiFiltrada
    .filter((resultado:any) => dadosForm.every((res:any) => {
      if (res.operador === 'maior que') {
        return Number(resultado[res.filtro]) > Number(res.valor);
      }
      if (res.operador === 'menor que') {
        return Number(resultado[res.filtro]) < Number(res.valor);
      }
      if (res.operador === 'igual a') {
        return Number(resultado[res.filtro]) === Number(res.valor);
      }
      return false;
    }));

  return (
    <div>
      <label>
        Busca
        <input
          type="text"
          name="nome"
          onChange={ handleBusca }
          value={ infoForm.nome }
          data-testid="name-filter"
        />

      </label>
      <form>
        <select
          name="filtro"
          onChange={ handleBusca }
          data-testid="column-filter"
        >
          {arrayOriginal.map((elemento, index) => (
            <option key={ index } value={ elemento }>{elemento}</option>
          ))}
        </select>
        <select
          name="operador"
          onChange={ handleBusca }
          data-testid="comparison-filter"
        >
          <option value="maior que">maior que</option>
          <option value="menor que">menor que</option>
          <option value="igual a">igual a</option>
        </select>
        <input
          name="valor"
          value={ infoForm.valor }
          type="number"
          onChange={ handleBusca }
          data-testid="value-filter"
        />
        <button
          data-testid="button-filter"
          onClick={ handleClickAddFiltro }
          type="button"
        >
          Adicionar filtro
        </button>
        {dadosForm.map((filtroAplicado) => (
          <div key={ filtroAplicado.filtro } data-testid="filter">
            <p>{filtroAplicado.filtro}</p>
            <p>{filtroAplicado.operador}</p>
            <p>{filtroAplicado.valor}</p>
            <button
              type="button"
              onClick={ () => removerFiltroAplicado(filtroAplicado.filtro) }
            >
              Remover item
            </button>
          </div>
        ))}
        <button
          type="button"
          onClick={ removeTudo }
          data-testid="button-remove-filters"
        >
          Remover todas filtragens
        </button>
        <label>
          Ordenar por
          <select
            data-testid="column-sort"
            onChange={ (e) => setOrdenacao({ ...ordenacao, ordem: e.target.value }) }
          >
            {
              filtros.map((filtro, index) => (
                <option key={ index } value={ filtro }>{filtro}</option>
              ))
            }
          </select>
        </label>
        <input
          type="radio"
          name="ordenacao"
          data-testid="column-sort-input-asc"
          value="ASC"
          onClick={ () => setOrdenacao({ ...ordenacao, ascendente: 'ASC' }) }
        />
        Ascendente
        <input
          type="radio"
          name="ordenacao"
          data-testid="column-sort-input-desc"
          value="DESC"
          onClick={ () => setOrdenacao({ ...ordenacao, ascendente: 'DESC' }) }
        />
        Descendente
        <button
          data-testid="column-sort-button"
          type="button"
          onClick={ ordemDaLista }
        >
          Ordenar
        </button>
      </form>
      <table>
        <thead>
          <tr>
            <th>Name</th>
            <th>Rotation_period</th>
            <th>Orbital_period</th>
            <th>Diameter</th>
            <th>Climate</th>
            <th>Gravity</th>
            <th>Terrain</th>
            <th>Surface_water</th>
            <th>Population</th>
            <th>Films</th>
            <th>Created</th>
            <th>Edited</th>
            <th>URL</th>
          </tr>
        </thead>
        <tbody>
          {limpaResultados?.map((infoData, index) => (
            <tr key={ index }>
              <td data-testid="planet-name">{infoData.name}</td>
              <td>{infoData.rotation_period}</td>
              <td>{infoData.orbital_period}</td>
              <td>{infoData.diameter}</td>
              <td>{infoData.climate}</td>
              <td>{infoData.gravity}</td>
              <td>{infoData.terrain}</td>
              <td>{infoData.surface_water}</td>
              <td>{infoData.population}</td>
              <td>
                <ul>
                  {infoData.films.map((film, indexFilm) => (
                    <li key={ indexFilm }>{film}</li>
                  ))}
                </ul>
              </td>
              <td>
                {infoData.created}
              </td>
              <td>
                {infoData.edited}
              </td>
              <td>
                {infoData.url}
              </td>
            </tr>
          ))}
        </tbody>
      </table>
    </div>
  );
}