focar na tela de equipa

This commit is contained in:
2026-01-07 10:40:48 +00:00
parent 44937ca6d3
commit b7ca72ed19
12 changed files with 454 additions and 285 deletions

View File

@@ -12,7 +12,6 @@ class CustomNavBar extends StatelessWidget {
@override
Widget build(BuildContext context) {
// Usar NavigationBar (Material 3) ao invés de BottomNavigationBar
return NavigationBar(
selectedIndex: selectedIndex,
onDestinationSelected: onItemSelected,
@@ -21,25 +20,30 @@ class CustomNavBar extends StatelessWidget {
elevation: 1,
height: 70,
destinations: const [
NavigationDestination(
icon: Icon(Icons.home_outlined),
selectedIcon: Icon(Icons.home_filled),
label: 'Home',
),
NavigationDestination(
icon: Icon(Icons.sports_soccer_outlined),
selectedIcon: Icon(Icons.sports_soccer),
label: 'Jogo',
),
NavigationDestination(
icon: Icon(Icons.people_outline),
selectedIcon: Icon(Icons.people),
label: 'Equipas',
),
NavigationDestination(
icon: Icon(Icons.insights_outlined),
selectedIcon: Icon(Icons.insights),
label: 'Status',
),
],
);

View File

@@ -1,48 +1,110 @@
import 'package:flutter/material.dart';
import 'package:playmaker/controllers/register_controller.dart';
import '../Controllers/register_controller.dart';
class RegisterFormFields extends StatelessWidget {
class RegisterHeader extends StatelessWidget {
const RegisterHeader({super.key});
@override
Widget build(BuildContext context) {
final screenWidth = MediaQuery.of(context).size.width;
// Mesma lógica de tamanhos do Login
final logoSize = screenWidth > 600 ? 150.0 : 100.0;
final titleFontSize = screenWidth > 600 ? 48.0 : 36.0;
final subtitleFontSize = screenWidth > 600 ? 22.0 : 18.0;
return Column(
children: [
Icon(
Icons.person_add_outlined,
size: logoSize,
color: const Color(0xFFE74C3C)
),
const SizedBox(height: 10),
Text(
'Nova Conta',
style: TextStyle(
fontSize: titleFontSize,
fontWeight: FontWeight.bold,
color: Colors.grey[900],
),
),
const SizedBox(height: 5),
Text(
'Cria o teu perfil no BasketTrack',
style: TextStyle(
fontSize: subtitleFontSize,
color: Colors.grey[600],
fontWeight: FontWeight.w500,
),
textAlign: TextAlign.center,
),
],
);
}
}
class RegisterFormFields extends StatefulWidget {
final RegisterController controller;
const RegisterFormFields({super.key, required this.controller});
@override
State<RegisterFormFields> createState() => _RegisterFormFieldsState();
}
class _RegisterFormFieldsState extends State<RegisterFormFields> {
bool _obscurePassword = true;
@override
Widget build(BuildContext context) {
final verticalPadding = MediaQuery.of(context).size.width > 600 ? 22.0 : 16.0;
final screenWidth = MediaQuery.of(context).size.width;
// Padding vertical idêntico ao login
final verticalPadding = screenWidth > 600 ? 22.0 : 16.0;
return Column(
children: [
// Campo Email
TextField(
controller: controller.emailController,
controller: widget.controller.emailController,
decoration: InputDecoration(
labelText: 'E-mail',
prefixIcon: const Icon(Icons.email_outlined),
errorText: controller.emailError,
// O erro agora vem diretamente do controller
errorText: widget.controller.emailError,
border: OutlineInputBorder(borderRadius: BorderRadius.circular(12)),
contentPadding: EdgeInsets.symmetric(vertical: verticalPadding, horizontal: 16),
),
keyboardType: TextInputType.emailAddress,
),
const SizedBox(height: 20),
// Campo Password
TextField(
controller: controller.passwordController,
obscureText: true,
controller: widget.controller.passwordController,
obscureText: _obscurePassword,
decoration: InputDecoration(
labelText: 'Palavra-passe',
prefixIcon: const Icon(Icons.lock_outlined),
errorText: controller.passwordError,
errorText: widget.controller.passwordError,
suffixIcon: IconButton(
icon: Icon(_obscurePassword ? Icons.visibility_outlined : Icons.visibility_off_outlined),
onPressed: () => setState(() => _obscurePassword = !_obscurePassword),
),
border: OutlineInputBorder(borderRadius: BorderRadius.circular(12)),
contentPadding: EdgeInsets.symmetric(vertical: verticalPadding, horizontal: 16),
),
),
const SizedBox(height: 20),
// NOVO: Campo Confirmar Password
// Campo Confirmar Password
TextField(
controller: controller.confirmPasswordController,
obscureText: true,
controller: widget.controller.confirmPasswordController,
obscureText: _obscurePassword,
decoration: InputDecoration(
labelText: 'Confirmar Palavra-passe',
prefixIcon: const Icon(Icons.lock_clock_outlined),
errorText: controller.confirmPasswordError, // Erro específico
errorText: widget.controller.confirmPasswordError,
border: OutlineInputBorder(borderRadius: BorderRadius.circular(12)),
contentPadding: EdgeInsets.symmetric(vertical: verticalPadding, horizontal: 16),
),
@@ -50,4 +112,61 @@ class RegisterFormFields extends StatelessWidget {
],
);
}
}
class RegisterButton extends StatelessWidget {
final RegisterController controller;
final VoidCallback onRegisterSuccess;
const RegisterButton({
super.key,
required this.controller,
required this.onRegisterSuccess,
});
@override
Widget build(BuildContext context) {
final screenWidth = MediaQuery.of(context).size.width;
// Mesmos tamanhos exatos do LoginButton
final buttonHeight = screenWidth > 600 ? 70.0 : 58.0;
final fontSize = screenWidth > 600 ? 22.0 : 18.0;
return SizedBox(
width: double.infinity,
height: buttonHeight,
child: ElevatedButton(
onPressed: controller.isLoading ? null : () async {
final success = await controller.signUp();
if (success) {
onRegisterSuccess();
}
},
style: ElevatedButton.styleFrom(
backgroundColor: const Color(0xFFE74C3C),
foregroundColor: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(14),
),
elevation: 3,
),
child: controller.isLoading
? const SizedBox(
width: 28,
height: 28,
child: CircularProgressIndicator(
strokeWidth: 3,
valueColor: AlwaysStoppedAnimation<Color>(Colors.white),
),
)
: Text(
'Criar Conta',
style: TextStyle(
fontSize: fontSize,
fontWeight: FontWeight.w700,
),
),
),
);
}
}