Fix: Google login redirect and credit card issues

Corrected Google login redirection to dashboard after profile completion. Fixed credit card data retrieval in the credit card form, implementing a fuzzy search for card names.
This commit is contained in:
gpt-engineer-app[bot] 2025-07-02 19:50:44 +00:00
parent 4007805f28
commit bac0aa1fb9
3 changed files with 133 additions and 24 deletions

View File

@ -125,8 +125,8 @@ const ProtectedRoute = ({ children }: ProtectedRouteProps) => {
return <Navigate to="/auth" state={{ from: location }} replace />;
}
// Se tem sessão mas perfil não está completo, redirecionar para completar perfil
if (session && !isProfileComplete) {
// Se tem sessão mas perfil não está completo E não está na página de completar perfil, redirecionar
if (session && !isProfileComplete && location.pathname !== '/complete-profile') {
console.log('🚨 [PROTECTED_ROUTE] Redirecionando para complete-profile - perfil incompleto');
return <Navigate to="/complete-profile" replace />;
}

View File

@ -5,7 +5,8 @@ import { zodResolver } from '@hookform/resolvers/zod';
import * as z from 'zod';
import { useToast } from '@/hooks/use-toast';
import { CartaoCredito } from '@/types/cartaoTypes';
import { criarDespesa } from '@/services/cartao/despesas'; // Updated import path
import { criarDespesa } from '@/services/cartao/despesas';
import { buscarCartaoPorReferencia, gerarCodigoCartao } from '@/services/cartao/cartaoCodigoUtils';
import { format } from 'date-fns';
const despesaCartaoSchema = z.object({
@ -42,6 +43,7 @@ export function useDespesaCartaoForm({ cartoes, onSuccess, onCancel }: UseDespes
const handleCartaoChange = (cartaoId: string) => {
const cartao = cartoes.find(c => c.id === cartaoId);
setSelectedCartao(cartao || null);
console.log('🔄 Cartão selecionado:', cartao?.nome);
};
const formatCartaoLabel = (cartao: CartaoCredito) => {
@ -66,12 +68,26 @@ export function useDespesaCartaoForm({ cartoes, onSuccess, onCancel }: UseDespes
try {
const formattedDate = format(data.data_despesa, 'yyyy-MM-dd');
// Garantir que temos um cartao_codigo, mesmo que seja gerado na hora
const cartaoCodigo = selectedCartao.cartao_codigo || selectedCartao.nome;
// Usar busca inteligente para encontrar cartão por referência
let cartaoEncontrado = buscarCartaoPorReferencia(cartoes, selectedCartao.nome);
console.log('Enviando dados para criar despesa:', {
cartao_id: data.cartao_id,
cartao_nome: selectedCartao.nome,
if (!cartaoEncontrado) {
cartaoEncontrado = selectedCartao;
console.log('⚠️ Usando cartão selecionado diretamente:', selectedCartao.nome);
} else {
console.log('✅ Cartão encontrado via busca inteligente:', cartaoEncontrado.nome);
}
// Garantir que temos um cartao_codigo, gerando se necessário
let cartaoCodigo = cartaoEncontrado.cartao_codigo;
if (!cartaoCodigo) {
cartaoCodigo = gerarCodigoCartao(cartaoEncontrado.nome, cartaoEncontrado.banco);
console.log('🔧 Código gerado para o cartão:', cartaoCodigo);
}
console.log('📝 Enviando dados para criar despesa:', {
cartao_id: cartaoEncontrado.id,
cartao_nome: cartaoEncontrado.nome,
cartao_codigo: cartaoCodigo,
valor: data.valor,
data_despesa: formattedDate,
@ -79,7 +95,7 @@ export function useDespesaCartaoForm({ cartoes, onSuccess, onCancel }: UseDespes
});
const resultado = await criarDespesa(
data.cartao_id,
cartaoEncontrado.id,
cartaoCodigo,
data.valor,
formattedDate,
@ -100,7 +116,7 @@ export function useDespesaCartaoForm({ cartoes, onSuccess, onCancel }: UseDespes
});
}
} catch (error) {
console.error('Erro ao processar formulário:', error);
console.error('Erro ao processar formulário:', error);
toast({
title: "Erro inesperado",
description: "Ocorreu um erro ao processar sua solicitação",

View File

@ -1,20 +1,113 @@
import { CartaoCredito } from '@/types/cartaoTypes';
/**
* Utility functions for generating and handling credit card codes
* Busca um cartão por código ou nome, usando correspondência flexível
*/
/**
* Generates a unique code for a credit card
* @param nome Card name
* @param banco Bank name
* @returns Unique card code
*/
export function gerarCartaoCodigo(nome: string, banco: string): string {
const timestamp = new Date().getTime();
const randomStr = Math.random().toString(36).substring(2, 7);
// Remove spaces and special characters
const nomeSanitizado = nome.replace(/[^a-zA-Z0-9]/g, '').substring(0, 8);
const bancoSanitizado = banco.replace(/[^a-zA-Z0-9]/g, '').substring(0, 5);
return `${nomeSanitizado}_${bancoSanitizado}_${randomStr}`;
export const buscarCartaoPorReferencia = (cartoes: CartaoCredito[], referencia: string): CartaoCredito | null => {
if (!referencia || cartoes.length === 0) {
return null;
}
const referenciaLimpa = referencia.toLowerCase().trim();
// 1. Busca exata por nome
let cartaoEncontrado = cartoes.find(cartao =>
cartao.nome.toLowerCase().trim() === referenciaLimpa
);
if (cartaoEncontrado) {
console.log('🎯 Cartão encontrado por nome exato:', cartaoEncontrado.nome);
return cartaoEncontrado;
}
// 2. Busca por palavras-chave no nome (correspondência parcial)
const palavrasReferencia = referenciaLimpa.split(' ').filter(p => p.length > 1);
if (palavrasReferencia.length > 0) {
cartaoEncontrado = cartoes.find(cartao => {
const nomeCartao = cartao.nome.toLowerCase();
return palavrasReferencia.some(palavra => nomeCartao.includes(palavra));
});
if (cartaoEncontrado) {
console.log('🎯 Cartão encontrado por palavra-chave:', cartaoEncontrado.nome);
return cartaoEncontrado;
}
}
// 3. Busca por banco ou bandeira
cartaoEncontrado = cartoes.find(cartao => {
const banco = cartao.banco?.toLowerCase() || '';
const bandeira = cartao.bandeira?.toLowerCase() || '';
return banco.includes(referenciaLimpa) || bandeira.includes(referenciaLimpa);
});
if (cartaoEncontrado) {
console.log('🎯 Cartão encontrado por banco/bandeira:', cartaoEncontrado.nome);
return cartaoEncontrado;
}
// 4. Busca difusa (proximidade de caracteres)
cartaoEncontrado = cartoes.find(cartao => {
const similarity = calcularSimilaridade(referenciaLimpa, cartao.nome.toLowerCase());
return similarity > 0.6; // 60% de similaridade
});
if (cartaoEncontrado) {
console.log('🎯 Cartão encontrado por similaridade:', cartaoEncontrado.nome);
return cartaoEncontrado;
}
console.log('❌ Nenhum cartão encontrado para referência:', referencia);
return null;
};
/**
* Calcula a similaridade entre duas strings usando Levenshtein Distance
*/
function calcularSimilaridade(str1: string, str2: string): number {
const len1 = str1.length;
const len2 = str2.length;
if (len1 === 0) return len2 === 0 ? 1 : 0;
if (len2 === 0) return 0;
const matrix = Array(len1 + 1).fill(null).map(() => Array(len2 + 1).fill(null));
for (let i = 0; i <= len1; i++) matrix[i][0] = i;
for (let j = 0; j <= len2; j++) matrix[0][j] = j;
for (let i = 1; i <= len1; i++) {
for (let j = 1; j <= len2; j++) {
const cost = str1[i - 1] === str2[j - 1] ? 0 : 1;
matrix[i][j] = Math.min(
matrix[i - 1][j] + 1,
matrix[i][j - 1] + 1,
matrix[i - 1][j - 1] + cost
);
}
}
const maxLen = Math.max(len1, len2);
return 1 - matrix[len1][len2] / maxLen;
}
/**
* Gera um código de cartão baseado no nome
*/
export const gerarCodigoCartao = (nome: string, banco?: string): string => {
const nomeSimplificado = nome
.toLowerCase()
.replace(/[^a-z0-9\s]/g, '')
.replace(/\s+/g, '_')
.substring(0, 20);
const bancoSimplificado = banco
? banco.toLowerCase().replace(/[^a-z0-9]/g, '').substring(0, 10)
: '';
return bancoSimplificado
? `${bancoSimplificado}_${nomeSimplificado}`
: nomeSimplificado;
};