import 'package:flutter/material.dart'; import 'package:yoshi_papas_app/widgets/widgets.dart'; import 'package:provider/provider.dart'; import '../../themes/themes.dart'; import '../../viewmodels/viewmodels.dart'; class PerfilScreen extends StatefulWidget { const PerfilScreen({Key? key}) : super(key: key); @override State createState() => _PerfilState(); } class _PerfilState extends State { final _passActualController = TextEditingController(); final _passNuevoController = TextEditingController(); final _passNuevoConfirmarController = TextEditingController(); bool _isChangingPassword = false; @override void initState() { super.initState(); final viewModel = Provider.of(context, listen: false); Future(() async { viewModel.setLoading(true); await viewModel.fetchProfile(); viewModel.setLoading(false); }); if (!mounted) return; } @override void dispose() { // Desecha los controladores cuando ya no sean necesarios _passActualController.dispose(); _passNuevoController.dispose(); _passNuevoConfirmarController.dispose(); super.dispose(); } @override Widget build(BuildContext context) { final profileViewModel = Provider.of(context); final perfil = profileViewModel.profile; final isLoading = profileViewModel.isLoading; final loginViewModel = Provider.of(context); final errores = loginViewModel.errores; return Scaffold( appBar: AppBar( title: const Text( 'Perfil', style: TextStyle(color: Colors.black), ), ), body: isLoading ? const Center( child: CircularProgressIndicator(), ) : SingleChildScrollView( child: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ const SizedBox( height: 15, ), //Nombre de usuario Text( '${perfil.nombre}', style: const TextStyle( fontSize: 20, fontWeight: FontWeight.bold, ), ), const SizedBox( height: 10, ), const Padding( padding: EdgeInsets.symmetric(horizontal: 20), child: Divider(thickness: 1.2), ), const SizedBox( height: 10, ), //Nombre completo de usuario ListTile( leading: const Icon(Icons.person_pin_rounded), title: Text('${perfil.nombre}'), ), //Email de usuario ListTile( leading: const Icon(Icons.email), title: Text('${perfil.correo}'), ), const Padding( padding: EdgeInsets.symmetric(horizontal: 20), child: Divider(thickness: 1.2), ), Padding( padding: const EdgeInsets.all(15), child: Column( children: [ //CONTRASEÑA AppTextField( autofillHints: [AutofillHints.newPassword], maxLines: 1, controller: _passActualController, // Usa el controlador de estado obscureText: profileViewModel.obscureTextPassActual, prefixIcon: const Icon(Icons.lock), suffixIcon: IconButton( icon: Icon( profileViewModel.obscureTextPassActual ? Icons.visibility_off : Icons.visibility, ), onPressed: () => profileViewModel .toggleObscureTextPassActual(), ), labelText: 'Contraseña Actual', hintText: 'Introduzca su contraseña actual', ), const SizedBox( height: 15, ), AppTextField( autofillHints: [AutofillHints.newPassword], maxLines: 1, controller: _passNuevoController, // Usa el controlador de estado obscureText: profileViewModel.obscureTextPassNuevo, prefixIcon: const Icon(Icons.lock), suffixIcon: IconButton( icon: Icon( profileViewModel.obscureTextPassNuevo ? Icons.visibility_off : Icons.visibility, ), onPressed: () => profileViewModel .toggleObscureTextPassNuevo(), ), labelText: 'Nueva Contraseña', hintText: 'Introduzca su nueva contraseña', ), const SizedBox( height: 15, ), AppTextField( autofillHints: [AutofillHints.newPassword], maxLines: 1, controller: _passNuevoConfirmarController, // Usa el controlador de estado obscureText: profileViewModel .obscureTextPassNuevoConfirmar, prefixIcon: const Icon(Icons.lock), suffixIcon: IconButton( icon: Icon( profileViewModel.obscureTextPassNuevoConfirmar ? Icons.visibility_off : Icons.visibility, ), onPressed: () => profileViewModel .toggleObscureTextPassNuevoConfirmar(), ), labelText: 'Confirmar Nueva Contraseña', hintText: 'Confirme su nueva contraseña', ), const SizedBox( height: 20, ), Align( alignment: Alignment.topLeft, child: SizedBox( height: 75, width: 380, child: ElevatedButton( style: ButtonStyle( shape: MaterialStatePropertyAll( RoundedRectangleBorder( borderRadius: BorderRadius.circular(10), ), ), backgroundColor: MaterialStatePropertyAll( AppTheme.primary), ), onPressed: _isChangingPassword ? null // Deshabilita el botón si la solicitud está en progreso : () async { // Verificar que la contraseña nueva no sea igual a la contraseña actual if (_passActualController.text == _passNuevoController.text) { ScaffoldMessenger.of(context) .showSnackBar( const SnackBar( content: Text( 'La nueva contraseña debe ser diferente a la actual')), ); return; } // Verificar que la nueva contraseña y la confirmación sean iguales if (_passNuevoController.text != _passNuevoConfirmarController .text) { ScaffoldMessenger.of(context) .showSnackBar( const SnackBar( content: Text( 'La nueva contraseña y la confirmación no coinciden')), ); return; } setState(() { _isChangingPassword = true; // Indicar que el cambio de contraseña está en progreso. }); // Intentar cambiar la contraseña llamando al método correspondiente en el ViewModel. final cambioExitoso = await profileViewModel .cambiarContrasena( _passActualController.text, _passNuevoController.text, ); // Regresar a la pantalla anterior sólo si el cambio fue exitoso. if (cambioExitoso && mounted) { // Si quieres mostrar un mensaje de éxito antes de salir, puedes usar un SnackBar aquí. ScaffoldMessenger.of(context) .showSnackBar( const SnackBar( content: Text( 'Contraseña cambiada con éxito')), ); // Usar un delay para dar tiempo al SnackBar a que se muestre antes de salir. await Future.delayed( const Duration(seconds: 2)); Navigator.of(context) .pop(); // Salir de la pantalla actual. } else { // Si el cambio no fue exitoso, mostrar un SnackBar con el mensaje de error. ScaffoldMessenger.of(context) .showSnackBar( const SnackBar( content: Text( 'Ocurrió un error al guardar el perfil')), ); } // Permitir más cambios de contraseña al restablecer el estado. if (mounted) { setState(() { _isChangingPassword = false; }); } }, child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Text('Guardar', style: TextStyle( fontSize: 18, color: AppTheme.secondary)), ], ), ), ), ), ], )) ], ), ), ), ); } }