Add CEP autocompletion by ViaCEP/ECT

Signed-off-by: Rodrigo Martins <rodrigo.sousa.577@gmail.com>
This commit is contained in:
rodrigo committed 2025-04-11 21:24:56 -03:00
1 parent d9d1a68f1b
commit 1a9f71ab64
1 file changed
+25 -14
+25 -14
View File
@@ -190,7 +190,7 @@ export const ClienteModal: React.FC<ClienteModalProps> = ({
// Monitorar o valor do CEP para autopreenchimento // Monitorar o valor do CEP para autopreenchimento
const cepValue = watch("cep"); const cepValue = watch("cep");
// Função para buscar dados do CEP - versão aprimorada // Função para buscar dados do CEP - versão otimizada para forçar atualização da UI
const fetchAddressByCep = useCallback(async (cep: string) => { const fetchAddressByCep = useCallback(async (cep: string) => {
if (!cep || cep.length !== 8) return; if (!cep || cep.length !== 8) return;
@@ -202,57 +202,68 @@ export const ClienteModal: React.FC<ClienteModalProps> = ({
); );
if (response.data && !response.data.erro) { if (response.data && !response.data.erro) {
// Preencher os campos do formulário com os dados retornados // Força atualização imediata dos campos com notificação de mudança
setValue("endereco", response.data.logradouro, { setValue("endereco", response.data.logradouro || "", {
shouldDirty: true, shouldDirty: true,
shouldTouch: true, shouldTouch: true,
shouldValidate: true, shouldValidate: true,
}); });
setValue("bairro", response.data.bairro, { setValue("bairro", response.data.bairro || "", {
shouldDirty: true, shouldDirty: true,
shouldTouch: true, shouldTouch: true,
shouldValidate: true, shouldValidate: true,
}); });
setValue("cidade", response.data.localidade, { setValue("cidade", response.data.localidade || "", {
shouldDirty: true, shouldDirty: true,
shouldTouch: true, shouldTouch: true,
shouldValidate: true, shouldValidate: true,
}); });
setValue("estado", response.data.uf, { setValue("estado", response.data.uf || "", {
shouldDirty: true, shouldDirty: true,
shouldTouch: true, shouldTouch: true,
shouldValidate: true, shouldValidate: true,
}); });
// Adicione um pequeno atraso para garantir que a UI reflita as mudanças // Forçar atualização da UI - esta é a parte crucial
const event = new Event('input', { bubbles: true });
// Disparar eventos nos campos para garantir atualização visual
['endereco', 'bairro', 'cidade', 'estado'].forEach(field => {
const element = document.querySelector(`[name="${field}"]`) as HTMLInputElement;
if (element) {
element.dispatchEvent(event);
}
});
// Focar no campo número após o preenchimento automático
setTimeout(() => { setTimeout(() => {
// Focar no campo número após o preenchimento automático
const numeroInput = document.querySelector( const numeroInput = document.querySelector(
'input[name="numero"]', 'input[name="numero"]'
) as HTMLInputElement; ) as HTMLInputElement;
if (numeroInput) numeroInput.focus(); if (numeroInput) numeroInput.focus();
}, 100); }, 100);
} else { } else {
console.error("CEP não encontrado"); console.error("CEP não encontrado");
// Opcional: exibir uma notificação para o usuário // Notificar o usuário sobre o CEP não encontrado
alert("CEP não encontrado. Por favor, verifique o CEP informado.");
} }
} catch (error) { } catch (error) {
console.error("Erro ao buscar CEP:", error); console.error("Erro ao buscar CEP:", error);
// Opcional: exibir uma notificação de erro para o usuário alert("Erro ao buscar informações do CEP. Por favor, tente novamente.");
} finally { } finally {
setIsLoadingCep(false); setIsLoadingCep(false);
} }
}, [setValue]); }, [setValue]);
// Efeito para monitorar mudanças no CEP - versão mais robusta // Efeito para monitorar mudanças no CEP com debounce otimizado
useEffect(() => { useEffect(() => {
// Implementar debounce para evitar múltiplas chamadas // Limpar qualquer timer existente
const timer = setTimeout(() => { const timer = setTimeout(() => {
const cleanCep = cepValue?.replace(/\D/g, ""); const cleanCep = cepValue?.replace(/\D/g, "");
if (cleanCep && cleanCep.length === 8) { if (cleanCep && cleanCep.length === 8) {
fetchAddressByCep(cleanCep); fetchAddressByCep(cleanCep);
} }
}, 300); // Debounce de 300ms }, 200); // Reduzir debounce para resposta mais rápida
return () => clearTimeout(timer); return () => clearTimeout(timer);
}, [cepValue, fetchAddressByCep]); }, [cepValue, fetchAddressByCep]);