diff --git a/web/src/App.tsx b/web/src/App.tsx
index cad4db6..4e4b9ec 100644
--- a/web/src/App.tsx
+++ b/web/src/App.tsx
@@ -1,23 +1,6 @@
-import { RouterProvider } from 'react-router-dom';
-import { router } from './routes';
-
-const App = () => ;
-import { useEffect } from 'react'
-import { signIn } from './lib/auth'
-
-useEffect(() => {
- ;(async () => {
- try {
- await signIn('TEU_EMAIL', 'TUA_PASSWORD')
- console.log('LOGIN OK')
- } catch (e: any) {
- console.log('LOGIN ERRO:', e.message)
- }
- })()
-}, [])
-
-
-export default App;
-
-
+import { RouterProvider } from 'react-router-dom'
+import { router } from './routes'
+export default function App() {
+ return
+}
diff --git a/web/src/components/auth/RequireAuth.tsx b/web/src/components/auth/RequireAuth.tsx
new file mode 100644
index 0000000..86e4636
--- /dev/null
+++ b/web/src/components/auth/RequireAuth.tsx
@@ -0,0 +1,20 @@
+import { useEffect, useState } from 'react'
+import { Navigate } from 'react-router-dom'
+import { getUser } from '../../lib/auth'
+
+export function RequireAuth({ children }: { children: React.ReactNode }) {
+ const [loading, setLoading] = useState(true)
+ const [ok, setOk] = useState(false)
+
+ useEffect(() => {
+ ;(async () => {
+ const user = await getUser()
+ setOk(!!user)
+ setLoading(false)
+ })()
+ }, [])
+
+ if (loading) return null
+ if (!ok) return
+ return <>{children}>
+}
diff --git a/web/src/lib/auth.ts b/web/src/lib/auth.ts
index d61383e..d35c4b6 100644
--- a/web/src/lib/auth.ts
+++ b/web/src/lib/auth.ts
@@ -1,19 +1,13 @@
import { supabase } from './supabase'
export async function signIn(email: string, password: string) {
- const { data, error } = await supabase.auth.signInWithPassword({
- email,
- password,
- })
+ const { data, error } = await supabase.auth.signInWithPassword({ email, password })
if (error) throw error
return data
}
export async function signUp(email: string, password: string) {
- const { data, error } = await supabase.auth.signUp({
- email,
- password,
- })
+ const { data, error } = await supabase.auth.signUp({ email, password })
if (error) throw error
return data
}
@@ -24,6 +18,7 @@ export async function signOut() {
}
export async function getUser() {
- const { data } = await supabase.auth.getUser()
+ const { data, error } = await supabase.auth.getUser()
+ if (error) return null
return data.user
}
diff --git a/web/src/lib/events.ts b/web/src/lib/events.ts
new file mode 100644
index 0000000..0a313e2
--- /dev/null
+++ b/web/src/lib/events.ts
@@ -0,0 +1,26 @@
+import { supabase } from './supabase'
+import { getUser } from './auth'
+
+export type EventRow = {
+ id: number
+ title: string
+ description: string | null
+ date: string
+ user_id: string
+}
+
+// LISTAR eventos do utilizador logado
+export async function listEvents() {
+ const user = await getUser()
+ if (!user) {
+ throw new Error('Utilizador não autenticado')
+ }
+
+ const { data, error } = await supabase
+ .from('events')
+ .select('*')
+ .order('date', { ascending: true })
+
+ if (error) throw error
+ return (data ?? []) as EventRow[]
+}
diff --git a/web/src/pages/AuthLogin.tsx b/web/src/pages/AuthLogin.tsx
index afb020c..c8d411c 100644
--- a/web/src/pages/AuthLogin.tsx
+++ b/web/src/pages/AuthLogin.tsx
@@ -1,34 +1,38 @@
-import { FormEvent, useEffect, useState } from 'react';
-import { useNavigate, Link } from 'react-router-dom';
-import { Input } from '../components/ui/input';
-import { Button } from '../components/ui/button';
-import { Card } from '../components/ui/card';
-import { useApp } from '../context/AppContext';
-import { LogIn, Mail, Lock } from 'lucide-react';
+import { FormEvent, useEffect, useState } from 'react'
+import { useNavigate, Link } from 'react-router-dom'
+import { Input } from '../components/ui/input'
+import { Button } from '../components/ui/button'
+import { Card } from '../components/ui/card'
+import { LogIn } from 'lucide-react'
+import { signIn, getUser } from '../lib/auth'
export default function AuthLogin() {
- const [email, setEmail] = useState('cliente@demo.com');
- const [password, setPassword] = useState('123');
- const [error, setError] = useState('');
- const { login, user } = useApp();
- const navigate = useNavigate();
+ const [email, setEmail] = useState('cliente@demo.com')
+ const [password, setPassword] = useState('123')
+ const [error, setError] = useState('')
+ const navigate = useNavigate()
+ // Se já estiver logado, redireciona
useEffect(() => {
- if (!user) return;
- const target = user.role === 'barbearia' ? '/painel' : '/explorar';
- navigate(target, { replace: true });
- }, [user, navigate]);
+ ;(async () => {
+ const user = await getUser()
+ if (user) {
+ navigate('/explorar', { replace: true })
+ }
+ })()
+ }, [navigate])
- const onSubmit = (e: FormEvent) => {
- e.preventDefault();
- const ok = login(email, password);
- if (!ok) {
- setError('Credenciais inválidas');
- } else {
- const target = user?.role === 'barbearia' ? '/painel' : '/explorar';
- navigate(target);
+ async function handleLogin(e: FormEvent) {
+ e.preventDefault()
+ setError('')
+
+ try {
+ await signIn(email, password)
+ navigate('/explorar', { replace: true })
+ } catch {
+ setError('Credenciais inválidas')
}
- };
+ }
return (
@@ -37,8 +41,12 @@ export default function AuthLogin() {
-
Bem-vindo de volta
-
Entre na sua conta para continuar
+
+ Bem-vindo de volta
+
+
+ Entre na sua conta para continuar
+
@@ -47,31 +55,32 @@ export default function AuthLogin() {
Barbearia: barber@demo.com / 123
-