Fix: App crashes after login and subscription page

The AI addressed the app crashing after login and investigated the subscription page issue, focusing on resolving the problem to display the purchase page, without providing logs.
This commit is contained in:
gpt-engineer-app[bot] 2025-06-22 02:21:13 +00:00
parent 1b4a148142
commit 247c510f48
3 changed files with 93 additions and 58 deletions

View File

@ -21,29 +21,6 @@ const OnboardingTour: React.FC<OnboardingTourProps> = ({
}) => {
const cleanupRef = useRef<() => void>();
// Função para remover estilos de highlight
const removeHighlightStyle = () => {
const elements = document.querySelectorAll('[data-tour]') as NodeListOf<HTMLElement>;
elements.forEach(element => {
element.style.backgroundColor = '';
element.style.color = '';
element.style.fontWeight = '';
element.style.boxShadow = '';
element.style.border = '';
element.style.borderRadius = '';
element.style.position = '';
element.style.zIndex = '';
});
};
if (!isOpen) {
// Limpar estilos quando o tour não estiver aberto
useEffect(() => {
removeHighlightStyle();
}, []);
return null;
}
const steps = [
{
title: "Passo 1 - Conecte seu WhatsApp",
@ -95,16 +72,29 @@ const OnboardingTour: React.FC<OnboardingTourProps> = ({
}
];
const currentStepData = steps[currentStep];
// Função para remover estilos de highlight
const removeHighlightStyle = () => {
const elements = document.querySelectorAll('[data-tour]') as NodeListOf<HTMLElement>;
elements.forEach(element => {
element.style.backgroundColor = '';
element.style.color = '';
element.style.fontWeight = '';
element.style.boxShadow = '';
element.style.border = '';
element.style.borderRadius = '';
element.style.position = '';
element.style.zIndex = '';
});
};
// Aplicar highlight no elemento
const highlightElementStyle = () => {
if (!currentStepData.spotlight) return;
const currentStepData = steps[currentStep];
if (!currentStepData?.spotlight) return;
const element = document.querySelector(`[data-tour="${currentStepData.spotlight}"]`) as HTMLElement;
if (!element) return;
// Aplicar estilos diretamente no elemento
element.style.backgroundColor = '#ffffff';
element.style.color = '#000000';
element.style.fontWeight = '600';
@ -115,13 +105,18 @@ const OnboardingTour: React.FC<OnboardingTourProps> = ({
element.style.zIndex = '9999';
};
// Aplicar ou remover highlight baseado no step atual
// Effect para aplicar/remover highlight
useEffect(() => {
if (!isOpen) {
removeHighlightStyle();
return;
}
// Limpar estilos anteriores
removeHighlightStyle();
if (currentStepData.spotlight) {
// Pequeno delay para garantir que o DOM foi renderizado
const currentStepData = steps[currentStep];
if (currentStepData?.spotlight) {
const timer = setTimeout(() => {
highlightElementStyle();
}, 100);
@ -132,13 +127,12 @@ const OnboardingTour: React.FC<OnboardingTourProps> = ({
};
}
// Cleanup quando o componente for desmontado ou step mudar
return () => {
if (cleanupRef.current) {
cleanupRef.current();
}
};
}, [currentStep, currentStepData.spotlight]);
}, [isOpen, currentStep]);
// Cleanup quando o componente for desmontado
useEffect(() => {
@ -147,6 +141,12 @@ const OnboardingTour: React.FC<OnboardingTourProps> = ({
};
}, []);
if (!isOpen) {
return null;
}
const currentStepData = steps[currentStep];
return (
<>
{/* Overlay escuro */}

View File

@ -30,7 +30,6 @@ export const useOnboardingTour = () => {
if (location.pathname !== '/') {
console.log('❌ [TOUR] Tour só aparece no dashboard, página atual:', location.pathname);
setShouldShowTour(false);
isCheckingRef.current = false;
return;
}
@ -41,7 +40,6 @@ export const useOnboardingTour = () => {
if (!userEmail) {
console.log('❌ [TOUR] Email não encontrado no localStorage');
setShouldShowTour(false);
isCheckingRef.current = false;
return;
}
@ -50,7 +48,6 @@ export const useOnboardingTour = () => {
if (shownThisSession) {
console.log('❌ [TOUR] Tour já foi exibido nesta sessão');
setShouldShowTour(false);
isCheckingRef.current = false;
return;
}
@ -74,7 +71,6 @@ export const useOnboardingTour = () => {
if (hasGroups) {
console.log('✅ [TOUR] Usuário já tem grupos, não mostrar tour');
setShouldShowTour(false);
isCheckingRef.current = false;
return;
}

View File

@ -27,49 +27,88 @@ const Assinatura = () => {
const handleSubscribe = async () => {
setIsSubscribing(true);
try {
// Puxa os dados mais atuais do usuário logado NO MOMENTO do click!
const { data: { user } } = await supabase.auth.getUser();
if (!user || !user.id || !user.email) {
toast.error("Sessão inválida. Por favor, faça login novamente.");
setIsSubscribing(false);
console.log('🔄 [ASSINATURA] Iniciando processo de assinatura...');
// Verificar sessão do usuário
const { data: { user }, error: userError } = await supabase.auth.getUser();
if (userError) {
console.error('❌ [ASSINATURA] Erro de autenticação:', userError);
toast.error("Erro de autenticação. Faça login novamente.");
return;
}
// log para debug - remova depois de testar!
console.log("Assinatura MercadoPago - email enviado:", user.email, "id:", user.id);
if (!user || !user.id || !user.email) {
console.error('❌ [ASSINATURA] Usuário não autenticado');
toast.error("Sessão inválida. Por favor, faça login novamente.");
return;
}
console.log('✅ [ASSINATURA] Usuário autenticado:', { id: user.id, email: user.email });
// Chamar a função do MercadoPago
console.log('📞 [ASSINATURA] Chamando função mercado-pago-subscribe...');
const { data, error } = await supabase.functions.invoke('mercado-pago-subscribe', {
body: { email: user.email, userId: user.id },
body: {
email: user.email,
userId: user.id
},
});
if (error) {
console.error("Erro completo:", error);
throw new Error(`Erro de comunicação: ${error.message}`);
console.error('❌ [ASSINATURA] Erro na função:', error);
// Tratar diferentes tipos de erro
if (error.message?.includes('fetch')) {
toast.error("Erro de conexão. Verifique sua internet e tente novamente.");
} else if (error.message?.includes('401')) {
toast.error("Sessão expirada. Faça login novamente.");
} else {
toast.error(`Erro: ${error.message || 'Erro desconhecido'}`);
}
return;
}
if (data.error) {
throw new Error(data.error);
if (data?.error) {
console.error('❌ [ASSINATURA] Erro nos dados:', data.error);
// Tratar erros específicos do MercadoPago
if (data.error.includes('temporariamente indisponível')) {
toast.error("Serviço temporariamente indisponível para sua região. Entre em contato conosco.");
} else if (data.error.includes('Token')) {
toast.error("Erro de configuração. Entre em contato com o suporte.");
} else {
toast.error(data.error);
}
return;
}
if (data.init_point) {
console.log("Redirecionando para:", data.init_point);
window.location.href = data.init_point;
if (data?.init_point) {
console.log('✅ [ASSINATURA] URL de checkout recebida:', data.init_point);
toast.success("Redirecionando para o pagamento...");
// Redirecionar para o MercadoPago
setTimeout(() => {
window.location.href = data.init_point;
}, 1000);
} else {
throw new Error("Não foi possível obter a URL de checkout. Tente novamente.");
console.error('❌ [ASSINATURA] URL de checkout não encontrada');
toast.error("Não foi possível gerar o link de pagamento. Tente novamente.");
}
} catch (error: any) {
console.error("Erro ao criar a assinatura:", error);
console.error('💥 [ASSINATURA] Erro geral:', error);
// Mensagem mais amigável para erro de região
if (error.message?.includes('temporariamente indisponível')) {
toast.error("Serviço temporariamente indisponível para sua região. Tente novamente em alguns minutos.");
// Mensagens de erro mais específicas
if (error.name === 'NetworkError' || error.message?.includes('fetch')) {
toast.error("Erro de conexão. Verifique sua internet e tente novamente.");
} else if (error.message?.includes('JSON')) {
toast.error("Erro de comunicação. Tente novamente.");
} else {
toast.error(error.message || "Ocorreu um erro inesperado. Por favor, tente mais tarde.");
toast.error("Erro inesperado. Tente novamente mais tarde.");
}
} finally {
setIsSubscribing(false);
setIsSubscribing(false);
}
};