123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283 |
- 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<PerfilScreen> createState() => _PerfilState();
- }
- class _PerfilState extends State<PerfilScreen> {
- final _passActualController = TextEditingController();
- final _passNuevoController = TextEditingController();
- final _passNuevoConfirmarController = TextEditingController();
- bool _isChangingPassword = false;
- @override
- void initState() {
- super.initState();
- final viewModel = Provider.of<ProfileViewModel>(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<ProfileViewModel>(context);
- final perfil = profileViewModel.profile;
- final isLoading = profileViewModel.isLoading;
- final loginViewModel = Provider.of<LoginViewModel>(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)),
- ],
- ),
- ),
- ),
- ),
- ],
- ))
- ],
- ),
- ),
- ),
- );
- }
- }
|