app_drawer.dart 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329
  1. // ignore_for_file: must_be_immutable
  2. import 'package:flutter/material.dart';
  3. import 'package:yoshi_papas_app/views/categoria_producto/categoria_producto_screen.dart';
  4. import 'package:yoshi_papas_app/views/pedido/pedido_screen.dart';
  5. import 'package:yoshi_papas_app/views/producto/producto_screen.dart';
  6. import 'package:yoshi_papas_app/views/sucursal/sucursal_screen.dart';
  7. import 'package:yoshi_papas_app/views/variable/variable_screen.dart';
  8. import 'package:yoshi_papas_app/views/venta/venta_screen.dart';
  9. import 'package:provider/provider.dart';
  10. import '../models/models.dart';
  11. import '../services/services.dart';
  12. import '../themes/themes.dart';
  13. import '../viewmodels/login_view_model.dart';
  14. import '../viewmodels/viewmodels.dart';
  15. import '../views/descuento/descuento_screen.dart';
  16. import 'widgets_components.dart';
  17. class AppDrawer extends StatelessWidget {
  18. AppDrawer({super.key});
  19. Future<bool> _showExitConfirmationDialog(BuildContext context) async {
  20. bool shouldPop = false;
  21. await showDialog(
  22. context: context,
  23. builder: (context) => AlertDialog(
  24. surfaceTintColor: AppTheme.secondary,
  25. title: const Text('¿Cerrar sesión?'),
  26. content: const Text('¿Estás seguro de que quieres cerrar la sesión?'),
  27. actions: [
  28. TextButton(
  29. onPressed: () => Navigator.of(context).pop(false),
  30. child: const Text('Cancelar', style: TextStyle(color: Colors.red)),
  31. ),
  32. TextButton(
  33. onPressed: () async {
  34. Provider.of<LoginViewModel>(context, listen: false).logOut();
  35. Navigator.of(context).pushNamedAndRemoveUntil(
  36. 'login',
  37. (route) => false,
  38. );
  39. },
  40. child: const Text('Aceptar'),
  41. ),
  42. ],
  43. ),
  44. );
  45. return shouldPop;
  46. }
  47. @override
  48. Widget build(BuildContext context) {
  49. final permisoViewModel = Provider.of<PermisoViewModel>(context);
  50. List<String> userPermisos = permisoViewModel.userPermisos;
  51. BaseService baseService = BaseService(); // Instancia de BaseService
  52. String prefijoVersion = baseService.prefijoVersion();
  53. return Drawer(
  54. surfaceTintColor: Colors.white,
  55. backgroundColor: Colors.white,
  56. child: Column(
  57. children: [
  58. Container(
  59. width: double.infinity,
  60. decoration: BoxDecoration(
  61. color: AppTheme.primary,
  62. ),
  63. padding: EdgeInsets.only(
  64. top: MediaQuery.of(context).padding.top,
  65. ),
  66. child: const Column(
  67. children: [
  68. Padding(
  69. padding: EdgeInsets.all(8.0),
  70. child: Image(
  71. image: AssetImage('assets/JoshiLogoHorizontal.png'),
  72. height: 150,
  73. ),
  74. ),
  75. SizedBox(
  76. height: 10,
  77. ),
  78. SizedBox(
  79. height: 10,
  80. ),
  81. ],
  82. ),
  83. ),
  84. // HEADER
  85. Expanded(
  86. child: ListView(
  87. children: [
  88. ListTile(
  89. leading: circulo(const Icon(Icons.restaurant_menu)),
  90. title: const Text('Pedidos'),
  91. onTap: () => {
  92. Navigator.pop(context),
  93. Navigator.of(context).push(
  94. MaterialPageRoute(
  95. builder: (context) => const PedidoScreen(),
  96. ),
  97. ),
  98. },
  99. ),
  100. ListTile(
  101. leading: circulo(const Icon(Icons.menu_book_rounded)),
  102. title: const Text('Productos'),
  103. onTap: () => {
  104. Navigator.pop(context),
  105. Navigator.of(context).push(
  106. MaterialPageRoute(
  107. builder: (context) => ProductoScreen(),
  108. ),
  109. ),
  110. },
  111. ),
  112. if (userPermisos.contains(Usuario.VER_CATEGORIAS))
  113. ListTile(
  114. leading:
  115. circulo(const Icon(Icons.format_list_bulleted_rounded)),
  116. title: const Text('Categoría Producto'),
  117. onTap: () => {
  118. Navigator.pop(context),
  119. Navigator.of(context).push(
  120. MaterialPageRoute(
  121. builder: (context) => CategoriaProductoScreen(),
  122. ),
  123. ),
  124. },
  125. ),
  126. ListTile(
  127. leading: circulo(const Icon(Icons.receipt_long_outlined)),
  128. title: const Text('Pedidos Por Día'),
  129. onTap: () => {
  130. Navigator.pop(context),
  131. Navigator.of(context).push(
  132. MaterialPageRoute(
  133. builder: (context) => VentaScreen(),
  134. ),
  135. ),
  136. },
  137. ),
  138. if (userPermisos.contains(Usuario.VER_ADMIN))
  139. ExpansionTile(
  140. leading: circulo(const Icon(Icons.admin_panel_settings)),
  141. title: const Text('Administración'),
  142. children: [
  143. ListTile(
  144. leading: circulo(const Icon(Icons.discount)),
  145. title: const Text('Descuentos'),
  146. onTap: () => {
  147. Navigator.pop(context),
  148. Navigator.of(context).push(
  149. MaterialPageRoute(
  150. builder: (context) => DescuentoScreen(),
  151. ),
  152. ),
  153. },
  154. ),
  155. ListTile(
  156. leading: circulo(const Icon(Icons.discount)),
  157. title: const Text('Variables'),
  158. onTap: () => {
  159. Navigator.pop(context),
  160. Navigator.of(context).push(
  161. MaterialPageRoute(
  162. builder: (context) => VariablesScreen(),
  163. ),
  164. ),
  165. },
  166. ),
  167. if (userPermisos.contains(Usuario.VER_SUCURSALES))
  168. ListTile(
  169. leading:
  170. circulo(const Icon(Icons.storefront_outlined)),
  171. title: const Text('Sucursales'),
  172. onTap: () => {
  173. Navigator.pop(context),
  174. Navigator.of(context).push(
  175. MaterialPageRoute(
  176. builder: (context) => SucursalesPage(),
  177. ),
  178. ),
  179. },
  180. ),
  181. if (userPermisos.contains(Usuario.FORZAR_SINCRONIZACION))
  182. ListTile(
  183. leading: circulo(const Icon(Icons.sync)),
  184. title: const Text('Forzar Sincronización'),
  185. onTap: () async {
  186. bool confirmado = await showDialog(
  187. context: context,
  188. builder: (context) {
  189. return AlertDialog(
  190. title: const Text("Forzar Sincronización",
  191. style: TextStyle(
  192. fontWeight: FontWeight.w500,
  193. fontSize: 22)),
  194. content: const Text(
  195. '¿Estás seguro de que deseas forzar la sincronización?',
  196. style: TextStyle(fontSize: 18)),
  197. actions: [
  198. Row(
  199. mainAxisAlignment:
  200. MainAxisAlignment.spaceBetween,
  201. children: [
  202. TextButton(
  203. onPressed: () =>
  204. Navigator.of(context)
  205. .pop(false),
  206. child: const Text('No',
  207. style:
  208. TextStyle(fontSize: 18)),
  209. style: ButtonStyle(
  210. padding:
  211. MaterialStateProperty.all(
  212. EdgeInsets.fromLTRB(
  213. 20, 10, 20, 10)),
  214. backgroundColor:
  215. MaterialStateProperty.all(
  216. Colors.red),
  217. foregroundColor:
  218. MaterialStateProperty.all(
  219. AppTheme.secondary),
  220. ),
  221. ),
  222. TextButton(
  223. onPressed: () =>
  224. Navigator.of(context)
  225. .pop(true),
  226. child: const Text('Sí',
  227. style:
  228. TextStyle(fontSize: 18)),
  229. style: ButtonStyle(
  230. padding:
  231. MaterialStateProperty.all(
  232. EdgeInsets.fromLTRB(
  233. 20, 10, 20, 10)),
  234. backgroundColor:
  235. MaterialStateProperty.all(
  236. AppTheme.tertiary),
  237. foregroundColor:
  238. MaterialStateProperty.all(
  239. AppTheme.quaternary),
  240. ),
  241. ),
  242. ],
  243. ),
  244. ],
  245. );
  246. },
  247. ) ??
  248. false;
  249. if (confirmado) {
  250. showDialog(
  251. context: context,
  252. barrierDismissible: false,
  253. builder: (context) => AlertDialog(
  254. title: const Text("Sincronizando",
  255. style: TextStyle(
  256. fontWeight: FontWeight.w500,
  257. fontSize: 22)),
  258. content: Padding(
  259. padding:
  260. const EdgeInsetsDirectional.symmetric(
  261. horizontal: 120),
  262. child: const CircularProgressIndicator(),
  263. ),
  264. ),
  265. );
  266. try {
  267. await RepoService().forzarSincronizacion();
  268. Navigator.of(context, rootNavigator: true)
  269. .pop();
  270. Navigator.of(context).pop();
  271. ScaffoldMessenger.of(context).showSnackBar(
  272. SnackBar(
  273. content: const Text(
  274. 'Sincronización completada con éxito'),
  275. backgroundColor: Colors.green,
  276. ),
  277. );
  278. } catch (e) {
  279. Navigator.of(context, rootNavigator: true)
  280. .pop();
  281. Navigator.of(context).pop();
  282. ScaffoldMessenger.of(context).showSnackBar(
  283. SnackBar(
  284. content:
  285. Text('Error en la sincronización: $e'),
  286. backgroundColor: Colors.red,
  287. ),
  288. );
  289. }
  290. }
  291. },
  292. ),
  293. ],
  294. ),
  295. ListTile(
  296. leading: const Icon(Icons.logout),
  297. title: const Text('Cerrar sesión'),
  298. onTap: () {
  299. _showExitConfirmationDialog(context);
  300. },
  301. ),
  302. ],
  303. ),
  304. ),
  305. Padding(
  306. padding: const EdgeInsets.only(bottom: 10),
  307. child: Align(
  308. alignment: Alignment.bottomCenter,
  309. child: Text(
  310. '$prefijoVersion.1.24.10.28',
  311. style: const TextStyle(fontWeight: FontWeight.w300),
  312. ),
  313. ),
  314. ),
  315. ],
  316. ),
  317. );
  318. }
  319. }