home_screen.dart 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375
  1. import 'package:flutter/material.dart';
  2. import 'package:provider/provider.dart';
  3. import 'package:turquessa_mesas_hoster/core/models/producto_model.dart';
  4. import 'package:turquessa_mesas_hoster/mvvm/viewmodels/pedido_view_model.dart';
  5. import 'package:turquessa_mesas_hoster/mvvm/viewmodels/producto_view_model.dart';
  6. import 'package:turquessa_mesas_hoster/mvvm/views/home/carrito/carrito_screen.dart';
  7. import 'package:turquessa_mesas_hoster/utils/widgets/custom_appbar.dart';
  8. import 'package:turquessa_mesas_hoster/mvvm/views/home/categorias_navbar.dart';
  9. import 'package:turquessa_mesas_hoster/mvvm/viewmodels/home_view_model.dart';
  10. import 'package:turquessa_mesas_hoster/utils/widgets/modal_infonegaocio.dart';
  11. import 'package:turquessa_mesas_hoster/mvvm/views/home/producto/producto_screen.dart';
  12. import 'package:turquessa_mesas_hoster/utils/widgets/widgets.dart';
  13. import 'package:turquessa_mesas_hoster/utils/widgets/horario_modal.dart';
  14. const List<Map<String, dynamic>> items = [
  15. {
  16. 'nombre': 'Hamburguesa de res',
  17. 'descripcion': 'Hamburguesa de res con queso cheddar',
  18. 'precio': '\$ 120.00',
  19. 'imageUrl':
  20. 'https://cdn.pixabay.com/photo/2016/03/05/19/02/hamburger-1238246_960_720.jpg',
  21. },
  22. {
  23. 'nombre': 'Hamburguesa de pollo',
  24. 'descripcion': 'Hamburguesa de pollo con queso cheddar',
  25. 'precio': '\$ 100.00',
  26. 'imageUrl':
  27. 'https://cdn.pixabay.com/photo/2016/03/05/19/02/hamburger-1238246_960_720.jpg',
  28. },
  29. {
  30. 'nombre': 'Hamburguesa de res',
  31. 'descripcion': 'Hamburguesa de res con queso cheddar',
  32. 'precio': '\$ 120.00',
  33. 'imageUrl':
  34. 'https://cdn.pixabay.com/photo/2016/03/05/19/02/hamburger-1238246_960_720.jpg',
  35. },
  36. {
  37. 'nombre': 'Hamburguesa de pollo',
  38. 'descripcion': 'Hamburguesa de pollo con queso cheddar',
  39. 'precio': '\$ 100.00',
  40. 'imageUrl':
  41. 'https://cdn.pixabay.com/photo/2016/03/05/19/02/hamburger-1238246_960_720.jpg',
  42. },
  43. {
  44. 'nombre': 'Hamburguesa de pollo',
  45. 'descripcion': 'Hamburguesa de pollo con queso cheddar',
  46. 'precio': '\$ 100.00',
  47. 'imageUrl':
  48. 'https://cdn.pixabay.com/photo/2016/03/05/19/02/hamburger-1238246_960_720.jpg',
  49. },
  50. {
  51. 'nombre': 'Hamburguesa de pollo',
  52. 'descripcion': 'Hamburguesa de pollo con queso cheddar',
  53. 'precio': '\$ 100.00',
  54. 'imageUrl':
  55. 'https://cdn.pixabay.com/photo/2016/03/05/19/02/hamburger-1238246_960_720.jpg',
  56. },
  57. {
  58. 'nombre': 'Hamburguesa de pollo',
  59. 'descripcion': 'Hamburguesa de pollo con queso cheddar',
  60. 'precio': '\$ 100.00',
  61. 'imageUrl':
  62. 'https://cdn.pixabay.com/photo/2016/03/05/19/02/hamburger-1238246_960_720.jpg',
  63. },
  64. {
  65. 'nombre': 'Hamburguesa de pollo',
  66. 'descripcion': 'Hamburguesa de pollo con queso cheddar',
  67. 'precio': '\$ 100.00',
  68. 'imageUrl':
  69. 'https://cdn.pixabay.com/photo/2016/03/05/19/02/hamburger-1238246_960_720.jpg',
  70. },
  71. {
  72. 'nombre': 'Hamburguesa de pollo',
  73. 'descripcion': 'Hamburguesa de pollo con queso cheddar',
  74. 'precio': '\$ 100.00',
  75. 'imageUrl':
  76. 'https://cdn.pixabay.com/photo/2016/03/05/19/02/hamburger-1238246_960_720.jpg',
  77. },
  78. {
  79. 'nombre': 'Hamburguesa de pollo',
  80. 'descripcion': 'Hamburguesa de pollo con queso cheddar',
  81. 'precio': '\$ 100.00',
  82. 'imageUrl':
  83. 'https://cdn.pixabay.com/photo/2016/03/05/19/02/hamburger-1238246_960_720.jpg',
  84. },
  85. {
  86. 'nombre': 'Hamburguesa de pollo',
  87. 'descripcion': 'Hamburguesa de pollo con queso cheddar',
  88. 'precio': '\$ 100.00',
  89. 'imageUrl':
  90. 'https://cdn.pixabay.com/photo/2016/03/05/19/02/hamburger-1238246_960_720.jpg',
  91. },
  92. {
  93. 'nombre': 'Hamburguesa de pollo',
  94. 'descripcion': 'Hamburguesa de pollo con queso cheddar',
  95. 'precio': '\$ 100.00',
  96. 'imageUrl':
  97. 'https://cdn.pixabay.com/photo/2016/03/05/19/02/hamburger-1238246_960_720.jpg',
  98. },
  99. ];
  100. class HomeScreen extends StatefulWidget {
  101. const HomeScreen({Key? key}) : super(key: key);
  102. @override
  103. State<HomeScreen> createState() => _HomeScreenState();
  104. }
  105. class _HomeScreenState extends State<HomeScreen> {
  106. @override
  107. void initState() {
  108. super.initState();
  109. final homeViewModel = Provider.of<HomeViewModel>(context, listen: false);
  110. final productoViewModel =
  111. Provider.of<ProductoViewModel>(context, listen: false);
  112. setModalOffService(context);
  113. WidgetsBinding.instance.addPostFrameCallback((_) {
  114. Provider.of<ProductoViewModel>(context, listen: false)
  115. .sincronizarProductosYCategorias();
  116. homeViewModel.fetchLocalCategorias();
  117. homeViewModel.isHorarioServicio();
  118. productoViewModel.sincronizarProductos();
  119. productoViewModel.sincronizarCategorias();
  120. productoViewModel.fetchLocalAll();
  121. });
  122. }
  123. @override
  124. Widget build(BuildContext context) {
  125. final homeViewModel = Provider.of<HomeViewModel>(context, listen: false);
  126. return Scaffold(
  127. key: homeViewModel.scaffoldKey,
  128. drawer: const CustomDrawer(),
  129. bottomNavigationBar: BottomAppBar(
  130. color: Colors.black,
  131. child: Row(
  132. mainAxisAlignment: MainAxisAlignment.spaceAround,
  133. children: [
  134. IconButton(
  135. icon: const Icon(Icons.search, color: Colors.white),
  136. onPressed: () {
  137. homeViewModel.openDrawer();
  138. },
  139. ),
  140. IconButton(
  141. icon: const Icon(Icons.menu, color: Colors.white),
  142. onPressed: () {
  143. Navigator.of(context).pushNamed('carrito');
  144. },
  145. ),
  146. const Text(
  147. 'Producto',
  148. style: TextStyle(
  149. color: Colors.cyanAccent,
  150. fontWeight: FontWeight.bold,
  151. ),
  152. ),
  153. IconButton(
  154. icon: const Icon(Icons.favorite_border, color: Colors.white),
  155. onPressed: () {
  156. Navigator.of(context).pushNamed('perfil');
  157. },
  158. ),
  159. ],
  160. )),
  161. backgroundColor: Colors.white,
  162. body: CustomScrollView(
  163. slivers: [
  164. SliverAppBar(
  165. automaticallyImplyLeading: false,
  166. floating: true,
  167. expandedHeight: 200, // Ajusta la altura para acomodar la imagen
  168. flexibleSpace: FlexibleSpaceBar(
  169. background: Image.asset(
  170. 'assets/turquessa_prop.jpg',
  171. fit: BoxFit.cover,
  172. ),
  173. ),
  174. bottom: PreferredSize(
  175. preferredSize:
  176. Size.fromHeight(120), // Altura del contenido adicional
  177. child: Container(
  178. color: Color.fromARGB(255, 47, 208, 229),
  179. padding:
  180. const EdgeInsets.symmetric(horizontal: 20, vertical: 10),
  181. child: Row(
  182. children: [
  183. Container(
  184. width: 80,
  185. height: 80,
  186. decoration: BoxDecoration(
  187. color: Colors.white,
  188. borderRadius: BorderRadius.circular(12),
  189. ),
  190. child: Center(
  191. child: Image.asset('assets/logo.png'),
  192. ),
  193. ),
  194. const SizedBox(width: 20),
  195. const Text(
  196. 'Turquessa-Coffee',
  197. style: TextStyle(
  198. color: Colors.black,
  199. fontSize: 26,
  200. fontWeight: FontWeight.bold,
  201. ),
  202. ),
  203. const SizedBox(width: 15),
  204. GestureDetector(
  205. onTap: () {
  206. mostrarInformacionNegocioBottomSheet(context);
  207. },
  208. child: Container(
  209. padding: const EdgeInsets.all(8),
  210. decoration: BoxDecoration(
  211. shape: BoxShape.circle,
  212. border: Border.all(color: Colors.white, width: 2),
  213. ),
  214. child: const Icon(Icons.info,
  215. color: Colors.white, size: 20),
  216. ),
  217. ),
  218. ],
  219. ),
  220. ),
  221. ),
  222. ),
  223. SliverPersistentHeader(
  224. delegate: CategoriasSliverChild(),
  225. pinned: true,
  226. ),
  227. const SliverToBoxAdapter(
  228. child: Center(
  229. child: Text('Coffee',
  230. style: TextStyle(
  231. fontSize: 40,
  232. fontWeight: FontWeight.bold,
  233. fontStyle: FontStyle.italic,
  234. )),
  235. ),
  236. ),
  237. SliverList(
  238. delegate: SliverChildBuilderDelegate(
  239. (context, index) {
  240. return _buildBurgerItem(
  241. items[index]['nombre'],
  242. items[index]['descripcion'],
  243. items[index]['precio'],
  244. items[index]['imageUrl'],
  245. context,
  246. );
  247. },
  248. childCount: items.length,
  249. ))
  250. ],
  251. ));
  252. }
  253. }
  254. class CategoriasSliverChild extends SliverPersistentHeaderDelegate {
  255. @override
  256. Widget build(
  257. BuildContext context, double shrinkOffset, bool overlapsContent) {
  258. return CategoriasNavBar();
  259. }
  260. @override
  261. double get maxExtent => 120.0;
  262. @override
  263. double get minExtent => 120.0;
  264. @override
  265. bool shouldRebuild(covariant SliverPersistentHeaderDelegate oldDelegate) {
  266. return false;
  267. }
  268. }
  269. Widget _buildBurgerItem(String nombre, String descripcion, String precio,
  270. String imageUrl, BuildContext context) {
  271. return GestureDetector(
  272. onTap: () {
  273. Navigator.of(context).pushNamed('producto');
  274. },
  275. child: Column(
  276. children: [
  277. Padding(
  278. padding: const EdgeInsets.symmetric(vertical: 16, horizontal: 12),
  279. child: Row(
  280. crossAxisAlignment: CrossAxisAlignment.center,
  281. children: [
  282. // Imagen con borde redondeado
  283. ClipRRect(
  284. borderRadius: BorderRadius.circular(10),
  285. child: Image.network(
  286. imageUrl,
  287. width: 100,
  288. height: 100,
  289. fit: BoxFit.cover,
  290. errorBuilder: (context, error, stackTrace) {
  291. return Container(
  292. width: 100,
  293. height: 100,
  294. color: Colors.grey[300],
  295. child: const Icon(Icons.restaurant,
  296. size: 40, color: Colors.grey),
  297. );
  298. },
  299. ),
  300. ),
  301. const SizedBox(width: 16),
  302. Expanded(
  303. child: Column(
  304. crossAxisAlignment: CrossAxisAlignment.start,
  305. children: [
  306. // Título con estilo más negrita
  307. Text(
  308. nombre,
  309. style: const TextStyle(
  310. color: Colors.black,
  311. fontSize: 20,
  312. fontWeight: FontWeight.w800,
  313. ),
  314. maxLines: 1,
  315. overflow: TextOverflow.ellipsis,
  316. ),
  317. const SizedBox(height: 6),
  318. // Descripción con color gris más claro
  319. Text(
  320. descripcion,
  321. style: TextStyle(
  322. color: Colors.grey[500],
  323. fontSize: 16,
  324. fontWeight: FontWeight.w400,
  325. ),
  326. maxLines: 2,
  327. overflow: TextOverflow.ellipsis,
  328. ),
  329. const SizedBox(height: 12),
  330. // Precio con estilo destacado
  331. Text(
  332. precio ?? 'Sin Precio',
  333. style: const TextStyle(
  334. color: Colors.black,
  335. fontSize: 22,
  336. fontWeight: FontWeight.bold,
  337. ),
  338. ),
  339. ],
  340. ),
  341. ),
  342. Icon(
  343. Icons.add_circle_outline,
  344. size: 28,
  345. color: Colors.grey[700],
  346. ),
  347. ],
  348. ),
  349. ),
  350. Divider(
  351. height: 1,
  352. thickness: 1,
  353. color: Colors.grey[300],
  354. ),
  355. ],
  356. ),
  357. );
  358. }