diff --git a/lib/api/services/shared_local_storage_service.dart b/lib/api/services/shared_local_storage_service.dart index 32fb125..5355e71 100644 --- a/lib/api/services/shared_local_storage_service.dart +++ b/lib/api/services/shared_local_storage_service.dart @@ -1,6 +1,7 @@ import 'dart:convert'; import 'package:gohealth/api/interfaces/local_storage_interface.dart'; +import 'package:gohealth/api/models/product_models.dart'; import 'package:gohealth/api/models/user_models.dart'; import 'package:shared_preferences/shared_preferences.dart'; @@ -77,4 +78,65 @@ class SharedLocalStorageService implements ILocalStorage { value.clear(); }); } + + void saveProduct(ProductModels productModels) { + var shared = SharedPreferences.getInstance(); + shared.then((value) { + var products = value.getString('products'); + List list = []; + if (products != null) { + var decoded = jsonDecode(products) as List; + list = decoded.map((e) => ProductModels.fromJson(e)).toList(); + } + list.add(productModels); + value.setString('products', jsonEncode(list)); + }); + } + + Future> getAllProducts() { + var shared = SharedPreferences.getInstance(); + return shared.then((value) { + var products = value.getString('products'); + if (products != null) { + var decoded = jsonDecode(products) as List; + return decoded.map((e) => ProductModels.fromJson(e)).toList(); + } else { + throw Exception('No products found'); + } + }); + } + + getSelectedItems() { + var shared = SharedPreferences.getInstance(); + return shared.then((value) { + var products = value.getString('products'); + if (products != null) { + var decoded = jsonDecode(products) as List; + return decoded.map((e) => e.toString()).toList(); + } else { + throw Exception('No products found'); + } + }); + } + + void removeProduct(int? id) { + var shared = SharedPreferences.getInstance(); + shared.then((value) { + var products = value.getString('products'); + List list = []; + if (products != null) { + var decoded = jsonDecode(products) as List; + list = decoded.map((e) => ProductModels.fromJson(e)).toList(); + } + list.removeWhere((element) => element.id == id); + value.setString('products', jsonEncode(list)); + }); + } + + void clearCart() { + var shared = SharedPreferences.getInstance(); + shared.then((value) { + value.remove('products'); + }); + } } diff --git a/lib/src/app/home/cart/cart_page.dart b/lib/src/app/home/cart/cart_page.dart new file mode 100644 index 0000000..3ca651d --- /dev/null +++ b/lib/src/app/home/cart/cart_page.dart @@ -0,0 +1,127 @@ +import 'package:flutter/material.dart'; +import 'package:gohealth/api/models/product_models.dart'; +import 'package:gohealth/api/services/shared_local_storage_service.dart'; +import 'package:gohealth/src/app/home/home_page.dart'; +import 'package:gohealth/src/app/sessions/products/product_page.dart'; +import 'package:gohealth/src/components/header_bar.dart'; +import 'package:gohealth/src/components/side_menu.dart'; + +class CartPage extends StatefulWidget { + const CartPage({ Key? key }) : super(key: key); + + @override + _CartPageState createState() => _CartPageState(); +} + +class _CartPageState extends State { + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: const HeaderBarState(), + drawer: const SideMenu(), + bottomNavigationBar: Padding( + padding: const EdgeInsets.all(8.0), + child: FutureBuilder>( + future: SharedLocalStorageService().getAllProducts(), + builder: (context, snapshot) { + if (!snapshot.hasData || snapshot.data!.isEmpty) { + return const SizedBox.shrink(); + } else { + final total = snapshot.data!.fold( + 0.0, + (sum, item) => sum + (item.price ?? 0.0), + ); + return Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + ElevatedButton( + onPressed: () { + SharedLocalStorageService().clearCart(); + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar( + content: Text('Pedido finalizado com sucesso'), + backgroundColor: Colors.green, + duration: Duration(seconds: 2), + ), + ); + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => const Homepage())); + setState(() {}); + }, + child: const Text( + 'Finalizar Pedido', + style: TextStyle(color: Colors.white), + ), + style: ElevatedButton.styleFrom( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(6), + ), + backgroundColor: Colors.green, + ), + ), + Text( + 'Total: R\$${total.toStringAsFixed(2)}', + style: const TextStyle( + fontSize: 18, fontWeight: FontWeight.bold), + ), + ], + ); + } + }, + ), + ), + body: FutureBuilder>( + future: SharedLocalStorageService().getAllProducts(), + builder: (context, snapshot) { + if (snapshot.connectionState == ConnectionState.waiting) { + return const Center(child: CircularProgressIndicator()); + } else if (!snapshot.hasData || snapshot.data!.isEmpty) { + return const Center(child: Text('Nenhum produto no carrinho')); + } else if (snapshot.hasError) { + return Center(child: Text('Error: ${snapshot.error}')); + } else { + return ListView.builder( + itemCount: snapshot.data!.length, + itemBuilder: (context, index) { + final product = snapshot.data![index]; + return GestureDetector( + onTap: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => + ProductPage(productModels: snapshot.data![index]), + ), + ); + }, + child: Card( + margin: const EdgeInsets.all(10.0), + child: ListTile( + leading: Image.network(product.image ?? "https://via.placeholder.com/150", width: 50, height: 50, fit: BoxFit.cover), + title: Text(product.name!), + subtitle: Text( + 'Preço: R\$${product.price!.toStringAsFixed(2)}'), + trailing: IconButton( + icon: const Icon(Icons.delete), + onPressed: () { + setState(() { + snapshot.data!.removeAt(index); + SharedLocalStorageService() + .removeProduct(product.id); + }); + }, + ), + ), + ), + ); + }, + ); + } + }, + ), + ); + } +} \ No newline at end of file diff --git a/lib/src/app/login/login_page.dart b/lib/src/app/login/login_page.dart index 219d8b6..442a514 100644 --- a/lib/src/app/login/login_page.dart +++ b/lib/src/app/login/login_page.dart @@ -187,7 +187,7 @@ class LoginPageState extends State { print(user.toJson()); } - await Navigator.pushReplacement( + await Navigator.push( context, MaterialPageRoute( builder: (context) => const SplashPage(), @@ -205,7 +205,7 @@ class LoginPageState extends State { } }, child: const Text( - 'Login', + 'Logar', style: TextStyle( fontSize: 18.0, // Tamanho do texto fontWeight: FontWeight.w900, // Deixa o texto em negrito diff --git a/lib/src/app/register/register_page.dart b/lib/src/app/register/register_page.dart index 859cbb2..fdd55a5 100644 --- a/lib/src/app/register/register_page.dart +++ b/lib/src/app/register/register_page.dart @@ -235,7 +235,7 @@ class RegisterPageState extends State { print(user.toJson()); } - await Navigator.pushReplacement( + await Navigator.push( context, MaterialPageRoute( builder: (context) => const SplashPage(), @@ -260,9 +260,9 @@ class RegisterPageState extends State { } }, child: const Text( - 'Register', + 'Cadastrar', style: TextStyle( - fontSize: 18.0, // Tamanho do texto + fontSize: 12.0, // Tamanho do texto fontWeight: FontWeight.w900, // Deixa o texto em negrito ), ), diff --git a/lib/src/app/sessions/final_session.dart b/lib/src/app/sessions/final_session.dart index 40e1fc6..3b34d44 100644 --- a/lib/src/app/sessions/final_session.dart +++ b/lib/src/app/sessions/final_session.dart @@ -48,7 +48,7 @@ class FinalSessionState extends State { children: [ TextButton( onPressed: () { - Navigator.pushReplacement( + Navigator.push( context, MaterialPageRoute( builder: (context) => const SecondSessionPage())); @@ -92,7 +92,7 @@ class FinalSessionState extends State { ), TextButton( onPressed: () { - Navigator.pushReplacement( + Navigator.push( context, MaterialPageRoute( builder: (context) => const FinalSessionPage())); @@ -135,7 +135,7 @@ class FinalSessionState extends State { onPressed: () => { for (var item in itemSelected) {_viewModel.addProductInUser(item, _id!)}, - Navigator.pushReplacement( + Navigator.push( context, MaterialPageRoute( builder: (context) => const Homepage())) diff --git a/lib/src/app/sessions/first_session.dart b/lib/src/app/sessions/first_session.dart index be09bb0..eb8ff01 100644 --- a/lib/src/app/sessions/first_session.dart +++ b/lib/src/app/sessions/first_session.dart @@ -48,7 +48,7 @@ class FirstSessionState extends State { ), TextButton( onPressed: () { - Navigator.pushReplacement( + Navigator.push( context, MaterialPageRoute( builder: (context) => const SecondSessionPage())); diff --git a/lib/src/app/sessions/products/product_page.dart b/lib/src/app/sessions/products/product_page.dart index d393b1d..8f2d814 100644 --- a/lib/src/app/sessions/products/product_page.dart +++ b/lib/src/app/sessions/products/product_page.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; import 'package:gohealth/api/models/product_models.dart'; +import 'package:gohealth/api/services/shared_local_storage_service.dart'; import 'image_carousel.dart'; import 'product_details.dart'; import 'description_section.dart'; @@ -44,7 +45,18 @@ class ProductState extends State { bottomNavigationBar: Padding( padding: const EdgeInsets.all(16.0), child: ElevatedButton( - onPressed: () {}, + onPressed: () { + // Salvar os dados do produto no carrinho atráves do storage + SharedLocalStorageService().saveProduct(widget.productModels); + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text('Produto adicionado ao carrinho'), + backgroundColor: Colors.green, + duration: Duration(seconds: 2), + ), + ); + Navigator.pop(context); + }, child: Text('Adicionar ao carrinho'), style: ElevatedButton.styleFrom( padding: EdgeInsets.symmetric(vertical: 16), diff --git a/lib/src/app/sessions/second_session.dart b/lib/src/app/sessions/second_session.dart index 9131f6b..755ccea 100644 --- a/lib/src/app/sessions/second_session.dart +++ b/lib/src/app/sessions/second_session.dart @@ -18,7 +18,7 @@ class SecondSessionState extends State { children: [ TextButton( onPressed: () { - Navigator.pushReplacement( + Navigator.push( context, MaterialPageRoute( builder: (context) => const FirstSessionPage())); @@ -63,7 +63,7 @@ class SecondSessionState extends State { ), TextButton( onPressed: () { - Navigator.pushReplacement( + Navigator.push( context, MaterialPageRoute( builder: (context) => const FinalSessionPage())); diff --git a/lib/src/app/splash_page.dart b/lib/src/app/splash_page.dart index 98b77c6..a682c75 100644 --- a/lib/src/app/splash_page.dart +++ b/lib/src/app/splash_page.dart @@ -37,14 +37,14 @@ class SplashPageState extends State { Future.delayed(const Duration(seconds: 2), () { if (isLogged) { if (isFirstSession) { - Navigator.pushReplacement( + Navigator.push( context, MaterialPageRoute( builder: (context) => const FirstSessionPage(), ), ); } else { - Navigator.pushReplacement( + Navigator.push( context, MaterialPageRoute( builder: (context) => const Homepage(), @@ -52,7 +52,7 @@ class SplashPageState extends State { ); } } else { - Navigator.pushReplacement( + Navigator.push( context, MaterialPageRoute( builder: (context) => const LoginPage(), diff --git a/lib/src/components/header_bar.dart b/lib/src/components/header_bar.dart index b3ba0d8..29ed641 100644 --- a/lib/src/components/header_bar.dart +++ b/lib/src/components/header_bar.dart @@ -1,6 +1,7 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:gohealth/api/services/shared_local_storage_service.dart'; +import 'package:gohealth/src/app/home/cart/cart_page.dart'; class HeaderBarState extends StatefulWidget implements PreferredSizeWidget { const HeaderBarState({super.key}); @@ -84,6 +85,10 @@ class _HeaderBarState extends State { ], ), actions: [ + IconButton(onPressed: () { + Navigator.push( + context, MaterialPageRoute(builder: (BuildContext context) => const CartPage())); + }, icon: const Icon(Icons.shopping_cart)), IconButton( icon: const Icon(Icons.notifications), onPressed: () { diff --git a/lib/src/components/side_menu.dart b/lib/src/components/side_menu.dart index e256fc4..e5f2fb2 100644 --- a/lib/src/components/side_menu.dart +++ b/lib/src/components/side_menu.dart @@ -67,7 +67,7 @@ class SideMenuState extends State { ListTile( title: const Text('Tela Inicial', style: textStyle), onTap: () { - Navigator.pushReplacement( + Navigator.push( context, MaterialPageRoute( builder: (BuildContext context) => const Homepage())); @@ -88,7 +88,7 @@ class SideMenuState extends State { ListTile( title: const Text('Maps', style: textStyle), onTap: () async { - Navigator.pushReplacement( + Navigator.push( context, MaterialPageRoute( builder: (BuildContext context) => const MapsPage())); @@ -101,7 +101,7 @@ class SideMenuState extends State { await prefs.logout(); _repository.clearProfile(); - Navigator.pushReplacement( + Navigator.push( context, MaterialPageRoute( builder: (BuildContext context) => const SplashPage())); diff --git a/pubspec.lock b/pubspec.lock index 0b2a137..207e711 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -609,10 +609,10 @@ packages: dependency: transitive description: name: vm_service - sha256: f652077d0bdf60abe4c1f6377448e8655008eef28f128bc023f7b5e8dfeb48fc + sha256: "5c5f338a667b4c644744b661f309fb8080bb94b18a7e91ef1dbd343bed00ed6d" url: "https://pub.dev" source: hosted - version: "14.2.4" + version: "14.2.5" web: dependency: transitive description: