home_screen.dart 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332
  1. import 'package:flutter/material.dart';
  2. import 'package:provider/provider.dart';
  3. import 'package:turquessa_mesas_hoster/core/models/mesa_model.dart';
  4. import 'package:turquessa_mesas_hoster/utils/widgets/custom_appbar.dart';
  5. import '../../../utils/widgets/ordenes_card.dart';
  6. import '../../viewmodels/viewmodels.dart';
  7. class HomeScreen extends StatefulWidget {
  8. const HomeScreen({super.key});
  9. @override
  10. Formulario createState() => Formulario();
  11. }
  12. class Formulario extends State<HomeScreen> {
  13. int _selectedIndex = 0;
  14. @override
  15. void initState() {
  16. super.initState();
  17. final mesaViewModel = Provider.of<MesaViewModel>(context, listen: false);
  18. WidgetsBinding.instance.addPostFrameCallback((_) async {
  19. Provider.of<ProductoViewModel>(context, listen: false)
  20. .sincronizarProductosYCategorias();
  21. await mesaViewModel.sincronizarMesas();
  22. await mesaViewModel.fetchLocalAll(sinLimite: true, orderBy: 'nombre ASC');
  23. });
  24. }
  25. @override
  26. Widget build(BuildContext context) {
  27. final mesaViewModel = Provider.of<MesaViewModel>(context);
  28. final loginViewModel = Provider.of<LoginViewModel>(context);
  29. var _selectedIndex;
  30. return Scaffold(
  31. backgroundColor: Colors.grey.shade200,
  32. appBar: AppBar(
  33. title: const CustomAppbar(),
  34. ),
  35. body: Row(
  36. children: [
  37. NavigationRail(
  38. backgroundColor: Color.fromARGB(255, 25, 30, 41),
  39. selectedIndex: _selectedIndex,
  40. onDestinationSelected: (int index) {
  41. setState(() {
  42. _selectedIndex = index;
  43. });
  44. if (index == 3) {
  45. loginViewModel.showExitConfirmationDialog(context);
  46. }
  47. },
  48. labelType: NavigationRailLabelType.all,
  49. destinations: const [
  50. NavigationRailDestination(
  51. icon: Icon(Icons.home, color: Colors.white),
  52. selectedIcon: Icon(Icons.home_filled),
  53. label: Text('Inicio'),
  54. ),
  55. NavigationRailDestination(
  56. icon: Icon(Icons.search),
  57. selectedIcon: Icon(
  58. Icons.search_rounded,
  59. color: Colors.white,
  60. ),
  61. label: Text('Buscar'),
  62. ),
  63. NavigationRailDestination(
  64. icon: Icon(Icons.settings),
  65. selectedIcon: Icon(Icons.settings_rounded, color: Colors.white),
  66. label: Text('Ajustes'),
  67. ),
  68. NavigationRailDestination(
  69. icon: Icon(Icons.logout),
  70. selectedIcon: Icon(Icons.logout, color: Colors.white),
  71. label: Text('Cerrar Sesión'),
  72. ),
  73. ],
  74. ),
  75. Expanded(
  76. child: Center(
  77. child: GridView.builder(
  78. gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
  79. crossAxisCount: 4,
  80. childAspectRatio: 1.0,
  81. crossAxisSpacing: 10.0,
  82. mainAxisSpacing: 10.0,
  83. ),
  84. padding: const EdgeInsets.all(10),
  85. itemCount: mesaViewModel.mesas.length,
  86. itemBuilder: (context, index) {
  87. final mesa = mesaViewModel.mesas[index];
  88. return GestureDetector(
  89. onTap: () {
  90. setState(() {
  91. mesaViewModel.selectMesa(mesa);
  92. });
  93. },
  94. child: TableCard(
  95. icon: Icons.table_chart,
  96. //TODO: Agregar campo de estatus de la mesa para definir los colores
  97. color: (mesa.activa == true) ? Colors.blue : Colors.grey,
  98. title: mesa.nombre ?? 'Mesa sin nombre',
  99. ),
  100. );
  101. },
  102. ),
  103. ),
  104. ),
  105. if (mesaViewModel.selectedMesa != null)
  106. Expanded(
  107. child: Container(
  108. margin: const EdgeInsets.all(10),
  109. decoration: BoxDecoration(
  110. color: Colors.white,
  111. borderRadius: BorderRadius.circular(10),
  112. boxShadow: [
  113. BoxShadow(
  114. color: Colors.grey.withOpacity(0.2),
  115. blurRadius: 5,
  116. spreadRadius: 1,
  117. )
  118. ],
  119. ),
  120. child: TablaDetalles(
  121. status: EstadoPedido.disponible,
  122. table: mesaViewModel.selectedMesa ??
  123. Mesa(
  124. activa: false,
  125. id: 0,
  126. nombre: 'Mesa sin nombre',
  127. estado: EstadoPedido.disponible)),
  128. )),
  129. ],
  130. ),
  131. );
  132. }
  133. }
  134. class TableCard extends StatelessWidget {
  135. final IconData icon;
  136. final Color color;
  137. final String title;
  138. const TableCard(
  139. {super.key,
  140. required this.icon,
  141. required this.color,
  142. required this.title});
  143. @override
  144. Widget build(BuildContext context) {
  145. return Card(
  146. color: color,
  147. child: Column(
  148. mainAxisAlignment: MainAxisAlignment.center,
  149. children: [
  150. Icon(
  151. icon,
  152. size: 50,
  153. color: Colors.white,
  154. ),
  155. Text(
  156. title,
  157. style: const TextStyle(color: Colors.white, fontSize: 20),
  158. )
  159. ],
  160. ),
  161. );
  162. }
  163. }
  164. class TablaDetalles extends StatelessWidget {
  165. final Mesa table;
  166. final EstadoPedido status;
  167. const TablaDetalles({
  168. Key? key,
  169. required this.table,
  170. required this.status,
  171. }) : super(key: key);
  172. @override
  173. Widget build(BuildContext context) {
  174. return Container(
  175. margin: const EdgeInsets.all(10),
  176. decoration: BoxDecoration(
  177. color: Colors.white,
  178. borderRadius: BorderRadius.circular(10),
  179. boxShadow: [
  180. BoxShadow(
  181. color: Colors.grey.withOpacity(0.2),
  182. blurRadius: 5,
  183. spreadRadius: 1,
  184. )
  185. ],
  186. ),
  187. child: Column(
  188. children: [
  189. // Header
  190. Container(
  191. padding: const EdgeInsets.all(16),
  192. decoration: BoxDecoration(
  193. color: table.activa! ? Colors.blue : Colors.grey,
  194. borderRadius:
  195. const BorderRadius.vertical(top: Radius.circular(10)),
  196. ),
  197. child: Row(
  198. mainAxisAlignment: MainAxisAlignment.spaceBetween,
  199. children: [
  200. Row(
  201. children: [
  202. const Icon(Icons.table_restaurant,
  203. color: Colors.white, size: 24),
  204. const SizedBox(width: 8),
  205. Text(
  206. table.nombre ?? 'Mesa sin nombre',
  207. style: const TextStyle(
  208. color: Colors.white,
  209. fontSize: 20,
  210. fontWeight: FontWeight.bold,
  211. ),
  212. ),
  213. ],
  214. ),
  215. Container(
  216. padding:
  217. const EdgeInsets.symmetric(horizontal: 12, vertical: 6),
  218. decoration: BoxDecoration(
  219. color: Colors.white.withOpacity(0.2),
  220. borderRadius: BorderRadius.circular(20),
  221. ),
  222. child: Text(
  223. table.activa! ? 'Activa' : 'Inactiva',
  224. style: const TextStyle(
  225. color: Colors.white,
  226. fontWeight: FontWeight.bold,
  227. ),
  228. ),
  229. ),
  230. ],
  231. ),
  232. ),
  233. // Contenido scrolleable
  234. Expanded(
  235. child: SingleChildScrollView(
  236. child: Padding(
  237. padding: const EdgeInsets.all(16),
  238. child: Column(
  239. crossAxisAlignment: CrossAxisAlignment.start,
  240. children: [
  241. Text(
  242. 'ID: ${table.id}',
  243. style: const TextStyle(fontSize: 16),
  244. ),
  245. const SizedBox(height: 16),
  246. Row(
  247. children: [
  248. const Text('Estado: '),
  249. Text(
  250. status.toString().split('.').last,
  251. style: const TextStyle(
  252. fontWeight: FontWeight.bold,
  253. color: Colors.blue,
  254. ),
  255. ),
  256. ],
  257. ),
  258. const SizedBox(height: 16),
  259. IconDataByStatus(status: status),
  260. const SizedBox(height: 16),
  261. const OrdenesScreen(),
  262. ],
  263. ),
  264. ),
  265. ),
  266. ),
  267. ],
  268. ),
  269. );
  270. }
  271. }
  272. class IconDataByStatus extends StatelessWidget {
  273. final EstadoPedido status;
  274. const IconDataByStatus({Key? key, required this.status});
  275. @override
  276. Widget build(BuildContext context) {
  277. switch (status) {
  278. case EstadoPedido.disponible:
  279. return IconButton(
  280. onPressed: () {
  281. final mesaViewModel =
  282. Provider.of<MesaViewModel>(context, listen: false);
  283. mesaViewModel.CambiarEstadoPedidoMesa(EstadoPedido.preparacion);
  284. },
  285. style: ButtonStyle(
  286. backgroundColor: MaterialStateProperty.all(
  287. const Color.fromARGB(255, 220, 252, 232)),
  288. ),
  289. icon: const Icon(Icons.table_restaurant_rounded, color: Colors.green),
  290. );
  291. case EstadoPedido.surtida:
  292. return IconButton(
  293. onPressed: () {},
  294. icon: const Icon(Icons.coffee_rounded,
  295. color: Color.fromARGB(255, 220, 234, 254)),
  296. );
  297. case EstadoPedido.preparacion:
  298. return IconButton(
  299. onPressed: () {},
  300. icon: const Icon(Icons.kitchen_rounded,
  301. color: Color.fromARGB(255, 243, 232, 255)),
  302. );
  303. case EstadoPedido.cobrado:
  304. return IconButton(
  305. onPressed: () {},
  306. icon: const Icon(Icons.money_rounded,
  307. color: Color.fromARGB(255, 255, 238, 213)),
  308. );
  309. default:
  310. return IconButton(
  311. onPressed: () {},
  312. icon: const Icon(Icons.check_circle, color: Colors.grey),
  313. );
  314. }
  315. }
  316. }