login_screen.dart 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. import 'package:flutter/material.dart';
  2. import 'package:provider/provider.dart';
  3. import '../../models/models.dart';
  4. import '../../themes/themes.dart';
  5. import '../../viewmodels/viewmodels.dart';
  6. import '../../widgets/widgets.dart';
  7. import '../home/home_screen.dart';
  8. class LoginScreen extends StatefulWidget {
  9. const LoginScreen({Key? key}) : super(key: key);
  10. @override
  11. State<LoginScreen> createState() => _LoginScreenState();
  12. }
  13. class _LoginScreenState extends State<LoginScreen> {
  14. final _correo = TextEditingController();
  15. Sucursal? _selectedSucursal;
  16. @override
  17. void dispose() {
  18. super.dispose();
  19. _correo.dispose();
  20. }
  21. @override
  22. void initState() {
  23. super.initState();
  24. // Verifica la sesión almacenada
  25. WidgetsBinding.instance.addPostFrameCallback((_) {
  26. final loginViewModel =
  27. Provider.of<LoginViewModel>(context, listen: false);
  28. Provider.of<PermisoViewModel>(context, listen: false)
  29. .sincronizarPermisos();
  30. Provider.of<UsuarioViewModel>(context, listen: false)
  31. .sincronizarUsuarios();
  32. // Verificar la sesión
  33. loginViewModel.checkSession().then((_) {
  34. if (loginViewModel.status == Status.authenticated) {
  35. print("Sesión activa detectada, redirigiendo al HomeScreen.");
  36. Navigator.pushReplacement(
  37. context,
  38. MaterialPageRoute(builder: (context) => const HomeScreen()),
  39. );
  40. } else {
  41. print("No se detectó sesión, mostrando la pantalla de login.");
  42. final sucursalViewModel =
  43. Provider.of<SucursalViewModel>(context, listen: false);
  44. sucursalViewModel.sincronizarSucursales().then((_) {
  45. setState(() {
  46. final sucursales = sucursalViewModel.sucursales;
  47. _selectedSucursal = sucursales.firstWhere(
  48. (sucursal) => sucursal.seleccionado == 1,
  49. orElse: () =>
  50. sucursales.isNotEmpty ? sucursales[0] : Sucursal(),
  51. );
  52. });
  53. });
  54. }
  55. });
  56. });
  57. }
  58. @override
  59. Widget build(BuildContext context) {
  60. final loginViewModel = Provider.of<LoginViewModel>(context);
  61. // Mostrar la pantalla de carga `Cargando` mientras verifica la sesión
  62. if (loginViewModel.isLoading) {
  63. return const Cargando(); // Usa tu widget Cargando aquí
  64. }
  65. final size = MediaQuery.sizeOf(context);
  66. final sucursalViewModel = Provider.of<SucursalViewModel>(context);
  67. final sucursales = sucursalViewModel.sucursales;
  68. final errores = loginViewModel.errores;
  69. return Scaffold(
  70. backgroundColor: const Color.fromRGBO(245, 245, 245, 1),
  71. body: SingleChildScrollView(
  72. child: Padding(
  73. padding: const EdgeInsets.all(8.0),
  74. child: Column(
  75. mainAxisAlignment: MainAxisAlignment.center,
  76. children: [
  77. SizedBox(height: size.width < 1200 ? 20 : 100),
  78. const Image(
  79. image: AssetImage('assets/JoshiLogoHorizontal.png'),
  80. height: 250,
  81. ),
  82. const Text(
  83. 'Inicie sesión para acceder al sistema',
  84. style: TextStyle(fontSize: 26, fontWeight: FontWeight.bold),
  85. textAlign: TextAlign.center,
  86. ),
  87. const SizedBox(height: 20),
  88. // Campo de correo
  89. SizedBox(
  90. width: size.width < 1200 ? size.width : size.width * .35,
  91. child: Card(
  92. elevation: 5,
  93. shape: RoundedRectangleBorder(
  94. borderRadius: BorderRadius.circular(15)),
  95. child: Padding(
  96. padding: const EdgeInsets.all(15),
  97. child: Column(
  98. children: [
  99. AppDropdownModel<Sucursal>(
  100. etiqueta: 'Seleccione una sucursal',
  101. hint: 'Elija una sucursal',
  102. selectedValue: _selectedSucursal,
  103. onChanged: (Sucursal? newValue) {
  104. setState(() {
  105. _selectedSucursal = newValue;
  106. });
  107. },
  108. items: sucursales.map((Sucursal sucursal) {
  109. return DropdownMenuItem<Sucursal>(
  110. value: sucursal,
  111. child: Text(
  112. sucursal.nombre ?? '',
  113. style: const TextStyle(color: Colors.black),
  114. ),
  115. );
  116. }).toList(),
  117. ),
  118. const SizedBox(height: 5),
  119. AppTextField(
  120. autofillHints: [AutofillHints.username],
  121. prefixIcon: const Icon(Icons.mail),
  122. etiqueta: 'Correo electrónico',
  123. hintText: 'Introduzca su correo electrónico',
  124. errorText: errores?['correo'],
  125. controller: _correo,
  126. keyboardType: TextInputType.emailAddress,
  127. ),
  128. ],
  129. ),
  130. ),
  131. ),
  132. ),
  133. const SizedBox(height: 20),
  134. // Botón de login
  135. Align(
  136. alignment: Alignment.center,
  137. child: SizedBox(
  138. height: 75,
  139. width: 380,
  140. child: ElevatedButton(
  141. style: ButtonStyle(
  142. shape: MaterialStatePropertyAll(
  143. RoundedRectangleBorder(
  144. borderRadius: BorderRadius.circular(10),
  145. ),
  146. ),
  147. backgroundColor:
  148. MaterialStatePropertyAll(AppTheme.secondary),
  149. ),
  150. onPressed: () async {
  151. await loginViewModel.login(_correo.text);
  152. if (loginViewModel.status == Status.authenticated) {
  153. // Actualizar la sucursal seleccionada si el login es exitoso
  154. if (_selectedSucursal != null) {
  155. await sucursalViewModel
  156. .setSelectedSucursal(_selectedSucursal!);
  157. }
  158. Navigator.pushReplacement(
  159. context,
  160. MaterialPageRoute(
  161. builder: (context) => const HomeScreen()),
  162. );
  163. } else {
  164. String mensaje = "";
  165. if (loginViewModel.errores?["correo"] != null) {
  166. mensaje += "\n${loginViewModel.errores!["correo"]}";
  167. }
  168. if (mensaje.isNotEmpty && context.mounted) {
  169. return showDialog(
  170. context: context,
  171. builder: (context) {
  172. return AlertDialog(
  173. title: const Text("Alerta"),
  174. content: Text(mensaje),
  175. actions: [
  176. Row(children: [
  177. Expanded(
  178. child: TextButton(
  179. onPressed: () async {
  180. Navigator.pop(context);
  181. },
  182. child: const Text('Continuar'),
  183. ))
  184. ])
  185. ],
  186. );
  187. },
  188. );
  189. }
  190. }
  191. },
  192. child: const Row(
  193. mainAxisAlignment: MainAxisAlignment.center,
  194. children: [
  195. Text(
  196. 'Iniciar Sesión',
  197. style: TextStyle(fontSize: 18, color: Colors.white),
  198. ),
  199. ],
  200. ),
  201. ),
  202. ),
  203. ),
  204. const SizedBox(height: 20),
  205. ],
  206. ),
  207. ),
  208. ),
  209. );
  210. }
  211. }