diff --git a/app/AlunoHome.tsx b/app/AlunoHome.tsx new file mode 100644 index 0000000..a03dc68 --- /dev/null +++ b/app/AlunoHome.tsx @@ -0,0 +1,122 @@ +import React, { useState } from 'react'; +import { View, Text, TouchableOpacity, StyleSheet, SafeAreaView } from 'react-native'; +import { Calendar, LocaleConfig } from 'react-native-calendars'; + +// Configurações de idioma do calendário (opcional) +LocaleConfig.locales['pt'] = { + monthNames: [ + 'Janeiro','Fevereiro','Março','Abril','Maio','Junho', + 'Julho','Agosto','Setembro','Outubro','Novembro','Dezembro' + ], + monthNamesShort: [ + 'Jan','Fev','Mar','Abr','Mai','Jun','Jul','Ago','Set','Out','Nov','Dez' + ], + dayNames: [ + 'Domingo','Segunda','Terça','Quarta','Quinta','Sexta','Sábado' + ], + dayNamesShort: ['Dom','Seg','Ter','Qua','Qui','Sex','Sáb'], +}; +LocaleConfig.defaultLocale = 'pt'; + +export default function AlunoHome() { + const [presencaMarcada, setPresencaMarcada] = useState(true); + + function marcarPresenca() { + setPresencaMarcada(true); + } + + // Exemplo de datas marcadas no calendário + const diasMarcados = { + '2026-01-07': { marked: true, dotColor: 'green' }, // hoje presente marcada + '2026-01-06': { marked: true, dotColor: 'blue' }, // sumário enviado + }; + + return ( + + + + {/* Header */} + + Estágio + Controlo diário do aluno + + + {/* Botão Presença */} + + + {presencaMarcada ? 'Presença Marcada ✅' : 'Marcar Presença'} + + + + {/* Calendário abaixo do botão */} + + + + + + + ); +} + +const styles = StyleSheet.create({ + safeArea: { + flex: 1, + backgroundColor: '#f1f3f5', + }, + container: { + flex: 1, + paddingHorizontal: 20, + }, + header: { + marginTop: 20, + marginBottom: 25, + }, + headerTitulo: { + fontSize: 30, + fontWeight: 'bold', + color: '#111', + }, + headerSubtitulo: { + fontSize: 16, + color: '#6c757d', + marginTop: 4, + }, + botaoPresenca: { + backgroundColor: '#0d6efd', + paddingVertical: 16, + borderRadius: 12, + alignItems: 'center', + marginBottom: 20, + }, + botaoDesativado: { + backgroundColor: '#b6d4fe', + }, + textoBotao: { + color: '#ffffff', + fontSize: 17, + fontWeight: '600', + }, + calendarioContainer: { + marginBottom: 20, + }, + calendario: { + borderRadius: 16, + backgroundColor: '#fff', + padding: 10, + }, +}); diff --git a/app/_layout.tsx b/app/_layout.tsx index 51abe36..a3f20ef 100644 --- a/app/_layout.tsx +++ b/app/_layout.tsx @@ -7,7 +7,7 @@ export default function RootLayout() { <> - + ); diff --git a/app/dashboard.tsx b/app/dashboard.tsx deleted file mode 100644 index 61f7d6f..0000000 --- a/app/dashboard.tsx +++ /dev/null @@ -1,106 +0,0 @@ -// app/dashboard.tsx -import React from 'react'; -import { View, Text, TouchableOpacity, StyleSheet, ScrollView, SafeAreaView } from 'react-native'; - -export default function Dashboard() { - return ( - - - - {/* Header */} - - Bem-vindo, João! - - 🔔 - - - - {/* Sumários */} - - Sumários Recentes - - Sumário 1 - 10/12/2025 - Sumário 2 - 09/12/2025 - - Criar Sumário - - - - - {/* Presença */} - - Presença - - 📌 Marcar presença - - Última presença: 10/12/2025 - - - {/* Calendário */} - - Calendário - - [Calendário] - - - - {/* Justificar faltas */} - - Justificar Faltas - - Justificar falta - - - - {/* Chat */} - - Chat com o professor - - 💬 Abrir chat - - - - - - ); -} - -const styles = StyleSheet.create({ - safe: { - flex: 1, - backgroundColor: '#f8f9fa', - }, - container: { - flex: 1, - }, - header: { - flexDirection: 'row', - justifyContent: 'space-between', - alignItems: 'center', - marginBottom: 20, - paddingHorizontal: 5, - }, - title: { fontSize: 24, fontWeight: '700' }, - icon: { fontSize: 24 }, - section: { marginBottom: 20 }, - sectionTitle: { fontSize: 18, fontWeight: '600', marginBottom: 8 }, - card: { - backgroundColor: '#fff', - padding: 16, - borderRadius: 12, - shadowColor: '#000', - shadowOpacity: 0.1, - shadowOffset: { width: 0, height: 2 }, - shadowRadius: 4, - elevation: 3, - }, - button: { - marginTop: 10, - backgroundColor: '#0984e3', - paddingVertical: 12, - borderRadius: 10, - alignItems: 'center', - }, - buttonText: { color: '#fff', fontWeight: '700' }, - lastText: { marginTop: 8 }, -}); diff --git a/app/index.tsx b/app/index.tsx index ec509c5..5a2ee98 100644 --- a/app/index.tsx +++ b/app/index.tsx @@ -1,4 +1,8 @@ + + // app/index.tsx - TELA DE LOGIN + + import React, { useState } from 'react'; import { View, @@ -38,7 +42,7 @@ export default function LoginScreen() { setLoading(false); // Primeiro navega para a dashboard - router.replace('/dashboard'); // ⬅️ Certifica-te que o ficheiro é app/dashboard.tsx + router.replace('/AlunoHome'); // ⬅️ Certifica-te que o ficheiro é app/dashboard.tsx // Depois mostra alert de boas-vindas (opcional) setTimeout(() => { diff --git a/app/mainmenu.tsx b/app/mainmenu.tsx new file mode 100644 index 0000000..7f616c5 --- /dev/null +++ b/app/mainmenu.tsx @@ -0,0 +1,148 @@ +// app/screens/MainMenu.tsx +import React from 'react'; +import { + SafeAreaView, + ScrollView, + View, + Text, + TouchableOpacity, + StyleSheet, + StatusBar, +} from 'react-native'; + +// Isto é o teu menu principal +const MainMenu = () => { + // Lista dos botões do menu + const menuItems = [ + { id: 1, title: 'Criar Novo Sumário', icon: '📝' }, + { id: 2, title: 'Meus Sumários', icon: '📚' }, + { id: 3, title: 'Calendário', icon: '📅' }, + { id: 4, title: 'Notas', icon: '📊' }, + { id: 5, title: 'Horário', icon: '⏰' }, + { id: 6, title: 'Perfil', icon: '👤' }, + { id: 7, title: 'Configurações', icon: '⚙️' }, + { id: 8, title: 'Ajuda', icon: '❓' }, + ]; + + // Quando carregas num botão + const handlePress = (title: string) => { + console.log(`Carregaste em: ${title}`); + // Aqui mais tarde mete-se a navegação + }; + + return ( + + + + {/* Cabeçalho com o teu nome */} + + Bem-vindo de volta, Ricardo! + Desejamos-lhe um bom trabalho! + 06/01/2026, 14:41:52 + + + {/* Os botões todos em grid */} + + {menuItems.map((item) => ( + handlePress(item.title)} + > + + {item.icon} + + {item.title} + + ))} + + + {/* Botão grande em baixo */} + handlePress('Criar Novo Sumário')} + > + Criar Novo Sumário + + + ); +}; + +// Estilos (cores, tamanhos, etc.) +const styles = StyleSheet.create({ + container: { + flex: 1, + backgroundColor: '#f5f5f5', + }, + header: { + backgroundColor: 'white', + padding: 20, + borderBottomWidth: 1, + borderBottomColor: '#e0e0e0', + }, + greeting: { + fontSize: 22, + fontWeight: 'bold', + color: 'black', + }, + subGreeting: { + fontSize: 16, + color: 'gray', + marginTop: 5, + }, + date: { + fontSize: 14, + color: 'lightgray', + marginTop: 10, + }, + menuGrid: { + flexDirection: 'row', + flexWrap: 'wrap', + justifyContent: 'space-between', + padding: 10, + }, + menuItem: { + width: '48%', + backgroundColor: 'white', + borderRadius: 10, + padding: 15, + marginBottom: 15, + alignItems: 'center', + shadowColor: '#000', + shadowOffset: { width: 0, height: 2 }, + shadowOpacity: 0.1, + shadowRadius: 3, + elevation: 3, + }, + iconBox: { + width: 50, + height: 50, + borderRadius: 25, + backgroundColor: '#f0f0f0', + justifyContent: 'center', + alignItems: 'center', + marginBottom: 10, + }, + icon: { + fontSize: 24, + }, + menuText: { + fontSize: 14, + fontWeight: '600', + textAlign: 'center', + }, + bigButton: { + backgroundColor: '#2196F3', + margin: 20, + padding: 18, + borderRadius: 10, + alignItems: 'center', + }, + bigButtonText: { + color: 'white', + fontSize: 18, + fontWeight: 'bold', + }, +}); + +export default MainMenu; \ No newline at end of file diff --git a/app/register.tsx b/app/register.tsx index 5af0fff..98f76bd 100644 --- a/app/register.tsx +++ b/app/register.tsx @@ -1,5 +1,8 @@ + + // app/register.tsx - TELA DE CRIAR CONTA (CORRIGIDA) + import React, { useState } from 'react'; import { View, @@ -17,7 +20,7 @@ import { Link } from 'expo-router'; import { StatusBar } from 'expo-status-bar'; import { SafeAreaView } from 'react-native-safe-area-context'; -export default function RegisterScreen() { +export default function CriarContaScreen() { const [form, setForm] = useState({ nome: '', email: '', @@ -86,7 +89,7 @@ export default function RegisterScreen() { keyboardShouldPersistTaps="handled" > {/* BOTÃO VOLTAR ATRÁS */} - + diff --git a/package-lock.json b/package-lock.json index b41e907..8e90ea4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -27,6 +27,7 @@ "react": "19.1.0", "react-dom": "19.1.0", "react-native": "0.81.5", + "react-native-calendars": "^1.1313.0", "react-native-gesture-handler": "~2.28.0", "react-native-reanimated": "~4.1.1", "react-native-safe-area-context": "~5.6.0", @@ -8637,6 +8638,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "license": "MIT" + }, "node_modules/lodash.debounce": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", @@ -9205,6 +9212,16 @@ "node": ">=10" } }, + "node_modules/moment": { + "version": "2.30.1", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz", + "integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==", + "license": "MIT", + "optional": true, + "engines": { + "node": "*" + } + }, "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -10021,7 +10038,6 @@ "version": "15.8.1", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", - "dev": true, "license": "MIT", "dependencies": { "loose-envify": "^1.4.0", @@ -10033,7 +10049,6 @@ "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", - "dev": true, "license": "MIT" }, "node_modules/punycode": { @@ -10225,6 +10240,38 @@ } } }, + "node_modules/react-native-calendars": { + "version": "1.1313.0", + "resolved": "https://registry.npmjs.org/react-native-calendars/-/react-native-calendars-1.1313.0.tgz", + "integrity": "sha512-YQ7Vg57rBRVymolamYDTxZ0lPOELTDHQbTukTWdxR47aRBYJwKI6ocRbwcY5gYgyDwNgJS4uLGu5AvmYS74LYQ==", + "license": "MIT", + "dependencies": { + "hoist-non-react-statics": "^3.3.1", + "lodash": "^4.17.15", + "memoize-one": "^5.2.1", + "prop-types": "^15.5.10", + "react-native-safe-area-context": "4.5.0", + "react-native-swipe-gestures": "^1.0.5", + "recyclerlistview": "^4.0.0", + "xdate": "^0.8.0" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "moment": "^2.29.4" + } + }, + "node_modules/react-native-calendars/node_modules/react-native-safe-area-context": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/react-native-safe-area-context/-/react-native-safe-area-context-4.5.0.tgz", + "integrity": "sha512-0WORnk9SkREGUg2V7jHZbuN5x4vcxj/1B0QOcXJjdYWrzZHgLcUzYWWIUecUPJh747Mwjt/42RZDOaFn3L8kPQ==", + "license": "MIT", + "peerDependencies": { + "react": "*", + "react-native": "*" + } + }, "node_modules/react-native-gesture-handler": { "version": "2.28.0", "resolved": "https://registry.npmjs.org/react-native-gesture-handler/-/react-native-gesture-handler-2.28.0.tgz", @@ -10303,6 +10350,12 @@ "react-native": "*" } }, + "node_modules/react-native-swipe-gestures": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/react-native-swipe-gestures/-/react-native-swipe-gestures-1.0.5.tgz", + "integrity": "sha512-Ns7Bn9H/Tyw278+5SQx9oAblDZ7JixyzeOczcBK8dipQk2pD7Djkcfnf1nB/8RErAmMLL9iXgW0QHqiII8AhKw==", + "license": "MIT" + }, "node_modules/react-native-web": { "version": "0.21.2", "resolved": "https://registry.npmjs.org/react-native-web/-/react-native-web-0.21.2.tgz", @@ -10523,6 +10576,21 @@ } } }, + "node_modules/recyclerlistview": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/recyclerlistview/-/recyclerlistview-4.2.3.tgz", + "integrity": "sha512-STR/wj/FyT8EMsBzzhZ1l2goYirMkIgfV3gYEPxI3Kf3lOnu6f7Dryhyw7/IkQrgX5xtTcDrZMqytvteH9rL3g==", + "license": "Apache-2.0", + "dependencies": { + "lodash.debounce": "4.0.8", + "prop-types": "15.8.1", + "ts-object-utils": "0.0.5" + }, + "peerDependencies": { + "react": ">= 15.2.1", + "react-native": ">= 0.30.0" + } + }, "node_modules/reflect.getprototypeof": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz", @@ -11811,6 +11879,12 @@ "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==", "license": "Apache-2.0" }, + "node_modules/ts-object-utils": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/ts-object-utils/-/ts-object-utils-0.0.5.tgz", + "integrity": "sha512-iV0GvHqOmilbIKJsfyfJY9/dNHCs969z3so90dQWsO1eMMozvTpnB1MEaUbb3FYtZTGjv5sIy/xmslEz0Rg2TA==", + "license": "ISC" + }, "node_modules/tsconfig-paths": { "version": "3.15.0", "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", @@ -12714,6 +12788,12 @@ "node": ">=10.0.0" } }, + "node_modules/xdate": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/xdate/-/xdate-0.8.3.tgz", + "integrity": "sha512-1NhJWPJwN+VjbkACT9XHbQK4o6exeSVtS2CxhMPwUE7xQakoEFTlwra9YcqV/uHQVyeEUYoYC46VGDJ+etnIiw==", + "license": "(MIT OR GPL-2.0)" + }, "node_modules/xml2js": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.6.0.tgz", diff --git a/package.json b/package.json index ee475f9..14c9869 100644 --- a/package.json +++ b/package.json @@ -30,18 +30,19 @@ "react": "19.1.0", "react-dom": "19.1.0", "react-native": "0.81.5", + "react-native-calendars": "^1.1313.0", "react-native-gesture-handler": "~2.28.0", - "react-native-worklets": "0.5.1", "react-native-reanimated": "~4.1.1", "react-native-safe-area-context": "~5.6.0", "react-native-screens": "~4.16.0", - "react-native-web": "~0.21.0" + "react-native-web": "~0.21.0", + "react-native-worklets": "0.5.1" }, "devDependencies": { "@types/react": "~19.1.0", - "typescript": "~5.9.2", "eslint": "^9.25.0", - "eslint-config-expo": "~10.0.0" + "eslint-config-expo": "~10.0.0", + "typescript": "~5.9.2" }, "private": true }