diff --git a/app/AlunoHome.tsx b/app/Aluno/AlunoHome.tsx
similarity index 99%
rename from app/AlunoHome.tsx
rename to app/Aluno/AlunoHome.tsx
index bed089f..296fbd3 100644
--- a/app/AlunoHome.tsx
+++ b/app/Aluno/AlunoHome.tsx
@@ -9,7 +9,7 @@ import {
Alert, Platform, SafeAreaView, ScrollView, StatusBar, StyleSheet, Text, TextInput, TouchableOpacity, View
} from 'react-native';
import { Calendar, LocaleConfig } from 'react-native-calendars';
-import { useTheme } from '../themecontext';
+import { useTheme } from '../../themecontext';
// Configuração PT
LocaleConfig.locales['pt'] = {
diff --git a/app/definicoes.tsx b/app/Aluno/definicoes.tsx
similarity index 96%
rename from app/definicoes.tsx
rename to app/Aluno/definicoes.tsx
index 8a1eb45..444709e 100644
--- a/app/definicoes.tsx
+++ b/app/Aluno/definicoes.tsx
@@ -1,19 +1,19 @@
import { Ionicons } from '@expo/vector-icons';
import { useRouter } from 'expo-router';
-import React, { memo, useMemo, useState } from 'react'; // Importado useMemo e memo
+import { memo, useMemo, useState } from 'react'; // Importado useMemo e memo
import {
- Alert,
- Linking,
- Platform,
- SafeAreaView,
- StatusBar,
- StyleSheet,
- Switch,
- Text,
- TouchableOpacity,
- View
+ Alert,
+ Linking,
+ Platform,
+ SafeAreaView,
+ StatusBar,
+ StyleSheet,
+ Switch,
+ Text,
+ TouchableOpacity,
+ View
} from 'react-native';
-import { useTheme } from '../themecontext';
+import { useTheme } from '../../themecontext';
const Definicoes = memo(() => {
const router = useRouter();
diff --git a/app/mainmenu.tsx b/app/Aluno/mainmenu.tsx
similarity index 96%
rename from app/mainmenu.tsx
rename to app/Aluno/mainmenu.tsx
index 1e76c03..cf739d3 100644
--- a/app/mainmenu.tsx
+++ b/app/Aluno/mainmenu.tsx
@@ -1,6 +1,5 @@
-import React from 'react';
import { SafeAreaView, ScrollView, StatusBar, StyleSheet, Text, TouchableOpacity, View } from 'react-native';
-import { useTheme } from '../themecontext'; // Ajusta o caminho conforme a tua estrutura
+import { useTheme } from '../../themecontext'; // Ajusta o caminho conforme a tua estrutura
const MainMenu = () => {
const { isDarkMode } = useTheme();
diff --git a/app/perfil.tsx b/app/Aluno/perfil.tsx
similarity index 99%
rename from app/perfil.tsx
rename to app/Aluno/perfil.tsx
index abb9d35..1836295 100644
--- a/app/perfil.tsx
+++ b/app/Aluno/perfil.tsx
@@ -8,7 +8,7 @@ import {
Platform, SafeAreaView, ScrollView, StatusBar, StyleSheet,
Text, TouchableOpacity, View
} from 'react-native';
-import { useTheme } from '../themecontext';
+import { useTheme } from '../../themecontext';
export default function Perfil() {
const { isDarkMode } = useTheme();
diff --git a/app/Professor/ListaAlunos.tsx b/app/Professor/ListaAlunos.tsx
new file mode 100644
index 0000000..4dd0a12
--- /dev/null
+++ b/app/Professor/ListaAlunos.tsx
@@ -0,0 +1,97 @@
+import {
+ StyleSheet
+} from 'react-native';
+
+/* DADOS MOCK (SUBSTITUI PELO SUPABASE DEPOIS) */
+const alunos = [
+ {
+ id: '1',
+ nome: 'Ana Martins',
+ curso: 'Técnico de Informática',
+ turma: '12ºTIG',
+ empresa: 'Tech Solutions',
+ },
+ {
+ id: '2',
+ nome: 'Pedro Costa',
+ curso: 'Técnico de Informática',
+ turma: '11ºTIG',
+ empresa: 'SoftDev Lda',
+ },
+ {
+ id: '3',
+ nome: 'Rita Fernandes',
+ curso: 'Técnico de Informática',
+ turma: '12ºTIG',
+ empresa: 'WebWorks',
+ },
+];
+
+
+/* ESTILOS */
+
+const styles = StyleSheet.create({
+ container: {
+ flex: 1,
+ backgroundColor: '#f1f3f5',
+ },
+ content: {
+ padding: 20,
+ },
+ header: {
+ flexDirection: 'row',
+ alignItems: 'center',
+ marginBottom: 24,
+ },
+ title: {
+ flex: 1,
+ textAlign: 'center',
+ fontSize: 20,
+ fontWeight: '800',
+ color: '#212529',
+ },
+ card: {
+ flexDirection: 'row',
+ alignItems: 'center',
+ backgroundColor: '#fff',
+ borderRadius: 16,
+ padding: 16,
+ marginBottom: 12,
+ shadowColor: '#000',
+ shadowOpacity: 0.06,
+ shadowRadius: 8,
+ elevation: 3,
+ },
+ avatar: {
+ width: 44,
+ height: 44,
+ borderRadius: 22,
+ backgroundColor: '#0d6efd',
+ alignItems: 'center',
+ justifyContent: 'center',
+ marginRight: 14,
+ },
+ avatarText: {
+ color: '#fff',
+ fontWeight: '800',
+ fontSize: 18,
+ },
+ info: {
+ flex: 1,
+ },
+ nome: {
+ fontSize: 16,
+ fontWeight: '700',
+ color: '#212529',
+ },
+ sub: {
+ fontSize: 13,
+ color: '#6c757d',
+ marginTop: 2,
+ },
+ empresa: {
+ fontSize: 13,
+ color: '#495057',
+ marginTop: 4,
+ },
+});
diff --git a/app/Professor/PerfilProf.tsx b/app/Professor/PerfilProf.tsx
new file mode 100644
index 0000000..e82bf37
--- /dev/null
+++ b/app/Professor/PerfilProf.tsx
@@ -0,0 +1,254 @@
+import { Ionicons } from '@expo/vector-icons';
+import { useRouter } from 'expo-router';
+import { useState } from 'react';
+import {
+ Alert,
+ SafeAreaView,
+ ScrollView,
+ StyleSheet,
+ Text,
+ TextInput,
+ TouchableOpacity,
+ View,
+} from 'react-native';
+import { supabase } from '../lib/supabase';
+
+export default function PerfilProfessor() {
+ const router = useRouter();
+
+ const [editando, setEditando] = useState(false);
+
+ const [perfil, setPerfil] = useState({
+ nome: 'João Miranda',
+ email: 'joao.miranda@epvc.pt',
+ mecanografico: 'PROF-174',
+ area: 'Informática',
+ turmas: '12ºINF | 11ºINF | 10ºINF',
+ funcao: 'Orientador de Estágio',
+ });
+
+ const terminarSessao = async () => {
+ await supabase.auth.signOut();
+ router.replace('/');
+ };
+
+ const guardarPerfil = () => {
+ setEditando(false);
+ Alert.alert('Sucesso', 'Perfil atualizado com sucesso!');
+ // aqui depois ligas ao Supabase (update)
+ };
+
+ return (
+
+
+
+ {/* TOPO COM VOLTAR */}
+
+ router.back()}>
+
+
+ Perfil
+
+
+
+ {/* HEADER */}
+
+
+
+
+ {perfil.nome}
+ {perfil.funcao}
+
+
+ {/* INFORMAÇÕES */}
+
+
+ setPerfil({ ...perfil, nome: v })}
+ />
+
+
+
+ setPerfil({ ...perfil, mecanografico: v })}
+ />
+
+ setPerfil({ ...perfil, area: v })}
+ />
+
+ setPerfil({ ...perfil, turmas: v })}
+ />
+
+
+
+ {/* AÇÕES */}
+
+
+ {editando ? (
+
+
+ Guardar alterações
+
+ ) : (
+ setEditando(true)}
+ />
+ )}
+
+ router.push('/redefenirsenha2')}
+ />
+
+
+
+
+
+
+
+ );
+}
+
+/* COMPONENTES */
+
+function InfoField({
+ label,
+ value,
+ editable,
+ onChange,
+}: {
+ label: string;
+ value: string;
+ editable: boolean;
+ onChange?: (v: string) => void;
+}) {
+ return (
+
+ {label}
+ {editable ? (
+
+ ) : (
+ {value}
+ )}
+
+ );
+}
+
+function ActionButton({
+ icon,
+ text,
+ onPress,
+ danger = false,
+}: {
+ icon: any;
+ text: string;
+ onPress: () => void;
+ danger?: boolean;
+}) {
+ return (
+
+
+
+ {text}
+
+
+ );
+}
+
+/* ESTILOS */
+
+const styles = StyleSheet.create({
+ container: { flex: 1, backgroundColor: '#f1f3f5' },
+ content: { padding: 24 },
+
+ topBar: {
+ flexDirection: 'row',
+ alignItems: 'center',
+ justifyContent: 'space-between',
+ marginBottom: 20,
+ },
+ topTitle: {
+ fontSize: 18,
+ fontWeight: '700',
+ color: '#212529',
+ },
+
+ header: { alignItems: 'center', marginBottom: 32 },
+ avatar: {
+ width: 90, height: 90, borderRadius: 45,
+ backgroundColor: '#0d6efd',
+ alignItems: 'center', justifyContent: 'center',
+ marginBottom: 12,
+ },
+ name: { fontSize: 22, fontWeight: '800', color: '#212529' },
+ role: { fontSize: 14, color: '#6c757d', marginTop: 4 },
+
+ card: {
+ backgroundColor: '#fff',
+ borderRadius: 18,
+ padding: 20,
+ marginBottom: 24,
+ elevation: 4,
+ },
+
+ infoField: { marginBottom: 16 },
+ label: { fontSize: 12, color: '#6c757d', marginBottom: 4 },
+ value: { fontSize: 15, fontWeight: '600', color: '#212529' },
+ input: {
+ borderWidth: 1,
+ borderColor: '#ced4da',
+ borderRadius: 10,
+ padding: 10,
+ fontSize: 15,
+ backgroundColor: '#f8f9fa',
+ },
+
+ actions: { gap: 12 },
+
+ actionButton: {
+ flexDirection: 'row',
+ alignItems: 'center',
+ backgroundColor: '#fff',
+ borderRadius: 14,
+ padding: 16,
+ },
+ actionText: {
+ fontSize: 15,
+ fontWeight: '600',
+ marginLeft: 12,
+ color: '#0d6efd',
+ },
+
+ primaryButton: {
+ backgroundColor: '#0d6efd',
+ borderRadius: 14,
+ padding: 16,
+ flexDirection: 'row',
+ justifyContent: 'center',
+ alignItems: 'center',
+ },
+ primaryText: { color: '#fff', fontWeight: '700', marginLeft: 8 },
+
+ dangerButton: {
+ borderWidth: 1,
+ borderColor: '#dc3545',
+ },
+ dangerText: { color: '#dc3545' },
+});
diff --git a/app/Professor/ProfessorHome.tsx b/app/Professor/ProfessorHome.tsx
new file mode 100644
index 0000000..414f23c
--- /dev/null
+++ b/app/Professor/ProfessorHome.tsx
@@ -0,0 +1,147 @@
+import { Ionicons } from '@expo/vector-icons';
+import { useRouter } from 'expo-router';
+import {
+ SafeAreaView,
+ ScrollView,
+ StyleSheet,
+ Text,
+ TouchableOpacity,
+ View,
+} from 'react-native';
+
+export default function ProfessorMenu() {
+ const router = useRouter();
+
+ return (
+
+
+
+ {/* HEADER */}
+
+ Bem-vindo,
+ Professor 👨🏫
+ Painel de gestão
+
+
+ {/* GRID DE OPÇÕES */}
+
+
+ router.push('/perfil')}
+ />
+
+ router.push('/definicoes')}
+ />
+
+ router.push('/professor/sumarios')}
+ />
+
+ router.push('/professor/alunos')}
+ />
+
+ router.push('/professor/empresas')}
+ />
+
+
+
+
+
+ );
+}
+
+/* CARD REUTILIZÁVEL */
+function MenuCard({
+ icon,
+ title,
+ subtitle,
+ onPress,
+}: {
+ icon: any;
+ title: string;
+ subtitle: string;
+ onPress: () => void;
+}) {
+ return (
+
+
+ {title}
+ {subtitle}
+
+ );
+}
+
+const styles = StyleSheet.create({
+ container: {
+ flex: 1,
+ backgroundColor: '#f1f3f5',
+ },
+ content: {
+ padding: 24,
+ },
+ header: {
+ marginBottom: 32,
+ },
+ welcome: {
+ fontSize: 16,
+ color: '#6c757d',
+ },
+ name: {
+ fontSize: 28,
+ fontWeight: '800',
+ color: '#212529',
+ marginTop: 4,
+ },
+ subtitle: {
+ fontSize: 14,
+ color: '#6c757d',
+ marginTop: 6,
+ },
+ grid: {
+ flexDirection: 'row',
+ flexWrap: 'wrap',
+ justifyContent: 'space-between',
+ },
+ card: {
+ width: '48%',
+ backgroundColor: '#fff',
+ borderRadius: 18,
+ padding: 20,
+ marginBottom: 16,
+ alignItems: 'flex-start',
+ shadowColor: '#000',
+ shadowOffset: { width: 0, height: 4 },
+ shadowOpacity: 0.08,
+ shadowRadius: 10,
+ elevation: 4,
+ },
+ cardTitle: {
+ fontSize: 16,
+ fontWeight: '700',
+ marginTop: 12,
+ color: '#212529',
+ },
+ cardSubtitle: {
+ fontSize: 13,
+ color: '#6c757d',
+ marginTop: 4,
+ },
+});
diff --git a/app/Professor/redefenirsenha2.tsx b/app/Professor/redefenirsenha2.tsx
new file mode 100644
index 0000000..f8d4551
--- /dev/null
+++ b/app/Professor/redefenirsenha2.tsx
@@ -0,0 +1,131 @@
+// app/forgot-password.tsx
+import { useRouter } from 'expo-router';
+import { useState } from 'react';
+import {
+ ActivityIndicator,
+ Alert,
+ KeyboardAvoidingView,
+ Platform,
+ ScrollView,
+ StyleSheet,
+ Text,
+ TextInput,
+ TouchableOpacity,
+ View
+} from 'react-native';
+import { supabase } from '../lib/supabase';
+
+export default function ForgotPassword() {
+ const [email, setEmail] = useState('');
+ const [loading, setLoading] = useState(false);
+ const router = useRouter();
+
+ const handleSendResetEmail = async () => {
+ if (!email) {
+ Alert.alert('Atenção', 'Insira seu email');
+ return;
+ }
+
+ setLoading(true);
+ try {
+ const { error } = await supabase.auth.resetPasswordForEmail(email);
+ if (error) throw error;
+
+ Alert.alert('Sucesso!', 'Verifique seu email para redefinir a palavra-passe');
+ router.back(); // volta para login
+ } catch (err: any) {
+ Alert.alert('Erro', err.message);
+ } finally {
+ setLoading(false);
+ }
+ };
+
+ return (
+
+
+
+
+ Recuperar Palavra-passe
+ Insira seu email para receber o link de redefinição
+
+ {/* INPUT EMAIL */}
+
+
+ {/* BOTÃO ENVIAR LINK */}
+
+ {loading ? : ENVIAR LINK}
+
+
+ {/* BOTÃO VOLTAR */}
+ router.push('/Professor/PerfilProf')} style={styles.backContainer}>
+ ← Voltar atrás
+
+
+
+
+
+ );
+}
+
+const styles = StyleSheet.create({
+ scrollContainer: { flexGrow: 1, justifyContent: 'center', padding: 24 },
+ container: {
+ backgroundColor: '#fff',
+ borderRadius: 16,
+ padding: 24,
+ shadowColor: '#000',
+ shadowOffset: { width: 0, height: 6 },
+ shadowOpacity: 0.1,
+ shadowRadius: 12,
+ elevation: 5,
+ },
+ logo: {
+ width: 120,
+ height: 120,
+ alignSelf: 'center',
+ marginBottom: 20,
+ },
+ title: { fontSize: 24, fontWeight: '700', color: '#2d3436', marginBottom: 8, textAlign: 'center' },
+ subtitle: { fontSize: 14, color: '#636e72', marginBottom: 20, textAlign: 'center' },
+ input: {
+ backgroundColor: '#f1f2f6',
+ borderRadius: 12,
+ paddingHorizontal: 16,
+ paddingVertical: 14,
+ fontSize: 16,
+ marginBottom: 20,
+ borderWidth: 0,
+ color: '#2d3436',
+ },
+ button: {
+ backgroundColor: '#0984e3',
+ borderRadius: 12,
+ paddingVertical: 16,
+ alignItems: 'center',
+ marginBottom: 12,
+ shadowColor: '#0984e3',
+ shadowOffset: { width: 0, height: 4 },
+ shadowOpacity: 0.3,
+ shadowRadius: 6,
+ elevation: 3,
+ },
+ buttonDisabled: { backgroundColor: '#74b9ff' },
+ buttonText: { color: '#fff', fontSize: 17, fontWeight: '700' },
+ backContainer: { marginTop: 8, alignItems: 'center' },
+ backText: { color: '#0984e3', fontSize: 15, fontWeight: '500' },
+});
diff --git a/app/index.tsx b/app/index.tsx
index 058d1f4..50e2589 100644
--- a/app/index.tsx
+++ b/app/index.tsx
@@ -7,7 +7,7 @@ export default function LoginScreen() {
const router = useRouter();
const handleLoginSuccess = () => {
- router.replace('/AlunoHome');
+ router.replace('/Professor/ProfessorHome');
};
return (