diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index d0cd86a..d33c44a 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -30,5 +30,7 @@ + diff --git a/assets/images/Automated Grass cutter final version 8-3-2023 (1) final.pptx b/assets/images/Automated Grass cutter final version 8-3-2023 (1) final.pptx new file mode 100644 index 0000000..22c620a Binary files /dev/null and b/assets/images/Automated Grass cutter final version 8-3-2023 (1) final.pptx differ diff --git a/assets/images/Automated Grass cutter final version 8-3-2023 (1).pptx b/assets/images/Automated Grass cutter final version 8-3-2023 (1).pptx index 1bb57e2..bf79c23 100644 Binary files a/assets/images/Automated Grass cutter final version 8-3-2023 (1).pptx and b/assets/images/Automated Grass cutter final version 8-3-2023 (1).pptx differ diff --git a/assets/images/grass-close-up.png b/assets/images/grass-close-up.png new file mode 100644 index 0000000..fb24ad1 Binary files /dev/null and b/assets/images/grass-close-up.png differ diff --git a/assets/images/location-pin.png b/assets/images/location-pin.png new file mode 100644 index 0000000..4eb0579 Binary files /dev/null and b/assets/images/location-pin.png differ diff --git a/bug/pubspec.lock b/bug/pubspec.lock index 56c9d41..6d96d52 100644 --- a/bug/pubspec.lock +++ b/bug/pubspec.lock @@ -5,49 +5,56 @@ packages: dependency: transitive description: name: async - url: "https://pub.dartlang.org" + sha256: bfe67ef28df125b7dddcea62755991f807aa39a2492a23e1550161692950bbe0 + url: "https://pub.dev" source: hosted - version: "2.9.0" + version: "2.10.0" boolean_selector: dependency: transitive description: name: boolean_selector - url: "https://pub.dartlang.org" + sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" + url: "https://pub.dev" source: hosted - version: "2.1.0" + version: "2.1.1" characters: dependency: transitive description: name: characters - url: "https://pub.dartlang.org" + sha256: e6a326c8af69605aec75ed6c187d06b349707a27fbff8222ca9cc2cff167975c + url: "https://pub.dev" source: hosted version: "1.2.1" clock: dependency: transitive description: name: clock - url: "https://pub.dartlang.org" + sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf + url: "https://pub.dev" source: hosted version: "1.1.1" collection: dependency: transitive description: name: collection - url: "https://pub.dartlang.org" + sha256: cfc915e6923fe5ce6e153b0723c753045de46de1b4d63771530504004a45fae0 + url: "https://pub.dev" source: hosted - version: "1.16.0" + version: "1.17.0" cupertino_icons: dependency: "direct main" description: name: cupertino_icons - url: "https://pub.dartlang.org" + sha256: e35129dc44c9118cee2a5603506d823bab99c68393879edb440e0090d07586be + url: "https://pub.dev" source: hosted version: "1.0.5" fake_async: dependency: transitive description: name: fake_async - url: "https://pub.dartlang.org" + sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78" + url: "https://pub.dev" source: hosted version: "1.3.1" flutter: @@ -59,7 +66,8 @@ packages: dependency: "direct dev" description: name: flutter_lints - url: "https://pub.dartlang.org" + sha256: aeb0b80a8b3709709c9cc496cdc027c5b3216796bc0af0ce1007eaf24464fd4c + url: "https://pub.dev" source: hosted version: "2.0.1" flutter_test: @@ -67,39 +75,52 @@ packages: description: flutter source: sdk version: "0.0.0" + js: + dependency: transitive + description: + name: js + sha256: "5528c2f391ededb7775ec1daa69e65a2d61276f7552de2b5f7b8d34ee9fd4ab7" + url: "https://pub.dev" + source: hosted + version: "0.6.5" lints: dependency: transitive description: name: lints - url: "https://pub.dartlang.org" + sha256: "5e4a9cd06d447758280a8ac2405101e0e2094d2a1dbdd3756aec3fe7775ba593" + url: "https://pub.dev" source: hosted version: "2.0.1" matcher: dependency: transitive description: name: matcher - url: "https://pub.dartlang.org" + sha256: "16db949ceee371e9b99d22f88fa3a73c4e59fd0afed0bd25fc336eb76c198b72" + url: "https://pub.dev" source: hosted - version: "0.12.12" + version: "0.12.13" material_color_utilities: dependency: transitive description: name: material_color_utilities - url: "https://pub.dartlang.org" + sha256: d92141dc6fe1dad30722f9aa826c7fbc896d021d792f80678280601aff8cf724 + url: "https://pub.dev" source: hosted - version: "0.1.5" + version: "0.2.0" meta: dependency: transitive description: name: meta - url: "https://pub.dartlang.org" + sha256: "6c268b42ed578a53088d834796959e4a1814b5e9e164f147f580a386e5decf42" + url: "https://pub.dev" source: hosted version: "1.8.0" path: dependency: transitive description: name: path - url: "https://pub.dartlang.org" + sha256: db9d4f58c908a4ba5953fcee2ae317c94889433e5024c27ce74a37f94267945b + url: "https://pub.dev" source: hosted version: "1.8.2" sky_engine: @@ -111,50 +132,57 @@ packages: dependency: transitive description: name: source_span - url: "https://pub.dartlang.org" + sha256: dd904f795d4b4f3b870833847c461801f6750a9fa8e61ea5ac53f9422b31f250 + url: "https://pub.dev" source: hosted - version: "1.9.0" + version: "1.9.1" stack_trace: dependency: transitive description: name: stack_trace - url: "https://pub.dartlang.org" + sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5 + url: "https://pub.dev" source: hosted - version: "1.10.0" + version: "1.11.0" stream_channel: dependency: transitive description: name: stream_channel - url: "https://pub.dartlang.org" + sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8" + url: "https://pub.dev" source: hosted - version: "2.1.0" + version: "2.1.1" string_scanner: dependency: transitive description: name: string_scanner - url: "https://pub.dartlang.org" + sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" + url: "https://pub.dev" source: hosted - version: "1.1.1" + version: "1.2.0" term_glyph: dependency: transitive description: name: term_glyph - url: "https://pub.dartlang.org" + sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 + url: "https://pub.dev" source: hosted version: "1.2.1" test_api: dependency: transitive description: name: test_api - url: "https://pub.dartlang.org" + sha256: ad540f65f92caa91bf21dfc8ffb8c589d6e4dc0c2267818b4cc2792857706206 + url: "https://pub.dev" source: hosted - version: "0.4.12" + version: "0.4.16" vector_math: dependency: transitive description: name: vector_math - url: "https://pub.dartlang.org" + sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" + url: "https://pub.dev" source: hosted - version: "2.1.2" + version: "2.1.4" sdks: dart: ">=2.18.5 <3.0.0" diff --git a/lib/main.dart b/lib/main.dart index c18cfb1..027e4d3 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -3,7 +3,6 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:graduation_project/layout/app_layout/app_layout.dart'; - import 'package:graduation_project/modules/home-page/home-layout.dart'; import 'package:graduation_project/modules/lets-get-started/lets_get_started_screen.dart'; import 'package:graduation_project/modules/login/cubit/cubit.dart'; @@ -13,7 +12,6 @@ import 'package:graduation_project/modules/on_boarding/on_boarding_screen.dart'; import 'package:graduation_project/modules/registration/cubit/cubit.dart'; import 'package:graduation_project/modules/registration/registration_screen.dart'; import 'package:graduation_project/modules/splash/splash_screen.dart'; - import 'package:graduation_project/shared/bloc_observer.dart'; import 'package:firebase_core/firebase_core.dart'; import 'package:graduation_project/shared/constants/constants.dart'; @@ -33,7 +31,6 @@ void main() async { Bloc.observer = MyBlocObserver(); - await CacheHelper.init(); Bloc.observer = MyBlocObserver(); @@ -54,15 +51,11 @@ void main() async { else { widget = LetsGetStartedScreen(); } - - runApp(MyApp( startWidget: widget, )); } - - class MyApp extends StatelessWidget { final Widget startWidget; MyApp({ @@ -85,11 +78,12 @@ class MyApp extends StatelessWidget { theme: ThemeData( appBarTheme: AppBarTheme( systemOverlayStyle: SystemUiOverlayStyle( - statusBarColor: Colors.white, + statusBarColor: Colors.grey, ) ), ), home: SplashScreen(startWidget: startWidget,), + //SplashScreen(startWidget: startWidget,), ); }, ), diff --git a/lib/modules/aboutus_screen/aboutus_screen.dart b/lib/modules/aboutus_screen/aboutus_screen.dart new file mode 100644 index 0000000..126c26b --- /dev/null +++ b/lib/modules/aboutus_screen/aboutus_screen.dart @@ -0,0 +1,212 @@ +import 'package:flutter/material.dart'; + +import '../../layout/app_layout/app_layout.dart'; + +class AboutUs extends StatelessWidget { + const AboutUs({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + backgroundColor: Colors.white, + elevation: 0.00, + centerTitle:true , + title:const Text( + 'About Us', + style: TextStyle( + fontSize: 20, + fontWeight: FontWeight.bold, + color: Color(0xFF4d4d4d), + ), + ) , + leading: IconButton( + icon: const Icon( + Icons.arrow_back_ios_new_rounded, + color: Color(0xFF063C14), + size: 25, + ) , + onPressed:(){ + Navigator.push( + context, + MaterialPageRoute(builder: (context) => AppLayout()), + ); + } , + ) , + + ) , + body:SingleChildScrollView( + physics: BouncingScrollPhysics(), + child: Column( + children: [ + Padding( + padding: const EdgeInsets.all(20.0), + child: SingleChildScrollView( + scrollDirection: Axis.horizontal, + physics: NeverScrollableScrollPhysics(), + child: Row( + children: [ + Column( + children: [ + Text( + 'Our Vision', + style: TextStyle( + fontWeight: FontWeight.bold, + fontSize: 30, + ), + ), + Container( + width: 200, + height: 200, + child: SingleChildScrollView( + child: Column( + children: [ + Padding( + padding: const EdgeInsets.all(10.0), + child: Text( + 'At [Your Company Name], we envision a future where lawn care is effortless, eco-friendly, and smart. Our commitment to sustainability and innovation drives us to create cutting-edge solutions that not only simplify our customers\' lives but also contribute to a greener planet\. By harnessing the power of solar energy and automation, we aim to revolutionize the way people maintain their outdoor spaces', + style: TextStyle( + fontSize: 15, + color: Colors.grey + ), + ), + ), + ], + ), + ), + ), + ], + ), + SizedBox( + width: 20, + ), + SizedBox( + height: 250, + width: 150, + child: Image( + image: NetworkImage( + 'https://images.unsplash.com/photo-1527118732049-c88155f2107c?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxzZWFyY2h8Mnx8Z2lhbnQlMjBwYW5kYXxlbnwwfHwwfHw%3D&auto=format&fit=crop&w=500&q=60' + // 'https://flutter.github.io/assets-for-api-docs/assets/widgets/owl.jpg', + ), + ), + ), + ], + ), + ), + ), + Padding( + padding: const EdgeInsets.all(20.0), + child: SingleChildScrollView( + scrollDirection: Axis.horizontal, + physics: NeverScrollableScrollPhysics(), + child: Row( + children: [ + SizedBox( + height: 250, + width: 150, + child: Image( + image: NetworkImage( + 'https://images.unsplash.com/photo-1527118732049-c88155f2107c?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxzZWFyY2h8Mnx8Z2lhbnQlMjBwYW5kYXxlbnwwfHwwfHw%3D&auto=format&fit=crop&w=500&q=60' + // 'https://flutter.github.io/assets-for-api-docs/assets/widgets/owl.jpg', + ), + ), + ), + SizedBox( + width: 20, + ), + Column( + children: [ + Text( + 'Our Vision', + style: TextStyle( + fontWeight: FontWeight.bold, + fontSize: 30, + ), + ), + Container( + width: 200, + height: 200, + child: SingleChildScrollView( + child: Column( + children: [ + Padding( + padding: const EdgeInsets.all(10.0), + child: Text( + 'At [Your Company Name], we envision a future where lawn care is effortless, eco-friendly, and smart. Our commitment to sustainability and innovation drives us to create cutting-edge solutions that not only simplify our customers\' lives but also contribute to a greener planet\. By harnessing the power of solar energy and automation, we aim to revolutionize the way people maintain their outdoor spaces', + style: TextStyle( + fontSize: 15, + color: Colors.grey + ), + ), + ), + ], + ), + ), + ), + ], + ), + ], + ), + ), + ), + Padding( + padding: const EdgeInsets.all(20.0), + child: SingleChildScrollView( + scrollDirection: Axis.horizontal, + physics: NeverScrollableScrollPhysics(), + child: Row( + children: [ + Column( + children: [ + Text( + 'Our Vision', + style: TextStyle( + fontWeight: FontWeight.bold, + fontSize: 30, + ), + ), + Container( + width: 200, + height: 200, + child: SingleChildScrollView( + child: Column( + children: [ + Padding( + padding: const EdgeInsets.all(10.0), + child: Text( + 'At [Your Company Name], we envision a future where lawn care is effortless, eco-friendly, and smart. Our commitment to sustainability and innovation drives us to create cutting-edge solutions that not only simplify our customers\' lives but also contribute to a greener planet\. By harnessing the power of solar energy and automation, we aim to revolutionize the way people maintain their outdoor spaces', + style: TextStyle( + fontSize: 15, + color: Colors.grey + ), + ), + ), + ], + ), + ), + ), + ], + ), + SizedBox( + width: 20, + ), + SizedBox( + height: 250, + width: 150, + child: Image( + image: NetworkImage( + 'https://images.unsplash.com/photo-1527118732049-c88155f2107c?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxzZWFyY2h8Mnx8Z2lhbnQlMjBwYW5kYXxlbnwwfHwwfHw%3D&auto=format&fit=crop&w=500&q=60' + // 'https://flutter.github.io/assets-for-api-docs/assets/widgets/owl.jpg', + ), + ), + ), + ], + ), + ), + ), + ], + ), + ), + ); + } +} diff --git a/lib/modules/change_password_screen/change_password_screen.dart b/lib/modules/change_password_screen/change_password_screen.dart new file mode 100644 index 0000000..10d7751 --- /dev/null +++ b/lib/modules/change_password_screen/change_password_screen.dart @@ -0,0 +1,369 @@ +import 'package:conditional_builder_null_safety/conditional_builder_null_safety.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:graduation_project/layout/app_layout/app_layout.dart'; +import 'package:graduation_project/modules/change_password_screen/cubit/states.dart'; +import 'package:graduation_project/modules/login/cubit/cubit.dart'; +import 'package:graduation_project/modules/login/login_screen.dart'; +//import 'package:graduation_project/modules/registration/cubit/states.dart'; +import 'package:hexcolor/hexcolor.dart'; +import 'package:roundcheckbox/roundcheckbox.dart'; + +import '../../shared/components/components.dart'; +import 'cubit/cubit.dart'; + +class ChangePasswordScreen extends StatefulWidget { + @override + State createState() => _ChangePasswordScreenState(); +} + +class _ChangePasswordScreenState extends State { + var emailController = TextEditingController(); + + var passwordController = TextEditingController(); + + var confirmPasswordController = TextEditingController(); + + var nameController = TextEditingController(); + + var phoneNumberController = TextEditingController(); + + var addressController = TextEditingController(); + + bool termsChecked = false; + + String termsErrorText = ""; + String confirmPasswordErrorText = ""; + + var formKey = GlobalKey(); + + @override + Widget build(BuildContext context) { + return BlocProvider( + create: (context) => ChangePasswordCubit(), + child: BlocConsumer( + listener: (context, state) { + if(state is CreateUserSuccessState){ + navigateAndFinish(context, AppLayout()); + } + if(state is ChangePasswordErrorState) + { + showToast(errorMessage: state.error, state: ToastStates.ERROR); + } + if(state is ChangePasswordSuccessState){ + ChangePasswordCubit.get(context).saveChangePasswordData(uId: state.uId); + } + }, + builder: (context, state) { + return Scaffold( + + backgroundColor: Colors.white, + body: Container( + alignment: Alignment.center, + color: Colors.white, + width: double.infinity, + child: Form( + key: formKey, + child: Padding( + padding: const EdgeInsets.fromLTRB(0, 75.0, 0, 0), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + // defaultTextFormField( + // textController: nameController, + // hintText: 'Name', + // keyboardType: TextInputType.name, + // validator: (value) { + // if (value?.isEmpty == true) { + // return "Name cannot be empty"; + // } else { + // return null; + // } + // }, + // ), + // SizedBox( + // height: 18.0, + // ), + // defaultTextFormField( + // textController: emailController, + // hintText: "Email", + // keyboardType: TextInputType.emailAddress, + // validator: (value) { + // List mail = [ + // "gmail", + // "hotmail", + // "outlook", + // "yahoo" + // ]; + // if (value?.isEmpty == true) { + // return "Email cannot be empty"; + // } + // else if( + // value?.substring(value.indexOf("@")+1) != "gmail.com" && + // value?.substring(value.indexOf("@")+1) != "yahoo.com" && + // value?.substring(value.indexOf("@")+1) != "outlook.com" && + // value?.substring(value.indexOf("@")+1) != "hotmail.com" + // ){ + // showToast(errorMessage: "Email address is invalid.", state: ToastStates.ERROR); + // return "Invalid email address"; + // } + // else { + // print("Email: ${value?.substring(value.indexOf("@")+1)}"); + // return null; + // } + // }, + // ), + // SizedBox( + // height: 18.0, + // ), + // defaultTextFormField( + // textController: phoneNumberController, + // hintText: "Phone Number", + // keyboardType: TextInputType.phone, + // validator: (value) { + // if (value?.isEmpty == true) { + // return "Phone number cannot be empty"; + // } else { + // return null; + // } + // }, + // ), + // SizedBox( + // height: 18.0, + // ), + // defaultTextFormField( + // textController: addressController, + // hintText: "Address", + // keyboardType: TextInputType.streetAddress, + // validator: (value) { + // if (value?.isEmpty == true) { + // return "Address cannot be empty"; + // } else { + // return null; + // } + // }, + // ), + SizedBox( + height: 18.0, + ), + defaultTextFormField( + textController: passwordController, + hintText: "Password", + suffix: ChangePasswordCubit.get(context).suffix, + suffixPressed: (){ + ChangePasswordCubit.get(context).changePasswordVisibility(); + }, + keyboardType: TextInputType.visiblePassword, + validator: (value) { + if (value?.isEmpty == true) { + return "Password cannot be empty"; + } + else if(value!.length < 6){ + return "Password is too short"; + } + else { + return null; + } + }, + isPassword: ChangePasswordCubit.get(context).isPassword, + ), + SizedBox( + height: 18.0, + ), + defaultTextFormField( + textController: confirmPasswordController, + hintText: "Confirm Password", + keyboardType: TextInputType.visiblePassword, + validator: (value) { + if (value?.isEmpty == true) { + return "Password cannot be empty"; + } + else if(passwordController.text != confirmPasswordController.text){ + return "Passwords don't match"; + } + else { + return null; + } + }, + isPassword: true, + ), + Padding( + padding: const EdgeInsets.fromLTRB(0, 25, 0, 0), + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + // InkWell( + // onTap: () { + // setState(() { + // termsChecked = !termsChecked; + // }); + // }, + // child: termsChecked + // ? Icon( + // Icons.check_circle, + // color: HexColor("#00A429"), + // size: 20, + // ) + // : Icon( + // Icons.circle_outlined, + // color: HexColor("#00A429"), + // size: 20, + // ), + // ), + // Padding( + // padding: const EdgeInsets.fromLTRB(5, 2, 0, 0), + // child: Column( + // crossAxisAlignment: CrossAxisAlignment.start, + // children: [ + // Text( + // "I agree with the Terms of Service & Privacy Policy", + // style: TextStyle( + // fontSize: 13, + // ), + // ), + // Padding( + // padding: + // const EdgeInsets.fromLTRB(0, 5, 0, 0), + // child: Text( + // termsErrorText, + // style: TextStyle( + // color: Colors.red, + // fontSize: 11, + // ), + // ), + // ), + // ], + // ), + // ), + ], + ), + ), + SizedBox( + height: 50.0, + ), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + ConditionalBuilder( + condition: state is !ChangePasswordLoadingState, + builder: (context) => defaultLogInOutButton( + bColor: const Color(0xffc51a01), + wid: 140, + buttonText: 'Cancel', + onPressed: () { + navigateTo(context, LoginScreen()); + }, + ), + fallback: (context) => Center(child: CircularProgressIndicator( + valueColor: AlwaysStoppedAnimation(HexColor("#00A429")), + ),) + ), + SizedBox(width: 20,), + ConditionalBuilder( + condition: state is !ChangePasswordLoadingState, + builder: (context) => defaultLogInOutButton( + wid: 140, + buttonText: 'Confirm', + onPressed: () { + if (formKey.currentState?.validate() == true && + termsChecked == true) { + ChangePasswordCubit.get(context).userChangePassword( + name: nameController.text, + email: emailController.text, + password: passwordController.text, + phone: phoneNumberController.text, + ); + } + if (termsChecked == false) { + setState(() { + termsErrorText = + "Terms of service should be accepted"; + }); + } else { + setState(() { + termsErrorText = ""; + }); + } + }, + ), + fallback: (context) => Center(child: CircularProgressIndicator( + valueColor: AlwaysStoppedAnimation(HexColor("#00A429")), + ),) + ), + ], + ), + + // defaultLogInOutButton( + // buttonText: 'Sign up', + // onPressed: () { + // if (formKey.currentState?.validate() == true && + // termsChecked == true) { + // ChangePasswordCubit.get(context).userChangePassword( + // name: nameController.text, + // email: emailController.text, + // password: passwordController.text, + // phone: phoneNumberController.text, + // ); + // } + // if (termsChecked == false) { + // setState(() { + // termsErrorText = + // "Terms of service should be accepted"; + // }); + // } else { + // setState(() { + // termsErrorText = ""; + // }); + // } + // }, + // ), + SizedBox( + height: 70.0, + ), + Padding( + padding: const EdgeInsets.fromLTRB(65, 0, 0, 0), + child: Align( + alignment: Alignment.centerLeft, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + "Have an account?", + style: TextStyle( + color: HexColor("#87888F"), + fontSize: 13, + ), + ), + TextButton( + onPressed: () { + navigateAndFinish(context, LoginScreen()); + }, + child: Text( + "Sign in", + style: TextStyle( + color: HexColor("#000000"), + fontSize: 13, + ), + ), + style: TextButton.styleFrom( + padding: EdgeInsets.all(0), + alignment: Alignment.centerLeft, + ), + ), + ], + ), + ), + ), + ], + ), + ), + ), + ), + ); + }, + ), + ); + } +} diff --git a/lib/modules/change_password_screen/cubit/cubit.dart b/lib/modules/change_password_screen/cubit/cubit.dart new file mode 100644 index 0000000..f9a6b4a --- /dev/null +++ b/lib/modules/change_password_screen/cubit/cubit.dart @@ -0,0 +1,140 @@ +import 'package:bloc/bloc.dart'; +import 'package:cloud_firestore/cloud_firestore.dart'; +import 'package:firebase_auth/firebase_auth.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:graduation_project/models/user_model.dart'; +import 'package:graduation_project/modules/change_password_screen/cubit/states.dart'; +//import 'package:graduation_project/modules/registration/cubit/states.dart'; + +import '../../../layout/app_layout/app_layout.dart'; +import '../../../shared/components/components.dart'; +import '../../../shared/network/end_points.dart'; +import '../../../shared/network/local/cache_helper.dart'; +import '../../../shared/network/remote/dio_helper.dart'; + + +class ChangePasswordCubit extends Cubit { + ChangePasswordCubit() : super(ChangePasswordInitialState()); + + static ChangePasswordCubit get(context) => BlocProvider.of(context); + + void userChangePassword({ + required String name, + required String email, + required String password, + required String phone, + }) { + emit(ChangePasswordLoadingState()); + + FirebaseAuth.instance + .createUserWithEmailAndPassword( + email: email, + password: password + ) + .then((value){ + print(value.credential); + createUser( + name: name, + email: email, + phone: phone, + uId: value.user?.uid, + ); + }) + .catchError((error){ + emit(ChangePasswordErrorState(getMessageFromErrorCode(error.code))); + print(error.toString()); + }); + } + + String getMessageFromErrorCode(error) { + switch (error) { + case "ERROR_EMAIL_ALREADY_IN_USE": + case "account-exists-with-different-credential": + case "email-already-in-use": + return "Email already used. Go to login page."; + break; + case "ERROR_WRONG_PASSWORD": + case "wrong-password": + return "Wrong email/password combination."; + break; + case "ERROR_USER_NOT_FOUND": + case "user-not-found": + return "No user found with this email."; + break; + case "ERROR_USER_DISABLED": + case "user-disabled": + return "User disabled."; + break; + case "ERROR_TOO_MANY_REQUESTS": + case "operation-not-allowed": + case "too-many-requests": + return "Too many requests to log into this account."; + break; + case "ERROR_OPERATION_NOT_ALLOWED": + case "operation-not-allowed": + return "Server error, please try again later."; + break; + case "ERROR_INVALID_EMAIL": + case "invalid-email": + return "Email address is invalid."; + break; + default: + return "Registration failed. Please try again."; + break; + } + } + + void createUser({ + required String name, + required String email, + required String phone, + required String? uId, + }){ + UserModel model = UserModel( + name: name, + email: email, + phone: phone, + uId: uId, + isEmailVerified: false, + ); + FirebaseFirestore.instance + .collection('users') + .doc(uId) + .set(model.toMap()) + .then((value){ + emit(ChangePasswordSuccessState(uId)); + emit(CreateUserSuccessState()); + }) + .catchError((error){ + print(error.toString()); + emit(CreateUserErrorState(error.toString())); + }); + } + + void saveChangePasswordData({required String? uId, context}){ + emit(SaveChangePasswordDataLoading()); + + CacheHelper.saveData( + key: 'uId', + value: uId, + ).then((value){ + // navigateAndFinish(context, AppLayout()); + emit(SaveChangePasswordDataSuccess()); + }).catchError((error){ + emit(SaveChangePasswordDataError(error.toString())); + }); + } + + IconData suffix = Icons.visibility_outlined; + bool isPassword = true; + + void changePasswordVisibility(){ + isPassword = !isPassword; + + suffix = isPassword ? Icons.visibility_outlined: Icons.visibility_off_outlined; + + emit(ChangePasswordVisibilityState()); + } +} diff --git a/lib/modules/change_password_screen/cubit/states.dart b/lib/modules/change_password_screen/cubit/states.dart new file mode 100644 index 0000000..102746b --- /dev/null +++ b/lib/modules/change_password_screen/cubit/states.dart @@ -0,0 +1,36 @@ +abstract class ChangePasswordStates {} + +class ChangePasswordInitialState extends ChangePasswordStates{} + +class ChangePasswordLoadingState extends ChangePasswordStates{} + +class ChangePasswordSuccessState extends ChangePasswordStates{ + final String? uId; + + ChangePasswordSuccessState(this.uId); +} + +class ChangePasswordErrorState extends ChangePasswordStates{ + final String error; + + ChangePasswordErrorState(this.error); +} +class CreateUserSuccessState extends ChangePasswordStates{} + +class CreateUserErrorState extends ChangePasswordStates{ + final String error; + + CreateUserErrorState(this.error); +} + +class ChangePasswordVisibilityState extends ChangePasswordStates{} + +class SaveChangePasswordDataSuccess extends ChangePasswordStates{} + +class SaveChangePasswordDataLoading extends ChangePasswordStates{} + +class SaveChangePasswordDataError extends ChangePasswordStates{ + final String error; + + SaveChangePasswordDataError(this.error); +} \ No newline at end of file diff --git a/lib/modules/connection/bluetooth_manager.dart b/lib/modules/connection/bluetooth_manager.dart new file mode 100644 index 0000000..afd5993 --- /dev/null +++ b/lib/modules/connection/bluetooth_manager.dart @@ -0,0 +1,55 @@ +// import 'package:flutter/material.dart'; +// import 'package:flutter_blue_plus/flutter_blue_plus.dart'; +// +// +// class BluetoothManager { +// FlutterBlue _flutterBlue = FlutterBlue.instance; +// BluetoothDevice _esp32Device; +// late BluetoothCharacteristic _characteristic; +// +// Future scanAndConnect() async { +// _flutterBlue.startScan(timeout: Duration(seconds: 5)); +// +// _flutterBlue.scanResults.listen((List results) { +// for (ScanResult result in results) { +// if (result.device.name == 'ESP32') { +// _esp32Device = result.device; +// break; +// } +// } +// }); +// +// _flutterBlue.stopScan(); +// +// if (_esp32Device != null) { +// await _esp32Device.connect(); +// List services = await _esp32Device.discoverServices(); +// for (BluetoothService service in services) { +// if (service.uuid.toString() == 'YOUR_SERVICE_UUID') { +// _characteristic = service.characteristics.firstWhere( +// (c) => c.uuid.toString() == 'YOUR_CHARACTERISTIC_UUID'); +// break; +// } +// } +// } +// } +// +// Future sendData(String data) async { +// if (_characteristic != null) { +// await _characteristic.write(utf8.encode(data)); +// } +// } +// +// Stream> receiveData() { +// if (_characteristic != null) { +// return _characteristic.value; +// } +// return null; +// } +// +// Future disconnect() async { +// if (_esp32Device != null) { +// await _esp32Device.disconnect(); +// } +// } +// } \ No newline at end of file diff --git a/lib/modules/connection/connection_screen.dart b/lib/modules/connection/connection_screen.dart new file mode 100644 index 0000000..1504f20 --- /dev/null +++ b/lib/modules/connection/connection_screen.dart @@ -0,0 +1,196 @@ + +import 'dart:async'; +import 'dart:convert'show utf8; +import 'package:flutter/material.dart'; +import 'package:flutter_blue_plus/flutter_blue_plus.dart'; +import 'package:graduation_project/modules/settings/settings_screen.dart'; +import 'package:graduation_project/shared/components/components.dart'; + +class WifiSetter extends StatefulWidget { + @override + _WifiSetterState createState() => _WifiSetterState(); +} + +class _WifiSetterState extends State { + final String SERVICE_UUID = "7A0247E7-8E88-409B-A959-AB5092DDB03E"; + final String CHARACTERISTIC_UUID = "beb5483e-36e1-4688-b7f5-ea07361b26a8"; + final String TARGET_DEVICE_NAME = "ESP32"; + + FlutterBluePlus flutterBlue = FlutterBluePlus.instance; + StreamSubscription? scanSubscription; + + BluetoothDevice? targetDevice; + BluetoothCharacteristic? targetCharacteristic; + + String connectionText = ""; + + @override + void initState() { + super.initState(); + startScan(); + } + + startScan() { + setState(() { + connectionText = "Start Scanning"; + }); + + scanSubscription = flutterBlue.scan().listen((scanResult) { + print(scanResult.device.name); + if (scanResult.device.name.contains(TARGET_DEVICE_NAME)) { + stopScan(); + + setState(() { + connectionText = "Found Target Device"; + }); + + targetDevice = scanResult.device; + connectToDevice(); + } + }, onDone: () => stopScan()); + } + + stopScan() { + scanSubscription?.cancel(); + scanSubscription = null; + } + + connectToDevice() async { + if (targetDevice == null) { + return; + } + + setState(() { + connectionText = "Device Connecting"; + }); + + await targetDevice!.connect(); + + setState(() { + connectionText = "Device Connected"; + }); + + discoverServices(); + } + + disconnectFromDeivce() { + if (targetDevice == null) { + return; + } + + targetDevice!.disconnect(); + + setState(() { + connectionText = "Device Disconnected"; + }); + } + + discoverServices() async { + if (targetDevice == null) { + return; + } + + List services = await targetDevice!.discoverServices(); + services.forEach((service) { + if (service.uuid.toString() == SERVICE_UUID) { + service.characteristics.forEach((characteristics) { + if (characteristics.uuid.toString() == CHARACTERISTIC_UUID) { + targetCharacteristic = characteristics; + setState(() { + connectionText = "All Ready with ${targetDevice!.name}"; + }); + } + }); + } + }); + } + + writeData(String data) async { + if (targetCharacteristic == null) return; + + List bytes = utf8.encode(data); + await targetCharacteristic!.write(bytes); + } + + @override + void dispose() { + super.dispose(); + stopScan(); + } + + submitAction() { + var wifiData = '${wifiNameController.text},${wifiPasswordController.text}'; + writeData(wifiData); + } + + TextEditingController wifiNameController = TextEditingController(); + TextEditingController wifiPasswordController = TextEditingController(); + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + backgroundColor: Colors.white, + elevation: 0.00, + centerTitle:true , + leading:IconButton( + icon: const Icon( + Icons.arrow_back_ios_new_rounded, + color: Color(0xFF063C14), + size: 25, + ) , + onPressed:(){ + stopScan(); + Navigator.push( + context, + MaterialPageRoute(builder: (context) => Settings()), + ); + } , + ) , + title: Text( + connectionText, + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.bold, + color: Color(0xFF4d4d4d), + ), + ), + ), + body: Container( + child: targetCharacteristic == null + ? Center( + child: Text( + "Waiting...", + style: TextStyle(fontSize: 34, color: Colors.red), + ), + ) + : Column( + children: [ + Padding( + padding: const EdgeInsets.all(16), + child: TextField( + controller: wifiNameController, + decoration: InputDecoration(labelText: 'Wifi Name'), + ), + ), + Padding( + padding: const EdgeInsets.all(16), + child: TextField( + controller: wifiPasswordController, + decoration: InputDecoration(labelText: 'Wifi Password'), + ), + ), + Padding( + padding: const EdgeInsets.all(16), + child: defaultLogInOutButton( + buttonText: 'Submit', + onPressed: submitAction, + wid: 200, + high: 200, + ), + ) + ], + )), + ); + } +} diff --git a/lib/modules/controler/controler-screen.dart b/lib/modules/controler_screen/controler-screen.dart similarity index 100% rename from lib/modules/controler/controler-screen.dart rename to lib/modules/controler_screen/controler-screen.dart diff --git a/lib/modules/edit_profile_screen/cubit/cubit.dart b/lib/modules/edit_profile_screen/cubit/cubit.dart new file mode 100644 index 0000000..5793a30 --- /dev/null +++ b/lib/modules/edit_profile_screen/cubit/cubit.dart @@ -0,0 +1,139 @@ +import 'package:bloc/bloc.dart'; +import 'package:cloud_firestore/cloud_firestore.dart'; +import 'package:firebase_auth/firebase_auth.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:graduation_project/models/user_model.dart'; +import 'package:graduation_project/modules/registration/cubit/states.dart'; + +import '../../../layout/app_layout/app_layout.dart'; +import '../../../shared/components/components.dart'; +import '../../../shared/network/end_points.dart'; +import '../../../shared/network/local/cache_helper.dart'; +import '../../../shared/network/remote/dio_helper.dart'; + + +class RegisterCubit extends Cubit { + RegisterCubit() : super(RegisterInitialState()); + + static RegisterCubit get(context) => BlocProvider.of(context); + + void userRegister({ + required String name, + required String email, + required String password, + required String phone, + }) { + emit(RegisterLoadingState()); + + FirebaseAuth.instance + .createUserWithEmailAndPassword( + email: email, + password: password + ) + .then((value){ + print(value.credential); + createUser( + name: name, + email: email, + phone: phone, + uId: value.user?.uid, + ); + }) + .catchError((error){ + emit(RegisterErrorState(getMessageFromErrorCode(error.code))); + print(error.toString()); + }); + } + + String getMessageFromErrorCode(error) { + switch (error) { + case "ERROR_EMAIL_ALREADY_IN_USE": + case "account-exists-with-different-credential": + case "email-already-in-use": + return "Email already used. Go to login page."; + break; + case "ERROR_WRONG_PASSWORD": + case "wrong-password": + return "Wrong email/password combination."; + break; + case "ERROR_USER_NOT_FOUND": + case "user-not-found": + return "No user found with this email."; + break; + case "ERROR_USER_DISABLED": + case "user-disabled": + return "User disabled."; + break; + case "ERROR_TOO_MANY_REQUESTS": + case "operation-not-allowed": + case "too-many-requests": + return "Too many requests to log into this account."; + break; + case "ERROR_OPERATION_NOT_ALLOWED": + case "operation-not-allowed": + return "Server error, please try again later."; + break; + case "ERROR_INVALID_EMAIL": + case "invalid-email": + return "Email address is invalid."; + break; + default: + return "Registration failed. Please try again."; + break; + } + } + + void createUser({ + required String name, + required String email, + required String phone, + required String? uId, + }){ + UserModel model = UserModel( + name: name, + email: email, + phone: phone, + uId: uId, + isEmailVerified: false, + ); + FirebaseFirestore.instance + .collection('users') + .doc(uId) + .set(model.toMap()) + .then((value){ + emit(RegisterSuccessState(uId)); + emit(CreateUserSuccessState()); + }) + .catchError((error){ + print(error.toString()); + emit(CreateUserErrorState(error.toString())); + }); + } + + void saveRegisterData({required String? uId, context}){ + emit(SaveRegisterDataLoading()); + + CacheHelper.saveData( + key: 'uId', + value: uId, + ).then((value){ + // navigateAndFinish(context, AppLayout()); + emit(SaveRegisterDataSuccess()); + }).catchError((error){ + emit(SaveRegisterDataError(error.toString())); + }); + } + + IconData suffix = Icons.visibility_outlined; + bool isPassword = true; + + void changePasswordVisibility(){ + isPassword = !isPassword; + + suffix = isPassword ? Icons.visibility_outlined: Icons.visibility_off_outlined; + + emit(ChangePasswordVisibilityState()); + } +} diff --git a/lib/modules/edit_profile_screen/cubit/states.dart b/lib/modules/edit_profile_screen/cubit/states.dart new file mode 100644 index 0000000..16d6b7b --- /dev/null +++ b/lib/modules/edit_profile_screen/cubit/states.dart @@ -0,0 +1,36 @@ +abstract class RegisterStates {} + +class RegisterInitialState extends RegisterStates{} + +class RegisterLoadingState extends RegisterStates{} + +class RegisterSuccessState extends RegisterStates{ + final String? uId; + + RegisterSuccessState(this.uId); +} + +class RegisterErrorState extends RegisterStates{ + final String error; + + RegisterErrorState(this.error); +} +class CreateUserSuccessState extends RegisterStates{} + +class CreateUserErrorState extends RegisterStates{ + final String error; + + CreateUserErrorState(this.error); +} + +class ChangePasswordVisibilityState extends RegisterStates{} + +class SaveRegisterDataSuccess extends RegisterStates{} + +class SaveRegisterDataLoading extends RegisterStates{} + +class SaveRegisterDataError extends RegisterStates{ + final String error; + + SaveRegisterDataError(this.error); +} \ No newline at end of file diff --git a/lib/modules/edit_profile_screen/edit_profile_.dart b/lib/modules/edit_profile_screen/edit_profile_.dart new file mode 100644 index 0000000..d5483f8 --- /dev/null +++ b/lib/modules/edit_profile_screen/edit_profile_.dart @@ -0,0 +1,234 @@ +import 'package:conditional_builder_null_safety/conditional_builder_null_safety.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:graduation_project/layout/app_layout/app_layout.dart'; +import 'package:graduation_project/modules/login/cubit/cubit.dart'; +import 'package:graduation_project/modules/login/login_screen.dart'; +import 'package:graduation_project/modules/profile/profile_screen.dart'; +import 'package:graduation_project/modules/registration/cubit/states.dart'; +import 'package:hexcolor/hexcolor.dart'; +import 'package:roundcheckbox/roundcheckbox.dart'; + +import '../../shared/components/components.dart'; +import 'cubit/cubit.dart'; + +class EditProfileScreen extends StatefulWidget { + @override + State createState() => _EditProfileScreenState(); +} + +class _EditProfileScreenState extends State { + var emailController = TextEditingController(); + + var passwordController = TextEditingController(); + + var confirmPasswordController = TextEditingController(); + + var nameController = TextEditingController(); + + var phoneNumberController = TextEditingController(); + + var addressController = TextEditingController(); + + bool termsChecked = false; + + String termsErrorText = ""; + String confirmPasswordErrorText = ""; + + var formKey = GlobalKey(); + + @override + Widget build(BuildContext context) { + return BlocProvider( + create: (context) => RegisterCubit(), + child: BlocConsumer( + listener: (context, state) { + if(state is CreateUserSuccessState){ + navigateAndFinish(context, AppLayout()); + } + if(state is RegisterErrorState) + { + showToast(errorMessage: state.error, state: ToastStates.ERROR); + } + if(state is RegisterSuccessState){ + RegisterCubit.get(context).saveRegisterData(uId: state.uId); + } + }, + builder: (context, state) { + return Scaffold( + appBar: AppBar( + backgroundColor: Colors.white, + elevation: 0.00, + centerTitle: true, + title: const Text( + 'Edit Profile', + style: TextStyle( + fontSize: 20, + fontWeight: FontWeight.bold, + color: Color(0xFF4d4d4d), + ), + ), + leading: IconButton( + icon: const Icon( + Icons.arrow_back_ios_new_rounded, + color: Color(0xFF063C14), + size: 25, + ), + onPressed: () { + Navigator.push( + context, + MaterialPageRoute(builder: (context) => Profile()), + ); + }, + ), + ), + backgroundColor: Colors.white, + body: Container( + alignment: Alignment.center, + color: Colors.white, + width: double.infinity, + child: SingleChildScrollView( + child: Form( + key: formKey, + child: Padding( + padding: const EdgeInsets.fromLTRB(0, 75.0, 0, 0), + child: Column( + children: [ + defaultTextFormField( + textController: nameController, + hintText: 'New Name', + keyboardType: TextInputType.name, + validator: (value) { + if (value?.isEmpty == true) { + return "Name cannot be empty"; + } else { + return null; + } + }, + ), + SizedBox( + height: 18.0, + ), + defaultTextFormField( + textController: emailController, + hintText: "New Email", + keyboardType: TextInputType.emailAddress, + validator: (value) { + List mail = [ + "gmail", + "hotmail", + "outlook", + "yahoo" + ]; + if (value?.isEmpty == true) { + return "Email cannot be empty"; + } + else if( + value?.substring(value.indexOf("@")+1) != "gmail.com" && + value?.substring(value.indexOf("@")+1) != "yahoo.com" && + value?.substring(value.indexOf("@")+1) != "outlook.com" && + value?.substring(value.indexOf("@")+1) != "hotmail.com" + ){ + showToast(errorMessage: "Email address is invalid.", state: ToastStates.ERROR); + return "Invalid email address"; + } + else { + print("Email: ${value?.substring(value.indexOf("@")+1)}"); + return null; + } + }, + ), + SizedBox( + height: 18.0, + ), + defaultTextFormField( + textController: phoneNumberController, + hintText: " New Phone Number", + keyboardType: TextInputType.phone, + validator: (value) { + if (value?.isEmpty == true) { + return "Phone number cannot be empty"; + } else { + return null; + } + }, + ), + SizedBox( + height: 50.0, + ), + ConditionalBuilder( + condition: state is !RegisterLoadingState, + builder: (context) => defaultLogInOutButton( + buttonText: 'Confirm', + onPressed: () { + if (formKey.currentState?.validate() == true && + termsChecked == true) { + RegisterCubit.get(context).userRegister( + name: nameController.text, + email: emailController.text, + password: passwordController.text, + phone: phoneNumberController.text, + ); + } + if (termsChecked == false) { + setState(() { + termsErrorText = + "Terms of service should be accepted"; + }); + } else { + setState(() { + termsErrorText = ""; + }); + } + }, + ), + fallback: (context) => Center(child: CircularProgressIndicator( + valueColor: AlwaysStoppedAnimation(HexColor("#00A429")), + ),) + ), + // defaultLogInOutButton( + // buttonText: 'Sign up', + // onPressed: () { + // if (formKey.currentState?.validate() == true && + // termsChecked == true) { + // RegisterCubit.get(context).userRegister( + // name: nameController.text, + // email: emailController.text, + // password: passwordController.text, + // phone: phoneNumberController.text, + // ); + // } + // if (termsChecked == false) { + // setState(() { + // termsErrorText = + // "Terms of service should be accepted"; + // }); + // } else { + // setState(() { + // termsErrorText = ""; + // }); + // } + // }, + // ), + SizedBox( + height: 70.0, + ), + Padding( + padding: const EdgeInsets.fromLTRB(65, 0, 0, 0), + child: Align( + alignment: Alignment.centerLeft, + ), + ), + ], + ), + ), + ), + ), + ), + ); + }, + ), + ); + } +} diff --git a/lib/modules/feadback_screen/cubit/cubit.dart b/lib/modules/feadback_screen/cubit/cubit.dart new file mode 100644 index 0000000..a12455d --- /dev/null +++ b/lib/modules/feadback_screen/cubit/cubit.dart @@ -0,0 +1,14 @@ +import 'package:bloc/bloc.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:graduation_project/modules/feadback_screen/cubit/states.dart'; + +class FeedBackCubit extends Cubit +{ + FeedBackCubit() :super(FeedBackInitialState()); + + static FeedBackCubit get (context) => BlocProvider.of(context); + + final TextEditingController controller = TextEditingController(); + final GlobalKey dialogKey = GlobalKey(); +} \ No newline at end of file diff --git a/lib/modules/feadback_screen/cubit/states.dart b/lib/modules/feadback_screen/cubit/states.dart new file mode 100644 index 0000000..6b7e2a6 --- /dev/null +++ b/lib/modules/feadback_screen/cubit/states.dart @@ -0,0 +1,5 @@ +abstract class FeedBackStats {} + +class FeedBackInitialState extends FeedBackStats{} + +class FeedBackChangeState extends FeedBackStats{} \ No newline at end of file diff --git a/lib/modules/feadback_screen/feedback_screen.dart b/lib/modules/feadback_screen/feedback_screen.dart new file mode 100644 index 0000000..13ca259 --- /dev/null +++ b/lib/modules/feadback_screen/feedback_screen.dart @@ -0,0 +1,179 @@ +import 'package:cloud_firestore/cloud_firestore.dart'; +import 'package:firebase_core/firebase_core.dart'; +import 'package:graduation_project/firebase_options.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_rating_bar/flutter_rating_bar.dart'; +import 'package:graduation_project/modules/feadback_screen/cubit/cubit.dart'; +import 'package:graduation_project/modules/feadback_screen/cubit/states.dart'; +import 'package:graduation_project/shared/constants/constants.dart'; +import '../../layout/app_layout/app_layout.dart'; +import '../../shared/components/components.dart'; + +class FeedBack extends StatelessWidget { + //const ({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return BlocProvider( + create: (BuildContext) => FeedBackCubit(), + child: BlocConsumer( + listener: (context, state) {}, + builder: (context, state) { + return Scaffold( + backgroundColor: Colors.white, + appBar: AppBar( + backgroundColor: Colors.white, + elevation: 0.00, + centerTitle: true, + title: const Text( + 'Feedback', + style: TextStyle( + fontSize: 20, + fontWeight: FontWeight.bold, + color: Color(0xFF4d4d4d), + ), + ), + leading: IconButton( + icon: const Icon( + Icons.arrow_back_ios_new_rounded, + color: Color(0xFF063C14), + size: 25, + ), + onPressed: () { + Navigator.push( + context, + MaterialPageRoute(builder: (context) => AppLayout()), + ); + }, + ), + ), + body: SingleChildScrollView( + child: Center( + child: Column( + //crossAxisAlignment: CrossAxisAlignment.start, + children: [ + lineItem( + width: 300.0, + ), + const SizedBox( + height: 20, + ), + const Text( + ' Rate your experience', + style: + TextStyle(fontSize: 25, fontWeight: FontWeight.w500), + ), + const SizedBox( + height: 10, + ), + const Text( + ' Are you Satisfied With our service ?', + style: + TextStyle(fontSize: 13, fontWeight: FontWeight.w500), + ), + const SizedBox( + height: 10, + ), + RatingBar.builder( + initialRating: 1, + minRating: 1, + direction: Axis.horizontal, + allowHalfRating: true, + itemCount: 5, + itemPadding: const EdgeInsets.symmetric(horizontal: 4.0), + itemBuilder: (context, _) => const Icon( + Icons.star, + color: Colors.amber, + ), + onRatingUpdate: (rating) { + print(rating); + }, + ), + const SizedBox( + height: 20, + ), + lineItem(width: 300), + const SizedBox( + height: 20, + ), + const Text( + 'Tell us we can improve ?', + style: + TextStyle(fontSize: 13, fontWeight: FontWeight.w500), + ), + Padding( + padding: + EdgeInsets.symmetric(horizontal: 8, vertical: 16), + child: SizedBox( + width: 350, + height: 350, + child: TextFormField( + + controller: FeedBackCubit.get(context).controller, + key: FeedBackCubit.get(context).dialogKey, + maxLines: 6, + maxLength: 200, + keyboardType: TextInputType.multiline, + textInputAction: TextInputAction.done, + decoration: InputDecoration( + focusedBorder: OutlineInputBorder( + borderSide: BorderSide( + width: 2, + color: Color(0xff8CEA78), + ), + ), + enabledBorder: OutlineInputBorder( + borderSide: + BorderSide(width: 2, color: Colors.grey), + ), + // contentPadding: EdgeInsets.symmetric(vertical: 400.0), + border: OutlineInputBorder(), + hintText: 'what\'s on your mind ', + ), + validator: (String? text) + { + if(text==null||text.isEmpty) + { + return'Please enter a value'; + } + return null; + }, + ), + ), + ), + defaultLogInOutButton( + buttonText: 'submit', + onPressed: () async { + print(FeedBackCubit.get(context).controller.text); + if (FeedBackCubit.get(context) + .dialogKey + .currentState! + .validate()) { + String massage; + try { + final collection = FirebaseFirestore.instance + .collection('database'); + await collection.doc().set({ + 'timestamp': FieldValue.serverTimestamp(), + 'feedback':FeedBackCubit.get(context).controller.text, + }); + massage='Feedback sent successfully'; + } catch (_) { + massage = 'Error when sending'; + } + ScaffoldMessenger.of(context).showSnackBar(SnackBar(content:Text(massage))); + } + }, + wid: 350, + ), + ], + ), + ), + ), + ); + }, + ), + ); + } +} diff --git a/lib/modules/helpandsuport_screen/cubit/cubit.dart b/lib/modules/helpandsuport_screen/cubit/cubit.dart new file mode 100644 index 0000000..fb4bb91 --- /dev/null +++ b/lib/modules/helpandsuport_screen/cubit/cubit.dart @@ -0,0 +1,15 @@ +import 'package:bloc/bloc.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +//import 'package:graduation_project/modules/feadback_screen/cubit/states.dart'; +import 'package:graduation_project/modules/helpandsuport_screen/cubit/states.dart'; + +class HelpAndSupportCubit extends Cubit +{ + HelpAndSupportCubit() :super(HelpAndSupportInitialState()); + + static HelpAndSupportCubit get (context) => BlocProvider.of(context); + + final TextEditingController controller = TextEditingController(); + final GlobalKey dialogKey = GlobalKey(); +} \ No newline at end of file diff --git a/lib/modules/helpandsuport_screen/cubit/states.dart b/lib/modules/helpandsuport_screen/cubit/states.dart new file mode 100644 index 0000000..3966606 --- /dev/null +++ b/lib/modules/helpandsuport_screen/cubit/states.dart @@ -0,0 +1,5 @@ +abstract class HelpAndSupportStats {} + +class HelpAndSupportInitialState extends HelpAndSupportStats{} + +class HelpAndSupportChangeState extends HelpAndSupportStats{} \ No newline at end of file diff --git a/lib/modules/helpandsuport_screen/helpandsupport_screen.dart b/lib/modules/helpandsuport_screen/helpandsupport_screen.dart new file mode 100644 index 0000000..fbbd360 --- /dev/null +++ b/lib/modules/helpandsuport_screen/helpandsupport_screen.dart @@ -0,0 +1,181 @@ +import 'package:cloud_firestore/cloud_firestore.dart'; +import 'package:firebase_core/firebase_core.dart'; +import 'package:graduation_project/firebase_options.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_rating_bar/flutter_rating_bar.dart'; +import 'package:graduation_project/modules/feadback_screen/cubit/cubit.dart'; +import 'package:graduation_project/modules/feadback_screen/cubit/states.dart'; +import 'package:graduation_project/modules/helpandsuport_screen/cubit/cubit.dart'; +import 'package:graduation_project/shared/constants/constants.dart'; +import '../../layout/app_layout/app_layout.dart'; +import '../../shared/components/components.dart'; +import 'cubit/states.dart'; + +class HelpAndSupport extends StatelessWidget { + //const ({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return BlocProvider( + create: (BuildContext) => HelpAndSupportCubit(), + child: BlocConsumer( + listener: (context, state) {}, + builder: (context, state) { + return Scaffold( + backgroundColor: Colors.white, + appBar: AppBar( + backgroundColor: Colors.white, + elevation: 0.00, + centerTitle: true, + title: const Text( + 'Feedback', + style: TextStyle( + fontSize: 20, + fontWeight: FontWeight.bold, + color: Color(0xFF4d4d4d), + ), + ), + leading: IconButton( + icon: const Icon( + Icons.arrow_back_ios_new_rounded, + color: Color(0xFF063C14), + size: 25, + ), + onPressed: () { + Navigator.push( + context, + MaterialPageRoute(builder: (context) => AppLayout()), + ); + }, + ), + ), + body: SingleChildScrollView( + child: Center( + child: Column( + //crossAxisAlignment: CrossAxisAlignment.start, + children: [ + lineItem( + width: 300.0, + ), + const SizedBox( + height: 20, + ), + const Text( + ' Rate your experience', + style: + TextStyle(fontSize: 25, fontWeight: FontWeight.w500), + ), + const SizedBox( + height: 10, + ), + const Text( + ' Are you Satisfied With our service ?', + style: + TextStyle(fontSize: 13, fontWeight: FontWeight.w500), + ), + const SizedBox( + height: 10, + ), + // RatingBar.builder( + // initialRating: 1, + // minRating: 1, + // direction: Axis.horizontal, + // allowHalfRating: true, + // itemCount: 5, + // itemPadding: const EdgeInsets.symmetric(horizontal: 4.0), + // itemBuilder: (context, _) => const Icon( + // Icons.star, + // color: Colors.amber, + // ), + // onRatingUpdate: (rating) { + // print(rating); + // }, + // ), + // const SizedBox( + // height: 20, + // ), + lineItem(width: 300), + const SizedBox( + height: 20, + ), + const Text( + 'Tell us we can improve ?', + style: + TextStyle(fontSize: 13, fontWeight: FontWeight.w500), + ), + Padding( + padding: + EdgeInsets.symmetric(horizontal: 8, vertical: 16), + child: SizedBox( + width: 350, + height: 350, + child: TextFormField( + + controller: HelpAndSupportCubit.get(context).controller, + key: HelpAndSupportCubit.get(context).dialogKey, + maxLines: 6, + maxLength: 200, + keyboardType: TextInputType.multiline, + textInputAction: TextInputAction.done, + decoration: InputDecoration( + focusedBorder: OutlineInputBorder( + borderSide: BorderSide( + width: 2, + color: Color(0xff8CEA78), + ), + ), + enabledBorder: OutlineInputBorder( + borderSide: + BorderSide(width: 2, color: Colors.grey), + ), + // contentPadding: EdgeInsets.symmetric(vertical: 400.0), + border: OutlineInputBorder(), + hintText: 'what\'s on your mind ', + ), + validator: (String? text) + { + if(text==null||text.isEmpty) + { + return'Please enter a value'; + } + return null; + }, + ), + ), + ), + defaultLogInOutButton( + buttonText: 'submit', + onPressed: () async { + print(HelpAndSupportCubit.get(context).controller.text); + if (HelpAndSupportCubit.get(context) + .dialogKey + .currentState! + .validate()) { + String massage; + try { + final collection = FirebaseFirestore.instance + .collection('database'); + await collection.doc().set({ + 'timestamp': FieldValue.serverTimestamp(), + 'feedback':HelpAndSupportCubit.get(context).controller.text, + }); + massage='Feedback sent successfully'; + } catch (_) { + massage = 'Error when sending'; + } + ScaffoldMessenger.of(context).showSnackBar(SnackBar(content:Text(massage))); + } + }, + wid: 350, + ), + ], + ), + ), + ), + ); + }, + ), + ); + } +} diff --git a/lib/modules/home-page/home-layout.dart b/lib/modules/home-page/home-layout.dart index e929fb0..23217fa 100644 --- a/lib/modules/home-page/home-layout.dart +++ b/lib/modules/home-page/home-layout.dart @@ -1,7 +1,9 @@ import 'package:conditional_builder_null_safety/conditional_builder_null_safety.dart'; import 'package:firebase_auth/firebase_auth.dart'; import 'package:flutter/material.dart'; -import 'package:graduation_project/modules/controler/controler-screen.dart'; +import 'package:graduation_project/modules/aboutus_screen/aboutus_screen.dart'; +import 'package:graduation_project/modules/controler_screen/controler-screen.dart'; +import 'package:graduation_project/modules/location_screen/location_screen.dart'; import 'package:graduation_project/modules/settings/settings_screen.dart'; import 'package:graduation_project/shared/components/components.dart'; @@ -10,6 +12,8 @@ import 'package:flutter/services.dart'; import 'package:graduation_project/shared/cubit/cubit.dart'; import 'package:hexcolor/hexcolor.dart'; +import '../feadback_screen/feedback_screen.dart'; + class HomeScreen extends StatelessWidget { @@ -89,7 +93,9 @@ class HomeScreen extends StatelessWidget { boxSz: 0, imgHigh: 130, imgWid: 130, - ontap: (){ Navigator.of(context, rootNavigator: true).pushAndRemoveUntil( + ontap: () + { + Navigator.of(context, rootNavigator: true).pushAndRemoveUntil( MaterialPageRoute( builder: (BuildContext context) { return Grscreen(); @@ -103,11 +109,21 @@ class HomeScreen extends StatelessWidget { width:20 , ), homeCard( - cardMasage:'Check your readings' , - cardImage:'assets/images/soil1.png', + cardMasage:'Locate your mower' , + cardImage:'assets/images/location-pin.png', // imgHigh: , // imgWid: , - ontap: (){}, + ontap: () + { + Navigator.of(context, rootNavigator: true).pushAndRemoveUntil( + MaterialPageRoute( + builder: (BuildContext context) { + return MapScreen(); + }, + ), + (_) => false, + ); + }, ), ], ), @@ -125,7 +141,17 @@ class HomeScreen extends StatelessWidget { cardImage:'assets/images/feedback2.png', // imgHigh: , // imgWid: , - ontap: (){}, + ontap: () + { + Navigator.of(context, rootNavigator: true).pushAndRemoveUntil( + MaterialPageRoute( + builder: (BuildContext context) { + return FeedBack(); + }, + ), + (_) => false, + ); + }, ), const SizedBox( width:20 , @@ -135,7 +161,17 @@ class HomeScreen extends StatelessWidget { cardImage:'assets/images/aboutus1.png', // imgHigh: , // imgWid: , - ontap: (){}, + ontap: () + { + Navigator.of(context, rootNavigator: true).pushAndRemoveUntil( + MaterialPageRoute( + builder: (BuildContext context) { + return AboutUs(); + }, + ), + (_) => false, + ); + }, ), ], ), diff --git a/lib/modules/profile/edit_profile.dart b/lib/modules/location_screen/direction_repo.dart similarity index 100% rename from lib/modules/profile/edit_profile.dart rename to lib/modules/location_screen/direction_repo.dart diff --git a/lib/modules/location_screen/location_screen.dart b/lib/modules/location_screen/location_screen.dart new file mode 100644 index 0000000..2cf35de --- /dev/null +++ b/lib/modules/location_screen/location_screen.dart @@ -0,0 +1,153 @@ +import 'package:flutter/material.dart'; +import 'package:google_maps_flutter/google_maps_flutter.dart'; +import '../../layout/app_layout/app_layout.dart'; + +class MapScreen extends StatefulWidget { + const MapScreen({Key? key}) : super(key: key); + + @override + State createState() => _MapScreenState(); +} + +class _MapScreenState extends State { + static const _initialCameraPosition = CameraPosition( + target: LatLng(30.0444, 31.2357), + zoom: 11.5, + ); + GoogleMapController? _googleMapController; + Marker? _origin; + Marker? _destination; + + @override + void initState() { + _origin = Marker( + markerId: const MarkerId('mower'), + infoWindow: const InfoWindow(title: 'Origin'), + position: const LatLng(29.971229,31.288914), + ); + // _destination = Marker( + // markerId: const MarkerId('location2'), + // position: const LatLng(30.8882, 31.2888), + // ); + super.initState(); + } + + @override + void dispose() { + _googleMapController?.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + backgroundColor: Colors.white, + elevation: 0.00, + //centerTitle: true, + title: const Text( + 'Readings', + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.bold, + color: Color(0xFF4d4d4d), + ), + ), + actions: [ + TextButton( + onPressed: ()=>_googleMapController!.animateCamera( + CameraUpdate.newCameraPosition( + CameraPosition( + target: _origin!.position, + zoom: 14.5, + tilt: 50.0, + ), + ), + ), + style: TextButton.styleFrom( + foregroundColor: Colors.lightGreen, + textStyle: TextStyle( + fontWeight: FontWeight.w600 + ), + ), + child: Text('mower') + ), + // TextButton( + // onPressed: ()=>_googleMapController!.animateCamera( + // CameraUpdate.newCameraPosition( + // CameraPosition( + // target: _destination!.position, + // zoom: 14.5, + // tilt: 50.0, + // ), + // ), + // ), + // style: TextButton.styleFrom( + // foregroundColor: Colors.lightBlue, + // textStyle: TextStyle( + // fontWeight: FontWeight.w600 + // ), + // ), + // child: Text('destination') + // ), + // TextButton(onPressed: onPressed, child: child), + + ], + leading: IconButton( + icon: const Icon( + Icons.arrow_back_ios_new_rounded, + color: Color(0xFF063C14), + size: 25, + ), + onPressed: () { + Navigator.push( + context, + MaterialPageRoute(builder: (context) => AppLayout()), + ); + }, + ), + ), + body: GoogleMap( + myLocationButtonEnabled: false, + zoomControlsEnabled: false, + initialCameraPosition: _initialCameraPosition, + onMapCreated: (controller) => _googleMapController = controller, + markers: { + if (_origin != null) _origin!, + if (_destination != null) _destination!, + }, + onLongPress: _addMarker, + ), + floatingActionButton: FloatingActionButton( + child: const Icon(Icons.center_focus_strong), + backgroundColor: Colors.white, + foregroundColor: Colors.black, + onPressed: () => _googleMapController!.animateCamera( + CameraUpdate.newCameraPosition(_initialCameraPosition), + ), + ), + ); + } + + void _addMarker(LatLng pos) { + if (_origin == null || (_origin == null && _destination == null)) { + setState(() { + _origin = Marker( + markerId: const MarkerId('origin'), + infoWindow: const InfoWindow(title: 'Origin'), + icon: BitmapDescriptor.defaultMarkerWithHue(BitmapDescriptor.hueGreen), + position: pos, + ); + }); + } else { + setState(() { + _destination = Marker( + markerId: const MarkerId('destination'), + infoWindow: const InfoWindow(title: 'Destination'), + icon: BitmapDescriptor.defaultMarkerWithHue(BitmapDescriptor.hueBlue), + position: pos, + ); + }); + } + } +} \ No newline at end of file diff --git a/lib/modules/login/login_screen.dart b/lib/modules/login/login_screen.dart index 5cb0342..ec95fd1 100644 --- a/lib/modules/login/login_screen.dart +++ b/lib/modules/login/login_screen.dart @@ -4,12 +4,14 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:fluttertoast/fluttertoast.dart'; import 'package:graduation_project/layout/app_layout/app_layout.dart'; +//import 'package:graduation_project/modules/change_password_screen/change_password.dart'; import 'package:graduation_project/modules/home-page/home-layout.dart'; import 'package:graduation_project/shared/components/components.dart'; import 'package:graduation_project/modules/login/cubit/cubit.dart'; import 'package:graduation_project/shared/network/local/cache_helper.dart'; import 'package:hexcolor/hexcolor.dart'; +import '../change_password_screen/change_password_screen.dart'; import '../registration/registration_screen.dart'; import 'cubit/states.dart'; @@ -110,7 +112,9 @@ class LoginScreen extends StatelessWidget { child: Align( alignment: Alignment.centerLeft, child: TextButton( - onPressed: () {}, + onPressed: () { + navigateTo(context, ChangePasswordScreen()); + }, child: Text( "Forgot your password", style: TextStyle( diff --git a/lib/modules/profile/profile_screen.dart b/lib/modules/profile/profile_screen.dart index 189584a..877977d 100644 --- a/lib/modules/profile/profile_screen.dart +++ b/lib/modules/profile/profile_screen.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:graduation_project/modules/edit_profile_screen/edit_profile_.dart'; import 'package:graduation_project/modules/login/login_screen.dart'; import 'package:graduation_project/shared/constants/constants.dart'; @@ -15,7 +16,7 @@ class Profile extends StatelessWidget { backgroundColor: Colors.white, elevation: 0.00, centerTitle:true , - title:Text( + title:const Text( 'My Profile', style: TextStyle( fontSize: 16, @@ -28,13 +29,10 @@ class Profile extends StatelessWidget { children: [ lineItem(), Padding( - padding: const EdgeInsets.all(20.0), + padding: const EdgeInsets.all(50.0), child: Row( + mainAxisAlignment: MainAxisAlignment.center, children: [ - const CircleAvatar( - radius: 70, - backgroundImage:AssetImage ('assets/images/profile2.jpg'), - ), const SizedBox( width: 20.0, ), @@ -68,7 +66,9 @@ class Profile extends StatelessWidget { wid: 130, high: 40, buttonText: 'Edit Profile', - onPressed: () { } + onPressed: () { + navigateTo(context, EditProfileScreen()); + } ), ], ), diff --git a/lib/modules/settings/settings_screen.dart b/lib/modules/settings/settings_screen.dart index fb685b5..9f1c34e 100644 --- a/lib/modules/settings/settings_screen.dart +++ b/lib/modules/settings/settings_screen.dart @@ -1,8 +1,9 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; +import 'package:graduation_project/modules/connection/connection_screen.dart'; +import 'package:graduation_project/modules/helpandsuport_screen/helpandsupport_screen.dart'; import 'package:graduation_project/shared/components/components.dart'; - import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:graduation_project/modules/login/login_screen.dart'; import 'package:graduation_project/shared/constants/constants.dart'; @@ -28,7 +29,7 @@ class _SettingsState extends State { backgroundColor: Colors.white, elevation: 0.00, centerTitle: true, - title: Text( + title: const Text( 'Settings', style: TextStyle( fontSize: 16, @@ -42,12 +43,17 @@ class _SettingsState extends State { padding: const EdgeInsets.only(top: 20.0), child: Column( children: [ + lineItem(), defaultNavigator(navtext: 'Controls', onPresed: () {}), defaultNavigator( - navtext: 'Bluetooth settings', onPresed: () {}), + navtext: 'Connection settings', + onPresed: () { + navigateAndFinish(context, WifiSetter()); + } + ), defaultNavigator( - navtext: 'Help and support', onPresed: () {}), - SizedBox( + navtext: 'Help and support', onPresed: () { navigateAndFinish(context,HelpAndSupport());}), + const SizedBox( height: 20, ), Padding( @@ -58,7 +64,7 @@ class _SettingsState extends State { ), child: Row( children: [ - Text( + const Text( 'Dark mood', style: TextStyle( fontSize: 15.0, diff --git a/lib/shared/components/components.dart b/lib/shared/components/components.dart index 45a8b90..8e1797a 100644 --- a/lib/shared/components/components.dart +++ b/lib/shared/components/components.dart @@ -5,10 +5,10 @@ import 'package:graduation_project/shared/styles/colors.dart'; import 'package:hexcolor/hexcolor.dart'; Widget defaultTextFormField({ - required TextEditingController textController, + TextEditingController? textController, required String hintText, required TextInputType keyboardType, - required String? Function(String?)? validator, + String? Function(String?)? validator, Function(String value)? onSubmit, bool isPassword = false, IconData? suffix, @@ -181,6 +181,7 @@ Widget homeCard ); Widget defaultLogInOutButton({ + Color bColor = const Color(0xff00A429), required String buttonText, required VoidCallback? onPressed, double? wid=155, @@ -190,7 +191,7 @@ width: wid, height: high, decoration: BoxDecoration( borderRadius: BorderRadius.circular(10), -color: HexColor("#00A429"), +color: bColor, ), child: MaterialButton( onPressed: onPressed, diff --git a/lib/shared/network/local/cache_helper.dart b/lib/shared/network/local/cache_helper.dart index a8d8ce9..b827d4d 100644 --- a/lib/shared/network/local/cache_helper.dart +++ b/lib/shared/network/local/cache_helper.dart @@ -5,7 +5,7 @@ class CacheHelper { static init() async { sharedPreferences = await SharedPreferences.getInstance(); - await sharedPreferences.clear(); + // await sharedPreferences.clear(); } static Future putData({ diff --git a/pubspec.lock b/pubspec.lock index 888e5a0..be47b61 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -5,156 +5,210 @@ packages: dependency: transitive description: name: _flutterfire_internals - url: "https://pub.dartlang.org" + sha256: "6a0ad72b2bcdb461749e40c01c478212a78db848dfcb2f10f2a461988bc5fb29" + url: "https://pub.dev" source: hosted - version: "1.0.17" + version: "1.1.1" async: dependency: transitive description: name: async - url: "https://pub.dartlang.org" + sha256: bfe67ef28df125b7dddcea62755991f807aa39a2492a23e1550161692950bbe0 + url: "https://pub.dev" source: hosted - version: "2.9.0" + version: "2.10.0" bloc: dependency: "direct main" description: name: bloc - url: "https://pub.dartlang.org" + sha256: "658a5ae59edcf1e58aac98b000a71c762ad8f46f1394c34a52050cafb3e11a80" + url: "https://pub.dev" source: hosted version: "8.1.1" boolean_selector: dependency: transitive description: name: boolean_selector - url: "https://pub.dartlang.org" + sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" + url: "https://pub.dev" source: hosted - version: "2.1.0" + version: "2.1.1" characters: dependency: transitive description: name: characters - url: "https://pub.dartlang.org" + sha256: e6a326c8af69605aec75ed6c187d06b349707a27fbff8222ca9cc2cff167975c + url: "https://pub.dev" source: hosted version: "1.2.1" clock: dependency: transitive description: name: clock - url: "https://pub.dartlang.org" + sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf + url: "https://pub.dev" source: hosted version: "1.1.1" cloud_firestore: dependency: "direct main" description: name: cloud_firestore - url: "https://pub.dartlang.org" + sha256: "7e15d929d3d82774bffaf4b2c0bfc85b429fe08dff7280a601c43f309cea1ebf" + url: "https://pub.dev" source: hosted - version: "4.4.4" + version: "4.5.3" cloud_firestore_platform_interface: dependency: transitive description: name: cloud_firestore_platform_interface - url: "https://pub.dartlang.org" + sha256: "76ba7b9dd43ce7f07e75a2349f3eb3e2c61e1bea88fec4798c3377cccf44cd7a" + url: "https://pub.dev" source: hosted - version: "5.11.4" + version: "5.12.1" cloud_firestore_web: dependency: transitive description: name: cloud_firestore_web - url: "https://pub.dartlang.org" + sha256: "0c1305722339e0b3fc0ce62bf6233b3f8762cc105a26af02171b849e6a3b3727" + url: "https://pub.dev" source: hosted - version: "3.3.4" + version: "3.4.2" collection: dependency: transitive description: name: collection - url: "https://pub.dartlang.org" + sha256: cfc915e6923fe5ce6e153b0723c753045de46de1b4d63771530504004a45fae0 + url: "https://pub.dev" source: hosted - version: "1.16.0" + version: "1.17.0" conditional_builder_null_safety: dependency: "direct main" description: name: conditional_builder_null_safety - url: "https://pub.dartlang.org" + sha256: "4428f40c20e222acead5e424fb9fba261733fc9da06ef58a08d9477207b0adfd" + url: "https://pub.dev" source: hosted version: "0.0.6" + convert: + dependency: transitive + description: + name: convert + sha256: "0f08b14755d163f6e2134cb58222dd25ea2a2ee8a195e53983d57c075324d592" + url: "https://pub.dev" + source: hosted + version: "3.1.1" + crypto: + dependency: transitive + description: + name: crypto + sha256: ff625774173754681d66daaf4a448684fb04b78f902da9cb3d308c19cc5e8bab + url: "https://pub.dev" + source: hosted + version: "3.0.3" cupertino_icons: dependency: "direct main" description: name: cupertino_icons - url: "https://pub.dartlang.org" + sha256: e35129dc44c9118cee2a5603506d823bab99c68393879edb440e0090d07586be + url: "https://pub.dev" source: hosted version: "1.0.5" dio: dependency: "direct main" description: name: dio - url: "https://pub.dartlang.org" + sha256: "0894a098594263fe1caaba3520e3016d8a855caeb010a882273189cca10f11e9" + url: "https://pub.dev" source: hosted - version: "5.0.1" + version: "5.1.1" + event_bus: + dependency: transitive + description: + name: event_bus + sha256: "44baa799834f4c803921873e7446a2add0f3efa45e101a054b1f0ab9b95f8edc" + url: "https://pub.dev" + source: hosted + version: "2.0.0" fake_async: dependency: transitive description: name: fake_async - url: "https://pub.dartlang.org" + sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78" + url: "https://pub.dev" source: hosted version: "1.3.1" ffi: dependency: transitive description: name: ffi - url: "https://pub.dartlang.org" + sha256: a38574032c5f1dd06c4aee541789906c12ccaab8ba01446e800d9c5b79c4a978 + url: "https://pub.dev" source: hosted version: "2.0.1" file: dependency: transitive description: name: file - url: "https://pub.dartlang.org" + sha256: "1b92bec4fc2a72f59a8e15af5f52cd441e4a7860b49499d69dfa817af20e925d" + url: "https://pub.dev" source: hosted version: "6.1.4" firebase_auth: dependency: "direct main" description: name: firebase_auth - url: "https://pub.dartlang.org" + sha256: "8c97619ed2633148c41c344a59461f23c73bf8aa477ae48296703f06d9621fb0" + url: "https://pub.dev" source: hosted - version: "4.2.10" + version: "4.4.2" firebase_auth_platform_interface: dependency: transitive description: name: firebase_auth_platform_interface - url: "https://pub.dartlang.org" + sha256: f7db119be795d79533c503887075a0315fc3ae1da6f9a9cd4f9100a62c68859c + url: "https://pub.dev" source: hosted - version: "6.11.12" + version: "6.13.1" firebase_auth_web: dependency: transitive description: name: firebase_auth_web - url: "https://pub.dartlang.org" + sha256: "45687246f5be811baf3810652460acd0f3d8c98f9d8f8b1961d7cc5c15c1e803" + url: "https://pub.dev" source: hosted - version: "5.2.9" + version: "5.3.2" firebase_core: dependency: "direct main" description: name: firebase_core - url: "https://pub.dartlang.org" + sha256: "239e4ac688674a7e7b5476fd16b0d8e2b5a453d464f32091af3ce1df4ebb7316" + url: "https://pub.dev" source: hosted - version: "2.7.1" + version: "2.10.0" firebase_core_platform_interface: dependency: transitive description: name: firebase_core_platform_interface - url: "https://pub.dartlang.org" + sha256: "0df0a064ab0cad7f8836291ca6f3272edd7b83ad5b3540478ee46a0849d8022b" + url: "https://pub.dev" source: hosted - version: "4.5.3" + version: "4.6.0" firebase_core_web: dependency: transitive description: name: firebase_core_web - url: "https://pub.dartlang.org" + sha256: "347351a8f0518f3343d79a9a0690fa67ad232fc32e2ea270677791949eac792b" + url: "https://pub.dev" source: hosted - version: "2.2.2" + version: "2.3.0" + fixnum: + dependency: transitive + description: + name: fixnum + sha256: "25517a4deb0c03aa0f32fd12db525856438902d9c16536311e76cdc57b31d7d1" + url: "https://pub.dev" + source: hosted + version: "1.1.0" flutter: dependency: "direct main" description: flutter @@ -164,21 +218,56 @@ packages: dependency: "direct main" description: name: flutter_bloc - url: "https://pub.dartlang.org" + sha256: "434951eea948dbe87f737b674281465f610b8259c16c097b8163ce138749a775" + url: "https://pub.dev" source: hosted version: "8.1.2" + flutter_blue_plus: + dependency: "direct main" + description: + name: flutter_blue_plus + sha256: "4e49b45d2f1ec9855826ed0af7d2b78b7d2a3e5743b3ae72aec59eb3790356d9" + url: "https://pub.dev" + source: hosted + version: "1.4.0" flutter_lints: dependency: "direct dev" description: name: flutter_lints - url: "https://pub.dartlang.org" + sha256: aeb0b80a8b3709709c9cc496cdc027c5b3216796bc0af0ce1007eaf24464fd4c + url: "https://pub.dev" source: hosted version: "2.0.1" + flutter_plugin_android_lifecycle: + dependency: transitive + description: + name: flutter_plugin_android_lifecycle + sha256: "96af49aa6b57c10a312106ad6f71deed5a754029c24789bbf620ba784f0bd0b0" + url: "https://pub.dev" + source: hosted + version: "2.0.14" + flutter_polyline_points: + dependency: "direct main" + description: + name: flutter_polyline_points + sha256: "02699e69142f51a248d784b6e3eec524194467fca5f7c4da19699ce2368b6980" + url: "https://pub.dev" + source: hosted + version: "1.0.0" + flutter_rating_bar: + dependency: "direct main" + description: + name: flutter_rating_bar + sha256: d2af03469eac832c591a1eba47c91ecc871fe5708e69967073c043b2d775ed93 + url: "https://pub.dev" + source: hosted + version: "4.0.1" flutter_switch: dependency: "direct main" description: name: flutter_switch - url: "https://pub.dartlang.org" + sha256: b91477f926bba135d2d203d7b24367492662d8d9c3aa6adb960b14c1087d3c41 + url: "https://pub.dev" source: hosted version: "0.3.2" flutter_test: @@ -195,191 +284,282 @@ packages: dependency: "direct main" description: name: fluttertoast - url: "https://pub.dartlang.org" + sha256: "2f9c4d3f4836421f7067a28f8939814597b27614e021da9d63e5d3fb6e212d25" + url: "https://pub.dev" source: hosted version: "8.2.1" + google_maps_flutter: + dependency: "direct main" + description: + name: google_maps_flutter + sha256: "0a7e0bd1dfe594bc86892d2e69062e3f80b267e378042d82e6b87a8efc798013" + url: "https://pub.dev" + source: hosted + version: "2.2.6" + google_maps_flutter_android: + dependency: transitive + description: + name: google_maps_flutter_android + sha256: "640419bb8bf1353c6698c5ca0eb3773e58b08e820eb111e84a648e6de2b3f4a0" + url: "https://pub.dev" + source: hosted + version: "2.4.14" + google_maps_flutter_ios: + dependency: transitive + description: + name: google_maps_flutter_ios + sha256: e9ad74415a222573625a2c1717adc1e375b18e8ce660fc12db734d1bda1132d4 + url: "https://pub.dev" + source: hosted + version: "2.2.1" + google_maps_flutter_platform_interface: + dependency: transitive + description: + name: google_maps_flutter_platform_interface + sha256: a07811d2b82055815ede75e1fe4b7b76f71a0b4820b26f71bdaddd157d6a3e20 + url: "https://pub.dev" + source: hosted + version: "2.2.6" hexcolor: dependency: "direct main" description: name: hexcolor - url: "https://pub.dartlang.org" + sha256: c07f4bbb9095df87eeca87e7c69e8c3d60f70c66102d7b8d61c4af0453add3f6 + url: "https://pub.dev" source: hosted version: "3.0.1" + http: + dependency: transitive + description: + name: http + sha256: "5895291c13fa8a3bd82e76d5627f69e0d85ca6a30dcac95c4ea19a5d555879c2" + url: "https://pub.dev" + source: hosted + version: "0.13.6" http_parser: dependency: transitive description: name: http_parser - url: "https://pub.dartlang.org" + sha256: "2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b" + url: "https://pub.dev" source: hosted version: "4.0.2" intl: dependency: transitive description: name: intl - url: "https://pub.dartlang.org" + sha256: "910f85bce16fb5c6f614e117efa303e85a1731bb0081edf3604a2ae6e9a3cc91" + url: "https://pub.dev" source: hosted version: "0.17.0" js: dependency: transitive description: name: js - url: "https://pub.dartlang.org" + sha256: "5528c2f391ededb7775ec1daa69e65a2d61276f7552de2b5f7b8d34ee9fd4ab7" + url: "https://pub.dev" source: hosted - version: "0.6.4" + version: "0.6.5" lints: dependency: transitive description: name: lints - url: "https://pub.dartlang.org" + sha256: "5e4a9cd06d447758280a8ac2405101e0e2094d2a1dbdd3756aec3fe7775ba593" + url: "https://pub.dev" source: hosted version: "2.0.1" matcher: dependency: transitive description: name: matcher - url: "https://pub.dartlang.org" + sha256: "16db949ceee371e9b99d22f88fa3a73c4e59fd0afed0bd25fc336eb76c198b72" + url: "https://pub.dev" source: hosted - version: "0.12.12" + version: "0.12.13" material_color_utilities: dependency: transitive description: name: material_color_utilities - url: "https://pub.dartlang.org" + sha256: d92141dc6fe1dad30722f9aa826c7fbc896d021d792f80678280601aff8cf724 + url: "https://pub.dev" source: hosted - version: "0.1.5" + version: "0.2.0" meta: dependency: transitive description: name: meta - url: "https://pub.dartlang.org" + sha256: "6c268b42ed578a53088d834796959e4a1814b5e9e164f147f580a386e5decf42" + url: "https://pub.dev" source: hosted version: "1.8.0" + mqtt_client: + dependency: "direct main" + description: + name: mqtt_client + sha256: ba10ec490ded55dc4e77bbc992529d823fb15d0d5ec68c2895f960312060c541 + url: "https://pub.dev" + source: hosted + version: "9.8.1" nested: dependency: transitive description: name: nested - url: "https://pub.dartlang.org" + sha256: "03bac4c528c64c95c722ec99280375a6f2fc708eec17c7b3f07253b626cd2a20" + url: "https://pub.dev" source: hosted version: "1.0.0" path: dependency: transitive description: name: path - url: "https://pub.dartlang.org" + sha256: db9d4f58c908a4ba5953fcee2ae317c94889433e5024c27ce74a37f94267945b + url: "https://pub.dev" source: hosted version: "1.8.2" path_provider_linux: dependency: transitive description: name: path_provider_linux - url: "https://pub.dartlang.org" + sha256: "2ae08f2216225427e64ad224a24354221c2c7907e448e6e0e8b57b1eb9f10ad1" + url: "https://pub.dev" source: hosted - version: "2.1.9" + version: "2.1.10" path_provider_platform_interface: dependency: transitive description: name: path_provider_platform_interface - url: "https://pub.dartlang.org" + sha256: "57585299a729335f1298b43245842678cb9f43a6310351b18fb577d6e33165ec" + url: "https://pub.dev" source: hosted version: "2.0.6" path_provider_windows: dependency: transitive description: name: path_provider_windows - url: "https://pub.dartlang.org" + sha256: d3f80b32e83ec208ac95253e0cd4d298e104fbc63cb29c5c69edaed43b0c69d6 + url: "https://pub.dev" source: hosted - version: "2.1.4" + version: "2.1.6" persistent_bottom_nav_bar: dependency: "direct main" description: name: persistent_bottom_nav_bar - url: "https://pub.dartlang.org" + sha256: e2e031e3366fde01511e372a9a19d720a9b252bb456e5c8d77a30d7a4a2ddfb0 + url: "https://pub.dev" source: hosted version: "5.0.2" platform: dependency: transitive description: name: platform - url: "https://pub.dartlang.org" + sha256: "4a451831508d7d6ca779f7ac6e212b4023dd5a7d08a27a63da33756410e32b76" + url: "https://pub.dev" source: hosted version: "3.1.0" plugin_platform_interface: dependency: transitive description: name: plugin_platform_interface - url: "https://pub.dartlang.org" + sha256: "6a2128648c854906c53fa8e33986fc0247a1116122f9534dd20e3ab9e16a32bc" + url: "https://pub.dev" source: hosted version: "2.1.4" process: dependency: transitive description: name: process - url: "https://pub.dartlang.org" + sha256: "53fd8db9cec1d37b0574e12f07520d582019cb6c44abf5479a01505099a34a09" + url: "https://pub.dev" source: hosted version: "4.2.4" + protobuf: + dependency: transitive + description: + name: protobuf + sha256: "01dd9bd0fa02548bf2ceee13545d4a0ec6046459d847b6b061d8a27237108a08" + url: "https://pub.dev" + source: hosted + version: "2.1.0" provider: dependency: transitive description: name: provider - url: "https://pub.dartlang.org" + sha256: cdbe7530b12ecd9eb455bdaa2fcb8d4dad22e80b8afb4798b41479d5ce26847f + url: "https://pub.dev" source: hosted version: "6.0.5" roundcheckbox: dependency: "direct main" description: name: roundcheckbox - url: "https://pub.dartlang.org" + sha256: "5d6f607ed9d26fde0072af2545f56d84a6b6d2a45972b0c41f90c2d73224f339" + url: "https://pub.dev" source: hosted version: "2.0.5" + rxdart: + dependency: transitive + description: + name: rxdart + sha256: "0c7c0cedd93788d996e33041ffecda924cc54389199cde4e6a34b440f50044cb" + url: "https://pub.dev" + source: hosted + version: "0.27.7" shared_preferences: dependency: "direct main" description: name: shared_preferences - url: "https://pub.dartlang.org" + sha256: "858aaa72d8f61637d64e776aca82e1c67e6d9ee07979123c5d17115031c1b13b" + url: "https://pub.dev" source: hosted - version: "2.0.18" + version: "2.1.0" shared_preferences_android: dependency: transitive description: name: shared_preferences_android - url: "https://pub.dartlang.org" + sha256: "6478c6bbbecfe9aced34c483171e90d7c078f5883558b30ec3163cf18402c749" + url: "https://pub.dev" source: hosted - version: "2.0.16" + version: "2.1.4" shared_preferences_foundation: dependency: transitive description: name: shared_preferences_foundation - url: "https://pub.dartlang.org" + sha256: "0c1c16c56c9708aa9c361541a6f0e5cc6fc12a3232d866a687a7b7db30032b07" + url: "https://pub.dev" source: hosted - version: "2.1.4" + version: "2.2.1" shared_preferences_linux: dependency: transitive description: name: shared_preferences_linux - url: "https://pub.dartlang.org" + sha256: "9d387433ca65717bbf1be88f4d5bb18f10508917a8fa2fb02e0fd0d7479a9afa" + url: "https://pub.dev" source: hosted - version: "2.1.4" + version: "2.2.0" shared_preferences_platform_interface: dependency: transitive description: name: shared_preferences_platform_interface - url: "https://pub.dartlang.org" + sha256: fb5cf25c0235df2d0640ac1b1174f6466bd311f621574997ac59018a6664548d + url: "https://pub.dev" source: hosted - version: "2.1.1" + version: "2.2.0" shared_preferences_web: dependency: transitive description: name: shared_preferences_web - url: "https://pub.dartlang.org" + sha256: "74083203a8eae241e0de4a0d597dbedab3b8fef5563f33cf3c12d7e93c655ca5" + url: "https://pub.dev" source: hosted - version: "2.0.5" + version: "2.1.0" shared_preferences_windows: dependency: transitive description: name: shared_preferences_windows - url: "https://pub.dartlang.org" + sha256: "5e588e2efef56916a3b229c3bfe81e6a525665a454519ca51dbcc4236a274173" + url: "https://pub.dev" source: hosted - version: "2.1.4" + version: "2.2.0" sky_engine: dependency: transitive description: flutter @@ -389,86 +569,122 @@ packages: dependency: "direct main" description: name: sleek_circular_slider - url: "https://pub.dartlang.org" + sha256: "8844d036269a13e60dda4e16534d30d27cacaff8d2f10d042d9d61d111468b13" + url: "https://pub.dev" source: hosted version: "2.0.1" smooth_page_indicator: dependency: "direct main" description: name: smooth_page_indicator - url: "https://pub.dartlang.org" + sha256: "725bc638d5e79df0c84658e1291449996943f93bacbc2cec49963dbbab48d8ae" + url: "https://pub.dev" source: hosted - version: "1.0.1" + version: "1.1.0" source_span: dependency: transitive description: name: source_span - url: "https://pub.dartlang.org" + sha256: dd904f795d4b4f3b870833847c461801f6750a9fa8e61ea5ac53f9422b31f250 + url: "https://pub.dev" source: hosted - version: "1.9.0" + version: "1.9.1" stack_trace: dependency: transitive description: name: stack_trace - url: "https://pub.dartlang.org" + sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5 + url: "https://pub.dev" source: hosted - version: "1.10.0" + version: "1.11.0" stream_channel: dependency: transitive description: name: stream_channel - url: "https://pub.dartlang.org" + sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8" + url: "https://pub.dev" + source: hosted + version: "2.1.1" + stream_transform: + dependency: transitive + description: + name: stream_transform + sha256: "14a00e794c7c11aa145a170587321aedce29769c08d7f58b1d141da75e3b1c6f" + url: "https://pub.dev" source: hosted version: "2.1.0" string_scanner: dependency: transitive description: name: string_scanner - url: "https://pub.dartlang.org" + sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" + url: "https://pub.dev" source: hosted - version: "1.1.1" + version: "1.2.0" + syncfusion_flutter_core: + dependency: transitive + description: + name: syncfusion_flutter_core + sha256: dfd138a0cea87d6b1c624513b4b620f06515d884d65f1fa5fb93345266c7592c + url: "https://pub.dev" + source: hosted + version: "21.2.4" + syncfusion_flutter_sliders: + dependency: "direct main" + description: + name: syncfusion_flutter_sliders + sha256: e7e3feaa16ab5821b0062b7addcb98f7d4bd734cff37909c5169e494fb717d91 + url: "https://pub.dev" + source: hosted + version: "21.2.4" term_glyph: dependency: transitive description: name: term_glyph - url: "https://pub.dartlang.org" + sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 + url: "https://pub.dev" source: hosted version: "1.2.1" test_api: dependency: transitive description: name: test_api - url: "https://pub.dartlang.org" + sha256: ad540f65f92caa91bf21dfc8ffb8c589d6e4dc0c2267818b4cc2792857706206 + url: "https://pub.dev" source: hosted - version: "0.4.12" + version: "0.4.16" typed_data: dependency: transitive description: name: typed_data - url: "https://pub.dartlang.org" + sha256: "26f87ade979c47a150c9eaab93ccd2bebe70a27dc0b4b29517f2904f04eb11a5" + url: "https://pub.dev" source: hosted version: "1.3.1" vector_math: dependency: transitive description: name: vector_math - url: "https://pub.dartlang.org" + sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" + url: "https://pub.dev" source: hosted - version: "2.1.2" + version: "2.1.4" win32: dependency: transitive description: name: win32 - url: "https://pub.dartlang.org" + sha256: dd8f9344bc305ae2923e3d11a2a911d9a4e2c7dd6fe0ed10626d63211a69676e + url: "https://pub.dev" source: hosted - version: "3.1.3" + version: "4.1.3" xdg_directories: dependency: transitive description: name: xdg_directories - url: "https://pub.dartlang.org" + sha256: ee1505df1426458f7f60aac270645098d318a8b4766d85fde75f76f2e21807d1 + url: "https://pub.dev" source: hosted version: "1.0.0" sdks: - dart: ">=2.18.5 <3.0.0" - flutter: ">=3.0.0" + dart: ">=2.19.0 <3.0.0" + flutter: ">=3.3.0" diff --git a/pubspec.yaml b/pubspec.yaml index 1317b7e..0b88ba3 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -32,6 +32,10 @@ dependencies: flutter: sdk: flutter persistent_bottom_nav_bar: ^5.0.2 + flutter_blue_plus: ^1.4.0 + + + # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. @@ -47,7 +51,11 @@ dependencies: flutter_switch: ^0.3.2 sleek_circular_slider: ^2.0.1 smooth_page_indicator: ^1.0.1 - + mqtt_client: ^9.8.1 + flutter_rating_bar: ^4.0.1 + syncfusion_flutter_sliders: ^21.2.4 + flutter_polyline_points: ^1.0.0 + google_maps_flutter: ^2.2.6 #firebase firebase_core: ^2.7.0 firebase_auth: ^4.2.9 diff --git a/test/widget_test.dart b/test/widget_test.dart index 81c2356..00965e8 100644 --- a/test/widget_test.dart +++ b/test/widget_test.dart @@ -13,7 +13,7 @@ import 'package:graduation_project/main.dart'; void main() { testWidgets('Counter increments smoke test', (WidgetTester tester) async { // Build our app and trigger a frame. - await tester.pumpWidget(const MyApp()); + // await tester.pumpWidget( MyApp()); // Verify that our counter starts at 0. expect(find.text('0'), findsOneWidget);