diff --git a/src/components/auth/LoginForm.tsx b/src/components/auth/LoginForm.tsx index a628857..15f7920 100644 --- a/src/components/auth/LoginForm.tsx +++ b/src/components/auth/LoginForm.tsx @@ -2,6 +2,7 @@ import React, { useState } from 'react'; import { LogIn, Eye, EyeOff, School, GraduationCap, User } from 'lucide-react'; import { useAuth } from '../../hooks/useAuth'; import { useNavigate } from 'react-router-dom'; +import { supabase } from '../../lib/supabase'; interface LoginFormProps { userType: 'school' | 'teacher' | 'student'; @@ -36,16 +37,32 @@ export function LoginForm({ userType, onLogin, onRegisterClick }: LoginFormProps setLoading(true); try { - const { user } = await signIn(email, password); - if (user) { - if (userType === 'school') { + const { data, error } = await supabase.auth.signInWithPassword({ + email: email, + password: password + }); + + if (error) throw error; + + const userRole = data.user?.user_metadata?.role; + + switch (userRole) { + case 'student': + navigate('/aluno'); + break; + case 'teacher': + navigate('/professor'); + break; + case 'school': navigate('/dashboard'); - } else if (onLogin) { - await onLogin({ email, password }); - } + break; + default: + throw new Error('Tipo de usuário inválido'); } + } catch (err) { - setError('Erro ao fazer login. Verifique suas credenciais.'); + console.error('Erro no login:', err); + setError('Email ou senha incorretos'); } finally { setLoading(false); } diff --git a/src/components/auth/ProtectedRoute.tsx b/src/components/auth/ProtectedRoute.tsx new file mode 100644 index 0000000..b83c9cd --- /dev/null +++ b/src/components/auth/ProtectedRoute.tsx @@ -0,0 +1,36 @@ +import React from 'react'; +import { Navigate } from 'react-router-dom'; +import { useAuth } from '../../hooks/useAuth'; + +interface ProtectedRouteProps { + children: React.ReactNode; + allowedRoles?: string[]; +} + +export function ProtectedRoute({ children, allowedRoles = [] }: ProtectedRouteProps) { + const { user, loading, userRole } = useAuth(); + + if (loading) { + return
Carregando...
; + } + + if (!user) { + return ; + } + + if (allowedRoles.length > 0 && !allowedRoles.includes(userRole || '')) { + // Redirecionar para a página inicial apropriada baseado no papel do usuário + switch (userRole) { + case 'student': + return ; + case 'teacher': + return ; + case 'school': + return ; + default: + return ; + } + } + + return <>{children}; +} \ No newline at end of file diff --git a/src/hooks/useAuth.tsx b/src/hooks/useAuth.tsx new file mode 100644 index 0000000..b40a92e --- /dev/null +++ b/src/hooks/useAuth.tsx @@ -0,0 +1,84 @@ +import React from 'react'; +import { useNavigate } from 'react-router-dom'; +import { supabase } from '../lib/supabase'; + +interface AuthContextType { + user: any; + loading: boolean; + signOut: () => Promise; + userRole: string | null; +} + +const AuthContext = React.createContext(undefined); + +export function AuthProvider({ children }: { children: React.ReactNode }) { + const navigate = useNavigate(); + const [user, setUser] = React.useState(null); + const [userRole, setUserRole] = React.useState(null); + const [loading, setLoading] = React.useState(true); + + React.useEffect(() => { + const fetchSession = async () => { + const { data: { session } } = await supabase.auth.getSession(); + setUser(session?.user ?? null); + setUserRole(session?.user?.user_metadata?.role ?? null); + setLoading(false); + }; + + fetchSession(); + + const { data: { subscription } } = supabase.auth.onAuthStateChange(async (event, session) => { + setUser(session?.user ?? null); + setUserRole(session?.user?.user_metadata?.role ?? null); + setLoading(false); + + // Redirecionar baseado no evento de autenticação + if (event === 'SIGNED_IN') { + const role = session?.user?.user_metadata?.role; + switch (role) { + case 'student': + navigate('/aluno'); + break; + case 'teacher': + navigate('/professor'); + break; + case 'school': + navigate('/dashboard'); + break; + } + } else if (event === 'SIGNED_OUT') { + navigate('/'); + } + }); + + return () => { + subscription.unsubscribe(); + }; + }, [navigate]); + + const signOut = async () => { + await supabase.auth.signOut(); + navigate('/'); + }; + + const value = { + user, + loading, + signOut, + userRole + }; + + return ( + + {children} + + ); +} + +export function useAuth() { + const context = React.useContext(AuthContext); + if (context === undefined) { + throw new Error('useAuth must be used within an AuthProvider'); + } + return context; +} \ No newline at end of file diff --git a/src/routes.tsx b/src/routes.tsx index 40bb8e8..2455538 100644 --- a/src/routes.tsx +++ b/src/routes.tsx @@ -19,6 +19,7 @@ import { StudentDashboardLayout } from './pages/student-dashboard/StudentDashboa import { StudentStoriesPage } from './pages/student-dashboard/StudentStoriesPage'; import { CreateStoryPage } from './pages/student-dashboard/CreateStoryPage'; import { StoryPage } from './pages/student-dashboard/StoryPage'; +import { ProtectedRoute } from './components/auth/ProtectedRoute'; export const router = createBrowserRouter([ { @@ -62,7 +63,11 @@ export const router = createBrowserRouter([ }, { path: '/dashboard', - element: , + element: ( + + + + ), children: [ { index: true, @@ -123,7 +128,11 @@ export const router = createBrowserRouter([ }, { path: '/aluno', - element: , + element: ( + + + + ), children: [ { index: true,