login_screen.dart 7.6 KB

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