diff --git a/lib/constant/style.dart b/lib/constant/style.dart index 4425b92..f2697b5 100644 --- a/lib/constant/style.dart +++ b/lib/constant/style.dart @@ -10,30 +10,30 @@ class AppStyle { fontSize: 36, color: AppColor.accentColor, fontFamily: box.read(BoxName.lang) == 'ar' - // ?GoogleFonts.notoNaskhArabic().fontFamily - ? GoogleFonts.notoNaskhArabic().fontFamily - : GoogleFonts.roboto().fontFamily); + // ?GoogleFonts.markaziText().fontFamily + ? GoogleFonts.markaziText().fontFamily + : GoogleFonts.inter().fontFamily); static TextStyle headTitle2 = TextStyle( fontWeight: FontWeight.bold, fontSize: 24, color: AppColor.writeColor, fontFamily: box.read(BoxName.lang) == 'ar' - ? GoogleFonts.notoNaskhArabic().fontFamily - : GoogleFonts.roboto().fontFamily); + ? GoogleFonts.markaziText().fontFamily + : GoogleFonts.inter().fontFamily); static TextStyle title = TextStyle( fontWeight: FontWeight.normal, - fontSize: 14, + fontSize: 16, color: AppColor.writeColor, fontFamily: box.read(BoxName.lang) == 'ar' - ? GoogleFonts.notoNaskhArabic().fontFamily - : GoogleFonts.roboto().fontFamily); + ? GoogleFonts.markaziText().fontFamily + : GoogleFonts.inter().fontFamily); static TextStyle subtitle = TextStyle( fontWeight: FontWeight.bold, fontSize: 12, color: AppColor.writeColor, fontFamily: box.read(BoxName.lang) == 'ar' - ? GoogleFonts.notoNaskhArabic().fontFamily - : GoogleFonts.roboto().fontFamily); + ? GoogleFonts.markaziText().fontFamily + : GoogleFonts.inter().fontFamily); static TextStyle number = const TextStyle( fontWeight: FontWeight.bold, fontSize: 14, diff --git a/lib/controller/functions/package_info.dart b/lib/controller/functions/package_info.dart index 68f00ff..82def9a 100644 --- a/lib/controller/functions/package_info.dart +++ b/lib/controller/functions/package_info.dart @@ -1,6 +1,8 @@ import 'dart:convert'; import 'dart:io'; +import 'dart:ui'; import 'package:sefer_driver/constant/box_name.dart'; +import 'package:sefer_driver/constant/colors.dart'; import 'package:sefer_driver/constant/links.dart'; import 'package:sefer_driver/controller/functions/crud.dart'; import 'package:flutter/cupertino.dart'; @@ -15,7 +17,7 @@ Future checkForUpdate(BuildContext context) async { final packageInfo = await PackageInfo.fromPlatform(); final currentVersion = packageInfo.buildNumber; final version = packageInfo.version; - print('currentVersion is : $currentVersion'); + // print('currentVersion is : $currentVersion'); // Fetch the latest version from your server String latestVersion = await getPackageInfo(); box.write(BoxName.packagInfo, version); @@ -41,36 +43,118 @@ void showUpdateDialog(BuildContext context) { final String storeUrl = Platform.isAndroid ? 'https://play.google.com/store/apps/details?id=com.sefer_driver' : 'https://apps.apple.com/ae/app/sefer-driver/id6502189302'; - showCupertinoDialog( + + showGeneralDialog( context: context, barrierDismissible: false, - builder: (BuildContext context) { - return CupertinoAlertDialog( - title: Text('Update Available'.tr), - content: Text( - 'A new version of the app is available. Please update to the latest version.' - .tr, + barrierColor: Colors.black.withOpacity(0.5), + pageBuilder: (_, __, ___) { + return BackdropFilter( + filter: ImageFilter.blur(sigmaX: 5, sigmaY: 5), + child: Center( + child: AlertDialog( + // Using AlertDialog for a more Material Design look + shape: RoundedRectangleBorder( + borderRadius: + BorderRadius.circular(16)), // More rounded corners + elevation: 4, // Add a bit more elevation + contentPadding: EdgeInsets.zero, // Remove default content padding + content: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Padding( + padding: const EdgeInsets.only(top: 20.0), + child: Image.asset( + 'assets/images/logo.png', + height: 72, // Slightly larger logo + width: 72, + ), + ), + const SizedBox(height: 16), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 24.0), + child: Text( + 'Update Available'.tr, + textAlign: TextAlign.center, + style: Theme.of(context).textTheme.titleLarge?.copyWith( + // Use theme's title style + fontWeight: FontWeight.bold, + ), + ), + ), + Padding( + padding: const EdgeInsets.all(24.0), + child: Text( + 'A new version of the app is available. Please update to the latest version.' + .tr, // More encouraging message + textAlign: TextAlign.center, + style: Theme.of(context).textTheme.bodyMedium?.copyWith( + // Use theme's body style + color: Colors.black87, + ), + ), + ), + const Divider(height: 0), + Row( + children: [ + Expanded( + child: TextButton( + // Using TextButton for "Cancel" + onPressed: () => Navigator.pop(context), + style: TextButton.styleFrom( + foregroundColor: Colors.grey, + shape: const RoundedRectangleBorder( + borderRadius: BorderRadius.only( + bottomLeft: Radius.circular(16), + ), + ), + ), + child: Text('Cancel'.tr), + ), + ), + const SizedBox( + height: 48, + child: VerticalDivider(width: 0), // Using VerticalDivider + ), + Expanded( + child: ElevatedButton( + // Using ElevatedButton for "Update" + onPressed: () async { + if (await canLaunchUrl(Uri.parse(storeUrl))) { + await launchUrl(Uri.parse(storeUrl)); + } + if (context.mounted) Navigator.pop(context); + }, + style: ElevatedButton.styleFrom( + backgroundColor: AppColor + .primaryColor, // Use theme's primary color + foregroundColor: Theme.of(context) + .colorScheme + .onPrimary, // Use theme's onPrimary color + shape: const RoundedRectangleBorder( + borderRadius: BorderRadius.only( + bottomRight: Radius.circular(16), + ), + ), + ), + child: Text('Update'.tr), + ), + ), + ], + ), + ], + ), + ), ), - actions: [ - CupertinoDialogAction( - child: Text('Update'.tr), - onPressed: () async { - if (await canLaunchUrl(Uri.parse(storeUrl))) { - await launchUrl(Uri.parse(storeUrl)); - } else { - print('Could not launch $storeUrl'); - } - - Navigator.of(context).pop(); - }, - ), - CupertinoDialogAction( - child: Text('Cancel'.tr), - onPressed: () async { - Navigator.of(context).pop(); - }, - ), - ], + ); + }, + transitionBuilder: (_, animation, __, child) { + return ScaleTransition( + scale: CurvedAnimation( + parent: animation, + curve: Curves.easeOutCubic, // More natural curve + ), + child: child, ); }, ); diff --git a/lib/controller/local/local_controller.dart b/lib/controller/local/local_controller.dart index 1543c1d..93d42b9 100644 --- a/lib/controller/local/local_controller.dart +++ b/lib/controller/local/local_controller.dart @@ -1,94 +1,88 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; - -import '../../constant/box_name.dart'; -import '../../main.dart'; -import '../themes/themes.dart'; +import 'package:sefer_driver/constant/box_name.dart'; +import 'package:sefer_driver/main.dart'; +import 'package:sefer_driver/controller/themes/themes.dart'; class LocaleController extends GetxController { Locale? language; String countryCode = ''; - void restartApp() { - // Get.offAll(MyApp); - runApp(MyApp()); - } - ThemeData appTheme = themeEnglish; + ThemeData appTheme = lightThemeEnglish; - changeLang(String langcode) { + void changeLang(String langcode) { Locale locale; switch (langcode) { case "ar": locale = const Locale("ar"); - appTheme = themeArabic; + appTheme = lightThemeArabic; box.write(BoxName.lang, 'ar'); break; case "en": locale = const Locale("en"); - appTheme = themeEnglish; + appTheme = lightThemeEnglish; box.write(BoxName.lang, 'en'); break; case "tr": locale = const Locale("tr"); - appTheme = themeEnglish; + appTheme = lightThemeEnglish; box.write(BoxName.lang, 'tr'); break; case "fr": locale = const Locale("fr"); - appTheme = themeEnglish; + appTheme = lightThemeEnglish; box.write(BoxName.lang, 'fr'); break; case "it": locale = const Locale("it"); - appTheme = themeEnglish; + appTheme = lightThemeEnglish; box.write(BoxName.lang, 'it'); break; case "de": locale = const Locale("de"); - appTheme = themeEnglish; + appTheme = lightThemeEnglish; box.write(BoxName.lang, 'de'); break; case "el": locale = const Locale("el"); - appTheme = themeEnglish; + appTheme = lightThemeEnglish; box.write(BoxName.lang, 'el'); break; case "es": locale = const Locale("es"); - appTheme = themeEnglish; + appTheme = lightThemeEnglish; box.write(BoxName.lang, 'es'); break; case "fa": locale = const Locale("fa"); - appTheme = themeEnglish; + appTheme = lightThemeEnglish; box.write(BoxName.lang, 'fa'); break; case "zh": locale = const Locale("zh"); - appTheme = themeEnglish; + appTheme = lightThemeEnglish; box.write(BoxName.lang, 'zh'); break; case "ru": locale = const Locale("ru"); - appTheme = themeEnglish; + appTheme = lightThemeEnglish; box.write(BoxName.lang, 'ru'); break; case "hi": locale = const Locale("hi"); - appTheme = themeEnglish; + appTheme = lightThemeEnglish; box.write(BoxName.lang, 'hi'); break; default: locale = Locale(Get.deviceLocale!.languageCode); box.write(BoxName.lang, Get.deviceLocale!.languageCode); - appTheme = themeEnglish; + appTheme = lightThemeEnglish; break; } box.write(BoxName.lang, langcode); Get.changeTheme(appTheme); Get.updateLocale(locale); - restartApp(); update(); } diff --git a/lib/controller/local/translations.dart b/lib/controller/local/translations.dart index 782d122..9dd87bb 100644 --- a/lib/controller/local/translations.dart +++ b/lib/controller/local/translations.dart @@ -925,10 +925,50 @@ Store your money with us and receive it in your bank as a monthly salary.''': "You will get cost of your work for this trip": "ستحصل على تكلفة عملك لهذه الرحلة", "in your wallet": "في محفظتك", - "you gain": "تكسب", + "you gain": "تكسب", "Account": "الحساب", + "Wallet": "المحفظة", "Maintenance Offer": "عرض الصيانة", + "Enter your Question here": "أدخل سؤالك هنا", + "Ineligible for Offer": "غير مؤهل للحصول على العرض", + "You should complete 500 trips to unlock this feature.": + "يجب عليك إكمال 500 رحلة لتفعيل هذه الميزة.", + "Thank You!": "شكراً لك!", + "Your rating has been submitted.": "تم إرسال تقييمك.", + "General": "عام", + "Language": "اللغة", + "You can change the language of the app": "يمكنك تغيير لغة التطبيق", + "Change Country": "تغيير الدولة", + "Don't start trip if passenger not in your car": + "لا تبدأ الرحلة إذا لم يكن الراكب في سيارتك", + "You can change the Country to get all features": + "يمكنك تغيير الدولة للحصول على جميع الميزات", + "Slide to End Trip": "‏اسحب لإنهاء الرحلة", + "App Preferences": "تفضيلات التطبيق", + "Google Map App": "تطبيق خرائط جوجل", + "If you want to make Google Map App run directly when you apply order": + "إذا كنت تريد تشغيل تطبيق خرائط جوجل مباشرة عند تطبيق الطلب", + "Vibration": "الاهتزاز", + + "Help & Support": "المساعدة والدعم", + + "Please select a rating before submitting.": + "يرجى تحديد تقييم قبل الإرسال.", + + "Please check back later for available rides.": + "يرجى التحقق مرة أخرى لاحقًا للحصول على الرحلات المتاحة.", + "Please enter your question": "يرجى إدخال سؤالك", + "Submit Question": "إرسال السؤال", + "Your Questions": "أسئلتك", + "No questions asked yet.": "لم يتم طرح أي أسئلة بعد.", + "Activities": "الأنشطة", + "History of Trip": "سجل الرحلات", + "Available for rides": "متاح للرحلات", + "Support": "الدعم", + + "Helping Center": "مركز المساعدة", + "More": "المزيد", "Order Cancelled": "الطلب ملغى", "Order Cancelled by Passenger": "تم إلغاء الطلب من قبل الراكب", - "Success": "النجاح", + "Success": "‏تمام", "Feedback data saved successfully": "تم حفظ بيانات التقييم بنجاح", "No Promo for today .": "لا ترويج لليوم.", "Select your destination": "اختر وجهتك", diff --git a/lib/controller/notification/notification_captain_controller.dart b/lib/controller/notification/notification_captain_controller.dart index 68d474d..5fc65de 100644 --- a/lib/controller/notification/notification_captain_controller.dart +++ b/lib/controller/notification/notification_captain_controller.dart @@ -1,8 +1,10 @@ import 'dart:convert'; +import 'package:flutter/cupertino.dart'; import 'package:get/get.dart'; import 'package:sefer_driver/constant/style.dart'; import 'package:sefer_driver/views/widgets/elevated_btn.dart'; +import 'package:sefer_driver/views/widgets/mydialoug.dart'; import '../../constant/box_name.dart'; import '../../constant/links.dart'; @@ -20,16 +22,43 @@ class NotificationCaptainController extends GetxController { link: AppLink.getNotificationCaptain, payload: {'driverID': box.read(BoxName.driverID)}); if (res == "failure") { - Get.defaultDialog( - title: 'There is no notification yet'.tr, - titleStyle: AppStyle.title, - middleText: '', - confirm: MyElevatedButton( - title: 'Back', + // MyDialog().getDialog('There is no notification yet'.tr, '', () { + // Get.back(); + // Get.back(); + // }); + Get.dialog( + CupertinoAlertDialog( + title: Column( + children: [ + const Icon( + CupertinoIcons.bell_slash_fill, + color: CupertinoColors.systemGrey, + size: 40, + ), + const SizedBox(height: 12), + Text( + 'There is no notification yet'.tr, + style: const TextStyle( + fontSize: 17, + fontWeight: FontWeight.w600, + ), + ), + ], + ), + actions: [ + CupertinoDialogAction( onPressed: () { Get.back(); Get.back(); - })); + }, + child: Text('Back'.tr), + ), + ], + ), + barrierDismissible: true, + transitionCurve: Curves.easeOutBack, + transitionDuration: const Duration(milliseconds: 200), + ); } notificationData = jsonDecode(res); // sql.insertData(notificationData['message'], TableName.captainNotification); diff --git a/lib/controller/notification/ride_available_controller.dart b/lib/controller/notification/ride_available_controller.dart index e9fc9d7..8dbac9d 100644 --- a/lib/controller/notification/ride_available_controller.dart +++ b/lib/controller/notification/ride_available_controller.dart @@ -1,6 +1,8 @@ import 'dart:convert'; import 'dart:math'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/services.dart'; import 'package:sefer_driver/constant/box_name.dart'; import 'package:sefer_driver/controller/functions/location_controller.dart'; import 'package:geolocator/geolocator.dart'; @@ -79,31 +81,98 @@ class RideAvailableController extends GetxController { // } getRideAvailable() async { - isLoading = true; - LatLngBounds bounds = calculateBounds( - Get.find().myLocation!.latitude, - Get.find().myLocation!.longitude, - 4000); - var payload = { - // "carType": box.read(BoxName.carTypeOfDriver).toString(), - 'southwestLat': bounds.southwest.latitude.toString(), - 'southwestLon': bounds.southwest.longitude.toString(), - 'northeastLat': bounds.northeast.latitude.toString(), - 'northeastLon': bounds.northeast.longitude.toString(), - }; - Log.print('payload: ${payload}'); - var res = await CRUD().get(link: AppLink.getRideWaiting, payload: payload); - Log.print('res: ${res}'); + try { + isLoading = true; + update(); - if (res != 'failure') { - rideAvailableMap = jsonDecode(res); + LatLngBounds bounds = calculateBounds( + Get.find().myLocation!.latitude, + Get.find().myLocation!.longitude, + 4000); + + var payload = { + 'southwestLat': bounds.southwest.latitude.toString(), + 'southwestLon': bounds.southwest.longitude.toString(), + 'northeastLat': bounds.northeast.latitude.toString(), + 'northeastLon': bounds.northeast.longitude.toString(), + }; + + var res = + await CRUD().get(link: AppLink.getRideWaiting, payload: payload); + + if (res != 'failure') { + rideAvailableMap = jsonDecode(res); + isLoading = false; + update(); + } else { + HapticFeedback.lightImpact(); + Get.dialog( + CupertinoAlertDialog( + title: Column( + mainAxisSize: MainAxisSize.min, + children: [ + const Icon( + CupertinoIcons.car, + size: 44, + color: CupertinoColors.systemGrey, + ), + const SizedBox(height: 12), + Text( + "No Rides Available".tr, + style: const TextStyle( + fontSize: 17, + fontWeight: FontWeight.w600, + ), + ), + ], + ), + content: Padding( + padding: const EdgeInsets.only(top: 8), + child: Text( + "Please check back later for available rides.".tr, + style: const TextStyle( + fontSize: 13, + color: CupertinoColors.systemGrey, + ), + ), + ), + actions: [ + CupertinoDialogAction( + onPressed: () { + Get.back(); + Get.back(); + }, + child: Text('OK'.tr), + ), + ], + ), + barrierDismissible: true, + transitionCurve: Curves.easeOutBack, + transitionDuration: const Duration(milliseconds: 200), + ); + } + } catch (e) { isLoading = false; update(); - } else { - MyDialog().getDialog("No Rides Available".tr, '', () { - Get.back(); - Get.back(); - }); + Get.dialog( + CupertinoAlertDialog( + title: const Icon( + CupertinoIcons.exclamationmark_triangle_fill, + color: CupertinoColors.systemRed, + size: 44, + ), + content: Text( + "Error fetching rides. Please try again.".tr, + style: const TextStyle(fontSize: 14), + ), + actions: [ + CupertinoDialogAction( + onPressed: () => Get.back(), + child: Text('OK'.tr), + ), + ], + ), + ); } } diff --git a/lib/controller/themes/themes.dart b/lib/controller/themes/themes.dart index 7de5aa1..8e81e2a 100644 --- a/lib/controller/themes/themes.dart +++ b/lib/controller/themes/themes.dart @@ -1,21 +1,22 @@ import 'package:flutter/material.dart'; import 'package:sefer_driver/constant/style.dart'; - import '../../constant/colors.dart'; -ThemeData themeEnglish = ThemeData( - fontFamily: "PlayfairDisplay", +ThemeData lightThemeEnglish = ThemeData( + brightness: Brightness.light, + fontFamily: "SFPro", textTheme: TextTheme( - displaySmall: AppStyle.title, - displayLarge: AppStyle.title, - displayMedium: AppStyle.title, - bodyLarge: AppStyle.title, - bodyMedium: AppStyle.title), + displaySmall: AppStyle.title, + displayLarge: AppStyle.headTitle, + displayMedium: AppStyle.headTitle2, + bodyLarge: AppStyle.title, + bodyMedium: AppStyle.subtitle, + ), primarySwatch: Colors.blue, dialogTheme: DialogTheme( backgroundColor: AppColor.secondaryColor, contentTextStyle: AppStyle.title, - titleTextStyle: AppStyle.title, + titleTextStyle: AppStyle.headTitle2, ), appBarTheme: AppBarTheme( elevation: 0, @@ -25,35 +26,122 @@ ThemeData themeEnglish = ThemeData( color: AppColor.primaryColor, ), toolbarTextStyle: TextTheme( - titleSmall: AppStyle.subtitle, - headlineSmall: AppStyle.title, - titleLarge: AppStyle.headTitle2) - .bodyMedium, + titleSmall: AppStyle.subtitle, + headlineSmall: AppStyle.title, + titleLarge: AppStyle.headTitle2, + ).bodyMedium, titleTextStyle: TextTheme( - titleSmall: AppStyle.subtitle, - headlineSmall: AppStyle.title, - titleLarge: AppStyle.headTitle2) - .titleLarge, + titleSmall: AppStyle.subtitle, + headlineSmall: AppStyle.title, + titleLarge: AppStyle.headTitle2, + ).titleLarge, ), ); -ThemeData themeArabic = ThemeData( - fontFamily: 'mohanad', - textTheme: const TextTheme( - displayLarge: TextStyle( - fontWeight: FontWeight.bold, - fontSize: 22, - color: AppColor.primaryColor), - displayMedium: TextStyle( - fontWeight: FontWeight.bold, - fontSize: 26, - color: AppColor.primaryColor), - bodyLarge: TextStyle( - height: 2, - color: AppColor.accentColor, - fontWeight: FontWeight.bold, - fontSize: 14), - bodyMedium: - TextStyle(height: 2, color: AppColor.accentColor, fontSize: 14)), +ThemeData darkThemeEnglish = ThemeData( + brightness: Brightness.dark, + fontFamily: "SFPro", + textTheme: TextTheme( + displaySmall: AppStyle.title, + displayLarge: AppStyle.headTitle, + displayMedium: AppStyle.headTitle2, + bodyLarge: AppStyle.title, + bodyMedium: AppStyle.subtitle, + ), primarySwatch: Colors.blue, + dialogTheme: DialogTheme( + backgroundColor: AppColor.secondaryColor, + contentTextStyle: AppStyle.title, + titleTextStyle: AppStyle.headTitle2, + ), + appBarTheme: AppBarTheme( + elevation: 0, + color: AppColor.secondaryColor, + centerTitle: true, + iconTheme: const IconThemeData( + color: AppColor.primaryColor, + ), + toolbarTextStyle: TextTheme( + titleSmall: AppStyle.subtitle, + headlineSmall: AppStyle.title, + titleLarge: AppStyle.headTitle2, + ).bodyMedium, + titleTextStyle: TextTheme( + titleSmall: AppStyle.subtitle, + headlineSmall: AppStyle.title, + titleLarge: AppStyle.headTitle2, + ).titleLarge, + ), +); + +ThemeData lightThemeArabic = ThemeData( + brightness: Brightness.light, + fontFamily: 'SFArabic', + textTheme: TextTheme( + displaySmall: AppStyle.title, + displayLarge: AppStyle.headTitle, + displayMedium: AppStyle.headTitle2, + bodyLarge: AppStyle.title, + bodyMedium: AppStyle.subtitle, + ), + primarySwatch: Colors.blue, + dialogTheme: DialogTheme( + backgroundColor: AppColor.secondaryColor, + contentTextStyle: AppStyle.title, + titleTextStyle: AppStyle.headTitle2, + ), + appBarTheme: AppBarTheme( + elevation: 0, + color: AppColor.secondaryColor, + centerTitle: true, + iconTheme: const IconThemeData( + color: AppColor.primaryColor, + ), + toolbarTextStyle: TextTheme( + titleSmall: AppStyle.subtitle, + headlineSmall: AppStyle.title, + titleLarge: AppStyle.headTitle2, + ).bodyMedium, + titleTextStyle: TextTheme( + titleSmall: AppStyle.subtitle, + headlineSmall: AppStyle.title, + titleLarge: AppStyle.headTitle2, + ).titleLarge, + ), +); + +ThemeData darkThemeArabic = ThemeData( + brightness: Brightness.dark, + fontFamily: 'SFArabic', + textTheme: TextTheme( + displaySmall: AppStyle.title, + displayLarge: AppStyle.headTitle, + displayMedium: AppStyle.headTitle2, + bodyLarge: AppStyle.title, + bodyMedium: AppStyle.subtitle, + ), + primarySwatch: Colors.blue, + dialogTheme: DialogTheme( + backgroundColor: AppColor.secondaryColor, + contentTextStyle: AppStyle.title, + titleTextStyle: AppStyle.headTitle2, + ), + appBarTheme: AppBarTheme( + elevation: 0, + color: AppColor.secondaryColor, + centerTitle: true, + iconTheme: const IconThemeData( + color: AppColor.primaryColor, + ), + toolbarTextStyle: TextTheme( + titleSmall: AppStyle.subtitle, + headlineSmall: AppStyle.title, + titleLarge: AppStyle.headTitle2, + ).bodyMedium, + titleTextStyle: TextTheme( + titleSmall: AppStyle.subtitle, + headlineSmall: AppStyle.title, + titleLarge: AppStyle.headTitle2, + ).titleLarge, + ), ); diff --git a/lib/views/Rate/rate_app_page.dart b/lib/views/Rate/rate_app_page.dart index 660017a..23ef7bd 100644 --- a/lib/views/Rate/rate_app_page.dart +++ b/lib/views/Rate/rate_app_page.dart @@ -1,84 +1,142 @@ -import 'package:sefer_driver/views/widgets/elevated_btn.dart'; -import 'package:sefer_driver/views/widgets/my_textField.dart'; +import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; import '../../controller/rate/rate_app_controller.dart'; class RatingScreen extends StatelessWidget { - // Initialize the RatingController using GetX for state management final RatingController ratingController = Get.put(RatingController()); @override Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar( - // Display title "Rate Our App", with .tr for localization support - title: Text("Rate Our App".tr), + return CupertinoPageScaffold( + navigationBar: CupertinoNavigationBar( + middle: Text( + "Rate Our App".tr, + style: const TextStyle(fontWeight: FontWeight.bold), + ), ), - body: Center( - child: Obx(() { - // Observe changes in userRating; when updated, rebuild the UI accordingly - return Padding( - padding: const EdgeInsets.all(8.0), - child: ListView( - // mainAxisAlignment: - // MainAxisAlignment.center, // Center content vertically - children: [ - ClipRRect( - borderRadius: BorderRadius.circular(15), - child: Image.asset('assets/images/logo.gif')), - const SizedBox(height: 10), - // Text prompt asking the user to rate the app, with localization support - Text("How would you rate our app?".tr), - const SizedBox(height: 10), // Vertical spacing between elements - MyTextForm( - controller: ratingController.comment, - label: 'write comment here'.tr, - hint: 'write comment here'.tr, - type: TextInputType.name, - ), - // Build and display the row of rating stars - _buildRatingStars(), + child: SafeArea( + child: SingleChildScrollView( + child: Center( + child: Obx(() { + return Padding( + padding: + const EdgeInsets.symmetric(horizontal: 20, vertical: 30), + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + // App logo or visual + ClipRRect( + borderRadius: BorderRadius.circular(16), + child: Image.asset( + 'assets/images/logo.gif', + height: 120, + ), + ), + const SizedBox(height: 20), - const SizedBox( - height: 20), // Additional spacing before the button + // Rating Prompt + Text( + "How would you rate our app?".tr, + textAlign: TextAlign.center, + style: CupertinoTheme.of(context) + .textTheme + .navTitleTextStyle + .copyWith(fontSize: 18, fontWeight: FontWeight.w600), + ), + const SizedBox(height: 20), - // Button to submit the selected rating - MyElevatedButton( - onPressed: () { - // Calls submitRating() method in the controller with the current rating value - ratingController - .submitRating(ratingController.userRating.value); - }, - // Button text "Submit Rating" with localization support - title: "Submit Rating".tr, + // Comment Box + CupertinoTextField( + controller: ratingController.comment, + placeholder: 'Write your comment here'.tr, + padding: const EdgeInsets.all(12), + decoration: BoxDecoration( + border: Border.all(color: CupertinoColors.systemGrey4), + borderRadius: BorderRadius.circular(12), + color: CupertinoColors.white, + ), + prefix: Padding( + padding: const EdgeInsets.only(left: 8.0), + child: Icon(CupertinoIcons.pencil_ellipsis_rectangle, + color: CupertinoColors.systemGrey), + ), + ), + const SizedBox(height: 20), + + // Star Rating Section + _buildRatingStars(), + + const SizedBox(height: 30), + + // Submit Button + CupertinoButton( + padding: const EdgeInsets.symmetric( + horizontal: 24, vertical: 14), + borderRadius: BorderRadius.circular(12), + color: CupertinoColors.activeGreen, + onPressed: () { + if (ratingController.userRating.value > 0) { + ratingController + .submitRating(ratingController.userRating.value); + Get.snackbar( + "Thank You!".tr, + "Your rating has been submitted.".tr, + backgroundColor: CupertinoColors.systemGrey6, + snackPosition: SnackPosition.BOTTOM, + margin: const EdgeInsets.all(16), + borderRadius: 12, + ); + } else { + Get.snackbar( + "Error".tr, + "Please select a rating before submitting.".tr, + backgroundColor: CupertinoColors.systemRed, + snackPosition: SnackPosition.BOTTOM, + margin: const EdgeInsets.all(16), + borderRadius: 12, + ); + } + }, + child: Text( + "Submit Rating".tr, + style: const TextStyle( + color: CupertinoColors.white, + fontSize: 16, + fontWeight: FontWeight.bold, + ), + ), + ), + ], ), - ], - ), - ); - }), + ); + }), + ), + ), ), ); } - // Widget function to display a row of clickable star icons for rating + // Widget for building rating stars with animations Widget _buildRatingStars() { return Row( - mainAxisAlignment: - MainAxisAlignment.center, // Center-aligns stars horizontally + mainAxisAlignment: MainAxisAlignment.center, children: List.generate(5, (index) { - return IconButton( - // Display a star icon, filled if selected, otherwise grey - icon: Icon( - Icons.star, - color: index < ratingController.userRating.value - ? Colors.orange // Orange for selected stars - : Colors.grey, // Grey for unselected stars - ), - onPressed: () { - // Update user rating in the controller when a star is clicked + return GestureDetector( + onTap: () { ratingController.userRating.value = index + 1; }, + child: AnimatedContainer( + duration: const Duration(milliseconds: 300), + margin: const EdgeInsets.symmetric(horizontal: 4), + child: Icon( + CupertinoIcons.star_fill, + size: 40, + color: index < ratingController.userRating.value + ? CupertinoColors.systemYellow + : CupertinoColors.systemGrey3, + ), + ), ); }), ); diff --git a/lib/views/home/Captin/About Us/settings_captain.dart b/lib/views/home/Captin/About Us/settings_captain.dart index 03f08f4..f0c6c71 100644 --- a/lib/views/home/Captin/About Us/settings_captain.dart +++ b/lib/views/home/Captin/About Us/settings_captain.dart @@ -2,7 +2,6 @@ import 'package:sefer_driver/constant/colors.dart'; import 'package:sefer_driver/controller/profile/setting_controller.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; -import 'package:flutter_font_icons/flutter_font_icons.dart'; import 'package:get/get.dart'; import 'package:sefer_driver/constant/style.dart'; import 'package:sefer_driver/views/lang/languages.dart'; @@ -25,140 +24,134 @@ class SettingsCaptain extends StatelessWidget { title: 'Settings'.tr, body: [ ListView( + physics: const BouncingScrollPhysics(), children: [ - ListTile( - leading: const Icon(Icons.language), - title: Text( - 'Language'.tr, - style: AppStyle.headTitle2, - ), - subtitle: Text('You can change the language of the app'.tr), - onTap: () => Get.to(const Language()), - ), - const Divider( - endIndent: 44, - indent: 44, - ), - ListTile( - leading: const Icon(Icons.place_outlined), - title: Text( - 'Change Country'.tr, - style: AppStyle.headTitle2, - ), - subtitle: - Text('You can change the Country to get all features'.tr), - onTap: () => Get.to(MyScafolld( - title: 'Change Country'.tr, - body: [CountryPickerFromSetting()], - isleading: true)), - ), - const Divider( - endIndent: 44, - indent: 44, - ), - ListTile( - leading: const Icon( - MaterialCommunityIcons.map_marker_radius, - color: AppColor.redColor, - ), - title: Text( - 'Google Map App'.tr, - style: AppStyle.headTitle2, - ), - subtitle: Text( - 'If you want to make Google Map App run directly when you apply order' - .tr), - trailing: - GetBuilder(builder: (settingController) { - return CupertinoSwitch( - value: settingController.isGoogleMapsEnabled, - activeColor: AppColor.primaryColor, - onChanged: (bool value) { - settingController.onChangMapApp(); - }, - ); - }), - ), - const Divider( - endIndent: 44, - indent: 44, - ), - ListTile( - leading: const Icon(Icons.question_answer), - title: Text( - 'Frequently Questions'.tr, - style: AppStyle.headTitle2, - ), - subtitle: Text( - 'You can change the Country to get all features'.tr, - style: AppStyle.title, - ), - onTap: () => Get.to(() => const FrequentlyQuestionsPage()), - ), - const Divider( - endIndent: 44, - indent: 44, - ), - ListTile( - leading: const Icon(Icons.vibration), - title: Text( - 'Vibration'.tr, - style: AppStyle.headTitle2, - ), - subtitle: Text( - "You can change the vibration feedback for all buttons".tr, - style: AppStyle.title, - ), - trailing: GetBuilder( - builder: (controller) => CupertinoSwitch( - value: controller.isVibrate, - onChanged: controller.changeVibrateOption, - activeColor: AppColor.primaryColor, - )), - onTap: () => print('3'), - ), - const Divider( - endIndent: 44, - indent: 44, - ), - ListTile( - leading: const Icon(Icons.help_outline), - title: Text( - "How to use SEFER".tr, - style: AppStyle.headTitle2, - ), - subtitle: Text( - ''.tr, - style: AppStyle.title, - ), - onTap: () => Get.to(() => const UsingAppPage()), + // General Section + _buildSectionHeader('General'.tr), + CupertinoListSection( + margin: EdgeInsets.zero, + children: [ + CupertinoListTile( + leading: const Icon(CupertinoIcons.globe), + title: Text('Language'.tr, style: AppStyle.headTitle2), + subtitle: Text('You can change the language of the app'.tr, + style: AppStyle.subtitle), + trailing: const CupertinoListTileChevron(), + onTap: () => Get.to(const Language()), + ), + CupertinoListTile( + leading: const Icon(CupertinoIcons.flag_fill), + title: Text('Change Country'.tr, style: AppStyle.headTitle2), + subtitle: Text( + 'You can change the Country to get all features'.tr, + style: AppStyle.subtitle), + trailing: const CupertinoListTileChevron(), + onTap: () => Get.to( + MyScafolld( + title: 'Change Country'.tr, + body: [CountryPickerFromSetting()], + isleading: true, + // isCupertino: true, // Indicate it's a Cupertino style page + ), + ), + ), + ], ), - const Divider( - endIndent: 44, - indent: 44, + // App Preferences Section + _buildSectionHeader('App Preferences'.tr), + CupertinoListSection( + margin: EdgeInsets.zero, + children: [ + CupertinoListTile( + leading: Icon( + CupertinoIcons.map_pin_ellipse, + color: AppColor.redColor, + ), + title: Text('Google Map App'.tr, style: AppStyle.headTitle2), + subtitle: Text( + 'If you want to make Google Map App run directly when you apply order' + .tr, + style: AppStyle.subtitle, + ), + trailing: GetBuilder( + builder: (settingController) { + return CupertinoSwitch( + value: settingController.isGoogleMapsEnabled, + activeTrackColor: AppColor.primaryColor, + onChanged: (bool value) { + settingController.onChangMapApp(); + }, + ); + }, + ), + ), + CupertinoListTile( + leading: Icon(Icons.vibration), + title: Text('Vibration'.tr, style: AppStyle.headTitle2), + subtitle: Text( + "You can change the vibration feedback for all buttons".tr, + style: AppStyle.subtitle, + ), + trailing: GetBuilder( + builder: (controller) => CupertinoSwitch( + value: controller.isVibrate, + onChanged: controller.changeVibrateOption, + activeTrackColor: AppColor.primaryColor, + ), + ), + onTap: () => print('3'), + ), + ], ), - ListTile( - leading: const Icon(Icons.account_balance_outlined), - title: Text( - 'About Us'.tr, - style: AppStyle.headTitle2, - ), - subtitle: Text( - 'You can change the Country to get all features'.tr, - style: AppStyle.title, - ), - onTap: () => Get.to(() => const AboutPage()), + + // Help & Support Section + _buildSectionHeader('Help & Support'.tr), + CupertinoListSection( + margin: EdgeInsets.zero, + children: [ + CupertinoListTile( + leading: const Icon(CupertinoIcons.question_circle_fill), + title: Text('Frequently Questions'.tr, + style: AppStyle.headTitle2), + trailing: const CupertinoListTileChevron(), + onTap: () => Get.to(() => const FrequentlyQuestionsPage()), + ), + CupertinoListTile( + leading: const Icon(CupertinoIcons.hand_raised_fill), + title: + Text("How to use SEFER".tr, style: AppStyle.headTitle2), + trailing: const CupertinoListTileChevron(), + onTap: () => Get.to(() => const UsingAppPage()), + ), + CupertinoListTile( + leading: const Icon(CupertinoIcons.info_circle_fill), + title: Text('About Us'.tr, style: AppStyle.headTitle2), + trailing: const CupertinoListTileChevron(), + onTap: () => Get.to(() => const AboutPage()), + ), + ], ), - // ListTile( - // leading: const Icon(Icons.account_circle), - // title: const Text('Account'), - // onTap: () => Navigator.pushNamed(context, '/account-settings'), - // ), + const SizedBox(height: 16), ], ), ], isleading: true, + // isCupertino: true, // Indicate this screen is generally Cupertino style + ); + } + + Widget _buildSectionHeader(String title) { + return Padding( + padding: const EdgeInsets.only(left: 16.0, top: 20.0, bottom: 10.0), + child: Text( + title, + style: const TextStyle( + fontSize: 17.0, + fontWeight: FontWeight.w600, + color: CupertinoColors.secondaryLabel, + ), + ), ); } } diff --git a/lib/views/home/Captin/assurance_health_page.dart b/lib/views/home/Captin/assurance_health_page.dart index 4d6654a..09c9816 100644 --- a/lib/views/home/Captin/assurance_health_page.dart +++ b/lib/views/home/Captin/assurance_health_page.dart @@ -175,7 +175,7 @@ class AssuranceHealthPage extends StatelessWidget { // .tr, // backgroundColor: // CupertinoColors.systemGrey); - mySnackbarSuccess( + mySnackeBarError( "You have chosen not to proceed with health insurance." .tr); }, diff --git a/lib/views/home/Captin/home_captain/drawer_captain.dart b/lib/views/home/Captin/home_captain/drawer_captain.dart index f65f8d5..cffc450 100644 --- a/lib/views/home/Captin/home_captain/drawer_captain.dart +++ b/lib/views/home/Captin/home_captain/drawer_captain.dart @@ -1,5 +1,6 @@ import 'package:sefer_driver/constant/api_key.dart'; import 'package:sefer_driver/constant/links.dart'; +import 'package:sefer_driver/constant/style.dart'; import 'package:sefer_driver/controller/home/captin/home_captain_controller.dart'; import 'package:sefer_driver/views/Rate/rate_app_page.dart'; import 'package:sefer_driver/views/auth/captin/contact_us_page.dart'; @@ -25,108 +26,304 @@ import '../assurance_health_page.dart'; import '../maintain_center_page.dart'; import 'package:flutter/cupertino.dart'; +// class CupertinoDrawerCaptain extends StatelessWidget { +// final ImageController imageController = Get.put(ImageController()); + +// @override +// Widget build(BuildContext context) { +// return CupertinoPageScaffold( +// navigationBar: CupertinoNavigationBar( +// middle: Text('Menu'.tr), +// ), +// child: SafeArea( +// child: CustomScrollView( +// slivers: [ +// const SliverToBoxAdapter(child: const UserAccountHeader()), +// SliverList( +// delegate: SliverChildListDelegate([ +// _buildDivider(), +// _buildDrawerItem( +// icon: CupertinoIcons.money_dollar, +// text: 'Wallet'.tr, +// onTap: () => Get.to(() => WalletCaptain()), +// ), +// _buildDivider(), +// _buildDrawerItem( +// icon: CupertinoIcons.person, +// text: 'Profile'.tr, +// onTap: () => Get.to(() => ProfileCaptain()), +// ), +// _buildDivider(), +// _buildDrawerItem( +// icon: CupertinoIcons.clock, +// text: 'History of Trip'.tr, +// onTap: () => Get.to(() => const HistoryCaptain()), +// ), +// _buildDivider(), +// _buildDrawerItem( +// icon: CupertinoIcons.car_detailed, +// text: 'Available for rides'.tr, +// onTap: () => Get.to(() => const AvailableRidesPage()), +// ), +// _buildDivider(), +// _buildDrawerItem( +// icon: CupertinoIcons.bell, +// text: 'Notifications'.tr, +// onTap: () => Get.to(() => const NotificationCaptain()), +// ), +// _buildDivider(), +// _buildDrawerItem( +// icon: CupertinoIcons.question_circle, +// text: 'Helping Center'.tr, +// onTap: () => Get.to(() => HelpCaptain()), +// ), +// _buildDivider(), +// _buildDrawerItem( +// icon: CupertinoIcons.share, +// text: 'Share App'.tr, +// onTap: () => Get.to(() => InviteScreen()), +// ), +// _buildDivider(), +// _buildDrawerItem( +// icon: CupertinoIcons.wrench, +// text: "Maintenance Center".tr, +// onTap: () => Get.to(() => MaintainCenterPage()), +// ), +// _buildDivider(), +// _buildDrawerItem( +// icon: +// CupertinoIcons.heart, // Updated icon to represent health +// text: "Health Insurance".tr, // Updated English text +// onTap: () => Get.to(() => AssuranceHealthPage()), +// ), +// _buildDivider(), +// _buildDrawerItem( +// icon: CupertinoIcons.mail, +// text: "Contact Us".tr, +// onTap: () => Get.to(() => ContactUsPage()), +// ), +// _buildDivider(), +// _buildDrawerItem( +// icon: +// Icons.play_circle_filled, // Icon representing video play +// text: 'Videos Tutorials'.tr, +// onTap: () => Get.to(() => VideoListPage()), +// ), +// _buildDivider(), +// _buildDrawerItem( +// icon: Icons.star, // Another option with a filled star icon +// text: "Rate Our App".tr, +// onTap: () => Get.to(() => RatingScreen()), +// ), +// _buildDivider(), +// _buildDrawerItem( +// icon: CupertinoIcons.settings, +// text: 'Settings'.tr, +// onTap: () => Get.to(() => const SettingsCaptain()), +// ), +// _buildDivider(), +// _buildDrawerItem( +// icon: CupertinoIcons.square_arrow_right, +// text: 'Sign Out'.tr, +// onTap: () => Get.to(() => const LogoutCaptain()), +// ), +// _buildDivider(), +// ]), +// ), +// ], +// ), +// ), +// ); +// } + +// Widget _buildDivider() { +// return const Divider( +// thickness: 1, +// height: 1, +// color: CupertinoColors.systemGrey4, +// ); +// } + +// Widget _buildDrawerItem({ +// required IconData icon, +// required String text, +// required VoidCallback onTap, +// }) { +// return CupertinoButton( +// onPressed: onTap, +// child: Row( +// children: [ +// Icon(icon, color: CupertinoColors.activeBlue), +// const SizedBox(width: 10), +// Text(text, style: const TextStyle(color: CupertinoColors.label)), +// const Spacer(), +// const Icon(CupertinoIcons.right_chevron, +// color: CupertinoColors.systemGrey), +// ], +// ), +// ); +// } +// } + +// class UserAccountHeader extends StatelessWidget { +// const UserAccountHeader({super.key}); + +// @override +// Widget build(BuildContext context) { +// return Container( +// padding: const EdgeInsets.all(16), +// decoration: const BoxDecoration( +// gradient: LinearGradient( +// colors: [AppColor.blueColor, AppColor.twitterColor], +// begin: Alignment.topLeft, +// end: Alignment.bottomRight, +// ), +// ), +// child: Column( +// crossAxisAlignment: CrossAxisAlignment.start, +// children: [ +// GetBuilder( +// builder: (imageController) { +// return Stack( +// children: [ +// imageController.isloading +// ? const CupertinoActivityIndicator() +// : Container( +// width: 100, +// height: 100, +// decoration: BoxDecoration( +// shape: BoxShape.circle, +// image: DecorationImage( +// fit: BoxFit.cover, +// image: NetworkImage( +// '${AppLink.seferCairoServer}/portrate_captain_image/${box.read(BoxName.driverID)}.jpg', +// ), +// ), +// ), +// ), +// Positioned( +// right: 0, +// top: 0, +// child: CupertinoButton( +// onPressed: () { +// imageController.choosImagePicture( +// AppLink.uploadImage1, 'portrait'); +// }, +// child: const Icon(CupertinoIcons.pencil_circle_fill, +// color: CupertinoColors.white), +// ), +// ), +// ], +// ); +// }, +// ), +// const SizedBox(height: 10), +// Text( +// '${box.read(BoxName.nameDriver).toString().split(' ')[0]} ${box.read(BoxName.nameDriver).toString().split(' ')[1]}', +// style: const TextStyle( +// color: CupertinoColors.white, +// fontSize: 18, +// fontWeight: FontWeight.bold), +// ), +// const SizedBox(height: 5), +// Text( +// box.read(BoxName.emailDriver), +// style: const TextStyle(color: CupertinoColors.white, fontSize: 14), +// ), +// const SizedBox(height: 10), +// Row( +// children: [ +// Text( +// Get.find().rating.toString(), +// style: const TextStyle( +// color: CupertinoColors.systemYellow, fontSize: 16), +// ), +// const SizedBox(width: 5), +// // You might want to replace this with a Cupertino-style rating widget +// // For now, we'll use text to represent stars +// // const Text('★★★★★', +// // style: TextStyle(color: CupertinoColors.systemYellow)), + +// Container( +// padding: const EdgeInsets.symmetric(horizontal: 4, vertical: 1), +// color: AppColor.greenColor, +// child: RatingBar.builder( +// initialRating: double.parse( +// Get.find().rating.toString()), +// minRating: 1, +// direction: Axis.horizontal, +// itemCount: 5, +// itemSize: 20, +// itemPadding: const EdgeInsets.symmetric(horizontal: 2), +// itemBuilder: (context, _) => const Icon( +// Icons.star, +// color: Colors.amber, +// ), +// onRatingUpdate: (rating) {}, +// ), +// ), +// ], +// ), +// ], +// ), +// ); +// } +// } class CupertinoDrawerCaptain extends StatelessWidget { final ImageController imageController = Get.put(ImageController()); @override Widget build(BuildContext context) { return CupertinoPageScaffold( + backgroundColor: CupertinoColors.systemGroupedBackground, navigationBar: CupertinoNavigationBar( - middle: Text('Menu'.tr), + middle: Text('Menu'.tr, + style: const TextStyle(fontSize: 17, fontWeight: FontWeight.w600)), + backgroundColor: Colors.transparent, + border: null, ), child: SafeArea( child: CustomScrollView( slivers: [ - const SliverToBoxAdapter(child: const UserAccountHeader()), + const SliverToBoxAdapter(child: UserAccountHeader()), SliverList( delegate: SliverChildListDelegate([ - _buildDivider(), + const SizedBox(height: 10), + _buildSectionHeader('Account'.tr), _buildDrawerItem( - icon: CupertinoIcons.money_dollar, + icon: CupertinoIcons.money_dollar_circle_fill, text: 'Wallet'.tr, onTap: () => Get.to(() => WalletCaptain()), ), - _buildDivider(), _buildDrawerItem( - icon: CupertinoIcons.person, + icon: CupertinoIcons.person_fill, text: 'Profile'.tr, onTap: () => Get.to(() => ProfileCaptain()), ), - _buildDivider(), + _buildSectionHeader('Activities'.tr), _buildDrawerItem( - icon: CupertinoIcons.clock, + icon: CupertinoIcons.clock_fill, text: 'History of Trip'.tr, onTap: () => Get.to(() => const HistoryCaptain()), ), - _buildDivider(), _buildDrawerItem( - icon: CupertinoIcons.car_detailed, + icon: CupertinoIcons.car_fill, text: 'Available for rides'.tr, onTap: () => Get.to(() => const AvailableRidesPage()), ), - _buildDivider(), + _buildSectionHeader('Support'.tr), _buildDrawerItem( - icon: CupertinoIcons.bell, + icon: CupertinoIcons.bell_fill, text: 'Notifications'.tr, onTap: () => Get.to(() => const NotificationCaptain()), ), - _buildDivider(), _buildDrawerItem( - icon: CupertinoIcons.question_circle, + icon: CupertinoIcons.question_circle_fill, text: 'Helping Center'.tr, onTap: () => Get.to(() => HelpCaptain()), ), - _buildDivider(), - _buildDrawerItem( - icon: CupertinoIcons.share, - text: 'Share App'.tr, - onTap: () => Get.to(() => InviteScreen()), - ), - _buildDivider(), - _buildDrawerItem( - icon: CupertinoIcons.wrench, - text: "Maintenance Center".tr, - onTap: () => Get.to(() => MaintainCenterPage()), - ), - _buildDivider(), - _buildDrawerItem( - icon: - CupertinoIcons.heart, // Updated icon to represent health - text: "Health Insurance".tr, // Updated English text - onTap: () => Get.to(() => AssuranceHealthPage()), - ), - _buildDivider(), - _buildDrawerItem( - icon: CupertinoIcons.mail, - text: "Contact Us".tr, - onTap: () => Get.to(() => ContactUsPage()), - ), - _buildDivider(), - _buildDrawerItem( - icon: - Icons.play_circle_filled, // Icon representing video play - text: 'Videos Tutorials'.tr, - onTap: () => Get.to(() => VideoListPage()), - ), - _buildDivider(), - _buildDrawerItem( - icon: Icons.star, // Another option with a filled star icon - text: "Rate Our App".tr, - onTap: () => Get.to(() => RatingScreen()), - ), - _buildDivider(), - _buildDrawerItem( - icon: CupertinoIcons.settings, - text: 'Settings'.tr, - onTap: () => Get.to(() => const SettingsCaptain()), - ), - _buildDivider(), - _buildDrawerItem( - icon: CupertinoIcons.square_arrow_right, - text: 'Sign Out'.tr, - onTap: () => Get.to(() => const LogoutCaptain()), - ), - _buildDivider(), + _buildSectionHeader('More'.tr), + ...moreMenuItems(), ]), ), ], @@ -135,11 +332,61 @@ class CupertinoDrawerCaptain extends StatelessWidget { ); } - Widget _buildDivider() { - return const Divider( - thickness: 1, - height: 1, - color: CupertinoColors.systemGrey4, + List moreMenuItems() => [ + _buildDrawerItem( + icon: CupertinoIcons.share_up, + text: 'Share App'.tr, + onTap: () => Get.to(() => InviteScreen()), + ), + _buildDrawerItem( + icon: CupertinoIcons.wrench_fill, + text: "Maintenance Center".tr, + onTap: () => Get.to(() => MaintainCenterPage()), + ), + _buildDrawerItem( + icon: CupertinoIcons.heart_fill, + text: "Health Insurance".tr, + onTap: () => Get.to(() => AssuranceHealthPage()), + ), + _buildDrawerItem( + icon: CupertinoIcons.mail_solid, + text: "Contact Us".tr, + onTap: () => Get.to(() => ContactUsPage()), + ), + _buildDrawerItem( + icon: CupertinoIcons.play_circle_fill, + text: 'Videos Tutorials'.tr, + onTap: () => Get.to(() => VideoListPage()), + ), + _buildDrawerItem( + icon: CupertinoIcons.star_fill, + text: "Rate Our App".tr, + onTap: () => Get.to(() => RatingScreen()), + ), + _buildDrawerItem( + icon: CupertinoIcons.settings_solid, + text: 'Settings'.tr, + onTap: () => Get.to(() => const SettingsCaptain()), + ), + _buildDrawerItem( + icon: CupertinoIcons.square_arrow_right, + text: 'Sign Out'.tr, + onTap: () => Get.to(() => const LogoutCaptain()), + isDestructive: true, + ), + ]; + + Widget _buildSectionHeader(String title) { + return Padding( + padding: const EdgeInsets.fromLTRB(16, 16, 16, 8), + child: Text( + title, + style: const TextStyle( + color: CupertinoColors.systemGrey, + fontSize: 13, + fontWeight: FontWeight.w600, + ), + ), ); } @@ -147,18 +394,45 @@ class CupertinoDrawerCaptain extends StatelessWidget { required IconData icon, required String text, required VoidCallback onTap, + bool isDestructive = false, }) { - return CupertinoButton( - onPressed: onTap, - child: Row( - children: [ - Icon(icon, color: CupertinoColors.activeBlue), - const SizedBox(width: 10), - Text(text, style: const TextStyle(color: CupertinoColors.label)), - const Spacer(), - const Icon(CupertinoIcons.right_chevron, - color: CupertinoColors.systemGrey), - ], + return Container( + margin: const EdgeInsets.symmetric(horizontal: 8, vertical: 2), + decoration: BoxDecoration( + color: CupertinoColors.white, + borderRadius: BorderRadius.circular(10), + ), + child: CupertinoButton( + padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12), + onPressed: onTap, + child: Row( + children: [ + Icon( + icon, + color: isDestructive + ? CupertinoColors.destructiveRed + : CupertinoColors.activeBlue, + size: 22, + ), + const SizedBox(width: 12), + Text( + text, + style: AppStyle.title, + // TextStyle( + // color: isDestructive + // ? CupertinoColors.destructiveRed + // : CupertinoColors.label, + // fontSize: 16, + // ), + ), + const Spacer(), + Icon( + CupertinoIcons.chevron_right, + color: CupertinoColors.systemGrey3, + size: 18, + ), + ], + ), ), ); } @@ -170,13 +444,20 @@ class UserAccountHeader extends StatelessWidget { @override Widget build(BuildContext context) { return Container( - padding: const EdgeInsets.all(16), - decoration: const BoxDecoration( - gradient: LinearGradient( - colors: [AppColor.blueColor, AppColor.twitterColor], + padding: const EdgeInsets.fromLTRB(20, 20, 20, 24), + decoration: BoxDecoration( + gradient: const LinearGradient( + colors: [AppColor.blueColor, Color(0xFF2196F3)], begin: Alignment.topLeft, end: Alignment.bottomRight, ), + boxShadow: [ + BoxShadow( + color: Colors.black.withAlpha(10), + blurRadius: 10, + spreadRadius: 2, + ), + ], ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, @@ -185,83 +466,122 @@ class UserAccountHeader extends StatelessWidget { builder: (imageController) { return Stack( children: [ - imageController.isloading - ? const CupertinoActivityIndicator() - : Container( - width: 100, - height: 100, - decoration: BoxDecoration( - shape: BoxShape.circle, - image: DecorationImage( + Container( + width: 100, + height: 100, + decoration: BoxDecoration( + shape: BoxShape.circle, + border: Border.all(color: Colors.white, width: 3), + boxShadow: [ + BoxShadow( + color: Colors.black.withOpacity(0.2), + blurRadius: 8, + spreadRadius: 2, + ), + ], + ), + child: imageController.isloading + ? const CupertinoActivityIndicator() + : ClipRRect( + borderRadius: BorderRadius.circular(50), + child: Image.network( + '${AppLink.seferCairoServer}/portrate_captain_image/${box.read(BoxName.driverID)}.jpg', fit: BoxFit.cover, - image: NetworkImage( - '${AppLink.seferCairoServer}/portrate_captain_image/${box.read(BoxName.driverID)}.jpg', - ), ), ), - ), + ), Positioned( right: 0, - top: 0, + bottom: 0, child: CupertinoButton( + padding: EdgeInsets.zero, onPressed: () { imageController.choosImagePicture( AppLink.uploadImage1, 'portrait'); }, - child: const Icon(CupertinoIcons.pencil_circle_fill, - color: CupertinoColors.white), + child: Container( + padding: const EdgeInsets.all(6), + decoration: const BoxDecoration( + color: Colors.white, + shape: BoxShape.circle, + ), + child: const Icon( + CupertinoIcons.camera_fill, + color: AppColor.blueColor, + size: 20, + ), + ), ), ), ], ); }, ), - const SizedBox(height: 10), + const SizedBox(height: 16), Text( '${box.read(BoxName.nameDriver).toString().split(' ')[0]} ${box.read(BoxName.nameDriver).toString().split(' ')[1]}', style: const TextStyle( - color: CupertinoColors.white, - fontSize: 18, - fontWeight: FontWeight.bold), + color: Colors.white, + fontSize: 24, + fontWeight: FontWeight.bold, + shadows: [ + Shadow( + color: Colors.black26, + blurRadius: 2, + offset: Offset(0, 1), + ), + ], + ), ), - const SizedBox(height: 5), + const SizedBox(height: 4), Text( box.read(BoxName.emailDriver), - style: const TextStyle(color: CupertinoColors.white, fontSize: 14), + style: TextStyle( + color: Colors.white.withOpacity(0.9), + fontSize: 14, + ), ), - const SizedBox(height: 10), - Row( - children: [ - Text( - Get.find().rating.toString(), - style: const TextStyle( - color: CupertinoColors.systemYellow, fontSize: 16), - ), - const SizedBox(width: 5), - // You might want to replace this with a Cupertino-style rating widget - // For now, we'll use text to represent stars - // const Text('★★★★★', - // style: TextStyle(color: CupertinoColors.systemYellow)), - - Container( - padding: const EdgeInsets.symmetric(horizontal: 4, vertical: 1), - color: AppColor.greenColor, - child: RatingBar.builder( + const SizedBox(height: 12), + Container( + padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8), + decoration: BoxDecoration( + color: Colors.white.withOpacity(0.15), + borderRadius: BorderRadius.circular(20), + ), + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + // const Icon( + // CupertinoIcons.star_fill, + // color: CupertinoColors.systemYellow, + // size: 18, + // ), + // const SizedBox(width: 4), + Text( + Get.find().rating.toString(), + style: const TextStyle( + color: Colors.white, + fontSize: 16, + fontWeight: FontWeight.w600, + ), + ), + const SizedBox(width: 8), + RatingBar.builder( initialRating: double.parse( Get.find().rating.toString()), minRating: 1, direction: Axis.horizontal, itemCount: 5, - itemSize: 20, - itemPadding: const EdgeInsets.symmetric(horizontal: 2), + itemSize: 16, + ignoreGestures: true, itemBuilder: (context, _) => const Icon( - Icons.star, - color: Colors.amber, + CupertinoIcons.star_fill, + color: CupertinoColors.systemYellow, ), onRatingUpdate: (rating) {}, ), - ), - ], + ], + ), ), ], ), diff --git a/lib/views/home/Captin/home_captain/help_captain.dart b/lib/views/home/Captin/home_captain/help_captain.dart index 34c8539..09e10ab 100644 --- a/lib/views/home/Captin/home_captain/help_captain.dart +++ b/lib/views/home/Captin/home_captain/help_captain.dart @@ -4,6 +4,11 @@ import 'package:sefer_driver/controller/home/captin/help/help_controller.dart'; import 'package:sefer_driver/views/home/Captin/home_captain/help_details_replay_page.dart'; import 'package:flutter/cupertino.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:sefer_driver/controller/home/captin/help/help_controller.dart'; +import 'package:sefer_driver/views/home/Captin/home_captain/help_details_replay_page.dart'; class HelpCaptain extends StatelessWidget { HelpCaptain({super.key}); @@ -13,116 +18,131 @@ class HelpCaptain extends StatelessWidget { Get.put(HelpController()); return CupertinoPageScaffold( navigationBar: CupertinoNavigationBar( - middle: Text('Helping Page'.tr), + middle: Text( + 'Helping Page'.tr, + style: const TextStyle(fontWeight: FontWeight.bold), + ), leading: CupertinoButton( padding: EdgeInsets.zero, - child: Icon(CupertinoIcons.back), onPressed: () => Navigator.pop(context), + child: const Icon(CupertinoIcons.back), ), ), child: SafeArea( child: Padding( - padding: const EdgeInsets.all(16.0), - child: Column( + padding: const EdgeInsets.all( + 20.0), // Increased padding around the content + child: ListView( + // crossAxisAlignment: + // CrossAxisAlignment.stretch, // Stretch children to full width children: [ - Padding( - padding: const EdgeInsets.symmetric(vertical: 12.0), - child: Container( - padding: const EdgeInsets.all(16.0), - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(12.0), - border: Border.all( - color: CupertinoColors.systemGrey2, - ), - ), - child: Text( - 'If you need any help or have questions, this is the right place to do that. You are welcome!' - .tr, - style: CupertinoTheme.of(context).textTheme.textStyle, - textAlign: TextAlign.center, - ), + Container( + padding: + const EdgeInsets.all(18.0), // Slightly increased padding + decoration: BoxDecoration( + color: + CupertinoTheme.of(context).brightness == Brightness.light + ? CupertinoColors.systemGrey6 + : CupertinoColors.darkBackgroundGray, + borderRadius: + BorderRadius.circular(15.0), // More rounded corners ), - ), - Card( - elevation: 3, - color: CupertinoColors.systemGrey6, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(12.0), - ), - child: Padding( - padding: const EdgeInsets.all(16.0), - child: GetBuilder( - builder: (helpController) => Form( - key: helpController.formKey, - child: Column( - children: [ - CupertinoTextField( - controller: helpController.helpQuestionController, - placeholder: 'Enter your Question here'.tr, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(12), - border: Border.all( - color: CupertinoColors.systemGrey, - ), - ), - padding: const EdgeInsets.all(16), - clearButtonMode: OverlayVisibilityMode.editing, + child: Text( + 'If you need any help or have questions, this is the right place to do that. You are welcome!' + .tr, + style: + CupertinoTheme.of(context).textTheme.textStyle.copyWith( + fontSize: 16, // Slightly larger font size + color: CupertinoColors.label.resolveFrom( + context), // Ensure text color adapts to theme ), - const SizedBox(height: 20), - helpController.isLoading - ? const CupertinoActivityIndicator() - : CupertinoButton.filled( - onPressed: () { - if (helpController.formKey.currentState! - .validate()) { - helpController.addHelpQuestion(); - - // Clear the feedback form - helpController.formKey.currentState! - .reset(); - } - }, - child: Text('Submit Question'.tr), - ), - ], - ), - ), - ), + textAlign: TextAlign.center, ), ), const SizedBox(height: 20), + CupertinoFormSection.insetGrouped( + // Using CupertinoFormSection for better styling + header: Text('Submit Your Question'.tr), + margin: EdgeInsets.zero, + children: [ + GetBuilder( + builder: (helpController) => Form( + key: helpController.formKey, + child: CupertinoTextFormFieldRow( + controller: helpController.helpQuestionController, + placeholder: 'Enter your Question here'.tr, + autovalidateMode: AutovalidateMode.onUserInteraction, + validator: (value) { + if (value == null || value.isEmpty) { + return 'Please enter your question'.tr; + } + return null; + }, + prefix: const Icon(CupertinoIcons + .question_circle), // Added a prefix icon + ), + ), + ), + Padding( + padding: const EdgeInsets.symmetric( + horizontal: 16.0, vertical: 10.0), + child: GetBuilder( + builder: (helpController) => helpController.isLoading + ? const CupertinoActivityIndicator() + : CupertinoButton.filled( + onPressed: () { + if (helpController.formKey.currentState! + .validate()) { + helpController.addHelpQuestion(); + helpController.helpQuestionController + .clear(); // Clear the text field + } + }, + child: Text('Submit Question'.tr), + ), + ), + ), + ], + ), + const SizedBox(height: 20), + Text( + 'Your Questions'.tr, + style: CupertinoTheme.of(context) + .textTheme + .navTitleTextStyle + .copyWith( + fontWeight: FontWeight.bold, + ), + ), + const SizedBox(height: 10), Expanded( child: GetBuilder( - builder: (helpController) => Padding( - padding: const EdgeInsets.all(10), - child: Container( - decoration: BoxDecoration( - border: Border.all( - color: CupertinoColors.systemGrey2, - ), - borderRadius: BorderRadius.circular(12.0), - ), - child: ListView.builder( - itemCount: helpController.helpQuestionDate['message'] != - null - ? helpController.helpQuestionDate['message'].length - : 0, - itemBuilder: (BuildContext context, int index) { - var list = - helpController.helpQuestionDate['message'][index]; - return Padding( - padding: const EdgeInsets.all(3), - child: Container( - padding: const EdgeInsets.symmetric( - vertical: 12, horizontal: 16), - decoration: BoxDecoration( - border: Border.all( - color: CupertinoColors.activeGreen, - width: 2, + builder: (helpController) => + CupertinoListSection.insetGrouped( + margin: EdgeInsets.zero, + children: helpController.helpQuestionDate['message'] != null + ? List.generate( + helpController.helpQuestionDate['message'].length, + (index) { + var list = helpController + .helpQuestionDate['message'][index]; + return CupertinoListTile( + title: Text( + list['helpQuestion'], + overflow: TextOverflow.ellipsis, + ), + trailing: Row( + mainAxisSize: MainAxisSize.min, + children: [ + Text( + list['datecreated'], + style: CupertinoTheme.of(context) + .textTheme + .tabLabelTextStyle, + ), + const Icon(CupertinoIcons.chevron_forward), + ], ), - borderRadius: BorderRadius.circular(12), - ), - child: GestureDetector( onTap: () { helpController.getIndex( list['id'], list['helpQuestion']); @@ -130,33 +150,14 @@ class HelpCaptain extends StatelessWidget { .getHelpRepley(list['id'].toString()); Get.to(() => const HelpDetailsReplayPage()); }, - child: Row( - mainAxisAlignment: - MainAxisAlignment.spaceBetween, - children: [ - Expanded( - child: Text( - list['helpQuestion'], - style: CupertinoTheme.of(context) - .textTheme - .textStyle, - overflow: TextOverflow.ellipsis, - ), - ), - Text( - list['datecreated'], - style: CupertinoTheme.of(context) - .textTheme - .tabLabelTextStyle, - ), - ], - ), - ), + ); + }, + ) + : [ + Center( + child: Text('No questions asked yet.'.tr), ), - ); - }, - ), - ), + ], ), ), ), @@ -167,3 +168,165 @@ class HelpCaptain extends StatelessWidget { ); } } +// class HelpCaptain extends StatelessWidget { +// HelpCaptain({super.key}); + +// @override +// Widget build(BuildContext context) { +// Get.put(HelpController()); +// return CupertinoPageScaffold( +// navigationBar: CupertinoNavigationBar( +// middle: Text('Helping Page'.tr), +// leading: CupertinoButton( +// padding: EdgeInsets.zero, +// child: Icon(CupertinoIcons.back), +// onPressed: () => Navigator.pop(context), +// ), +// ), +// child: SafeArea( +// child: Padding( +// padding: const EdgeInsets.all(16.0), +// child: Column( +// children: [ +// Padding( +// padding: const EdgeInsets.symmetric(vertical: 12.0), +// child: Container( +// padding: const EdgeInsets.all(16.0), +// decoration: BoxDecoration( +// borderRadius: BorderRadius.circular(12.0), +// border: Border.all( +// color: CupertinoColors.systemGrey2, +// ), +// ), +// child: Text( +// 'If you need any help or have questions, this is the right place to do that. You are welcome!' +// .tr, +// style: CupertinoTheme.of(context).textTheme.textStyle, +// textAlign: TextAlign.center, +// ), +// ), +// ), +// Card( +// elevation: 3, +// color: CupertinoColors.systemGrey6, +// shape: RoundedRectangleBorder( +// borderRadius: BorderRadius.circular(12.0), +// ), +// child: Padding( +// padding: const EdgeInsets.all(16.0), +// child: GetBuilder( +// builder: (helpController) => Form( +// key: helpController.formKey, +// child: Column( +// children: [ +// CupertinoTextField( +// controller: helpController.helpQuestionController, +// placeholder: 'Enter your Question here'.tr, +// decoration: BoxDecoration( +// borderRadius: BorderRadius.circular(12), +// border: Border.all( +// color: CupertinoColors.systemGrey, +// ), +// ), +// padding: const EdgeInsets.all(16), +// clearButtonMode: OverlayVisibilityMode.editing, +// ), +// const SizedBox(height: 20), +// helpController.isLoading +// ? const CupertinoActivityIndicator() +// : CupertinoButton.filled( +// onPressed: () { +// if (helpController.formKey.currentState! +// .validate()) { +// helpController.addHelpQuestion(); + +// // Clear the feedback form +// helpController.formKey.currentState! +// .reset(); +// } +// }, +// child: Text('Submit Question'.tr), +// ), +// ], +// ), +// ), +// ), +// ), +// ), +// const SizedBox(height: 20), +// Expanded( +// child: GetBuilder( +// builder: (helpController) => Padding( +// padding: const EdgeInsets.all(10), +// child: Container( +// decoration: BoxDecoration( +// border: Border.all( +// color: CupertinoColors.systemGrey2, +// ), +// borderRadius: BorderRadius.circular(12.0), +// ), +// child: ListView.builder( +// itemCount: helpController.helpQuestionDate['message'] != +// null +// ? helpController.helpQuestionDate['message'].length +// : 0, +// itemBuilder: (BuildContext context, int index) { +// var list = +// helpController.helpQuestionDate['message'][index]; +// return Padding( +// padding: const EdgeInsets.all(3), +// child: Container( +// padding: const EdgeInsets.symmetric( +// vertical: 12, horizontal: 16), +// decoration: BoxDecoration( +// border: Border.all( +// color: CupertinoColors.activeGreen, +// width: 2, +// ), +// borderRadius: BorderRadius.circular(12), +// ), +// child: GestureDetector( +// onTap: () { +// helpController.getIndex( +// list['id'], list['helpQuestion']); +// helpController +// .getHelpRepley(list['id'].toString()); +// Get.to(() => const HelpDetailsReplayPage()); +// }, +// child: Row( +// mainAxisAlignment: +// MainAxisAlignment.spaceBetween, +// children: [ +// Expanded( +// child: Text( +// list['helpQuestion'], +// style: CupertinoTheme.of(context) +// .textTheme +// .textStyle, +// overflow: TextOverflow.ellipsis, +// ), +// ), +// Text( +// list['datecreated'], +// style: CupertinoTheme.of(context) +// .textTheme +// .tabLabelTextStyle, +// ), +// ], +// ), +// ), +// ), +// ); +// }, +// ), +// ), +// ), +// ), +// ), +// ], +// ), +// ), +// ), +// ); +// } +// } diff --git a/lib/views/home/Captin/home_captain/home_captin.dart b/lib/views/home/Captin/home_captain/home_captin.dart index bd1cdb5..53e766d 100644 --- a/lib/views/home/Captin/home_captain/home_captin.dart +++ b/lib/views/home/Captin/home_captain/home_captin.dart @@ -47,22 +47,92 @@ class HomeCaptain extends StatelessWidget { }); return Scaffold( appBar: AppBar( - // backgroundColor: AppColor.accentColor, - elevation: 1, - title: Text( - 'SEFER'.tr, - style: AppStyle.title.copyWith(fontSize: 22), + elevation: 2, + flexibleSpace: Container( + decoration: BoxDecoration( + gradient: LinearGradient( + colors: [Colors.white, Colors.grey.shade50], + begin: Alignment.topLeft, + end: Alignment.bottomRight, + ), + boxShadow: [ + BoxShadow( + color: Colors.grey.withOpacity(0.1), + spreadRadius: 1, + blurRadius: 4, + ), + ], + ), + ), + title: Row( + children: [ + Image.asset('assets/images/logo.png', height: 32), + const SizedBox(width: 8), + Text( + 'SEFER'.tr, + style: AppStyle.title.copyWith( + fontSize: 22, + fontWeight: FontWeight.w600, + color: AppColor.blueColor, + ), + ), + ], ), actions: [ - MyCircleContainer( - child: Text( - homeCaptainController.countRefuse.toString(), - style: AppStyle.title, + Padding( + padding: const EdgeInsets.symmetric(horizontal: 4), + child: MyCircleContainer( + child: Text( + homeCaptainController.countRefuse.toString(), + style: AppStyle.title, + ), ), ), + Container( + margin: const EdgeInsets.symmetric(horizontal: 4), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(12), + boxShadow: [ + BoxShadow( + color: Colors.grey.withOpacity(0.1), + spreadRadius: 1, + blurRadius: 4, + ), + ], + ), + child: Row( + children: [ + _MapControlButton( + icon: Icons.satellite_alt, + tooltip: 'Change Map Type'.tr, + onPressed: homeCaptainController.changeMapType, + ), + _MapControlButton( + icon: Icons.streetview_sharp, + tooltip: 'Toggle Traffic'.tr, + onPressed: homeCaptainController.changeMapTraffic, + ), + _MapControlButton( + icon: Icons.location_on, + tooltip: 'My Location'.tr, + onPressed: () { + homeCaptainController.mapHomeCaptainController! + .animateCamera(CameraUpdate.newLatLng(LatLng( + Get.find().myLocation.latitude, + Get.find().myLocation.longitude, + ))); + }, + ), + ], + ), + ), + const SizedBox(width: 8), ], ), - drawer: CupertinoDrawerCaptain(), + + drawer: + CupertinoDrawerCaptain(), // Add this widget at the bottom of the file body: Stack( children: [ GetBuilder(builder: (homeCaptainController) { @@ -419,28 +489,34 @@ class HomeCaptain extends StatelessWidget { border: Border.all(color: AppColor.blueColor), color: AppColor.secondaryColor, borderRadius: BorderRadius.circular(15)), - child: IconButton( - onPressed: () { - box.read(BoxName.rideStatus) == 'Applied' - ? { - Get.to(() => PassengerLocationMapPage(), - arguments: - box.read(BoxName.rideArguments)), - Get.put(MapDriverController()) - .changeRideToBeginToPassenger() - } - : { - Get.to(() => PassengerLocationMapPage(), - arguments: - box.read(BoxName.rideArguments)), - Get.put(MapDriverController()) - .startRideFromStartApp() - }; + child: GestureDetector( + onLongPress: () { + box.write(BoxName.rideStatus, 'delete'); + homeCaptainController.update(); }, - icon: const Icon( - Icons.rice_bowl, - size: 29, - color: AppColor.blueColor, + child: IconButton( + onPressed: () { + box.read(BoxName.rideStatus) == 'Applied' + ? { + Get.to(() => PassengerLocationMapPage(), + arguments: box + .read(BoxName.rideArguments)), + Get.put(MapDriverController()) + .changeRideToBeginToPassenger() + } + : { + Get.to(() => PassengerLocationMapPage(), + arguments: box + .read(BoxName.rideArguments)), + Get.put(MapDriverController()) + .startRideFromStartApp() + }; + }, + icon: const Icon( + Icons.rice_bowl, + size: 29, + color: AppColor.blueColor, + ), ), ), ), @@ -599,3 +675,37 @@ bool _checkIfFirstTime() { void _markAsNotFirstTime() { box.write(BoxName.isFirstTime, 'false'); } + +class _MapControlButton extends StatelessWidget { + final IconData icon; + final VoidCallback onPressed; + final String tooltip; + + const _MapControlButton({ + required this.icon, + required this.onPressed, + required this.tooltip, + }); + + @override + Widget build(BuildContext context) { + return Tooltip( + message: tooltip, + child: Material( + color: Colors.transparent, + child: InkWell( + borderRadius: BorderRadius.circular(12), + onTap: onPressed, + child: Container( + padding: const EdgeInsets.all(8), + child: Icon( + icon, + size: 24, + color: AppColor.blueColor, + ), + ), + ), + ), + ); + } +} diff --git a/lib/views/home/Captin/home_captain/widget/left_menu_map_captain.dart b/lib/views/home/Captin/home_captain/widget/left_menu_map_captain.dart index 3763bd2..343c00f 100644 --- a/lib/views/home/Captin/home_captain/widget/left_menu_map_captain.dart +++ b/lib/views/home/Captin/home_captain/widget/left_menu_map_captain.dart @@ -1,18 +1,14 @@ import 'package:sefer_driver/constant/box_name.dart'; import 'package:sefer_driver/controller/firebase/local_notification.dart'; import 'package:sefer_driver/main.dart'; -import 'package:sefer_driver/views/auth/captin/cards/egypt_card_a_i.dart'; import 'package:sefer_driver/views/home/Captin/orderCaptin/vip_order_page.dart'; import 'package:flutter/material.dart'; import 'package:flutter_font_icons/flutter_font_icons.dart'; import 'package:get/get.dart'; import 'package:sefer_driver/controller/home/captin/home_captain_controller.dart'; -import 'package:google_maps_flutter/google_maps_flutter.dart'; import '../../../../../constant/colors.dart'; import '../../../../Rate/ride_calculate_driver.dart'; -import '../../../../../controller/functions/location_controller.dart'; -import '../../../../widgets/mydialoug.dart'; GetBuilder leftMainMenuCaptainIcons() { return GetBuilder( @@ -21,113 +17,6 @@ GetBuilder leftMainMenuCaptainIcons() { left: 6, child: Column( children: [ - // AnimatedContainer( - // duration: const Duration(microseconds: 200), - // width: controller.widthMapTypeAndTraffic, - // decoration: BoxDecoration( - // border: Border.all(color: AppColor.blueColor), - // color: AppColor.secondaryColor, - // borderRadius: BorderRadius.circular(15)), - // child: IconButton( - // onPressed: () { - // // key.forEach((key, apiKey) { - // // Get.to(() => SmsSignupEgypt()); - // // keys.forEach((key, apiKey) { - // String apikey = AK.secretKeyStripe; - // Log.print('apikey: ${apikey}'); - - // String encryptedApiKey = X.c(X.c(X.c(apikey, cs), cC), cn); - // Log.print('encryptedApiKey: ${encryptedApiKey}'); - - // String decryptedApiKey = - // X.r(X.r(X.r(encryptedApiKey, cn), cC), cs); - // Log.print('decryptedApiKey: ${decryptedApiKey}'); - - // // if (decryptedApiKey == retrievedStringS) { - // // } else { - // // } - // // } - // // ); - // }, - // icon: const Icon( - // FontAwesome.map_signs, - // size: 24, - // color: Colors.black, - // )), - // ), - - // const SizedBox( - // height: 5, - // ), - AnimatedContainer( - duration: const Duration(microseconds: 200), - width: controller.widthMapTypeAndTraffic, - decoration: BoxDecoration( - border: Border.all(color: AppColor.blueColor), - color: AppColor.secondaryColor, - borderRadius: BorderRadius.circular(15)), - child: IconButton( - onPressed: () { - controller.changeMapType(); - // Toast.show(context, 'This is a toast message!'); - }, - icon: const Icon( - Icons.satellite_alt, - size: 29, - color: AppColor.blueColor, - ), - ), - ), - const SizedBox( - height: 5, - ), - AnimatedContainer( - duration: const Duration(microseconds: 200), - width: controller.widthMapTypeAndTraffic, - decoration: BoxDecoration( - color: AppColor.secondaryColor, - border: Border.all(color: AppColor.blueColor), - borderRadius: BorderRadius.circular(15)), - child: IconButton( - onPressed: () { - controller.changeMapTraffic(); - // Toast.show(context, 'This is a toast message!'); - }, - icon: const Icon( - Icons.streetview_sharp, - size: 29, - color: AppColor.blueColor, - ), - ), - ), - const SizedBox( - height: 5, - ), - AnimatedContainer( - duration: const Duration(microseconds: 200), - width: controller.widthMapTypeAndTraffic, - decoration: BoxDecoration( - color: AppColor.secondaryColor, - border: Border.all(color: AppColor.blueColor), - borderRadius: BorderRadius.circular(15)), - child: IconButton( - onPressed: () { - controller.mapHomeCaptainController! - .animateCamera(CameraUpdate.newLatLng(LatLng( - Get.find().myLocation.latitude, - Get.find().myLocation.longitude, - ))); - }, - icon: const Icon( - Icons.location_on, - size: 29, - color: AppColor.blueColor, - ), - ), - ), - const SizedBox( - height: 5, - ), AnimatedContainer( duration: const Duration(microseconds: 200), width: controller.widthMapTypeAndTraffic, @@ -211,7 +100,7 @@ GetBuilder leftMainMenuCaptainIcons() { // child: Builder(builder: (context) { // return IconButton( // onPressed: () async { - // Get.to(EgyptCardAI()); + // MyCircularProgressIndicator(); // }, // icon: const Icon( // FontAwesome5.grin_tears, diff --git a/lib/views/home/Captin/maintain_center_page.dart b/lib/views/home/Captin/maintain_center_page.dart index 30360f0..d0277c4 100644 --- a/lib/views/home/Captin/maintain_center_page.dart +++ b/lib/views/home/Captin/maintain_center_page.dart @@ -6,93 +6,253 @@ import 'package:sefer_driver/views/widgets/my_scafold.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; +// class MaintainCenterPage extends StatelessWidget { +// MaintainCenterPage({super.key}); +// MaintainCenterController maintainCenterController = +// Get.put(MaintainCenterController()); + +// @override +// Widget build(BuildContext context) { +// return MyScafolld( +// title: "Maintenance Center".tr, +// body: [ +// GetBuilder( +// builder: (maintainCenterController) { +// return Padding( +// padding: const EdgeInsets.all(8.0), +// child: Column( +// children: [ +// Text( +// "When you complete 600 trips, you will be eligible to receive offers for maintenance of your car." +// .tr), +// const SizedBox( +// height: 10, +// ), +// Row( +// mainAxisAlignment: MainAxisAlignment.spaceAround, +// children: [ +// MyElevatedButton( +// title: "Show My Trip Count".tr, +// onPressed: () async { +// maintainCenterController.getTripCountByCaptain(); +// }), +// _buildPriceAvatar( +// maintainCenterController.tripCount['count'] == null +// ? '0' +// : maintainCenterController.tripCount['count'] +// .toString()) +// ], +// ), +// const SizedBox( +// height: 10, +// ), +// Container( +// decoration: AppStyle.boxDecoration, +// child: Padding( +// padding: const EdgeInsets.all(14), +// child: Text( +// "We have maintenance offers for your car. You can use them after completing 600 trips to get a 20% discount on car repairs. Enjoy using our SEFER app and be part of our SEFER family." +// .tr, +// style: AppStyle.title, +// ), +// ), +// ), +// const SizedBox( +// height: 10, +// ), +// MyElevatedButton( +// title: 'Show maintenance center near my location'.tr, +// onPressed: () { +// if (maintainCenterController.tripCount['count'] > 600) { +// } else { +// Get.snackbar("You should complete 600 trips".tr, '', +// backgroundColor: AppColor.yellowColor); +// } +// }) +// ], +// ), +// ); +// }) +// ], +// isleading: true); +// } + +// Widget _buildPriceAvatar(String count) { +// return Container( +// width: 80, +// height: 80, +// decoration: BoxDecoration( +// shape: BoxShape.circle, +// gradient: const RadialGradient( +// colors: [Color(0xFF4CAF50), Color(0xFF2E7D32)], +// center: Alignment.center, +// radius: 0.8, +// ), +// boxShadow: [ +// BoxShadow( +// color: Colors.black.withOpacity(0.2), +// blurRadius: 8, +// offset: const Offset(0, 4), +// ), +// ], +// ), +// child: Center( +// child: Text( +// count, +// style: const TextStyle( +// fontSize: 22, +// fontWeight: FontWeight.bold, +// color: Colors.white, +// ), +// ), +// ), +// ); +// } +// } + class MaintainCenterPage extends StatelessWidget { MaintainCenterPage({super.key}); - MaintainCenterController maintainCenterController = + final MaintainCenterController maintainCenterController = Get.put(MaintainCenterController()); @override Widget build(BuildContext context) { return MyScafolld( - title: "Maintenance Center".tr, - body: [ - GetBuilder( - builder: (maintainCenterController) { + title: "Maintenance Center".tr, + body: [ + GetBuilder( + builder: (controller) { return Padding( - padding: const EdgeInsets.all(8.0), + padding: const EdgeInsets.all(16.0), child: Column( + crossAxisAlignment: CrossAxisAlignment.start, children: [ + // Introduction Text with better styling Text( - "When you complete 600 trips, you will be eligible to receive offers for maintenance of your car." - .tr), - const SizedBox( - height: 10, + "When you complete 600 trips, you will be eligible to receive offers for maintenance of your car." + .tr, + style: Theme.of(context).textTheme.titleMedium!.copyWith( + color: Colors.grey[700], + height: 1.4, + ), ), - Row( - mainAxisAlignment: MainAxisAlignment.spaceAround, - children: [ - MyElevatedButton( - title: "Show My Trip Count".tr, - onPressed: () async { - maintainCenterController.getTripCountByCaptain(); - }), - _buildPriceAvatar( - maintainCenterController.tripCount['count'] == null - ? '0' - : maintainCenterController.tripCount['count'] - .toString()) - ], - ), - const SizedBox( - height: 10, - ), - Container( - decoration: AppStyle.boxDecoration, + const SizedBox(height: 20), + + // Trip Count Section in a Card + Card( + elevation: 4, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12), + ), child: Padding( - padding: const EdgeInsets.all(14), - child: Text( - "We have maintenance offers for your car. You can use them after completing 600 trips to get a 20% discount on car repairs. Enjoy using our SEFER app and be part of our SEFER family." - .tr, - style: AppStyle.title, + padding: const EdgeInsets.all(16.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Expanded( + child: MyElevatedButton( + title: "Show My Trip Count".tr, + onPressed: () async { + controller.getTripCountByCaptain(); + }, + ), + ), + const SizedBox(width: 16), + _buildPriceAvatar( + controller.tripCount['count'] == null + ? '0' + : controller.tripCount['count'].toString(), + ), + ], ), ), ), - const SizedBox( - height: 10, + const SizedBox(height: 20), + + // Maintenance Offer Information in a Card + Card( + elevation: 4, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12), + ), + child: Padding( + padding: const EdgeInsets.all(16.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + "Maintenance Offer".tr, + style: Theme.of(context).textTheme.titleLarge, + ), + const SizedBox(height: 8), + Text( + "We have maintenance offers for your car. You can use them after completing 600 trips to get a 20% discount on car repairs. Enjoy using our SEFER app and be part of our SEFER family." + .tr, + style: Theme.of(context) + .textTheme + .bodyMedium! + .copyWith( + color: Colors.grey[800], + height: 1.5, + ), + ), + ], + ), + ), ), - MyElevatedButton( + const SizedBox(height: 20), + + // Show Maintenance Center Button + SizedBox( + width: double.infinity, + child: MyElevatedButton( title: 'Show maintenance center near my location'.tr, onPressed: () { - if (maintainCenterController.tripCount['count'] > 600) { + if (controller.tripCount['count'] != null && + controller.tripCount['count'] >= 600) { + // Implement navigation or action to show maintenance centers + // For now, let's print a message + print("Navigating to maintenance centers..."); } else { - Get.snackbar("You should complete 600 trips".tr, '', - backgroundColor: AppColor.yellowColor); + Get.snackbar( + "Ineligible for Offer".tr, + "You should complete 500 trips to unlock this feature." + .tr, + backgroundColor: AppColor.yellowColor, + colorText: Colors.black, + snackPosition: SnackPosition.BOTTOM, + ); } - }) + }, + ), + ), ], ), ); - }) - ], - isleading: true); + }, + ), + ], + isleading: true, + ); } Widget _buildPriceAvatar(String count) { return Container( - width: 80, - height: 80, + width: 70, // Slightly reduced size + height: 70, decoration: BoxDecoration( shape: BoxShape.circle, - gradient: const RadialGradient( + gradient: const LinearGradient( + // Changed to LinearGradient colors: [Color(0xFF4CAF50), Color(0xFF2E7D32)], - center: Alignment.center, - radius: 0.8, + begin: Alignment.topLeft, + end: Alignment.bottomRight, ), boxShadow: [ BoxShadow( - color: Colors.black.withOpacity(0.2), - blurRadius: 8, - offset: const Offset(0, 4), + color: Colors.black.withOpacity(0.15), // Reduced opacity + blurRadius: 6, // Slightly reduced blur + offset: const Offset(0, 3), ), ], ), @@ -100,7 +260,7 @@ class MaintainCenterPage extends StatelessWidget { child: Text( count, style: const TextStyle( - fontSize: 22, + fontSize: 20, // Slightly reduced size fontWeight: FontWeight.bold, color: Colors.white, ), diff --git a/lib/views/home/Captin/mapDriverWidgets/driver_end_ride_bar.dart b/lib/views/home/Captin/mapDriverWidgets/driver_end_ride_bar.dart index bea5331..cb4f6b2 100644 --- a/lib/views/home/Captin/mapDriverWidgets/driver_end_ride_bar.dart +++ b/lib/views/home/Captin/mapDriverWidgets/driver_end_ride_bar.dart @@ -13,215 +13,249 @@ import '../../../widgets/elevated_btn.dart'; GetBuilder driverEndRideBar() { return GetBuilder( - builder: (mapDriverController) => mapDriverController.isRideStarted - ? Positioned( - left: 5, - top: 5, - right: 5, - child: Container( - decoration: AppStyle.boxDecoration1, - height: mapDriverController.remainingTimeTimerRideBegin < 60 - ? mapDriverController.driverEndPage = 190 - : mapDriverController.carType == 'Mishwar Vip' - ? 120 - : 170, - // width: 240, - child: Column( - mainAxisAlignment: MainAxisAlignment.spaceAround, - children: [ - mapDriverController.carType != 'Mishwar Vip' - ? Row( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - Column( - children: [ - const Icon(Icons.social_distance), - Text( - '${mapDriverController.distance} ${'KM'.tr}', - style: AppStyle.title, - ), - ], - ), - Column( - children: [ - const Icon(Icons.timelapse), - Text( - mapDriverController.hours > 1 - ? '${'${mapDriverController.hours}${' H and'.tr}'} ${mapDriverController.minutes} m' - : '${mapDriverController.minutes} ${'m'.tr}', - style: AppStyle.title), - ], - ), - Column( - children: [ - const Icon(Icons.money_sharp), - Text( - '${mapDriverController.paymentAmount} ${'\$'.tr}', - style: AppStyle.title), - ], - ), - ], - ) - : const SizedBox(), - mapDriverController.carType != 'Speed' && - mapDriverController.carType != 'Awfar Car' && - mapDriverController.carType != 'Scooter' - ? Row( - mainAxisAlignment: MainAxisAlignment.spaceAround, - children: [ - Container( - width: Get.width * .2, - decoration: AppStyle.boxDecoration1, - child: Padding( - padding: const EdgeInsets.all(4), - child: Row( - children: [ - const Icon(Icons.timer), - Text( - mapDriverController - .stringRemainingTimeRideBegin1, - style: AppStyle.number, - ), - ], - ), - )), - Container( - width: Get.width * .2, - decoration: AppStyle.boxDecoration1, - child: Padding( - padding: const EdgeInsets.all(4), - child: Row( - children: [ - const Icon(Icons.location_on), - Text( - '${mapDriverController.recentDistanceToDash.toStringAsFixed(0)} ${'KM'.tr}', - style: AppStyle.number, - ), - ], - ), - ), - ), - Container( - width: Get.width * .2, - decoration: AppStyle.boxDecoration1, - child: Padding( - padding: const EdgeInsets.all(4.0), - child: Row( - children: [ - const Icon(Icons.attach_money), - Text( - mapDriverController.price - .toStringAsFixed(2), - style: AppStyle.number, - ), - ], - ), - ), - ), - ], - ) - : const SizedBox(), - // (mapDriverController.carType == 'Mashwari' || - // mapDriverController.carType == 'Comfort' || - // mapDriverController.carType == 'lady') && - // mapDriverController.remainingTimeTimerRideBegin > 60 - // ? Row( - // mainAxisAlignment: MainAxisAlignment.spaceAround, - // children: [ - // MyElevatedButton( - // title: 'End Ride'.tr, - // onPressed: () { - // mapDriverController.finishRideFromDriver(); - // }, - // kolor: AppColor.redColor, - // ), - // Container( - // decoration: AppStyle.boxDecoration1, - // child: Text( - // mapDriverController.carType, - // style: AppStyle.title, - // ), - // ) - // ], - // ) - // : + builder: (mapDriverController) => mapDriverController.isRideStarted + ? Positioned( + left: 5, + top: 5, + right: 5, + child: Container( + decoration: AppStyle.boxDecoration1.copyWith( + borderRadius: BorderRadius.circular(15), + boxShadow: [ + BoxShadow( + color: Colors.black.withOpacity(0.1), + blurRadius: 10, + offset: Offset(0, 5), + ), + ], + ), + padding: const EdgeInsets.all(10), + height: mapDriverController.remainingTimeTimerRideBegin < 60 + ? mapDriverController.driverEndPage = 190 + : mapDriverController.carType == 'Mishwar Vip' + ? 120 + : 170, + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + if (mapDriverController.carType != 'Mishwar Vip') + Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + _buildInfoColumn( + icon: Icons.social_distance, + text: '${mapDriverController.distance} ${'KM'.tr}', + ), + _buildInfoColumn( + icon: Icons.timelapse, + text: mapDriverController.hours > 1 + ? '${mapDriverController.hours} ${'H and'.tr} ${mapDriverController.minutes} m' + : '${mapDriverController.minutes} ${'m'.tr}', + ), + _buildInfoColumn( + icon: Icons.money_sharp, + text: + '${mapDriverController.paymentAmount} ${'\$'.tr}', + ), + ], + ), + if (mapDriverController.carType != 'Speed' && + mapDriverController.carType != 'Awfar Car' && + mapDriverController.carType != 'Scooter') Row( mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ - // mapDriverController.remainingTimeTimerRideBegin < - // 60 - // ? - SlideAction( - text: 'End Ride'.tr, - textStyle: const TextStyle( - fontSize: 18, - fontWeight: FontWeight.bold, - color: Colors.white, - ), - outerColor: AppColor.redColor, - innerColor: Colors.white, - sliderButtonIcon: const Icon( - Icons.arrow_forward, - color: AppColor.redColor, - ), - onSubmit: () { - mapDriverController.finishRideFromDriver(); - }, + _buildInfoBox( + icon: Icons.timer, + text: + mapDriverController.stringRemainingTimeRideBegin1, + ), + _buildInfoBox( + icon: Icons.location_on, + text: + '${mapDriverController.recentDistanceToDash.toStringAsFixed(0)} ${'KM'.tr}', + ), + _buildInfoBox( + icon: Icons.attach_money, + text: mapDriverController.price.toStringAsFixed(2), ), - // MyElevatedButton( - // title: 'End Ride'.tr, - // onPressed: () { - // mapDriverController.finishRideFromDriver(); - // }, - // kolor: AppColor.redColor, - // ), - // : const SizedBox(), - Container( - decoration: AppStyle.boxDecoration1, - child: Text( - mapDriverController.carType, - style: AppStyle.title, - ), - ) ], ), - mapDriverController.carType != 'Comfort' && - mapDriverController.carType != 'Mishwar Vip' && - mapDriverController.carType != 'Lady' - ? Stack( - children: [ - SizedBox( - width: Get.width * .9, - child: Center( - child: LinearProgressIndicator( - backgroundColor: AppColor.greyColor, - color: mapDriverController - .remainingTimeTimerRideBegin < - 60 - ? AppColor.redColor - : AppColor.greenColor, - minHeight: 25, - borderRadius: BorderRadius.circular(6), - value: mapDriverController - .progressTimerRideBegin - .toDouble(), - ), - ), - ), - Center( - child: Text( - mapDriverController - .stringRemainingTimeRideBegin, - style: AppStyle.title, - ), - ) - ], - ) - : const SizedBox(), - ], + _builtTimerAndCarType(), + Container( + width: Get.width * 0.8, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(15), + boxShadow: [ + BoxShadow( + color: AppColor.redColor.withOpacity(0.3), + blurRadius: 8, + offset: Offset(0, 4), + ), + ], + ), + child: SlideAction( + height: 50, + borderRadius: 15, + elevation: 4, + text: 'Slide to End Trip'.tr, + textStyle: AppStyle.title.copyWith( + fontSize: 18, + fontWeight: FontWeight.bold, + color: Colors.white, + ), + outerColor: AppColor.redColor, + innerColor: Colors.white, + sliderButtonIcon: const Icon( + Icons.arrow_forward_ios, + color: AppColor.redColor, + size: 24, + ), + sliderRotate: false, + onSubmit: () { + HapticFeedback.mediumImpact(); + mapDriverController.finishRideFromDriver(); + }, + ), + ) + ], + ), + ), + ) + : const SizedBox(), + ); +} + +class _builtTimerAndCarType extends StatelessWidget { + const _builtTimerAndCarType({ + super.key, + }); + + @override + Widget build(BuildContext context) { + final mapDriverController = Get.find(); + return Row( + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + Container( + decoration: AppStyle.boxDecoration1.copyWith( + boxShadow: [ + BoxShadow( + color: AppColor.accentColor.withOpacity(0.2), + blurRadius: 8, + offset: Offset(0, 4), + ), + ], + ), + padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), + child: Text( + mapDriverController.carType, + style: AppStyle.title, + ), + ), + if (mapDriverController.carType != 'Comfort' && + mapDriverController.carType != 'Mishwar Vip' && + mapDriverController.carType != 'Lady') + Container( + width: Get.width * 0.6, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(12), + gradient: LinearGradient( + colors: [ + mapDriverController.remainingTimeTimerRideBegin < 60 + ? AppColor.redColor.withOpacity(0.8) + : AppColor.greenColor.withOpacity(0.8), + mapDriverController.remainingTimeTimerRideBegin < 60 + ? AppColor.redColor + : AppColor.greenColor, + ], + begin: Alignment.centerLeft, + end: Alignment.centerRight, + ), + boxShadow: [ + BoxShadow( + color: (mapDriverController.remainingTimeTimerRideBegin < 60 + ? AppColor.redColor + : AppColor.greenColor) + .withOpacity(0.3), + blurRadius: 8, + offset: Offset(0, 4), ), - )) - : const SizedBox()); + ], + ), + child: ClipRRect( + borderRadius: BorderRadius.circular(12), + child: Stack( + children: [ + LinearProgressIndicator( + backgroundColor: Colors.white.withOpacity(0.2), + valueColor: AlwaysStoppedAnimation( + Colors.white.withOpacity(0.5), + ), + minHeight: 40, + value: + mapDriverController.progressTimerRideBegin.toDouble(), + ), + Center( + child: AnimatedDefaultTextStyle( + duration: Duration(milliseconds: 300), + style: AppStyle.title.copyWith( + color: Colors.white, + fontWeight: FontWeight.bold, + fontSize: + mapDriverController.remainingTimeTimerRideBegin < 60 + ? 18 + : 16, + shadows: [ + Shadow( + color: Colors.black26, + offset: Offset(0, 2), + blurRadius: 4, + ), + ], + ), + child: Text( + mapDriverController.stringRemainingTimeRideBegin, + ), + ), + ), + ], + ), + ), + ), + ], + ); + } +} + +Widget _buildInfoColumn({required IconData icon, required String text}) { + return Column( + children: [ + Icon(icon), + Text( + text, + style: AppStyle.title, + ), + ], + ); +} + +Widget _buildInfoBox({required IconData icon, required String text}) { + return Container( + width: Get.width * .2, + decoration: AppStyle.boxDecoration1, + padding: const EdgeInsets.all(4), + child: Row( + children: [ + Icon(icon), + SizedBox(width: 4), + Text( + text, + style: AppStyle.number, + ), + ], + ), + ); } GetBuilder speedCircle() { diff --git a/lib/views/home/Captin/mapDriverWidgets/passenger_info_window.dart b/lib/views/home/Captin/mapDriverWidgets/passenger_info_window.dart index df3dd4d..5713118 100644 --- a/lib/views/home/Captin/mapDriverWidgets/passenger_info_window.dart +++ b/lib/views/home/Captin/mapDriverWidgets/passenger_info_window.dart @@ -452,9 +452,12 @@ class PassengerInfoWindow extends StatelessWidget { kolor: AppColor.greenColor, onPressed: () { MyDialog().getDialog( - "Is the Passenger in your Car ?" - .tr, - "Don't start trip if not".tr, + "Is the Passenger in your Car?" + .tr, // "هل الراكب في سيارتك؟" + + "Don't start trip if passenger not in your car" + .tr, // "لا تبدأ الرحلة إذا لم يكن الراكب في سيارتك" + () async { await controller .startRideFromDriver(); diff --git a/lib/views/lang/languages.dart b/lib/views/lang/languages.dart index 83f0b34..a92767e 100644 --- a/lib/views/lang/languages.dart +++ b/lib/views/lang/languages.dart @@ -1,9 +1,7 @@ -import 'package:sefer_driver/constant/style.dart'; -import 'package:sefer_driver/views/home/Captin/home_captain/home_captin.dart'; -import 'package:flutter/material.dart'; +import 'package:flutter/cupertino.dart'; import 'package:get/get.dart'; +import 'package:sefer_driver/views/home/Captin/home_captain/home_captin.dart'; import 'package:sefer_driver/views/widgets/elevated_btn.dart'; - import '../../controller/local/local_controller.dart'; class Language extends StatelessWidget { @@ -11,203 +9,122 @@ class Language extends StatelessWidget { @override Widget build(BuildContext context) { - return Scaffold( - body: GetBuilder( - builder: (controller) => Center( - child: Container( - padding: const EdgeInsets.all(15), - child: ListView( - // mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - Text( - "Choose Language".tr, - style: Theme.of(context).textTheme.headlineLarge, + return CupertinoPageScaffold( + navigationBar: CupertinoNavigationBar( + middle: Text('Choose Language'.tr), + border: null, + ), + child: SafeArea( + child: GetBuilder( + builder: (controller) => Center( + child: Padding( + padding: const EdgeInsets.all(16), + child: Column( + children: [ + _buildHeader(), + const SizedBox(height: 20), + Expanded( + child: ListView( + physics: const BouncingScrollPhysics(), + children: [ + _buildLanguageButton( + 'العربية', 'ar', controller, context), + _buildLanguageButton( + 'English', 'en', controller, context), + _buildLanguageButton( + 'Türkçe', 'tr', controller, context), + _buildLanguageButton( + 'Français', 'fr', controller, context), + _buildLanguageButton( + 'Italiano', 'it', controller, context), + _buildLanguageButton( + 'Deutsch', 'de', controller, context), + _buildLanguageButton( + 'Ελληνικά', 'el', controller, context), + _buildLanguageButton( + 'Español', 'es', controller, context), + _buildLanguageButton( + 'فارسی', 'fa', controller, context), + _buildLanguageButton('中文', 'zh', controller, context), + _buildLanguageButton( + 'Русский', 'ru', controller, context), + _buildLanguageButton( + 'हिन्दी', 'hi', controller, context), + ], + ), + ), + ], ), - const SizedBox(height: 20), - MyElevatedButton( - title: 'العربية', - onPressed: () async { - await controller.changeLang("ar"); - Get.defaultDialog( - title: 'You should restart app to change language'.tr, - titleStyle: AppStyle.title, - middleText: '', - confirm: MyElevatedButton( - title: 'Ok'.tr, - onPressed: () { - Get.offAll(() => HomeCaptain()); - })); - }, - ), - MyElevatedButton( - title: "English", - onPressed: () { - controller.changeLang("en"); - Get.defaultDialog( - title: 'You should restart app to change language'.tr, - titleStyle: AppStyle.title, - middleText: '', - confirm: MyElevatedButton( - title: 'Ok'.tr, - onPressed: () { - Get.offAll(() => HomeCaptain()); - })); - }, - ), - MyElevatedButton( - title: "Türkçe", - onPressed: () { - controller.changeLang("tr"); - Get.defaultDialog( - title: 'You should restart app to change language'.tr, - titleStyle: AppStyle.title, - middleText: '', - confirm: MyElevatedButton( - title: 'Ok'.tr, - onPressed: () { - Get.offAll(() => HomeCaptain()); - })); - }, - ), - MyElevatedButton( - title: "Français", - onPressed: () { - controller.changeLang("fr"); - Get.defaultDialog( - title: 'You should restart app to change language'.tr, - titleStyle: AppStyle.title, - middleText: '', - confirm: MyElevatedButton( - title: 'Ok'.tr, - onPressed: () { - Get.offAll(() => HomeCaptain()); - })); - }, - ), - MyElevatedButton( - title: "Italiano", - onPressed: () { - controller.changeLang("it"); - Get.defaultDialog( - title: 'You should restart app to change language'.tr, - titleStyle: AppStyle.title, - middleText: '', - confirm: MyElevatedButton( - title: 'Ok'.tr, - onPressed: () { - Get.offAll(() => HomeCaptain()); - })); - }, - ), - MyElevatedButton( - title: "Deutsch", - onPressed: () { - controller.changeLang("de"); - Get.defaultDialog( - title: 'You should restart app to change language'.tr, - titleStyle: AppStyle.title, - middleText: '', - confirm: MyElevatedButton( - title: 'Ok'.tr, - onPressed: () { - Get.offAll(() => HomeCaptain()); - })); - }, - ), - MyElevatedButton( - title: "Ελληνικά", - onPressed: () { - controller.changeLang("el"); - Get.defaultDialog( - title: 'You should restart app to change language'.tr, - titleStyle: AppStyle.title, - middleText: '', - confirm: MyElevatedButton( - title: 'Ok'.tr, - onPressed: () { - Get.offAll(() => HomeCaptain()); - })); - }, - ), - MyElevatedButton( - title: "Español", - onPressed: () { - controller.changeLang("es"); - Get.defaultDialog( - title: 'You should restart app to change language'.tr, - titleStyle: AppStyle.title, - middleText: '', - confirm: MyElevatedButton( - title: 'Ok'.tr, - onPressed: () { - Get.offAll(() => HomeCaptain()); - })); - }, - ), - MyElevatedButton( - title: "فارسی", - onPressed: () { - controller.changeLang("fa"); - Get.defaultDialog( - title: 'You should restart app to change language'.tr, - titleStyle: AppStyle.title, - middleText: '', - confirm: MyElevatedButton( - title: 'Ok'.tr, - onPressed: () { - Get.offAll(() => HomeCaptain()); - })); - }, - ), - MyElevatedButton( - title: "中文", - onPressed: () { - controller.changeLang("zh"); - Get.defaultDialog( - title: 'You should restart app to change language'.tr, - titleStyle: AppStyle.title, - middleText: '', - confirm: MyElevatedButton( - title: 'Ok'.tr, - onPressed: () { - Get.offAll(() => HomeCaptain()); - })); - }, - ), - MyElevatedButton( - title: "Русский", - onPressed: () { - controller.changeLang("ru"); - Get.defaultDialog( - title: 'You should restart app to change language'.tr, - titleStyle: AppStyle.title, - middleText: '', - confirm: MyElevatedButton( - title: 'Ok'.tr, - onPressed: () { - Get.offAll(() => HomeCaptain()); - })); - }, - ), - MyElevatedButton( - title: "हिन्दी", - onPressed: () { - controller.changeLang("hi"); - Get.defaultDialog( - title: 'You should restart app to change language'.tr, - titleStyle: AppStyle.title, - middleText: '', - confirm: MyElevatedButton( - title: 'Ok'.tr, - onPressed: () { - Get.offAll(() => HomeCaptain()); - })); - }, - ), - ], + ), ), ), ), - )); + ); + } + + Widget _buildHeader() { + return Container( + padding: const EdgeInsets.all(20), + decoration: BoxDecoration( + gradient: const LinearGradient( + colors: [Color(0xFF2196F3), Color(0xFF1976D2)], + begin: Alignment.topLeft, + end: Alignment.bottomRight, + ), + borderRadius: BorderRadius.circular(16), + boxShadow: [ + BoxShadow( + color: CupertinoColors.systemBlue.withOpacity(0.2), + blurRadius: 10, + offset: const Offset(0, 4), + ), + ], + ), + child: Column( + children: [ + const Icon( + CupertinoIcons.globe, + color: CupertinoColors.white, + size: 48, + ), + const SizedBox(height: 16), + Text( + 'Choose Language'.tr, + style: const TextStyle( + color: CupertinoColors.white, + fontSize: 22, + fontWeight: FontWeight.bold, + ), + textAlign: TextAlign.center, + ), + ], + ), + ); + } + + Widget _buildLanguageButton(String title, String langCode, + LocaleController controller, BuildContext context) { + return Padding( + padding: const EdgeInsets.symmetric(vertical: 8), + child: MyElevatedButton( + title: title, + onPressed: () async { + controller.changeLang(langCode); + showCupertinoDialog( + context: context, + builder: (context) => CupertinoAlertDialog( + title: Text('You should restart app to change language'.tr), + actions: [ + CupertinoDialogAction( + child: Text('Ok'.tr), + onPressed: () { + Get.offAll(() => HomeCaptain()); + }, + ), + ], + ), + ); + }, + )); } } diff --git a/lib/views/widgets/elevated_btn.dart b/lib/views/widgets/elevated_btn.dart index 9cc179e..8bf8fa7 100644 --- a/lib/views/widgets/elevated_btn.dart +++ b/lib/views/widgets/elevated_btn.dart @@ -5,7 +5,9 @@ import 'package:sefer_driver/constant/style.dart'; import 'package:flutter/services.dart'; import 'package:vibration/vibration.dart'; +import '../../constant/box_name.dart'; import '../../constant/colors.dart'; +import '../../main.dart'; class MyElevatedButton extends StatelessWidget { final String title; @@ -22,17 +24,25 @@ class MyElevatedButton extends StatelessWidget { @override Widget build(BuildContext context) { + bool vibrate = box.read(BoxName.isvibrate) ?? true; return ElevatedButton( style: ButtonStyle( - backgroundColor: MaterialStateProperty.all(kolor), + backgroundColor: WidgetStateProperty.all(AppColor.blueColor), + shadowColor: WidgetStateProperty.all(Colors.transparent), + shape: WidgetStateProperty.all( + RoundedRectangleBorder( + borderRadius: BorderRadius.circular(8), + ), + ), ), onPressed: () async { // Handle haptic feedback for both iOS and Android - if (Platform.isIOS) { - HapticFeedback.selectionClick(); - } else { - Vibration.vibrate(duration: 100); - // Vibrate.vibrateWithPauses(pauses); + if (vibrate == true) { + if (Platform.isIOS) { + HapticFeedback.selectionClick(); + } else if (Platform.isAndroid) { + await Vibration.vibrate(duration: vibrateDuration); + } else {} } // Ensure the onPressed callback is called after haptic feedback diff --git a/lib/views/widgets/error_snakbar.dart b/lib/views/widgets/error_snakbar.dart index 8b7e73b..0a129e4 100644 --- a/lib/views/widgets/error_snakbar.dart +++ b/lib/views/widgets/error_snakbar.dart @@ -1,69 +1,123 @@ import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; import 'package:get/get.dart'; import '../../constant/colors.dart'; +class SnackbarConfig { + static const duration = Duration(seconds: 3); + static const animationDuration = Duration(milliseconds: 300); + static const margin = EdgeInsets.symmetric(horizontal: 16, vertical: 10); + static const borderRadius = 12.0; + static const elevation = 6.0; + + static final BoxShadow shadow = BoxShadow( + color: Colors.black.withOpacity(0.1), + blurRadius: 10, + offset: const Offset(0, 2), + ); +} + SnackbarController mySnackeBarError(String message) { + // Trigger error haptic feedback + HapticFeedback.mediumImpact(); + return Get.snackbar( 'Error'.tr, message, - backgroundColor: AppColor.redColor.withOpacity(0.9), + backgroundColor: AppColor.redColor.withOpacity(0.95), colorText: AppColor.secondaryColor, - icon: const Icon(Icons.error, color: AppColor.secondaryColor), + icon: const Icon( + Icons.error_outline_rounded, + color: AppColor.secondaryColor, + size: 28, + ), shouldIconPulse: true, snackPosition: SnackPosition.TOP, - margin: const EdgeInsets.all(10), - borderRadius: 10, - animationDuration: const Duration(milliseconds: 500), - forwardAnimationCurve: Curves.easeOutBack, - reverseAnimationCurve: Curves.easeInBack, + margin: SnackbarConfig.margin, + borderRadius: SnackbarConfig.borderRadius, + duration: SnackbarConfig.duration, + animationDuration: SnackbarConfig.animationDuration, + forwardAnimationCurve: Curves.easeOutCirc, + reverseAnimationCurve: Curves.easeInCirc, + boxShadows: [SnackbarConfig.shadow], + padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 12), titleText: Text( 'Error'.tr, style: const TextStyle( - fontWeight: FontWeight.bold, + fontWeight: FontWeight.w700, color: Colors.white, fontSize: 16, + letterSpacing: 0.2, ), ), messageText: Text( message, style: TextStyle( - color: Colors.white.withOpacity(0.9), + color: Colors.white.withOpacity(0.95), fontSize: 14, + height: 1.3, ), ), + onTap: (_) { + HapticFeedback.lightImpact(); + Get.closeCurrentSnackbar(); + }, + isDismissible: true, + dismissDirection: DismissDirection.horizontal, + overlayBlur: 0.8, + overlayColor: Colors.black12, ); } SnackbarController mySnackbarSuccess(String message) { + // Trigger success haptic feedback + HapticFeedback.lightImpact(); + return Get.snackbar( 'Success'.tr, message, - backgroundColor: AppColor.greenColor - .withOpacity(0.9), // Assuming green color for success + backgroundColor: AppColor.greenColor.withOpacity(0.95), colorText: AppColor.secondaryColor, - icon: const Icon(Icons.check_circle, color: AppColor.secondaryColor), + icon: const Icon( + Icons.check_circle_outline_rounded, + color: AppColor.secondaryColor, + size: 28, + ), shouldIconPulse: true, snackPosition: SnackPosition.TOP, - margin: const EdgeInsets.all(10), - borderRadius: 10, - animationDuration: const Duration(milliseconds: 500), - forwardAnimationCurve: Curves.easeOutBack, - reverseAnimationCurve: Curves.easeInBack, + margin: SnackbarConfig.margin, + borderRadius: SnackbarConfig.borderRadius, + duration: SnackbarConfig.duration, + animationDuration: SnackbarConfig.animationDuration, + forwardAnimationCurve: Curves.easeOutCirc, + reverseAnimationCurve: Curves.easeInCirc, + boxShadows: [SnackbarConfig.shadow], + padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 12), titleText: Text( 'Success'.tr, style: const TextStyle( - fontWeight: FontWeight.bold, + fontWeight: FontWeight.w700, color: Colors.white, fontSize: 16, + letterSpacing: 0.2, ), ), messageText: Text( message, style: TextStyle( - color: Colors.white.withOpacity(0.9), + color: Colors.white.withOpacity(0.95), fontSize: 14, + height: 1.3, ), ), + onTap: (_) { + HapticFeedback.lightImpact(); + Get.closeCurrentSnackbar(); + }, + isDismissible: true, + dismissDirection: DismissDirection.horizontal, + overlayBlur: 0.8, + overlayColor: Colors.black12, ); } diff --git a/lib/views/widgets/mycircular.dart b/lib/views/widgets/mycircular.dart index 2fe8e35..c0a9d80 100644 --- a/lib/views/widgets/mycircular.dart +++ b/lib/views/widgets/mycircular.dart @@ -1,36 +1,131 @@ import 'package:flutter/material.dart'; -class MyCircularProgressIndicator extends StatelessWidget { +class MyCircularProgressIndicator extends StatefulWidget { final Color backgroundColor; + final double size; + final Color progressColor; + final double strokeWidth; const MyCircularProgressIndicator({ super.key, this.backgroundColor = Colors.transparent, + this.size = 110, + this.progressColor = Colors.blue, + this.strokeWidth = 3.0, }); + @override + State createState() => + _MyCircularProgressIndicatorState(); +} + +class _MyCircularProgressIndicatorState + extends State + with SingleTickerProviderStateMixin { + late AnimationController _controller; + late Animation _scaleAnimation; + late Animation _rotationAnimation; + + @override + void initState() { + super.initState(); + _controller = AnimationController( + duration: const Duration(seconds: 2), + vsync: this, + )..repeat(reverse: true); + + _scaleAnimation = Tween( + begin: 0.95, + end: 1.05, + ).animate(CurvedAnimation( + parent: _controller, + curve: Curves.easeInOut, + )); + + _rotationAnimation = Tween( + begin: 0, + end: 2, + ).animate(CurvedAnimation( + parent: _controller, + curve: Curves.linear, + )); + } + + @override + void dispose() { + _controller.dispose(); + super.dispose(); + } + @override Widget build(BuildContext context) { return Center( - child: Container( - width: 110, - height: 110, - decoration: BoxDecoration( - color: backgroundColor, - shape: BoxShape.circle, - ), - child: Stack( - children: [ - const Center(child: CircularProgressIndicator()), - Column( - children: [ - Align( - alignment: Alignment.center, - child: Image.asset('assets/images/logo.gif'), - ), - ], + child: AnimatedBuilder( + animation: _controller, + builder: (context, child) { + return Transform.scale( + scale: _scaleAnimation.value, + child: Container( + width: widget.size, + height: widget.size, + decoration: BoxDecoration( + color: widget.backgroundColor, + shape: BoxShape.circle, + boxShadow: [ + BoxShadow( + color: widget.progressColor.withAlpha(30), + blurRadius: 12, + spreadRadius: 2, + ), + ], + ), + child: Stack( + alignment: Alignment.center, + children: [ + // Outer rotating progress indicator + Transform.rotate( + angle: _rotationAnimation.value * 3.14, + child: CircularProgressIndicator( + strokeWidth: widget.strokeWidth, + valueColor: AlwaysStoppedAnimation( + widget.progressColor, + ), + ), + ), + // Inner static progress indicator + CircularProgressIndicator( + strokeWidth: widget.strokeWidth * 0.7, + valueColor: AlwaysStoppedAnimation( + widget.progressColor.withAlpha(150), + ), + ), + // Logo container with scale animation + ScaleTransition( + scale: Tween( + begin: 0.9, + end: 1.0, + ).animate(CurvedAnimation( + parent: _controller, + curve: Curves.easeInOut, + )), + child: Container( + width: widget.size * 0.7, + height: widget.size * 0.7, + decoration: BoxDecoration( + shape: BoxShape.circle, + color: widget.backgroundColor, + ), + child: Image.asset( + 'assets/images/logo.gif', + fit: BoxFit.contain, + ), + ), + ), + ], + ), ), - ], - ), + ); + }, ), ); } diff --git a/lib/views/widgets/mydialoug.dart b/lib/views/widgets/mydialoug.dart index cdf4399..60230f3 100644 --- a/lib/views/widgets/mydialoug.dart +++ b/lib/views/widgets/mydialoug.dart @@ -1,58 +1,139 @@ import 'dart:ui'; import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; import 'package:get/get.dart'; import 'package:sefer_driver/constant/colors.dart'; import 'package:sefer_driver/constant/style.dart'; import 'package:sefer_driver/controller/functions/tts.dart'; +class DialogConfig { + static const Duration animationDuration = Duration(milliseconds: 200); + static const double blurStrength = 8.0; + static const double cornerRadius = 14.0; + static final BoxDecoration decoration = BoxDecoration( + borderRadius: BorderRadius.circular(cornerRadius), + boxShadow: [ + BoxShadow( + color: Colors.black.withAlpha(38), // 0.15 opacity + blurRadius: 16, + offset: const Offset(0, 8), + ), + ], + ); +} + class MyDialog extends GetxController { void getDialog(String title, String? midTitle, VoidCallback onPressed) { final textToSpeechController = Get.put(TextToSpeechController()); + HapticFeedback.mediumImpact(); + Get.dialog( - BackdropFilter( - filter: ImageFilter.blur(sigmaX: 5, sigmaY: 5), - child: CupertinoAlertDialog( - title: Text( - title, - style: AppStyle.title.copyWith( - fontSize: 20, - fontWeight: FontWeight.bold, + TweenAnimationBuilder( + duration: DialogConfig.animationDuration, + tween: Tween(begin: 0.0, end: 1.0), + builder: (context, value, child) { + return Transform.scale( + scale: 0.95 + (0.05 * value), + child: Opacity(opacity: value, child: child), + ); + }, + child: BackdropFilter( + filter: ImageFilter.blur( + sigmaX: DialogConfig.blurStrength, + sigmaY: DialogConfig.blurStrength, + ), + child: Theme( + data: ThemeData.light().copyWith( + dialogBackgroundColor: CupertinoColors.systemBackground, + ), + child: CupertinoAlertDialog( + title: Column( + children: [ + Text( + title, + style: AppStyle.title.copyWith( + fontSize: 20, + fontWeight: FontWeight.w700, + letterSpacing: -0.5, + color: AppColor.primaryColor, + ), + ), + const SizedBox(height: 8), + ], + ), + content: Column( + children: [ + CupertinoButton( + padding: const EdgeInsets.all(8), + onPressed: () async { + HapticFeedback.selectionClick(); + await textToSpeechController.speakText(title); + await textToSpeechController.speakText(midTitle!); + }, + child: Container( + padding: const EdgeInsets.all(8), + decoration: BoxDecoration( + color: + AppColor.primaryColor.withAlpha(26), // 0.1 opacity + borderRadius: BorderRadius.circular(8), + ), + child: Icon( + CupertinoIcons.speaker_2_fill, + color: AppColor.primaryColor, + size: 24, + ), + ), + ), + const SizedBox(height: 8), + Text( + midTitle!, + style: AppStyle.title.copyWith( + fontSize: 16, + height: 1.3, + color: Colors.black87, + ), + textAlign: TextAlign.center, + ), + ], + ), + actions: [ + CupertinoDialogAction( + onPressed: () { + HapticFeedback.lightImpact(); + Get.back(); + }, + child: Text( + 'Cancel', + style: TextStyle( + color: AppColor.redColor, + fontWeight: FontWeight.w600, + fontSize: 17, + ), + ), + ), + CupertinoDialogAction( + onPressed: () { + HapticFeedback.mediumImpact(); + onPressed(); + }, + child: Text( + 'OK'.tr, + style: TextStyle( + color: AppColor.greenColor, + fontWeight: FontWeight.w600, + fontSize: 17, + ), + ), + ), + ], ), ), - content: Column( - children: [ - CupertinoButton( - onPressed: () async { - await textToSpeechController.speakText(title); - await textToSpeechController.speakText(midTitle!); - }, - child: const Icon(CupertinoIcons.speaker_2, - color: AppColor.primaryColor), - ), - Text( - midTitle!, - style: AppStyle.title.copyWith(fontSize: 16), - ), - ], - ), - actions: [ - CupertinoDialogAction( - child: const Text('Cancel', - style: TextStyle(color: AppColor.redColor)), - onPressed: () { - Get.back(); - }, - ), - CupertinoDialogAction( - onPressed: onPressed, - child: Text('OK'.tr, - style: const TextStyle(color: AppColor.greenColor)), - ), - ], ), ), - barrierDismissible: false, + barrierDismissible: true, + barrierColor: Colors.black.withAlpha(102), // 0.4 opacity ); } } @@ -61,46 +142,104 @@ class MyDialogContent extends GetxController { void getDialog(String title, Widget? content, VoidCallback onPressed) { final textToSpeechController = Get.put(TextToSpeechController()); + HapticFeedback.mediumImpact(); + Get.dialog( - BackdropFilter( - filter: ImageFilter.blur(sigmaX: 5, sigmaY: 5), - child: CupertinoAlertDialog( - title: Text( - title, - style: AppStyle.title.copyWith( - fontSize: 20, - fontWeight: FontWeight.bold, - ), + TweenAnimationBuilder( + duration: DialogConfig.animationDuration, + tween: Tween(begin: 0.0, end: 1.0), + builder: (context, value, child) { + return Transform.scale( + scale: 0.95 + (0.05 * value), + child: Opacity(opacity: value, child: child), + ); + }, + child: BackdropFilter( + filter: ImageFilter.blur( + sigmaX: DialogConfig.blurStrength, + sigmaY: DialogConfig.blurStrength, ), - content: Column( - children: [ - CupertinoButton( - onPressed: () async { - await textToSpeechController.speakText(title); - }, - child: const Icon(CupertinoIcons.headphones, - color: AppColor.primaryColor), + child: Theme( + data: ThemeData.light().copyWith( + dialogBackgroundColor: CupertinoColors.systemBackground, + ), + child: CupertinoAlertDialog( + title: Column( + children: [ + Text( + title, + style: AppStyle.title.copyWith( + fontSize: 20, + fontWeight: FontWeight.w700, + letterSpacing: -0.5, + color: AppColor.primaryColor, + ), + ), + const SizedBox(height: 8), + ], ), - content! - ], + content: Column( + children: [ + CupertinoButton( + padding: const EdgeInsets.all(8), + onPressed: () async { + HapticFeedback.selectionClick(); + await textToSpeechController.speakText(title); + }, + child: Container( + padding: const EdgeInsets.all(8), + decoration: BoxDecoration( + color: + AppColor.primaryColor.withAlpha(26), // 0.1 opacity + borderRadius: BorderRadius.circular(8), + ), + child: Icon( + CupertinoIcons.headphones, + color: AppColor.primaryColor, + size: 24, + ), + ), + ), + const SizedBox(height: 12), + content!, + ], + ), + actions: [ + CupertinoDialogAction( + onPressed: () { + HapticFeedback.lightImpact(); + Get.back(); + }, + child: Text( + 'Cancel', + style: TextStyle( + color: AppColor.redColor, + fontWeight: FontWeight.w600, + fontSize: 17, + ), + ), + ), + CupertinoDialogAction( + onPressed: () { + HapticFeedback.mediumImpact(); + onPressed(); + }, + child: Text( + 'OK'.tr, + style: TextStyle( + color: AppColor.greenColor, + fontWeight: FontWeight.w600, + fontSize: 17, + ), + ), + ), + ], + ), ), - actions: [ - CupertinoDialogAction( - child: const Text('Cancel', - style: TextStyle(color: AppColor.redColor)), - onPressed: () { - Get.back(); - }, - ), - CupertinoDialogAction( - onPressed: onPressed, - child: Text('OK'.tr, - style: const TextStyle(color: AppColor.greenColor)), - ), - ], ), ), - barrierDismissible: false, + barrierDismissible: true, + barrierColor: Colors.black.withAlpha(102), // 0.4 opacity ); } }