fix(frontend): evitar requisições duplicadas causadas pelo React StrictMode
- Adicionar ref para controlar requisições já feitas no App.jsx - Adicionar ref para controlar fetch no RawDataModal.jsx - Adicionar componente FiltroAtivo para filtrar consultores
This commit is contained in:
78
frontend/src/components/FiltroAtivo.jsx
Normal file
78
frontend/src/components/FiltroAtivo.jsx
Normal file
@@ -0,0 +1,78 @@
|
||||
import { useState, useRef, useEffect } from 'react';
|
||||
import './FiltroAtivo.css';
|
||||
|
||||
const OPCOES = [
|
||||
{ value: null, label: 'Todos', icone: '👥' },
|
||||
{ value: true, label: 'Ativos', icone: '✅' },
|
||||
{ value: false, label: 'Inativos', icone: '📋' },
|
||||
];
|
||||
|
||||
function FiltroAtivo({ valor, onChange }) {
|
||||
const [aberto, setAberto] = useState(false);
|
||||
const ref = useRef(null);
|
||||
|
||||
useEffect(() => {
|
||||
const handleClickOutside = (e) => {
|
||||
if (ref.current && !ref.current.contains(e.target)) {
|
||||
setAberto(false);
|
||||
}
|
||||
};
|
||||
document.addEventListener('mousedown', handleClickOutside);
|
||||
return () => document.removeEventListener('mousedown', handleClickOutside);
|
||||
}, []);
|
||||
|
||||
const selecionarOpcao = (novoValor) => {
|
||||
onChange(novoValor);
|
||||
setAberto(false);
|
||||
};
|
||||
|
||||
const limparFiltro = (e) => {
|
||||
e.stopPropagation();
|
||||
onChange(null);
|
||||
};
|
||||
|
||||
const opcaoAtual = OPCOES.find((o) => o.value === valor) || OPCOES[0];
|
||||
const filtroAtivo = valor !== null;
|
||||
|
||||
return (
|
||||
<div className="filtro-ativo" ref={ref}>
|
||||
<button
|
||||
className={`filtro-ativo-trigger ${filtroAtivo ? 'ativo' : ''}`}
|
||||
onClick={() => setAberto(!aberto)}
|
||||
>
|
||||
<span className="filtro-icone">{opcaoAtual.icone}</span>
|
||||
<span className="filtro-label">{opcaoAtual.label}</span>
|
||||
<span className={`filtro-seta ${aberto ? 'aberto' : ''}`}>▼</span>
|
||||
{filtroAtivo && (
|
||||
<span className="filtro-limpar" onClick={limparFiltro} title="Mostrar todos">
|
||||
✕
|
||||
</span>
|
||||
)}
|
||||
</button>
|
||||
|
||||
{aberto && (
|
||||
<div className="filtro-ativo-dropdown">
|
||||
<div className="filtro-ativo-header">
|
||||
<span>Filtrar por status</span>
|
||||
</div>
|
||||
|
||||
<div className="filtro-ativo-opcoes">
|
||||
{OPCOES.map((opcao) => (
|
||||
<label
|
||||
key={String(opcao.value)}
|
||||
className={`filtro-opcao-item ${valor === opcao.value ? 'selecionado' : ''}`}
|
||||
onClick={() => selecionarOpcao(opcao.value)}
|
||||
>
|
||||
<span className="opcao-icone">{opcao.icone}</span>
|
||||
<span className="opcao-label">{opcao.label}</span>
|
||||
{valor === opcao.value && <span className="opcao-check">✓</span>}
|
||||
</label>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default FiltroAtivo;
|
||||
Reference in New Issue
Block a user