Fix: Handle invalid session on subscription page

The subscription page now correctly handles invalid sessions, even after logging out and back in.
This commit is contained in:
gpt-engineer-app[bot] 2025-06-15 20:32:43 +00:00
parent d7f2847a84
commit 26cd75ae81
2 changed files with 56 additions and 71 deletions

View File

@ -1,59 +1,45 @@
import { ReactNode, useEffect, useState } from 'react'; import { ReactNode, useEffect, useState } from 'react';
import { Navigate, useLocation } from 'react-router-dom'; import { Navigate, useLocation } from 'react-router-dom';
import { useToast } from "@/components/ui/use-toast";
import LoadingState from '../whatsapp/LoadingState'; import LoadingState from '../whatsapp/LoadingState';
import { authStore } from '@/stores/authStore'; import { authStore } from '@/stores/authStore';
import { supabase } from '@/integrations/supabase/client';
import { Session } from '@supabase/supabase-js';
interface ProtectedRouteProps { interface ProtectedRouteProps {
children: ReactNode; children: ReactNode;
} }
const ProtectedRoute = ({ children }: ProtectedRouteProps) => { const ProtectedRoute = ({ children }: ProtectedRouteProps) => {
const [session, setSession] = useState<Session | null>(null);
const [isLoading, setIsLoading] = useState(true); const [isLoading, setIsLoading] = useState(true);
const { toast } = useToast();
const location = useLocation(); const location = useLocation();
const setLoggedIn = authStore((state) => state.setLoggedIn); const setLoggedIn = authStore((state) => state.setLoggedIn);
const setUser = authStore((state) => state.setUser);
// Use a single state variable to track authentication status
const [authStatus, setAuthStatus] = useState<'loading' | 'authenticated' | 'unauthenticated'>('loading');
useEffect(() => { useEffect(() => {
const checkAuthentication = () => { // Checa a sessão ao carregar o componente
try { supabase.auth.getSession().then(({ data: { session } }) => {
// Check if we have stored authentication status setSession(session);
const storedAuth = localStorage.getItem('autenticado') === 'true'; setIsLoading(false);
const userId = localStorage.getItem('userId'); });
if (storedAuth && userId) { // Escuta por mudanças no estado de autenticação (login/logout)
console.log('Usando autenticação armazenada: autenticado'); const { data: { subscription } } = supabase.auth.onAuthStateChange(
setAuthStatus('authenticated'); (_event, session) => {
setLoggedIn(true); setSession(session);
} else { setLoggedIn(!!session);
console.log('Nenhuma sessão encontrada, redirecionando para login'); setUser(session?.user ? { id: session.user.id } : null);
setAuthStatus('unauthenticated');
setLoggedIn(false);
// Only show toast once when transitioning to unauthenticated
toast({
title: "Autenticação necessária",
description: "Por favor, faça login para acessar esta página"
});
}
} catch (error) {
console.error('Erro ao verificar autenticação:', error);
setAuthStatus('unauthenticated');
setLoggedIn(false);
} finally {
setIsLoading(false); setIsLoading(false);
} }
}; );
checkAuthentication();
}, [toast, setLoggedIn]); // Only check once on mount, with stable dependencies
// Se estiver carregando, mostrar estado de carregamento return () => {
if (isLoading || authStatus === 'loading') { subscription.unsubscribe();
};
}, [setLoggedIn, setUser]);
if (isLoading) {
return ( return (
<div className="flex items-center justify-center min-h-screen"> <div className="flex items-center justify-center min-h-screen">
<LoadingState message="Verificando autenticação..." /> <LoadingState message="Verificando autenticação..." />
@ -61,12 +47,12 @@ const ProtectedRoute = ({ children }: ProtectedRouteProps) => {
); );
} }
// Se não estiver autenticado, redirecionar para a página de login - use replace para evitar histórico if (!session) {
if (authStatus === 'unauthenticated') { // Redireciona para a página de login se não houver sessão
return <Navigate to="/auth" state={{ from: location }} replace />; return <Navigate to="/auth" state={{ from: location }} replace />;
} }
// Se estiver autenticado, renderizar o conteúdo protegido // Renderiza o conteúdo protegido se houver sessão
return <>{children}</>; return <>{children}</>;
}; };

View File

@ -12,48 +12,47 @@ import {
DropdownMenuSeparator, DropdownMenuSeparator,
DropdownMenuTrigger, DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu"; } from "@/components/ui/dropdown-menu";
import { supabase } from '@/integrations/supabase/client';
const Header = () => { const Header = () => {
const navigate = useNavigate(); const navigate = useNavigate();
const { toast } = useToast(); const { toast } = useToast();
const [userName, setUserName] = useState(() => { const [userName, setUserName] = useState('Usuário');
// Obter o nome do usuário do localStorage ou usar seu email como fallback
return localStorage.getItem('userName') || localStorage.getItem('userEmail') || 'Usuário';
});
// Atualize o nome se mudar no localStorage
useEffect(() => { useEffect(() => {
const handleStorageChange = () => { const fetchUser = async () => {
setUserName(localStorage.getItem('userName') || localStorage.getItem('userEmail') || 'Usuário'); const { data: { user } } = await supabase.auth.getUser();
if (user) {
setUserName(user.email || 'Usuário');
}
}; };
window.addEventListener('storage', handleStorageChange); fetchUser();
return () => { const { data: { subscription } } = supabase.auth.onAuthStateChange((_event, session) => {
window.removeEventListener('storage', handleStorageChange); setUserName(session?.user?.email || 'Usuário');
};
}, []);
const handleLogout = () => {
// Limpar informações de sessão
localStorage.removeItem('autenticado');
localStorage.removeItem('userId');
localStorage.removeItem('userName');
localStorage.removeItem('userEmail');
// Dispatch a storage event to notify other components about logout
window.dispatchEvent(new StorageEvent('storage', {
key: 'autenticado',
newValue: null
}));
toast({
title: "Logout realizado",
description: "Você foi desconectado com sucesso"
}); });
// Redirecionar para a página de login return () => subscription.unsubscribe();
navigate('/auth'); }, []);
const handleLogout = async () => {
const { error } = await supabase.auth.signOut();
if (error) {
console.error('Error logging out:', error);
toast({
title: "Erro no logout",
description: "Não foi possível desconectar. Tente novamente.",
variant: 'destructive'
});
} else {
toast({
title: "Logout realizado",
description: "Você foi desconectado com sucesso"
});
navigate('/auth', { replace: true });
}
}; };
return ( return (