diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 0e8d9c1..d9a10cb 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -4,7 +4,7 @@ + android:icon="@mipmap/launcher_icon"> + + + + diff --git a/android/app/src/main/res/mipmap-hdpi/launcher_icon.png b/android/app/src/main/res/mipmap-hdpi/launcher_icon.png new file mode 100644 index 0000000..7ead7d6 Binary files /dev/null and b/android/app/src/main/res/mipmap-hdpi/launcher_icon.png differ diff --git a/android/app/src/main/res/mipmap-mdpi/launcher_icon.png b/android/app/src/main/res/mipmap-mdpi/launcher_icon.png new file mode 100644 index 0000000..32a8f2d Binary files /dev/null and b/android/app/src/main/res/mipmap-mdpi/launcher_icon.png differ diff --git a/android/app/src/main/res/mipmap-xhdpi/launcher_icon.png b/android/app/src/main/res/mipmap-xhdpi/launcher_icon.png new file mode 100644 index 0000000..f743e15 Binary files /dev/null and b/android/app/src/main/res/mipmap-xhdpi/launcher_icon.png differ diff --git a/android/app/src/main/res/mipmap-xxhdpi/launcher_icon.png b/android/app/src/main/res/mipmap-xxhdpi/launcher_icon.png new file mode 100644 index 0000000..bc2110f Binary files /dev/null and b/android/app/src/main/res/mipmap-xxhdpi/launcher_icon.png differ diff --git a/android/app/src/main/res/mipmap-xxxhdpi/launcher_icon.png b/android/app/src/main/res/mipmap-xxxhdpi/launcher_icon.png new file mode 100644 index 0000000..6e67ccf Binary files /dev/null and b/android/app/src/main/res/mipmap-xxxhdpi/launcher_icon.png differ diff --git a/android/app/src/main/res/values/colors.xml b/android/app/src/main/res/values/colors.xml new file mode 100644 index 0000000..ab98328 --- /dev/null +++ b/android/app/src/main/res/values/colors.xml @@ -0,0 +1,4 @@ + + + #ffffff + \ No newline at end of file diff --git a/assets/app_icon.webp b/assets/app_icon.webp new file mode 100644 index 0000000..0239cbd Binary files /dev/null and b/assets/app_icon.webp differ diff --git a/assets/done_icon.webp b/assets/done_icon.webp new file mode 100644 index 0000000..2b4b874 Binary files /dev/null and b/assets/done_icon.webp differ diff --git a/assets/light/diagnosis_icon.png b/assets/light/diagnosis_icon.png new file mode 100644 index 0000000..0ed1b11 Binary files /dev/null and b/assets/light/diagnosis_icon.png differ diff --git a/assets/light/helpIcon.png b/assets/light/helpIcon.png new file mode 100644 index 0000000..c64b8c9 Binary files /dev/null and b/assets/light/helpIcon.png differ diff --git a/assets/light/license_icon.png b/assets/light/license_icon.png new file mode 100644 index 0000000..f8b13ec Binary files /dev/null and b/assets/light/license_icon.png differ diff --git a/assets/light/repair_icon.png b/assets/light/repair_icon.png new file mode 100644 index 0000000..3bc5bd3 Binary files /dev/null and b/assets/light/repair_icon.png differ diff --git a/assets/light/siana_icon.png b/assets/light/siana_icon.png new file mode 100644 index 0000000..a6d3959 Binary files /dev/null and b/assets/light/siana_icon.png differ diff --git a/assets/light/tunnig_icon.png b/assets/light/tunnig_icon.png new file mode 100644 index 0000000..76c6019 Binary files /dev/null and b/assets/light/tunnig_icon.png differ diff --git a/assets/user.webp b/assets/user.webp index 4c38f24..c4e25fc 100644 Binary files a/assets/user.webp and b/assets/user.webp differ diff --git a/assets/welcome_icon.webp b/assets/welcome_icon.webp new file mode 100644 index 0000000..e96bd8d Binary files /dev/null and b/assets/welcome_icon.webp differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png index dc9ada4..29620eb 100644 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png index 7353c41..cbc518f 100644 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png index 797d452..0ada57a 100644 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png index 6ed2d93..2785b29 100644 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png index 4cd7b00..367b5c6 100644 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png index fe73094..2dbe245 100644 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png index 321773c..520cc9f 100644 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png index 797d452..0ada57a 100644 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png index 502f463..7000ea0 100644 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png index 0ec3034..b07ff6a 100644 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@1x.png new file mode 100644 index 0000000..8518a22 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@1x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@2x.png new file mode 100644 index 0000000..d162b08 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@2x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@1x.png new file mode 100644 index 0000000..619ebef Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@1x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@2x.png new file mode 100644 index 0000000..aee0ff1 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@2x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png index 0ec3034..b07ff6a 100644 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png index e9f5fea..4622ed3 100644 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@1x.png new file mode 100644 index 0000000..7ead7d6 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@1x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@2x.png new file mode 100644 index 0000000..bc2110f Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@2x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png index 84ac32a..595d38e 100644 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png index 8953cba..a721dc6 100644 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png index 0467bf1..9eafd72 100644 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png differ diff --git a/lib/Done_screen.dart b/lib/Done_screen.dart new file mode 100644 index 0000000..bb56304 --- /dev/null +++ b/lib/Done_screen.dart @@ -0,0 +1,33 @@ +import 'package:flutter/material.dart'; +import 'package:stepn/MapScreen.dart'; + +import 'forms/data/formsContollers.dart'; + +class DoneScreen extends StatelessWidget { + const DoneScreen({super.key}); + + @override + Widget build(BuildContext context) { + // Clear form after sending request to API + FormsControllers.clearForm(); + + return Scaffold( + body: Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + const Image(image: AssetImage("assets/done_icon.webp"),height: 300,width: 300,), + const Text("طلبك وصلنا, هنتواصل معاك في أسرع وقت",style: TextStyle(fontSize: 20),), + const SizedBox(height: 20,), + ElevatedButton(onPressed: () { + Navigator.of(context).pushAndRemoveUntil( + MaterialPageRoute(builder: (context) => const MapScreen()), + (Route route) => false, + ); + }, child: const Text("القائمة الرئيسية")) + ], + ), + ), + ); + } +} diff --git a/lib/MapScreen.dart b/lib/MapScreen.dart index 3aad250..a232bdb 100644 --- a/lib/MapScreen.dart +++ b/lib/MapScreen.dart @@ -1,31 +1,47 @@ +import 'package:connectivity_plus/connectivity_plus.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:google_maps_flutter/google_maps_flutter.dart'; import 'package:location/location.dart'; +import 'package:page_transition/page_transition.dart'; import 'package:stepn/forms/DiagnosisForm.dart'; import 'package:stepn/forms/HelpForm.dart'; import 'package:stepn/forms/LicenseForm.dart'; import 'package:stepn/forms/UserInfoForm.dart'; import 'package:stepn/forms/data/UserData.dart'; import 'forms/data/Services.dart'; -import 'main.dart'; + + + +class MapScreen extends StatefulWidget { + const MapScreen({super.key}); + + @override + MapScreenState createState() => MapScreenState(); +} class MapScreenState extends State with WidgetsBindingObserver { + @override + void initState() { + super.initState(); + WidgetsBinding.instance.addObserver(this); + _loadMapStyles(); + } + late GoogleMapController mapController; late String _darkMapStyle; late String _lightMapStyle; String selectedService=""; + + // Function load map themes Future _loadMapStyles() async { _darkMapStyle = await rootBundle.loadString('assets/json/dark_mode_style.json'); _lightMapStyle =await rootBundle.loadString('assets/json/light_mode_style.json'); await rootBundle.loadString('assets/map_styles/light.json'); } - @override - void initState() { - super.initState(); - WidgetsBinding.instance.addObserver(this); - _loadMapStyles(); - } + + + // Change map theme when device theme is changed @override void didChangePlatformBrightness() { setState(() { @@ -33,11 +49,14 @@ class MapScreenState extends State with WidgetsBindingObserver { }); } + // Remove the theme observer used by the map @override void dispose() { WidgetsBinding.instance.removeObserver(this); super.dispose(); } + + // Set the style of the map based on device theme Future _setMapStyle() async { final theme = WidgetsBinding.instance.platformDispatcher.platformBrightness; @@ -51,7 +70,9 @@ class MapScreenState extends State with WidgetsBindingObserver { @override Widget build(BuildContext context) { + return Scaffold( + // Floating button to get current location floatingActionButton: Padding( padding: const EdgeInsets.only(bottom: 200.0), child: FloatingActionButton( @@ -59,9 +80,10 @@ class MapScreenState extends State with WidgetsBindingObserver { child: const Icon(Icons.my_location_rounded), ), ), - floatingActionButtonLocation: FloatingActionButtonLocation.endFloat, + // Main column of the app body: Column( children: [ + // Map view Expanded( child: GoogleMap( myLocationEnabled: true, @@ -88,11 +110,12 @@ class MapScreenState extends State with WidgetsBindingObserver { ), ), ), - + // Services buttons container Container( padding: const EdgeInsets.all(16.0), child: Column( children: [ + // Title text const Align( alignment: Alignment.topRight, child: Text( @@ -102,14 +125,16 @@ class MapScreenState extends State with WidgetsBindingObserver { ), ), + // Space between title and services list const SizedBox(height: 20,), + // Services list SingleChildScrollView( padding: const EdgeInsets.symmetric(horizontal: 20), scrollDirection: Axis.horizontal, child:Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ - + // Help me Service button ElevatedButton( style: ButtonStyle( padding: MaterialStateProperty.all(const EdgeInsets.symmetric(vertical: 12,horizontal: 27)), @@ -120,26 +145,34 @@ class MapScreenState extends State with WidgetsBindingObserver { ) ), onPressed: () { + if(UserData.currentLocation == null){ + showLocationRequestSnackBar(); + return; + } // Handle button click UserData.serviceType=Services.HELP; Navigator.push( context, - MaterialPageRoute(builder: (context) => const HelpForm()) + PageTransition(child: const HelpForm(), + type: PageTransitionType.bottomToTop, + duration: const Duration(milliseconds: 500)) ); }, - child: const Column( + child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Column( children: [ - Image(image: AssetImage("assets/helpIcon.png"),width: 60,height: 60,), - Text('الحقني',style:TextStyle(fontSize: 15,fontFamily: 'Roboto')), + Image(image: getIcon("helpIcon.png"),width: 60,height: 60,), + const Text('الحقني',style:TextStyle(fontSize: 15,fontFamily: 'Roboto')), ], ) ], ), ), + // Space const SizedBox(width: 20,), + // Car care service button ElevatedButton( style: ButtonStyle( padding: MaterialStateProperty.all(const EdgeInsets.symmetric(vertical: 12,horizontal: 27)), @@ -150,21 +183,29 @@ class MapScreenState extends State with WidgetsBindingObserver { ) ), onPressed: () { + if(UserData.currentLocation == null){ + showLocationRequestSnackBar(); + return; + } // Handle button click UserData.serviceType=Services.CARE; Navigator.push( context, - MaterialPageRoute(builder: (context) => const UserInfoForm()) + PageTransition(child:const UserInfoForm(), + type: PageTransitionType.bottomToTop, + duration: const Duration(milliseconds: 500)) ); }, - child: const Column( + child: Column( children: [ - Image(image: AssetImage("assets/siana_icon.png"),width:60 ,height: 60 ,), - Text('صيانة'), + Image(image: getIcon("siana_icon.png"),width:60 ,height: 60 ,), + const Text('صيانة'), ], ), ), + // Space const SizedBox(width: 20,), + // Tuning service button ElevatedButton( style: ButtonStyle( padding: MaterialStateProperty.all(const EdgeInsets.symmetric(vertical: 12,horizontal: 27)), @@ -175,21 +216,29 @@ class MapScreenState extends State with WidgetsBindingObserver { ) ), onPressed: () { + if(UserData.currentLocation == null){ + showLocationRequestSnackBar(); + return; + } // Handle button click UserData.serviceType=Services.TUNNING; Navigator.push( context, - MaterialPageRoute(builder: (context) => const UserInfoForm()) + PageTransition(child:const UserInfoForm(), + type: PageTransitionType.bottomToTop + , duration: const Duration(milliseconds: 500)) ); }, - child: const Column( + child: Column( children: [ - Image(image: AssetImage("assets/tunnig_icon.png"),height: 60,width: 60,), - Text('تعديل'), + Image(image: getIcon("tunnig_icon.png"),height: 60,width: 60,), + const Text('تعديل'), ], ), ), + // Space const SizedBox(width: 20,), + // Fixing service button ElevatedButton( style: ButtonStyle( padding: MaterialStateProperty.all(const EdgeInsets.symmetric(vertical: 12,horizontal: 27)), @@ -200,20 +249,28 @@ class MapScreenState extends State with WidgetsBindingObserver { ) ), onPressed: () { + if(UserData.currentLocation == null){ + showLocationRequestSnackBar(); + return; + } UserData.serviceType=Services.REPAIR; Navigator.push( context, - MaterialPageRoute(builder: (context) => const UserInfoForm()) + PageTransition(child:const UserInfoForm(), + type: PageTransitionType.bottomToTop, + duration: const Duration(milliseconds: 500)) ); }, - child: const Column( + child: Column( children: [ - Image(image: AssetImage("assets/repair_icon.png"),height: 60,width: 60,), - Text('تصليح'), + Image(image: getIcon("repair_icon.png"),height: 60,width: 60,), + const Text('تصليح'), ], ), ), + // Space const SizedBox(width: 20,), + // Diagnosis service button ElevatedButton( style: ButtonStyle( padding: MaterialStateProperty.all(const EdgeInsets.symmetric(vertical: 12,horizontal: 27)), @@ -224,21 +281,32 @@ class MapScreenState extends State with WidgetsBindingObserver { ) ), onPressed: () { + if(UserData.currentLocation == null){ + showLocationRequestSnackBar(); + return; + } // Handle button click UserData.serviceType=Services.DIAGNOSIS; Navigator.push( context, - MaterialPageRoute(builder: (context) => const DiagnosisForm()) + PageTransition(child:const DiagnosisForm(), + type: PageTransitionType.bottomToTop, + duration: const Duration(milliseconds: 500)) ); }, - child: const Column( + + child: Column( + children: [ - Image(image: AssetImage('assets/diagnosis_icon.png'),width: 60,height: 60,), - Text('كشف'), + + Image(image:getIcon("diagnosis_icon.png") ,width: 60,height: 60,), + const Text('كشف'), ], ), ), + // Space const SizedBox(width: 20,), + // Licensing service button ElevatedButton( style: ButtonStyle( padding: MaterialStateProperty.all(const EdgeInsets.symmetric(vertical: 12,horizontal: 27)), @@ -249,17 +317,23 @@ class MapScreenState extends State with WidgetsBindingObserver { ) ), onPressed: () { + if(UserData.currentLocation == null){ + showLocationRequestSnackBar(); + return; + } // Handle button click UserData.serviceType=Services.LICENSE; Navigator.push( context, - MaterialPageRoute(builder: (context) => const LicenseForm()) + PageTransition(child:const LicenseForm(), + type: PageTransitionType.bottomToTop, + duration: const Duration(milliseconds: 500)) ); }, - child: const Column( + child: Column( children: [ - Image(image: AssetImage("assets/license_icon.png"),width: 60,height: 60,), - Text('ترخيص'), + Image(image: getIcon("license_icon.png"),width: 60,height: 60,), + const Text('ترخيص'), ], ), ), @@ -273,22 +347,86 @@ class MapScreenState extends State with WidgetsBindingObserver { ), ); } + // Get current location void _currentLocation() async { + bool isConnected = await checkInternetConnection(); + // First check internet connection + if (!isConnected) { + // Show SnackBar if there is no internet connection + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar( + backgroundColor: Colors.grey, + content: Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + Text('حصل مشكلة في الاتصال ب الانترنت'), + SizedBox(width: 10,), + Icon(Icons.signal_wifi_connected_no_internet_4_outlined), + ], + ), + duration: Duration(seconds: 3), + ), + ); + return; + } + var location = Location(); try { UserData.currentLocation = await location.getLocation(); } on Exception { UserData.currentLocation = null; } - if(UserData.currentLocation!=null) { - + // Move map view camera position to current location + if (UserData.currentLocation != null) { mapController.animateCamera(CameraUpdate.newCameraPosition( - CameraPosition( - bearing: 0, - target: LatLng(UserData.currentLocation!.latitude!, UserData.currentLocation!.longitude!), - zoom: 17.0, - ), - )); + CameraPosition( + bearing: 0, + target: LatLng(UserData.currentLocation!.latitude!, UserData.currentLocation!.longitude!), + zoom: 17.0, + ), + )); } } + + // Get icon image for assets folder based on device theme + AssetImage getIcon(String name){ + AssetImage img; + final theme = WidgetsBinding.instance.platformDispatcher.platformBrightness; + if (theme == Brightness.dark) { + img=AssetImage("assets/light/$name"); + } else { + img=AssetImage("assets/$name") ; + + } + return img; + } + + // Check internet connection + Future checkInternetConnection() async { + var connectivityResult = await (Connectivity().checkConnectivity()); + if (connectivityResult == ConnectivityResult.mobile || + connectivityResult == ConnectivityResult.wifi) { + return true; // Internet connection is available + } else { + return false; // No internet connection + } + } + + // Show snack bar asking user to click on 'Get my location' floating button + void showLocationRequestSnackBar(){ + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar( + backgroundColor: Colors.grey, + content: Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + Text('دوس علي زرار تحديد الموقع عشان نقدر نعرف مكانك'), + SizedBox(width: 10,), + Icon(Icons.my_location_sharp), + ], + ), + duration: Duration(seconds: 3), + ) + ); + } } \ No newline at end of file diff --git a/lib/Welcome_screen.dart b/lib/Welcome_screen.dart new file mode 100644 index 0000000..0cec03b --- /dev/null +++ b/lib/Welcome_screen.dart @@ -0,0 +1,101 @@ +import 'package:flutter/material.dart'; +import 'package:permission_handler/permission_handler.dart'; +import 'package:stepn/MapScreen.dart'; + +// Helper class to handle location permission +class LocationPermissionHandler { + static Future requestLocationPermission() async { + // Check if the location permission is already granted + var status = await Permission.location.status; + if (status == PermissionStatus.granted) { + return true; // Permission already granted + } + + // If the permission has been denied or restricted, request it + if (status.isDenied || status.isRestricted) { + status = await Permission.location.request(); + } + + // Return true if the permission is granted after requesting, otherwise return false + return status == PermissionStatus.granted; + } +} + +// Welcome screen widget +class WelcomeScreen extends StatefulWidget { + const WelcomeScreen({Key? key}) : super(key: key); + + @override + State createState() => _WelcomeScreenState(); +} + +class _WelcomeScreenState extends State { + @override + Widget build(BuildContext context) { + return Directionality( + textDirection: TextDirection.rtl, + child: Scaffold( + appBar: AppBar( + title: const Text('أهلا بيك في تطبيق استبن', + style: TextStyle( + fontWeight: FontWeight.bold, + fontSize: 30, + fontFamily: 'Roboto')), + ), + body: Builder( + builder: (context) => Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + const Image( + image: AssetImage("assets/welcome_icon.webp"), + width: 300, + height: 300, + ), + const Text( + "أهلا بيك في تطبيق أستبن ، بنقدملك خدمات متكاملة لعربيتك وحل مشاكلها.و علشان نقدر نساعدك محتاجين تسمحلنا نعرف مكانك.", + style: TextStyle(fontSize: 22), + textAlign: TextAlign.center, + ), + const SizedBox( + height: 20, + ), + ElevatedButton( + style: ElevatedButton.styleFrom( + padding: const EdgeInsets.symmetric( + horizontal: 20, vertical: 10)), + onPressed: () async { + // Request location permission + bool isPermissionGranted = + await LocationPermissionHandler.requestLocationPermission(); + + if (isPermissionGranted) { + // If permission is granted, navigate to the home screen + navigateHome(); + } else { + // If permission is denied, show a snack bar + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar( + content: Text('تم رفض إذن الموقع'), + duration: Duration(seconds: 3), + ), + ); + } + }, + child: const Text( + 'السماح بالوصول للموقع', + style: TextStyle(fontSize: 20), + ), + ), + ], + ), + ), + ), + ); + } + + // Function to navigate to the home screen + void navigateHome() { + Navigator.pushReplacement( + context, MaterialPageRoute(builder: (context) => const MapScreen())); + } +} diff --git a/lib/forms/CarCareForm.dart b/lib/forms/CarCareForm.dart index d731597..6a203a8 100644 --- a/lib/forms/CarCareForm.dart +++ b/lib/forms/CarCareForm.dart @@ -6,6 +6,10 @@ import 'package:image_picker/image_picker.dart'; import 'package:stepn/forms/data/CarData.dart'; import 'package:stepn/forms/data/formsContollers.dart'; +import '../Done_screen.dart'; + +// Global key for the care form +var careFormKey = GlobalKey(); class CareForm extends StatefulWidget { const CareForm({super.key}); @@ -18,64 +22,62 @@ class _CareFormState extends State { final ImagePicker picker = ImagePicker(); - //we can upload image from camera or from gallery based on parameter + // Function to get an image from either the camera or gallery Future getImage(ImageSource media) async { var img = await picker.pickImage(source: media); setState(() { - if (img!=null) { + if (img != null) { CarData.carPhoto.add(img); } }); } - //show popup dialog - void myAlert() { + // Function to show a dialog for selecting image source + void selectImageSourceDialog() { showDialog( - context: context, - builder: (BuildContext context) { - return Directionality( - textDirection: TextDirection.rtl, - child: AlertDialog( - shape: - RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)), - title: Text('تحب تفتح الكاميرا ولا تجيب الصورة من معرض الصور ؟'), - content: Container( - height: MediaQuery.of(context).size.height / 6, - child: Column( - children: [ - ElevatedButton( - //if user click this button, user can upload image from gallery - onPressed: () { - Navigator.pop(context); - getImage(ImageSource.gallery); - }, - child: Row( - children: [ - Icon(Icons.image), - Text('من معرض الصور'), - ], - ), + context: context, + builder: (BuildContext context) { + return Directionality( + textDirection: TextDirection.rtl, + child: AlertDialog( + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)), + title: Text('تحب تفتح الكاميرا ولا تجيب الصورة من معرض الصور ؟'), + content: Container( + height: MediaQuery.of(context).size.height / 6, + child: Column( + children: [ + ElevatedButton( + onPressed: () { + Navigator.pop(context); + getImage(ImageSource.gallery); + }, + child: Row( + children: [ + Icon(Icons.image), + Text('من معرض الصور'), + ], ), - ElevatedButton( - //if user click this button. user can upload image from camera - onPressed: () { - Navigator.pop(context); - getImage(ImageSource.camera); - }, - child: Row( - children: [ - Icon(Icons.camera), - Text('افتح الكاميرا'), - ], - ), + ), + ElevatedButton( + onPressed: () { + Navigator.pop(context); + getImage(ImageSource.camera); + }, + child: Row( + children: [ + Icon(Icons.camera), + Text('افتح الكاميرا'), + ], ), - ], - ), + ), + ], ), ), - ); - }); + ), + ); + }, + ); } @override @@ -84,107 +86,150 @@ class _CareFormState extends State { textDirection: TextDirection.rtl, child: Scaffold( appBar: AppBar( - title: Text('صيانة', style: TextStyle(fontWeight: FontWeight.bold,fontSize: 30,fontFamily: 'Roboto')), + title: Text('صيانة', style: TextStyle(fontWeight: FontWeight.bold, fontSize: 30, fontFamily: 'Roboto')), ), body: SingleChildScrollView( + // Main form column child: Column( children: [ - const Image(image :AssetImage('assets/siana.png'),width: 200,height: 200,), - Padding( - padding: const EdgeInsets.only(left: 20,right: 20,bottom: 20), - child: TextFormField( - keyboardType: TextInputType.number, - controller: FormsControllers.kilosController, - decoration: const InputDecoration( - border: OutlineInputBorder(), - labelText: "عداد", - prefixIcon: Icon(Icons.speed_rounded), + const Image(image: AssetImage('assets/siana.png'), width: 200, height: 200,), + Form( + key: careFormKey, + // Car kilometers number + child: Padding( + padding: const EdgeInsets.only(left: 20, right: 20, bottom: 20), + child: TextFormField( + keyboardType: TextInputType.number, + validator: (value) { + if (value == null || value.isEmpty) { + return "من فضلك دخل عداد العربية الحالي"; + } + return null; + }, + controller: FormsControllers.kilosController, + decoration: const InputDecoration( + border: OutlineInputBorder(), + labelText: "عداد", + prefixIcon: Icon(Icons.speed_rounded), + ), ), ), ), + // Car state description Padding( - padding: const EdgeInsets.only(left: 20,right: 20,bottom: 20), + padding: const EdgeInsets.only(left: 20, right: 20, bottom: 20), child: TextFormField( keyboardType: TextInputType.multiline, minLines: 1, maxLines: 20, controller: FormsControllers.descriptionController, - decoration: const InputDecoration( + decoration: const InputDecoration( border: OutlineInputBorder(), labelText: "وصف حالة العربية دلوقتي (اختياري)", prefixIcon: Icon(Icons.notes), ), ), ), + // Add image button ElevatedButton( onPressed: () { - if(CarData.carPhoto.length==6){ + if (CarData.carPhoto.length == 6) { showDialog( - context: context, - builder: (BuildContext context) { - return Directionality( - textDirection: TextDirection.rtl, - child:AlertDialog(icon: Icon(Icons.error_outline),title: Text("الحد الأقصي للصور ٦"), - content: Text("تقدر تدوس علي اي صورة من اللي موجودين علشان تمسحها"),) - );}); - } - else { - myAlert(); + context: context, + builder: (BuildContext context) { + return Directionality( + textDirection: TextDirection.rtl, + child: AlertDialog( + icon: Icon(Icons.error_outline), + title: Text("الحد الأقصي للصور ٦"), + content: Text("تقدر تدوس علي اي صورة من اللي موجودين علشان تمسحها"), + ), + ); + }, + ); + } else { + selectImageSourceDialog(); } }, child: Text('صورة العربية'), ), + // Space SizedBox( height: 10, ), + // Loaded images preview Row( - children: [SizedBox(width: 10,),for(int i=0; i const DoneScreen()), + ); + } + }, + style: TextButton.styleFrom( + padding: const EdgeInsets.symmetric(horizontal: 170, vertical: 15), + ), + child: const Text("تمام", style: TextStyle(fontWeight: FontWeight.bold, fontSize: 20)), ), ], ), @@ -193,5 +238,3 @@ class _CareFormState extends State { ); } } - - diff --git a/lib/forms/DiagnosisForm.dart b/lib/forms/DiagnosisForm.dart index 16da510..7c99707 100644 --- a/lib/forms/DiagnosisForm.dart +++ b/lib/forms/DiagnosisForm.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; +import '../Done_screen.dart'; import 'data/formsContollers.dart'; var diagnosisFormKey = GlobalKey(); class DiagnosisForm extends StatelessWidget { @@ -7,16 +8,21 @@ class DiagnosisForm extends StatelessWidget { @override Widget build(BuildContext context) { return Directionality( + // Set text direction textDirection: TextDirection.rtl, child: Scaffold( + // To resized with the keyboard resizeToAvoidBottomInset: true, + // App bar appBar: AppBar( title: const Text("أكشفلي", style: TextStyle(fontWeight: FontWeight.bold,fontSize: 30,fontFamily: 'Roboto') ), ), + body: SingleChildScrollView( + // Main form column child: Column( children: [ Form( @@ -92,8 +98,7 @@ class DiagnosisForm extends StatelessWidget { ), ), ), - - + // Car state description text box Padding( padding: const EdgeInsets.only(left: 20,right: 20,bottom: 20), child: TextFormField( @@ -115,15 +120,16 @@ class DiagnosisForm extends StatelessWidget { //Next button ElevatedButton( onPressed: (){ + // Validate input data if(diagnosisFormKey.currentState!.validate()){ - + Navigator.pushReplacement( + context, + MaterialPageRoute(builder: (context) => const DoneScreen()) + ); } }, style: TextButton.styleFrom( - foregroundColor: Colors.white, - backgroundColor: Colors.amber, padding: const EdgeInsets.symmetric(horizontal:170,vertical: 15), - disabledBackgroundColor: Colors.grey ), child: const Text("تمام",style: TextStyle(fontWeight: FontWeight.bold,fontSize: 20),) ), diff --git a/lib/forms/HelpForm.dart b/lib/forms/HelpForm.dart index 9d1ee8b..a6789b6 100644 --- a/lib/forms/HelpForm.dart +++ b/lib/forms/HelpForm.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:stepn/Done_screen.dart'; import 'data/formsContollers.dart'; var helpFormKey = GlobalKey(); @@ -69,7 +70,7 @@ class HelpForm extends StatelessWidget { ), ), ), - + //Car state description Padding( padding: const EdgeInsets.only(left: 20,right: 20,bottom: 20), child: TextFormField( @@ -84,25 +85,21 @@ class HelpForm extends StatelessWidget { ), ), ), - - ], ), ), - //Next button ElevatedButton( onPressed: (){ if(helpFormKey.currentState!.validate()){ - + Navigator.pushReplacement( + context, + MaterialPageRoute(builder: (context) => const DoneScreen()) + ); } - }, style: TextButton.styleFrom( - foregroundColor: Colors.white, - backgroundColor: Colors.amber, padding: const EdgeInsets.symmetric(horizontal:170,vertical: 15), - disabledBackgroundColor: Colors.grey ), child: const Text("تمام",style: TextStyle(fontWeight: FontWeight.bold,fontSize: 20),) ), diff --git a/lib/forms/PhotosFunctions.dart b/lib/forms/PhotosFunctions.dart deleted file mode 100644 index e69de29..0000000 diff --git a/lib/forms/RepairForm.dart b/lib/forms/RepairForm.dart index 7f5ba26..9e26734 100644 --- a/lib/forms/RepairForm.dart +++ b/lib/forms/RepairForm.dart @@ -4,6 +4,8 @@ import 'package:image_picker/image_picker.dart'; import 'package:stepn/forms/data/CarData.dart'; import 'package:stepn/forms/data/formsContollers.dart'; +import '../Done_screen.dart'; + var repairFormKey = GlobalKey(); class RepairForm extends StatefulWidget { const RepairForm({super.key}); @@ -29,6 +31,7 @@ class _RepairFormState extends State { child: Column( children: [ const Image(image :AssetImage('assets/salah.png'),width: 200,height: 200,), + // Car state description Padding( padding: const EdgeInsets.only(left: 20,right: 20,bottom: 20), child: TextFormField( @@ -49,27 +52,30 @@ class _RepairFormState extends State { ), ), ), + // Add image button ElevatedButton( onPressed: () { if(CarData.carPhoto.length==6){ showDialog( context: context, builder: (BuildContext context) { - return Directionality( + return const Directionality( textDirection: TextDirection.rtl, child:AlertDialog(icon: Icon(Icons.error_outline),title: Text("الحد الأقصي للصور ٦"), content: Text("تقدر تدوس علي اي صورة من اللي موجودين علشان تمسحها"),) );}); } else { - myAlert(); + selectImageSourceDialog(); } }, - child: Text('صورة العربية'), + child: const Text('صورة العربية'), ), + // Space const SizedBox( height: 10, ), + // Loaded images preview Row( children: [const SizedBox(width: 10,),for(int i=0; i { ), ] ), + // Space const SizedBox(height: 20,), + // Payment method title const ListTile(title: Text("طريقة الدفع :"), subtitle: Text("الدفع هيكون مع المندوب اللي هيجيلك من فريقنا") ), + // Visa method radio button RadioListTile(toggleable: true,title: const Text("فيزا"),value: false, groupValue: CarData.isCashPayment, onChanged: (value){ setState(() { CarData.isCashPayment=value!; }); }), + // Cash method radio button RadioListTile(toggleable: true,title: const Text("كاش"),value: true, groupValue: CarData.isCashPayment, onChanged: (value){ setState(() { CarData.isCashPayment=value!; }); }), + // Space const SizedBox(height: 25), + // Next button ElevatedButton( onPressed: () { - repairFormKey.currentState!.validate(); + if(repairFormKey.currentState!.validate()){ + Navigator.pushReplacement( + context, + MaterialPageRoute(builder: (context) => const DoneScreen()) + ); + } }, style: TextButton.styleFrom( - foregroundColor: Colors.white, - backgroundColor: Colors.amber, padding: const EdgeInsets.symmetric(horizontal:170,vertical: 15), - disabledBackgroundColor: Colors.grey, ), child: const Text("تمام",style: TextStyle(fontWeight: FontWeight.bold,fontSize: 20),) ), @@ -139,8 +153,8 @@ class _RepairFormState extends State { }); } - //show popup dialog - void myAlert() { + //show popup dialog to select image source + void selectImageSourceDialog() { showDialog( context: context, builder: (BuildContext context) { @@ -149,8 +163,8 @@ class _RepairFormState extends State { child: AlertDialog( shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)), - title: Text('تحب تفتح الكاميرا ولا تجيب الصورة من معرض الصور ؟'), - content: Container( + title: const Text('تحب تفتح الكاميرا ولا تجيب الصورة من معرض الصور ؟'), + content: SizedBox( height: MediaQuery.of(context).size.height / 6, child: Column( children: [ @@ -160,7 +174,7 @@ class _RepairFormState extends State { Navigator.pop(context); getImage(ImageSource.gallery); }, - child: Row( + child: const Row( children: [ Icon(Icons.image), Text('من معرض الصور'), @@ -173,7 +187,7 @@ class _RepairFormState extends State { Navigator.pop(context); getImage(ImageSource.camera); }, - child: Row( + child: const Row( children: [ Icon(Icons.camera), Text('افتح الكاميرا'), diff --git a/lib/forms/TuningForm.dart b/lib/forms/TuningForm.dart index ac55dd2..c335eb2 100644 --- a/lib/forms/TuningForm.dart +++ b/lib/forms/TuningForm.dart @@ -4,10 +4,12 @@ import 'package:image_picker/image_picker.dart'; import 'package:stepn/forms/data/CarData.dart'; import 'package:stepn/forms/data/formsContollers.dart'; +import '../Done_screen.dart'; + bool x=true; -var tuningFormKey = GlobalKey(); + class TuningForm extends StatefulWidget{ const TuningForm({super.key}); @@ -29,7 +31,6 @@ class _TuningFormState extends State { ), body: SingleChildScrollView( child: Form( - key: tuningFormKey, child: Column( children: [ const Image(image :AssetImage('assets/tuning.png'),width: 200,height: 200,), @@ -142,185 +143,14 @@ class _TuningFormState extends State { Text("البودي (Body)"), ], )), - DropdownMenuItem( - alignment: AlignmentDirectional.centerStart, - child: SizedBox( - width: double.maxFinite, - child: StatefulBuilder( - builder: (BuildContext context, StateSetter setState) { - return CheckboxListTile( - - controlAffinity: ListTileControlAffinity.leading, - title: const Text("كيت"), - value: CarData.tuningItems.contains("كيت"), - onChanged: (value) { - setState(() { - if (CarData.tuningItems.contains("كيت")) { - CarData.tuningItems.remove("كيت"); - } else { - CarData.tuningItems.add("كيت"); - } - }); - }, - ); - } - ), - ), - ), - DropdownMenuItem( - alignment: AlignmentDirectional.centerStart, - child: SizedBox( - width: double.maxFinite, - child: StatefulBuilder( - builder: (BuildContext context, StateSetter setState) { - return CheckboxListTile( - - controlAffinity: ListTileControlAffinity.leading, - title: const Text("فونيس"), - value: CarData.tuningItems.contains("فونيس"), - onChanged: (value) { - setState(() { - if (CarData.tuningItems.contains("فونيس")) { - CarData.tuningItems.remove("فونيس"); - } else { - CarData.tuningItems.add("فونيس"); - } - }); - }, - ); - } - ), - ), - ), - DropdownMenuItem( - alignment: AlignmentDirectional.centerStart, - child: SizedBox( - width: double.maxFinite, - child: StatefulBuilder( - builder: (BuildContext context, StateSetter setState) { - return CheckboxListTile( - - controlAffinity: ListTileControlAffinity.leading, - title: const Text("سكن"), - value: CarData.tuningItems.contains("سكن"), - onChanged: (value) { - setState(() { - if (CarData.tuningItems.contains("سكن")) { - CarData.tuningItems.remove("سكن"); - } else { - CarData.tuningItems.add("سكن"); - } - }); - }, - ); - } - ), - ), - ), - DropdownMenuItem( - alignment: AlignmentDirectional.centerStart, - child: SizedBox( - width: double.maxFinite, - child: StatefulBuilder( - builder: (BuildContext context, StateSetter setState) { - return CheckboxListTile( - - controlAffinity: ListTileControlAffinity.leading, - title: const Text("دفيوزر"), - value: CarData.tuningItems.contains("دفيوزر"), - onChanged: (value) { - setState(() { - if (CarData.tuningItems.contains("دفيوزر")) { - CarData.tuningItems.remove("دفيوزر"); - } else { - CarData.tuningItems.add("دفيوزر"); - } - }); - }, - ); - } - ), - ), - ), - DropdownMenuItem( - alignment: AlignmentDirectional.centerStart, - child: SizedBox( - width: double.maxFinite, - child: StatefulBuilder( - builder: (BuildContext context, StateSetter setState) { - return CheckboxListTile( - - controlAffinity: ListTileControlAffinity.leading, - title: const Text("ستيكر"), - value: CarData.tuningItems.contains("ستيكر"), - onChanged: (value) { - setState(() { - if (CarData.tuningItems.contains("ستيكر")) { - CarData.tuningItems.remove("ستيكر"); - } else { - CarData.tuningItems.add("ستيكر"); - } - }); - }, - ); - } - ), - ), - ), - DropdownMenuItem( - alignment: AlignmentDirectional.centerStart, - child: SizedBox( - width: double.maxFinite, - child: StatefulBuilder( - builder: (BuildContext context, StateSetter setState) { - return CheckboxListTile( - - controlAffinity: ListTileControlAffinity.leading, - title: const Text("سبويلر"), - value: CarData.tuningItems.contains("سبويلر"), - onChanged: (value) { - setState(() { - if (CarData.tuningItems.contains("سبويلر")) { - CarData.tuningItems.remove("سبويلر"); - } else { - CarData.tuningItems.add("سبويلر"); - } - }); - }, - ); - } - ), - ), - ), - DropdownMenuItem( - alignment: AlignmentDirectional.centerStart, - child: SizedBox( - width: double.maxFinite, - child: StatefulBuilder( - builder: (BuildContext context, StateSetter setState) { - return CheckboxListTile( - - controlAffinity: ListTileControlAffinity.leading, - title: const Text("اوت ليت"), - value: CarData.tuningItems.contains("اوت ليت"), - onChanged: (value) { - setState(() { - if (CarData.tuningItems.contains("اوت ليت")) { - CarData.tuningItems.remove("اوت ليت"); - } else { - CarData.tuningItems.add("اوت ليت"); - } - }); - }, - ); - } - ), - ), - ), - - - - + + buildDropdownMenuItem("(kit)""كيت"), + buildDropdownMenuItem("فونيس"), + buildDropdownMenuItem("(Skin)""سكن"), + buildDropdownMenuItem("دفيوزر"), + buildDropdownMenuItem("(Sticker)""ستيكر"), + buildDropdownMenuItem("(Spoiler) سبويلر"), + buildDropdownMenuItem("(Outlet)""اوت ليت") ], ), ), @@ -343,83 +173,9 @@ class _TuningFormState extends State { Text("عفشة"), ], )), - DropdownMenuItem( - alignment: AlignmentDirectional.centerStart, - child: SizedBox( - width: double.maxFinite, - child: StatefulBuilder( - builder: (BuildContext context, StateSetter setState) { - return CheckboxListTile( - - controlAffinity: ListTileControlAffinity.leading, - title: const Text("اير"), - value: CarData.tuningItems.contains("اير"), - onChanged: (value) { - setState(() { - if (CarData.tuningItems.contains("اير")) { - CarData.tuningItems.remove("اير"); - } else { - CarData.tuningItems.add("اير"); - } - }); - }, - ); - } - ), - ), - ), - DropdownMenuItem( - alignment: AlignmentDirectional.centerStart, - child: SizedBox( - width: double.maxFinite, - child: StatefulBuilder( - builder: (BuildContext context, StateSetter setState) { - return CheckboxListTile( - - controlAffinity: ListTileControlAffinity.leading, - title: const Text("كويلات"), - value: CarData.tuningItems.contains("كويلات"), - onChanged: (value) { - setState(() { - if (CarData.tuningItems.contains("كويلات")) { - CarData.tuningItems.remove("كويلات"); - } else { - CarData.tuningItems.add("كويلات"); - } - }); - }, - ); - } - ), - ), - ), - DropdownMenuItem( - alignment: AlignmentDirectional.centerStart, - child: SizedBox( - width: double.maxFinite, - child: StatefulBuilder( - builder: (BuildContext context, StateSetter setState) { - return CheckboxListTile( - - controlAffinity: ListTileControlAffinity.leading, - title: const Text("تهبيط و تعليا"), - value: CarData.tuningItems.contains("تهبيط و تعليا"), - onChanged: (value) { - setState(() { - if (CarData.tuningItems.contains("تهبيط و تعليا")) { - CarData.tuningItems.remove("تهبيط و تعليا"); - } else { - CarData.tuningItems.add("تهبيط و تعليا"); - } - }); - }, - ); - } - ), - ), - ), - - + buildDropdownMenuItem( "(Air)""اير"), + buildDropdownMenuItem("كويلات"), + buildDropdownMenuItem("تهبيط و تعليا") ], onChanged: (value) { }, ), ), @@ -431,194 +187,24 @@ class _TuningFormState extends State { isExpanded: true, isDense: false, icon: const Icon(Icons.arrow_drop_down_circle_outlined), - value: "ايجزوست", + value: "ايجزوست (Exhaust)", alignment: AlignmentDirectional.centerEnd, items: [ const DropdownMenuItem( alignment: AlignmentDirectional.centerStart, - value: "ايجزوست",child: Row( + value: "ايجزوست (Exhaust)",child: Row( textDirection: TextDirection.rtl, children: [ - Text("ايجزوست"), + Text("ايجزوست (Exhaust)"), ], )), - DropdownMenuItem( - alignment: AlignmentDirectional.centerStart, - child: SizedBox( - width: double.maxFinite, - child: StatefulBuilder( - builder: (BuildContext context, StateSetter setState) { - return CheckboxListTile( - - controlAffinity: ListTileControlAffinity.leading, - title: const Text("ستريت بايب"), - value: CarData.tuningItems.contains("ستريت بايب"), - onChanged: (value) { - setState(() { - if (CarData.tuningItems.contains("ستريت بايب")) { - CarData.tuningItems.remove("ستريت بايب"); - } else { - CarData.tuningItems.add("ستريت بايب"); - } - }); - }, - ); - } - ), - ), - ), - DropdownMenuItem( - alignment: AlignmentDirectional.centerStart, - child: SizedBox( - width: double.maxFinite, - child: StatefulBuilder( - builder: (BuildContext context, StateSetter setState) { - return CheckboxListTile( - - controlAffinity: ListTileControlAffinity.leading, - title: const Text("داون بايب"), - value: CarData.tuningItems.contains("داون بايب"), - onChanged: (value) { - setState(() { - if (CarData.tuningItems.contains("داون بايب")) { - CarData.tuningItems.remove("داون بايب"); - } else { - CarData.tuningItems.add("داون بايب"); - } - }); - }, - ); - } - ), - ), - ), - DropdownMenuItem( - alignment: AlignmentDirectional.centerStart, - child: SizedBox( - width: double.maxFinite, - child: StatefulBuilder( - builder: (BuildContext context, StateSetter setState) { - return CheckboxListTile( - - controlAffinity: ListTileControlAffinity.leading, - title: const Text("ديڤل"), - value: CarData.tuningItems.contains("ديڤل"), - onChanged: (value) { - setState(() { - if (CarData.tuningItems.contains("ديڤل")) { - CarData.tuningItems.remove("ديڤل"); - } else { - CarData.tuningItems.add("ديڤل"); - } - }); - }, - ); - } - ), - ), - ), - DropdownMenuItem( - alignment: AlignmentDirectional.centerStart, - child: SizedBox( - width: double.maxFinite, - child: StatefulBuilder( - builder: (BuildContext context, StateSetter setState) { - return CheckboxListTile( - - controlAffinity: ListTileControlAffinity.leading, - title: const Text("علب بيثة"), - value: CarData.tuningItems.contains("علب بيثة"), - onChanged: (value) { - setState(() { - if (CarData.tuningItems.contains("علب بيثة")) { - CarData.tuningItems.remove("علب بيثة"); - } else { - CarData.tuningItems.add("علب بيثة"); - } - }); - }, - ); - } - ), - ), - ), - DropdownMenuItem( - alignment: AlignmentDirectional.centerStart, - child: SizedBox( - width: double.maxFinite, - child: StatefulBuilder( - builder: (BuildContext context, StateSetter setState) { - return CheckboxListTile( - - controlAffinity: ListTileControlAffinity.leading, - title: const Text("فيل كراكلز"), - value: CarData.tuningItems.contains("فيل كراكلز"), - onChanged: (value) { - setState(() { - if (CarData.tuningItems.contains("فيل كراكلز")) { - CarData.tuningItems.remove("فيل كراكلز"); - } else { - CarData.tuningItems.add("فيل كراكلز"); - } - }); - }, - ); - } - ), - ), - ), - DropdownMenuItem( - alignment: AlignmentDirectional.centerStart, - child: SizedBox( - width: double.maxFinite, - child: StatefulBuilder( - builder: (BuildContext context, StateSetter setState) { - return CheckboxListTile( - - controlAffinity: ListTileControlAffinity.leading, - title: const Text("باك فير"), - value: CarData.tuningItems.contains("باك فير"), - onChanged: (value) { - setState(() { - if (CarData.tuningItems.contains("باك فير")) { - CarData.tuningItems.remove("باك فير"); - } else { - CarData.tuningItems.add("باك فير"); - } - }); - }, - ); - } - ), - ), - ), - DropdownMenuItem( - alignment: AlignmentDirectional.centerStart, - child: SizedBox( - width: double.maxFinite, - child: StatefulBuilder( - builder: (BuildContext context, StateSetter setState) { - return CheckboxListTile( - - controlAffinity: ListTileControlAffinity.leading, - title: const Text("علب فالف ترونيك"), - value: CarData.tuningItems.contains("علب فالف ترونيك"), - onChanged: (value) { - setState(() { - if (CarData.tuningItems.contains("علب فالف ترونيك")) { - CarData.tuningItems.remove("علب فالف ترونيك"); - } else { - CarData.tuningItems.add("علب فالف ترونيك"); - } - }); - }, - ); - } - ), - ), - ), - - + buildDropdownMenuItem("(Straight pipe)" "ستريت بايب"), + buildDropdownMenuItem("(Downpipe) داون بايب"), + buildDropdownMenuItem("ديڤل"), + buildDropdownMenuItem("علب بيئة"), + buildDropdownMenuItem("فيل كراكلز"), + buildDropdownMenuItem("(Backfire) باك فاير"), + buildDropdownMenuItem("(Valvtronic) علب فالف ترونيك") ], onChanged: (value) { }, ), ), @@ -639,113 +225,14 @@ class _TuningFormState extends State { value: "ابديت اينچين",child: Row( textDirection: TextDirection.rtl, children: [ - Text("ابديت اينچين"), + Text("ابديت اينچين (Update Engine)"), ], )), - DropdownMenuItem( - alignment: AlignmentDirectional.centerStart, - child: SizedBox( - width: double.maxFinite, - child: StatefulBuilder( - builder: (BuildContext context, StateSetter setState) { - return CheckboxListTile( - - controlAffinity: ListTileControlAffinity.leading, - title: const Text("سيستم كامل"), - value: CarData.tuningItems.contains("سيستم كامل"), - onChanged: (value) { - setState(() { - if (CarData.tuningItems.contains("سيستم كامل")) { - CarData.tuningItems.remove("سيستم كامل"); - } else { - CarData.tuningItems.add("سيستم كامل"); - } - }); - }, - ); - } - ), - ), - ), - DropdownMenuItem( - alignment: AlignmentDirectional.centerStart, - child: SizedBox( - width: double.maxFinite, - child: StatefulBuilder( - builder: (BuildContext context, StateSetter setState) { - return CheckboxListTile( - - controlAffinity: ListTileControlAffinity.leading, - title: const Text("تيربو"), - value: CarData.tuningItems.contains("تيربو"), - onChanged: (value) { - setState(() { - if (CarData.tuningItems.contains("تيربو")) { - CarData.tuningItems.remove("تيربو"); - } else { - CarData.tuningItems.add("تيربو"); - } - }); - }, - ); - } - ), - ), - ), - DropdownMenuItem( - alignment: AlignmentDirectional.centerStart, - child: SizedBox( - width: double.maxFinite, - child: StatefulBuilder( - builder: (BuildContext context, StateSetter setState) { - return CheckboxListTile( - - controlAffinity: ListTileControlAffinity.leading, - title: const Text("ستيدچ"), - value: CarData.tuningItems.contains("ستيدچ"), - onChanged: (value) { - setState(() { - if (CarData.tuningItems.contains("ستيدچ")) { - CarData.tuningItems.remove("ستيدچ"); - } else { - CarData.tuningItems.add("ستيدچ"); - } - }); - }, - ); - } - ), - ), - ), - DropdownMenuItem( - alignment: AlignmentDirectional.centerStart, - child: SizedBox( - width: double.maxFinite, - child: StatefulBuilder( - builder: (BuildContext context, StateSetter setState) { - return CheckboxListTile( - - controlAffinity: ListTileControlAffinity.leading, - title: const Text("هدر"), - value: CarData.tuningItems.contains("هدر"), - onChanged: (value) { - setState(() { - if (CarData.tuningItems.contains("هدر")) { - CarData.tuningItems.remove("هدر"); - } else { - CarData.tuningItems.add("هدر"); - } - }); - }, - ); - } - ), - ), - ), + buildDropdownMenuItem("سيستم كامل"), + buildDropdownMenuItem("تيربو"), + buildDropdownMenuItem("هدر"), buildDropdownMenuItem("كولر"), buildDropdownMenuItem("فلتر") - - ], onChanged: (value) { }, ), ), @@ -791,21 +278,20 @@ class _TuningFormState extends State { isExpanded: true, isDense: false, icon: const Icon(Icons.arrow_drop_down_circle_outlined), - value: "بريكات", + value: "بريكات (Brakes)", alignment: AlignmentDirectional.centerEnd, items: [ const DropdownMenuItem( alignment: AlignmentDirectional.centerStart, - value: "بريكات",child: Row( + value: "بريكات (Brakes)",child: Row( textDirection: TextDirection.rtl, children: [ - Text("بريكات"), + Text("بريكات (Brakes)"), ], )), buildDropdownMenuItem("كليبرات"), buildDropdownMenuItem("ديسكات") - ], onChanged: (value) { }, ), ), @@ -817,15 +303,15 @@ class _TuningFormState extends State { isExpanded: true, isDense: false, icon: const Icon(Icons.arrow_drop_down_circle_outlined), - value: "ساوند سيستم", + value: "ساوند سيستم (Sound System)", alignment: AlignmentDirectional.centerEnd, items: [ const DropdownMenuItem( alignment: AlignmentDirectional.centerStart, - value: "ساوند سيستم",child: Row( + value: "ساوند سيستم (Sound System)",child: Row( textDirection: TextDirection.rtl, children: [ - Text("ساوند سيستم"), + Text("ساوند سيستم (Sound System)"), ], )), buildDropdownMenuItem("سماعات"), @@ -880,10 +366,10 @@ class _TuningFormState extends State { Text("تغيير لون"), ], )), - buildDropdownMenuItem("مط"), - buildDropdownMenuItem("ميتالك"), - buildDropdownMenuItem("سكن"), - buildDropdownMenuItem("كربون فيبر"), + buildDropdownMenuItem("(Matte) مط"), + buildDropdownMenuItem("(Metallic) ميتالك"), + buildDropdownMenuItem("(Skin) سكن"), + buildDropdownMenuItem("(Carbon fiber) كربون فيبر"), ], onChanged: (value) { }, @@ -917,7 +403,7 @@ class _TuningFormState extends State { );}); } else { - myAlert(); + selectImageSourceDialog(); } }, child: const Text('صورة العربية'), @@ -967,15 +453,26 @@ class _TuningFormState extends State { const SizedBox(height: 25), ElevatedButton( onPressed: () { - tuningFormKey.currentState!.validate(); + if(CarData.tuningItems.isEmpty){ + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar( + content: Text('من فضلك أختار الحاجات اللي حابب تعدلها'), + duration: Duration(seconds: 3), + ), + ); + return; + } + Navigator.pushReplacement( + context, + MaterialPageRoute(builder: (context) => const DoneScreen()) + ); + }, style: TextButton.styleFrom( - foregroundColor: Colors.white, - backgroundColor: Colors.amber, padding: const EdgeInsets.symmetric(horizontal:170,vertical: 15), - disabledBackgroundColor: Colors.grey, ), - child: const Text("تمام",style: TextStyle(fontWeight: FontWeight.bold,fontSize: 20),) + child: const Text("تمام", + style: TextStyle(fontWeight: FontWeight.bold,fontSize: 20),) ), ], ), @@ -1013,7 +510,6 @@ class _TuningFormState extends State { ); } //we can upload image from camera or from gallery based on parameter - //we can upload image from camera or from gallery based on parameter Future getImage(ImageSource media) async { var img = await picker.pickImage(source: media); @@ -1025,7 +521,7 @@ class _TuningFormState extends State { } //show popup dialog - void myAlert() { + void selectImageSourceDialog() { showDialog( context: context, builder: (BuildContext context) { diff --git a/lib/forms/UserInfoForm.dart b/lib/forms/UserInfoForm.dart index 9cccf1f..c776df9 100644 --- a/lib/forms/UserInfoForm.dart +++ b/lib/forms/UserInfoForm.dart @@ -78,7 +78,7 @@ class UserInfoForm extends StatelessWidget{ ), - //Model text box + //Manufacturer text box Padding( padding: const EdgeInsets.only(left: 20,right: 20,bottom: 20), child: TextFormField( @@ -115,7 +115,6 @@ class UserInfoForm extends StatelessWidget{ return "من فضلك اكتب موديل عربيتك"; } return null; - // return null; }, decoration: const InputDecoration( border: OutlineInputBorder(), @@ -197,8 +196,6 @@ class UserInfoForm extends StatelessWidget{ }, style: TextButton.styleFrom( - foregroundColor: Colors.white, - backgroundColor: Colors.amber, padding: const EdgeInsets.symmetric(horizontal:170,vertical: 15), disabledBackgroundColor: Colors.grey ), diff --git a/lib/forms/data/CarData.dart b/lib/forms/data/CarData.dart index 71d243d..05d8bfd 100644 --- a/lib/forms/data/CarData.dart +++ b/lib/forms/data/CarData.dart @@ -4,5 +4,4 @@ class CarData{ static bool isCashPayment=false; static List carPhoto=[]; static List tuningItems=[]; - } \ No newline at end of file diff --git a/lib/forms/data/UserData.dart b/lib/forms/data/UserData.dart index 3e1fb79..10a0964 100644 --- a/lib/forms/data/UserData.dart +++ b/lib/forms/data/UserData.dart @@ -3,8 +3,6 @@ import 'package:location/location.dart'; import 'Services.dart'; class UserData { -static bool check=false; static String serviceType=Services.NONE; static LocationData? currentLocation; - } diff --git a/lib/forms/data/formsContollers.dart b/lib/forms/data/formsContollers.dart index 779f55b..a81ae23 100644 --- a/lib/forms/data/formsContollers.dart +++ b/lib/forms/data/formsContollers.dart @@ -12,5 +12,14 @@ class FormsControllers{ static TextEditingController kilosController=TextEditingController(); static TextEditingController descriptionController=TextEditingController(); - + // Clear forms data +static void clearForm(){ + nameController.clear(); + phoneController.clear(); + modelController.clear(); + yearController.clear(); + manufactureController.clear(); + kilosController.clear(); + descriptionController.clear(); + } } \ No newline at end of file diff --git a/lib/main.dart b/lib/main.dart index 33b353e..cd7d9b7 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,32 +1,57 @@ import 'package:flutter/material.dart'; +import 'package:permission_handler/permission_handler.dart'; +import 'package:stepn/Welcome_screen.dart'; +import 'package:stepn/themes/darkTheme.dart'; +import 'package:stepn/themes/lightTheme.dart'; import 'MapScreen.dart'; +void main() async { + WidgetsFlutterBinding.ensureInitialized(); -void main() { - runApp(const MyApp()); + // Check if location permission is granted + Future isLocationPermissionGranted() async { + var status = await Permission.location.status; + return status == PermissionStatus.granted; + } + + var isLocation = await isLocationPermissionGranted(); + + // Run the appropriate app based on location permission status + runApp(isLocation ? const App() : const PermissionApp()); } -class MyApp extends StatelessWidget { - const MyApp({super.key}); +// App that runs when location permission is granted +class App extends StatelessWidget { + const App({Key? key}) : super(key: key); + @override Widget build(BuildContext context) { return Directionality( textDirection: TextDirection.rtl, child: MaterialApp( debugShowCheckedModeBanner: false, - theme: ThemeData.light(), - darkTheme: ThemeData.dark(), + theme: lightTheme(), + darkTheme: darkTheme(), home: const MapScreen(), ), ); } } -class MapScreen extends StatefulWidget { - const MapScreen({super.key}); +// App that runs when location permission is not granted +class PermissionApp extends StatelessWidget { + const PermissionApp({Key? key}) : super(key: key); @override - MapScreenState createState() => MapScreenState(); + Widget build(BuildContext context) { + return Directionality( + textDirection: TextDirection.rtl, + child: MaterialApp( + debugShowCheckedModeBanner: false, + theme: lightTheme(), + darkTheme: darkTheme(), + home: const WelcomeScreen(), + ), + ); + } } - - diff --git a/lib/themes/darkTheme.dart b/lib/themes/darkTheme.dart new file mode 100644 index 0000000..d3dfd3d --- /dev/null +++ b/lib/themes/darkTheme.dart @@ -0,0 +1,54 @@ +import 'package:flutter/material.dart'; + +ThemeData darkTheme() { + TextTheme basicTextTheme(TextTheme base) { + return base.copyWith( + displayLarge: base.displayLarge!.copyWith( + fontSize: 72.0, + fontWeight: FontWeight.bold, + fontFamily: 'Lato', + color: Colors.white, + ), + titleLarge: base.titleLarge!.copyWith( + fontSize: 23.0, + fontFamily: 'Lato', + ), + bodyMedium: base.bodyMedium!.copyWith( + fontSize: 16.0, + fontFamily: 'Lato', + color: const Color(0xFF16042E) + ), + headlineMedium: base.headlineMedium!.copyWith( + fontSize: 18.0, + fontFamily: 'Lato', + color: const Color(0xFF16042E) + ), + headlineSmall: base.headlineSmall!.copyWith( + fontSize: 18.0, + fontFamily: 'Lato', + color: Colors.deepPurple[50], + //buttons + ), + bodySmall: base.bodySmall!.copyWith( + fontSize: 12.0, + fontFamily: 'Lato', + ), + bodyLarge: base.bodyLarge!.copyWith( + color: Colors.deepPurple[300], + fontSize: 14, + ), + ); + } + + final ThemeData base = ThemeData.dark(); + return base.copyWith( + appBarTheme: const AppBarTheme(color: Color(0xFF16042E),), + scaffoldBackgroundColor: const Color(0xFF16042E), + elevatedButtonTheme: ElevatedButtonThemeData( + style:ElevatedButton.styleFrom( + backgroundColor: const Color(0xFF250C46), + foregroundColor: Colors.white) + ), + floatingActionButtonTheme: const FloatingActionButtonThemeData(backgroundColor: Color(0xFF16042E)) + ); +} \ No newline at end of file diff --git a/lib/themes/lightTheme.dart b/lib/themes/lightTheme.dart new file mode 100644 index 0000000..446a44d --- /dev/null +++ b/lib/themes/lightTheme.dart @@ -0,0 +1,69 @@ +import 'package:flutter/material.dart'; + +ThemeData lightTheme() { + TextTheme basicTextTheme(TextTheme base) { + return base.copyWith( + displayLarge: base.displayLarge!.copyWith( + fontSize: 72.0, + fontWeight: FontWeight.bold, + fontFamily: 'Lato', + color: Colors.white, + ), + titleLarge: base.titleLarge!.copyWith( + fontSize: 23.0, + fontFamily: 'Lato', + ), + bodyMedium: base.bodyMedium!.copyWith( + fontSize: 16.0, + fontFamily: 'Lato', + color: const Color(0xFF16042E) + ), + headlineMedium: base.headlineMedium!.copyWith( + fontSize: 18.0, + fontFamily: 'Lato', + color: const Color(0xFF16042E) + ), + headlineSmall: base.headlineSmall!.copyWith( + fontSize: 18.0, + fontFamily: 'Lato', + color: Colors.deepPurple[50], + //buttons + ), + bodySmall: base.bodySmall!.copyWith( + fontSize: 12.0, + fontFamily: 'Lato', + ), + bodyLarge: base.bodyLarge!.copyWith( + color: Colors.deepPurple[300], + fontSize: 14, + ), + ); + } + + final ThemeData base = ThemeData.light(); + return base.copyWith( + textTheme: basicTextTheme(base.textTheme), + primaryColor: Colors.deepPurple[300], + // scaffoldBackgroundColor: Color(0xFFD8CCE7), + secondaryHeaderColor: Colors.deepPurple[300], + iconTheme: IconThemeData( + color: Colors.deepPurple[300], + size: 20.0, + ), + buttonTheme: ButtonThemeData( + buttonColor: Colors.deepPurple[300], + shape: const RoundedRectangleBorder(), + textTheme: ButtonTextTheme.primary, + ), + elevatedButtonTheme: ElevatedButtonThemeData( + style:ElevatedButton.styleFrom( + backgroundColor: const Color(0xFFEADDFF), + foregroundColor: Colors.black) + ), + sliderTheme: SliderThemeData( + activeTrackColor: Colors.deepPurple[300], + overlayColor: Colors.deepPurple[300]?.withAlpha(32), + thumbColor: Colors.deepPurple[300], + ) + ); +} \ No newline at end of file diff --git a/pubspec.lock b/pubspec.lock index 8699116..7d04000 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -1,14 +1,22 @@ # Generated by pub # See https://dart.dev/tools/pub/glossary#lockfile packages: - animated_splash_screen: - dependency: "direct main" + archive: + dependency: transitive description: - name: animated_splash_screen - sha256: f45634db6ec4e8cf034c53e03f3bd83898a16fe3c9286bf5510b6831dfcf2124 + name: archive + sha256: "7b875fd4a20b165a3084bd2d210439b22ebc653f21cea4842729c0c30c82596b" url: "https://pub.dev" source: hosted - version: "1.3.0" + version: "3.4.9" + args: + dependency: transitive + description: + name: args + sha256: eef6c46b622e0494a36c5a12d10d77fb4e855501a91c1b9ef9339326e58f0596 + url: "https://pub.dev" + source: hosted + version: "2.4.2" async: dependency: transitive description: @@ -33,6 +41,22 @@ packages: url: "https://pub.dev" source: hosted version: "1.3.0" + checked_yaml: + dependency: transitive + description: + name: checked_yaml + sha256: feb6bed21949061731a7a75fc5d2aa727cf160b91af9a3e464c5e3a32e28b5ff + url: "https://pub.dev" + source: hosted + version: "2.0.3" + cli_util: + dependency: transitive + description: + name: cli_util + sha256: c05b7406fdabc7a49a3929d4af76bcaccbbffcbcdcf185b082e1ae07da323d19 + url: "https://pub.dev" + source: hosted + version: "0.4.1" clock: dependency: transitive description: @@ -49,6 +73,30 @@ packages: url: "https://pub.dev" source: hosted version: "1.18.0" + connectivity_plus: + dependency: "direct main" + description: + name: connectivity_plus + sha256: b74247fad72c171381dbe700ca17da24deac637ab6d43c343b42867acb95c991 + url: "https://pub.dev" + source: hosted + version: "3.0.6" + connectivity_plus_platform_interface: + dependency: transitive + description: + name: connectivity_plus_platform_interface + sha256: cf1d1c28f4416f8c654d7dc3cd638ec586076255d407cef3ddbdaf178272a71a + url: "https://pub.dev" + source: hosted + version: "1.2.4" + convert: + dependency: transitive + description: + name: convert + sha256: "0f08b14755d163f6e2134cb58222dd25ea2a2ee8a195e53983d57c075324d592" + url: "https://pub.dev" + source: hosted + version: "3.1.1" cross_file: dependency: transitive description: @@ -81,6 +129,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.6" + dbus: + dependency: transitive + description: + name: dbus + sha256: "365c771ac3b0e58845f39ec6deebc76e3276aa9922b0cc60840712094d9047ac" + url: "https://pub.dev" + source: hosted + version: "0.7.10" fake_async: dependency: transitive description: @@ -89,6 +145,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.3.1" + ffi: + dependency: transitive + description: + name: ffi + sha256: "7bf0adc28a23d395f19f3f1eb21dd7cfd1dd9f8e1c50051c069122e6853bc878" + url: "https://pub.dev" + source: hosted + version: "2.1.0" file_selector_linux: dependency: transitive description: @@ -126,6 +190,14 @@ packages: description: flutter source: sdk version: "0.0.0" + flutter_launcher_icons: + dependency: "direct main" + description: + name: flutter_launcher_icons + sha256: "526faf84284b86a4cb36d20a5e45147747b7563d921373d4ee0559c54fcdbcea" + url: "https://pub.dev" + source: hosted + version: "0.13.1" flutter_lints: dependency: "direct dev" description: @@ -180,10 +252,10 @@ packages: dependency: transitive description: name: geolocator_apple - sha256: ab90ae811c42ec2f6021e01eca71df00dee6ff1e69d2c2dafd4daeb0b793f73d + sha256: "1d938e2462cc5145c1402f89d49e70b60a2a51b89fb57414ced71417f1f479b1" url: "https://pub.dev" source: hosted - version: "2.3.2" + version: "2.3.3" geolocator_platform_interface: dependency: transitive description: @@ -280,6 +352,14 @@ packages: url: "https://pub.dev" source: hosted version: "4.0.2" + image: + dependency: transitive + description: + name: image + sha256: "028f61960d56f26414eb616b48b04eb37d700cbe477b7fb09bf1d7ce57fd9271" + url: "https://pub.dev" + source: hosted + version: "4.1.3" image_picker: dependency: "direct main" description: @@ -368,6 +448,14 @@ packages: url: "https://pub.dev" source: hosted version: "0.7.4" + json_annotation: + dependency: transitive + description: + name: json_annotation + sha256: b10a7b2ff83d83c777edba3c6a0f97045ddadd56c944e1a23a3fdf43a1bf4467 + url: "https://pub.dev" + source: hosted + version: "4.8.1" latlong2: dependency: "direct main" description: @@ -464,6 +552,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.4" + nm: + dependency: transitive + description: + name: nm + sha256: "2c9aae4127bdc8993206464fcc063611e0e36e72018696cd9631023a31b24254" + url: "https://pub.dev" + source: hosted + version: "0.5.0" page_transition: dependency: "direct main" description: @@ -528,6 +624,14 @@ packages: url: "https://pub.dev" source: hosted version: "0.2.0" + petitparser: + dependency: transitive + description: + name: petitparser + sha256: c15605cd28af66339f8eb6fbe0e541bfe2d1b72d5825efc6598f3e0a31b9ad27 + url: "https://pub.dev" + source: hosted + version: "6.0.2" plugin_platform_interface: dependency: transitive description: @@ -536,6 +640,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.7" + pointycastle: + dependency: transitive + description: + name: pointycastle + sha256: "7c1e5f0d23c9016c5bbd8b1473d0d3fb3fc851b876046039509e18e0c7485f2c" + url: "https://pub.dev" + source: hosted + version: "3.7.3" polylabel: dependency: transitive description: @@ -677,6 +789,22 @@ packages: url: "https://pub.dev" source: hosted version: "2.0.0" + xml: + dependency: transitive + description: + name: xml + sha256: b015a8ad1c488f66851d762d3090a21c600e479dc75e68328c52774040cf9226 + url: "https://pub.dev" + source: hosted + version: "6.5.0" + yaml: + dependency: transitive + description: + name: yaml + sha256: "75769501ea3489fca56601ff33454fe45507ea3bfb014161abc3b43ae25989d5" + url: "https://pub.dev" + source: hosted + version: "3.1.2" sdks: dart: ">=3.2.2 <4.0.0" flutter: ">=3.16.0" diff --git a/pubspec.yaml b/pubspec.yaml index 11f9a0d..46b5f6a 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -17,7 +17,18 @@ dependencies: image_picker: geolocator: ^9.0.2 page_transition: ^2.1.0 - animated_splash_screen: ^1.1.0 + connectivity_plus: ^3.0.6 + flutter_launcher_icons: ^0.13.1 + +flutter_launcher_icons: + android: "launcher_icon" + ios: true + image_path: "assets/app_icon.webp" + adaptive_icon_foreground: "assets/app_icon.webp" + adaptive_icon_background: "#ffffff" + + min_sdk_android: 21 + dev_dependencies: flutter_test: sdk: flutter @@ -27,3 +38,4 @@ flutter: assets: - assets/ - assets/json/ + - assets/light/ diff --git a/test/widget_test.dart b/test/widget_test.dart index f0e8c4d..91c855c 100644 --- a/test/widget_test.dart +++ b/test/widget_test.dart @@ -13,7 +13,7 @@ import 'package:stepn/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(const PermissionApp()); // Verify that our counter starts at 0. expect(find.text('0'), findsOneWidget);