diff --git a/src/components/onboarding/OnboardingTour.tsx b/src/components/onboarding/OnboardingTour.tsx index ea4818e..07f9ed6 100644 --- a/src/components/onboarding/OnboardingTour.tsx +++ b/src/components/onboarding/OnboardingTour.tsx @@ -21,29 +21,6 @@ const OnboardingTour: React.FC = ({ }) => { const cleanupRef = useRef<() => void>(); - // Função para remover estilos de highlight - const removeHighlightStyle = () => { - const elements = document.querySelectorAll('[data-tour]') as NodeListOf; - 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 = ({ } ]; - const currentStepData = steps[currentStep]; + // Função para remover estilos de highlight + const removeHighlightStyle = () => { + const elements = document.querySelectorAll('[data-tour]') as NodeListOf; + 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 = ({ 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 = ({ }; } - // 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 = ({ }; }, []); + if (!isOpen) { + return null; + } + + const currentStepData = steps[currentStep]; + return ( <> {/* Overlay escuro */} diff --git a/src/hooks/useOnboardingTour.ts b/src/hooks/useOnboardingTour.ts index 4328402..15d3d2e 100644 --- a/src/hooks/useOnboardingTour.ts +++ b/src/hooks/useOnboardingTour.ts @@ -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; } diff --git a/src/pages/Assinatura.tsx b/src/pages/Assinatura.tsx index b18b5f1..d74df3d 100644 --- a/src/pages/Assinatura.tsx +++ b/src/pages/Assinatura.tsx @@ -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); } };