This commit is contained in:
Hamza-Ayed
2024-12-22 16:06:07 +03:00
parent 2910750483
commit 0f16dd9293
22 changed files with 2531 additions and 1282 deletions

View File

@@ -10,30 +10,30 @@ class AppStyle {
fontSize: 36, fontSize: 36,
color: AppColor.accentColor, color: AppColor.accentColor,
fontFamily: box.read(BoxName.lang) == 'ar' fontFamily: box.read(BoxName.lang) == 'ar'
// ?GoogleFonts.notoNaskhArabic().fontFamily // ?GoogleFonts.markaziText().fontFamily
? GoogleFonts.notoNaskhArabic().fontFamily ? GoogleFonts.markaziText().fontFamily
: GoogleFonts.roboto().fontFamily); : GoogleFonts.inter().fontFamily);
static TextStyle headTitle2 = TextStyle( static TextStyle headTitle2 = TextStyle(
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
fontSize: 24, fontSize: 24,
color: AppColor.writeColor, color: AppColor.writeColor,
fontFamily: box.read(BoxName.lang) == 'ar' fontFamily: box.read(BoxName.lang) == 'ar'
? GoogleFonts.notoNaskhArabic().fontFamily ? GoogleFonts.markaziText().fontFamily
: GoogleFonts.roboto().fontFamily); : GoogleFonts.inter().fontFamily);
static TextStyle title = TextStyle( static TextStyle title = TextStyle(
fontWeight: FontWeight.normal, fontWeight: FontWeight.normal,
fontSize: 14, fontSize: 16,
color: AppColor.writeColor, color: AppColor.writeColor,
fontFamily: box.read(BoxName.lang) == 'ar' fontFamily: box.read(BoxName.lang) == 'ar'
? GoogleFonts.notoNaskhArabic().fontFamily ? GoogleFonts.markaziText().fontFamily
: GoogleFonts.roboto().fontFamily); : GoogleFonts.inter().fontFamily);
static TextStyle subtitle = TextStyle( static TextStyle subtitle = TextStyle(
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
fontSize: 12, fontSize: 12,
color: AppColor.writeColor, color: AppColor.writeColor,
fontFamily: box.read(BoxName.lang) == 'ar' fontFamily: box.read(BoxName.lang) == 'ar'
? GoogleFonts.notoNaskhArabic().fontFamily ? GoogleFonts.markaziText().fontFamily
: GoogleFonts.roboto().fontFamily); : GoogleFonts.inter().fontFamily);
static TextStyle number = const TextStyle( static TextStyle number = const TextStyle(
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
fontSize: 14, fontSize: 14,

View File

@@ -1,6 +1,8 @@
import 'dart:convert'; import 'dart:convert';
import 'dart:io'; import 'dart:io';
import 'dart:ui';
import 'package:sefer_driver/constant/box_name.dart'; 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/constant/links.dart';
import 'package:sefer_driver/controller/functions/crud.dart'; import 'package:sefer_driver/controller/functions/crud.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
@@ -15,7 +17,7 @@ Future<void> checkForUpdate(BuildContext context) async {
final packageInfo = await PackageInfo.fromPlatform(); final packageInfo = await PackageInfo.fromPlatform();
final currentVersion = packageInfo.buildNumber; final currentVersion = packageInfo.buildNumber;
final version = packageInfo.version; final version = packageInfo.version;
print('currentVersion is : $currentVersion'); // print('currentVersion is : $currentVersion');
// Fetch the latest version from your server // Fetch the latest version from your server
String latestVersion = await getPackageInfo(); String latestVersion = await getPackageInfo();
box.write(BoxName.packagInfo, version); box.write(BoxName.packagInfo, version);
@@ -41,36 +43,118 @@ void showUpdateDialog(BuildContext context) {
final String storeUrl = Platform.isAndroid final String storeUrl = Platform.isAndroid
? 'https://play.google.com/store/apps/details?id=com.sefer_driver' ? 'https://play.google.com/store/apps/details?id=com.sefer_driver'
: 'https://apps.apple.com/ae/app/sefer-driver/id6502189302'; : 'https://apps.apple.com/ae/app/sefer-driver/id6502189302';
showCupertinoDialog(
showGeneralDialog(
context: context, context: context,
barrierDismissible: false, barrierDismissible: false,
builder: (BuildContext context) { barrierColor: Colors.black.withOpacity(0.5),
return CupertinoAlertDialog( pageBuilder: (_, __, ___) {
title: Text('Update Available'.tr), return BackdropFilter(
content: Text( filter: ImageFilter.blur(sigmaX: 5, sigmaY: 5),
'A new version of the app is available. Please update to the latest version.' child: Center(
.tr, 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: <Widget>[ );
CupertinoDialogAction( },
child: Text('Update'.tr), transitionBuilder: (_, animation, __, child) {
onPressed: () async { return ScaleTransition(
if (await canLaunchUrl(Uri.parse(storeUrl))) { scale: CurvedAnimation(
await launchUrl(Uri.parse(storeUrl)); parent: animation,
} else { curve: Curves.easeOutCubic, // More natural curve
print('Could not launch $storeUrl'); ),
} child: child,
Navigator.of(context).pop();
},
),
CupertinoDialogAction(
child: Text('Cancel'.tr),
onPressed: () async {
Navigator.of(context).pop();
},
),
],
); );
}, },
); );

View File

@@ -1,94 +1,88 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:sefer_driver/constant/box_name.dart';
import '../../constant/box_name.dart'; import 'package:sefer_driver/main.dart';
import '../../main.dart'; import 'package:sefer_driver/controller/themes/themes.dart';
import '../themes/themes.dart';
class LocaleController extends GetxController { class LocaleController extends GetxController {
Locale? language; Locale? language;
String countryCode = ''; String countryCode = '';
void restartApp() {
// Get.offAll(MyApp);
runApp(MyApp());
}
ThemeData appTheme = themeEnglish; ThemeData appTheme = lightThemeEnglish;
changeLang(String langcode) { void changeLang(String langcode) {
Locale locale; Locale locale;
switch (langcode) { switch (langcode) {
case "ar": case "ar":
locale = const Locale("ar"); locale = const Locale("ar");
appTheme = themeArabic; appTheme = lightThemeArabic;
box.write(BoxName.lang, 'ar'); box.write(BoxName.lang, 'ar');
break; break;
case "en": case "en":
locale = const Locale("en"); locale = const Locale("en");
appTheme = themeEnglish; appTheme = lightThemeEnglish;
box.write(BoxName.lang, 'en'); box.write(BoxName.lang, 'en');
break; break;
case "tr": case "tr":
locale = const Locale("tr"); locale = const Locale("tr");
appTheme = themeEnglish; appTheme = lightThemeEnglish;
box.write(BoxName.lang, 'tr'); box.write(BoxName.lang, 'tr');
break; break;
case "fr": case "fr":
locale = const Locale("fr"); locale = const Locale("fr");
appTheme = themeEnglish; appTheme = lightThemeEnglish;
box.write(BoxName.lang, 'fr'); box.write(BoxName.lang, 'fr');
break; break;
case "it": case "it":
locale = const Locale("it"); locale = const Locale("it");
appTheme = themeEnglish; appTheme = lightThemeEnglish;
box.write(BoxName.lang, 'it'); box.write(BoxName.lang, 'it');
break; break;
case "de": case "de":
locale = const Locale("de"); locale = const Locale("de");
appTheme = themeEnglish; appTheme = lightThemeEnglish;
box.write(BoxName.lang, 'de'); box.write(BoxName.lang, 'de');
break; break;
case "el": case "el":
locale = const Locale("el"); locale = const Locale("el");
appTheme = themeEnglish; appTheme = lightThemeEnglish;
box.write(BoxName.lang, 'el'); box.write(BoxName.lang, 'el');
break; break;
case "es": case "es":
locale = const Locale("es"); locale = const Locale("es");
appTheme = themeEnglish; appTheme = lightThemeEnglish;
box.write(BoxName.lang, 'es'); box.write(BoxName.lang, 'es');
break; break;
case "fa": case "fa":
locale = const Locale("fa"); locale = const Locale("fa");
appTheme = themeEnglish; appTheme = lightThemeEnglish;
box.write(BoxName.lang, 'fa'); box.write(BoxName.lang, 'fa');
break; break;
case "zh": case "zh":
locale = const Locale("zh"); locale = const Locale("zh");
appTheme = themeEnglish; appTheme = lightThemeEnglish;
box.write(BoxName.lang, 'zh'); box.write(BoxName.lang, 'zh');
break; break;
case "ru": case "ru":
locale = const Locale("ru"); locale = const Locale("ru");
appTheme = themeEnglish; appTheme = lightThemeEnglish;
box.write(BoxName.lang, 'ru'); box.write(BoxName.lang, 'ru');
break; break;
case "hi": case "hi":
locale = const Locale("hi"); locale = const Locale("hi");
appTheme = themeEnglish; appTheme = lightThemeEnglish;
box.write(BoxName.lang, 'hi'); box.write(BoxName.lang, 'hi');
break; break;
default: default:
locale = Locale(Get.deviceLocale!.languageCode); locale = Locale(Get.deviceLocale!.languageCode);
box.write(BoxName.lang, Get.deviceLocale!.languageCode); box.write(BoxName.lang, Get.deviceLocale!.languageCode);
appTheme = themeEnglish; appTheme = lightThemeEnglish;
break; break;
} }
box.write(BoxName.lang, langcode); box.write(BoxName.lang, langcode);
Get.changeTheme(appTheme); Get.changeTheme(appTheme);
Get.updateLocale(locale); Get.updateLocale(locale);
restartApp();
update(); update();
} }

View File

@@ -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": "You will get cost of your work for this trip":
"ستحصل على تكلفة عملك لهذه الرحلة", "ستحصل على تكلفة عملك لهذه الرحلة",
"in your wallet": "في محفظتك", "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": "الطلب ملغى",
"Order Cancelled by Passenger": "تم إلغاء الطلب من قبل الراكب", "Order Cancelled by Passenger": "تم إلغاء الطلب من قبل الراكب",
"Success": "النجاح", "Success": "‏تمام",
"Feedback data saved successfully": "تم حفظ بيانات التقييم بنجاح", "Feedback data saved successfully": "تم حفظ بيانات التقييم بنجاح",
"No Promo for today .": "لا ترويج لليوم.", "No Promo for today .": "لا ترويج لليوم.",
"Select your destination": "اختر وجهتك", "Select your destination": "اختر وجهتك",

View File

@@ -1,8 +1,10 @@
import 'dart:convert'; import 'dart:convert';
import 'package:flutter/cupertino.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:sefer_driver/constant/style.dart'; import 'package:sefer_driver/constant/style.dart';
import 'package:sefer_driver/views/widgets/elevated_btn.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/box_name.dart';
import '../../constant/links.dart'; import '../../constant/links.dart';
@@ -20,16 +22,43 @@ class NotificationCaptainController extends GetxController {
link: AppLink.getNotificationCaptain, link: AppLink.getNotificationCaptain,
payload: {'driverID': box.read(BoxName.driverID)}); payload: {'driverID': box.read(BoxName.driverID)});
if (res == "failure") { if (res == "failure") {
Get.defaultDialog( // MyDialog().getDialog('There is no notification yet'.tr, '', () {
title: 'There is no notification yet'.tr, // Get.back();
titleStyle: AppStyle.title, // Get.back();
middleText: '', // });
confirm: MyElevatedButton( Get.dialog(
title: 'Back', 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: () { onPressed: () {
Get.back(); Get.back();
Get.back(); Get.back();
})); },
child: Text('Back'.tr),
),
],
),
barrierDismissible: true,
transitionCurve: Curves.easeOutBack,
transitionDuration: const Duration(milliseconds: 200),
);
} }
notificationData = jsonDecode(res); notificationData = jsonDecode(res);
// sql.insertData(notificationData['message'], TableName.captainNotification); // sql.insertData(notificationData['message'], TableName.captainNotification);

View File

@@ -1,6 +1,8 @@
import 'dart:convert'; import 'dart:convert';
import 'dart:math'; 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/constant/box_name.dart';
import 'package:sefer_driver/controller/functions/location_controller.dart'; import 'package:sefer_driver/controller/functions/location_controller.dart';
import 'package:geolocator/geolocator.dart'; import 'package:geolocator/geolocator.dart';
@@ -79,31 +81,98 @@ class RideAvailableController extends GetxController {
// } // }
getRideAvailable() async { getRideAvailable() async {
isLoading = true; try {
LatLngBounds bounds = calculateBounds( isLoading = true;
Get.find<LocationController>().myLocation!.latitude, update();
Get.find<LocationController>().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}');
if (res != 'failure') { LatLngBounds bounds = calculateBounds(
rideAvailableMap = jsonDecode(res); Get.find<LocationController>().myLocation!.latitude,
Get.find<LocationController>().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; isLoading = false;
update(); update();
} else { Get.dialog(
MyDialog().getDialog("No Rides Available".tr, '', () { CupertinoAlertDialog(
Get.back(); title: const Icon(
Get.back(); 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),
),
],
),
);
} }
} }

View File

@@ -1,21 +1,22 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:sefer_driver/constant/style.dart'; import 'package:sefer_driver/constant/style.dart';
import '../../constant/colors.dart'; import '../../constant/colors.dart';
ThemeData themeEnglish = ThemeData( ThemeData lightThemeEnglish = ThemeData(
fontFamily: "PlayfairDisplay", brightness: Brightness.light,
fontFamily: "SFPro",
textTheme: TextTheme( textTheme: TextTheme(
displaySmall: AppStyle.title, displaySmall: AppStyle.title,
displayLarge: AppStyle.title, displayLarge: AppStyle.headTitle,
displayMedium: AppStyle.title, displayMedium: AppStyle.headTitle2,
bodyLarge: AppStyle.title, bodyLarge: AppStyle.title,
bodyMedium: AppStyle.title), bodyMedium: AppStyle.subtitle,
),
primarySwatch: Colors.blue, primarySwatch: Colors.blue,
dialogTheme: DialogTheme( dialogTheme: DialogTheme(
backgroundColor: AppColor.secondaryColor, backgroundColor: AppColor.secondaryColor,
contentTextStyle: AppStyle.title, contentTextStyle: AppStyle.title,
titleTextStyle: AppStyle.title, titleTextStyle: AppStyle.headTitle2,
), ),
appBarTheme: AppBarTheme( appBarTheme: AppBarTheme(
elevation: 0, elevation: 0,
@@ -25,35 +26,122 @@ ThemeData themeEnglish = ThemeData(
color: AppColor.primaryColor, color: AppColor.primaryColor,
), ),
toolbarTextStyle: TextTheme( toolbarTextStyle: TextTheme(
titleSmall: AppStyle.subtitle, titleSmall: AppStyle.subtitle,
headlineSmall: AppStyle.title, headlineSmall: AppStyle.title,
titleLarge: AppStyle.headTitle2) titleLarge: AppStyle.headTitle2,
.bodyMedium, ).bodyMedium,
titleTextStyle: TextTheme( titleTextStyle: TextTheme(
titleSmall: AppStyle.subtitle, titleSmall: AppStyle.subtitle,
headlineSmall: AppStyle.title, headlineSmall: AppStyle.title,
titleLarge: AppStyle.headTitle2) titleLarge: AppStyle.headTitle2,
.titleLarge, ).titleLarge,
), ),
); );
ThemeData themeArabic = ThemeData( ThemeData darkThemeEnglish = ThemeData(
fontFamily: 'mohanad', brightness: Brightness.dark,
textTheme: const TextTheme( fontFamily: "SFPro",
displayLarge: TextStyle( textTheme: TextTheme(
fontWeight: FontWeight.bold, displaySmall: AppStyle.title,
fontSize: 22, displayLarge: AppStyle.headTitle,
color: AppColor.primaryColor), displayMedium: AppStyle.headTitle2,
displayMedium: TextStyle( bodyLarge: AppStyle.title,
fontWeight: FontWeight.bold, bodyMedium: AppStyle.subtitle,
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)),
primarySwatch: Colors.blue, 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,
),
); );

View File

@@ -1,84 +1,142 @@
import 'package:sefer_driver/views/widgets/elevated_btn.dart'; import 'package:flutter/cupertino.dart';
import 'package:sefer_driver/views/widgets/my_textField.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import '../../controller/rate/rate_app_controller.dart'; import '../../controller/rate/rate_app_controller.dart';
class RatingScreen extends StatelessWidget { class RatingScreen extends StatelessWidget {
// Initialize the RatingController using GetX for state management
final RatingController ratingController = Get.put(RatingController()); final RatingController ratingController = Get.put(RatingController());
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return CupertinoPageScaffold(
appBar: AppBar( navigationBar: CupertinoNavigationBar(
// Display title "Rate Our App", with .tr for localization support middle: Text(
title: Text("Rate Our App".tr), "Rate Our App".tr,
style: const TextStyle(fontWeight: FontWeight.bold),
),
), ),
body: Center( child: SafeArea(
child: Obx(() { child: SingleChildScrollView(
// Observe changes in userRating; when updated, rebuild the UI accordingly child: Center(
return Padding( child: Obx(() {
padding: const EdgeInsets.all(8.0), return Padding(
child: ListView( padding:
// mainAxisAlignment: const EdgeInsets.symmetric(horizontal: 20, vertical: 30),
// MainAxisAlignment.center, // Center content vertically child: Column(
children: [ crossAxisAlignment: CrossAxisAlignment.center,
ClipRRect( children: [
borderRadius: BorderRadius.circular(15), // App logo or visual
child: Image.asset('assets/images/logo.gif')), ClipRRect(
const SizedBox(height: 10), borderRadius: BorderRadius.circular(16),
// Text prompt asking the user to rate the app, with localization support child: Image.asset(
Text("How would you rate our app?".tr), 'assets/images/logo.gif',
const SizedBox(height: 10), // Vertical spacing between elements height: 120,
MyTextForm( ),
controller: ratingController.comment, ),
label: 'write comment here'.tr, const SizedBox(height: 20),
hint: 'write comment here'.tr,
type: TextInputType.name,
),
// Build and display the row of rating stars
_buildRatingStars(),
const SizedBox( // Rating Prompt
height: 20), // Additional spacing before the button 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 // Comment Box
MyElevatedButton( CupertinoTextField(
onPressed: () { controller: ratingController.comment,
// Calls submitRating() method in the controller with the current rating value placeholder: 'Write your comment here'.tr,
ratingController padding: const EdgeInsets.all(12),
.submitRating(ratingController.userRating.value); decoration: BoxDecoration(
}, border: Border.all(color: CupertinoColors.systemGrey4),
// Button text "Submit Rating" with localization support borderRadius: BorderRadius.circular(12),
title: "Submit Rating".tr, 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() { Widget _buildRatingStars() {
return Row( return Row(
mainAxisAlignment: mainAxisAlignment: MainAxisAlignment.center,
MainAxisAlignment.center, // Center-aligns stars horizontally
children: List.generate(5, (index) { children: List.generate(5, (index) {
return IconButton( return GestureDetector(
// Display a star icon, filled if selected, otherwise grey onTap: () {
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
ratingController.userRating.value = index + 1; 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,
),
),
); );
}), }),
); );

View File

@@ -2,7 +2,6 @@ import 'package:sefer_driver/constant/colors.dart';
import 'package:sefer_driver/controller/profile/setting_controller.dart'; import 'package:sefer_driver/controller/profile/setting_controller.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_font_icons/flutter_font_icons.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:sefer_driver/constant/style.dart'; import 'package:sefer_driver/constant/style.dart';
import 'package:sefer_driver/views/lang/languages.dart'; import 'package:sefer_driver/views/lang/languages.dart';
@@ -25,140 +24,134 @@ class SettingsCaptain extends StatelessWidget {
title: 'Settings'.tr, title: 'Settings'.tr,
body: [ body: [
ListView( ListView(
physics: const BouncingScrollPhysics(),
children: <Widget>[ children: <Widget>[
ListTile( // General Section
leading: const Icon(Icons.language), _buildSectionHeader('General'.tr),
title: Text( CupertinoListSection(
'Language'.tr, margin: EdgeInsets.zero,
style: AppStyle.headTitle2, children: [
), CupertinoListTile(
subtitle: Text('You can change the language of the app'.tr), leading: const Icon(CupertinoIcons.globe),
onTap: () => Get.to(const Language()), title: Text('Language'.tr, style: AppStyle.headTitle2),
), subtitle: Text('You can change the language of the app'.tr,
const Divider( style: AppStyle.subtitle),
endIndent: 44, trailing: const CupertinoListTileChevron(),
indent: 44, onTap: () => Get.to(const Language()),
), ),
ListTile( CupertinoListTile(
leading: const Icon(Icons.place_outlined), leading: const Icon(CupertinoIcons.flag_fill),
title: Text( title: Text('Change Country'.tr, style: AppStyle.headTitle2),
'Change Country'.tr, subtitle: Text(
style: AppStyle.headTitle2, 'You can change the Country to get all features'.tr,
), style: AppStyle.subtitle),
subtitle: trailing: const CupertinoListTileChevron(),
Text('You can change the Country to get all features'.tr), onTap: () => Get.to(
onTap: () => Get.to(MyScafolld( MyScafolld(
title: 'Change Country'.tr, title: 'Change Country'.tr,
body: [CountryPickerFromSetting()], body: [CountryPickerFromSetting()],
isleading: true)), isleading: true,
), // isCupertino: true, // Indicate it's a Cupertino style page
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<SettingController>(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<HomePageController>(
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()),
), ),
const Divider( // App Preferences Section
endIndent: 44, _buildSectionHeader('App Preferences'.tr),
indent: 44, 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<SettingController>(
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<HomePageController>(
builder: (controller) => CupertinoSwitch(
value: controller.isVibrate,
onChanged: controller.changeVibrateOption,
activeTrackColor: AppColor.primaryColor,
),
),
onTap: () => print('3'),
),
],
), ),
ListTile(
leading: const Icon(Icons.account_balance_outlined), // Help & Support Section
title: Text( _buildSectionHeader('Help & Support'.tr),
'About Us'.tr, CupertinoListSection(
style: AppStyle.headTitle2, margin: EdgeInsets.zero,
), children: [
subtitle: Text( CupertinoListTile(
'You can change the Country to get all features'.tr, leading: const Icon(CupertinoIcons.question_circle_fill),
style: AppStyle.title, title: Text('Frequently Questions'.tr,
), style: AppStyle.headTitle2),
onTap: () => Get.to(() => const AboutPage()), 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( const SizedBox(height: 16),
// leading: const Icon(Icons.account_circle),
// title: const Text('Account'),
// onTap: () => Navigator.pushNamed(context, '/account-settings'),
// ),
], ],
), ),
], ],
isleading: true, 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,
),
),
); );
} }
} }

View File

@@ -175,7 +175,7 @@ class AssuranceHealthPage extends StatelessWidget {
// .tr, // .tr,
// backgroundColor: // backgroundColor:
// CupertinoColors.systemGrey); // CupertinoColors.systemGrey);
mySnackbarSuccess( mySnackeBarError(
"You have chosen not to proceed with health insurance." "You have chosen not to proceed with health insurance."
.tr); .tr);
}, },

View File

@@ -1,5 +1,6 @@
import 'package:sefer_driver/constant/api_key.dart'; import 'package:sefer_driver/constant/api_key.dart';
import 'package:sefer_driver/constant/links.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/controller/home/captin/home_captain_controller.dart';
import 'package:sefer_driver/views/Rate/rate_app_page.dart'; import 'package:sefer_driver/views/Rate/rate_app_page.dart';
import 'package:sefer_driver/views/auth/captin/contact_us_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 '../maintain_center_page.dart';
import 'package:flutter/cupertino.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<ImageController>(
// 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<HomeCaptainController>().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<HomeCaptainController>().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 { class CupertinoDrawerCaptain extends StatelessWidget {
final ImageController imageController = Get.put(ImageController()); final ImageController imageController = Get.put(ImageController());
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return CupertinoPageScaffold( return CupertinoPageScaffold(
backgroundColor: CupertinoColors.systemGroupedBackground,
navigationBar: CupertinoNavigationBar( 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: SafeArea(
child: CustomScrollView( child: CustomScrollView(
slivers: [ slivers: [
const SliverToBoxAdapter(child: const UserAccountHeader()), const SliverToBoxAdapter(child: UserAccountHeader()),
SliverList( SliverList(
delegate: SliverChildListDelegate([ delegate: SliverChildListDelegate([
_buildDivider(), const SizedBox(height: 10),
_buildSectionHeader('Account'.tr),
_buildDrawerItem( _buildDrawerItem(
icon: CupertinoIcons.money_dollar, icon: CupertinoIcons.money_dollar_circle_fill,
text: 'Wallet'.tr, text: 'Wallet'.tr,
onTap: () => Get.to(() => WalletCaptain()), onTap: () => Get.to(() => WalletCaptain()),
), ),
_buildDivider(),
_buildDrawerItem( _buildDrawerItem(
icon: CupertinoIcons.person, icon: CupertinoIcons.person_fill,
text: 'Profile'.tr, text: 'Profile'.tr,
onTap: () => Get.to(() => ProfileCaptain()), onTap: () => Get.to(() => ProfileCaptain()),
), ),
_buildDivider(), _buildSectionHeader('Activities'.tr),
_buildDrawerItem( _buildDrawerItem(
icon: CupertinoIcons.clock, icon: CupertinoIcons.clock_fill,
text: 'History of Trip'.tr, text: 'History of Trip'.tr,
onTap: () => Get.to(() => const HistoryCaptain()), onTap: () => Get.to(() => const HistoryCaptain()),
), ),
_buildDivider(),
_buildDrawerItem( _buildDrawerItem(
icon: CupertinoIcons.car_detailed, icon: CupertinoIcons.car_fill,
text: 'Available for rides'.tr, text: 'Available for rides'.tr,
onTap: () => Get.to(() => const AvailableRidesPage()), onTap: () => Get.to(() => const AvailableRidesPage()),
), ),
_buildDivider(), _buildSectionHeader('Support'.tr),
_buildDrawerItem( _buildDrawerItem(
icon: CupertinoIcons.bell, icon: CupertinoIcons.bell_fill,
text: 'Notifications'.tr, text: 'Notifications'.tr,
onTap: () => Get.to(() => const NotificationCaptain()), onTap: () => Get.to(() => const NotificationCaptain()),
), ),
_buildDivider(),
_buildDrawerItem( _buildDrawerItem(
icon: CupertinoIcons.question_circle, icon: CupertinoIcons.question_circle_fill,
text: 'Helping Center'.tr, text: 'Helping Center'.tr,
onTap: () => Get.to(() => HelpCaptain()), onTap: () => Get.to(() => HelpCaptain()),
), ),
_buildDivider(), _buildSectionHeader('More'.tr),
_buildDrawerItem( ...moreMenuItems(),
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(),
]), ]),
), ),
], ],
@@ -135,11 +332,61 @@ class CupertinoDrawerCaptain extends StatelessWidget {
); );
} }
Widget _buildDivider() { List<Widget> moreMenuItems() => [
return const Divider( _buildDrawerItem(
thickness: 1, icon: CupertinoIcons.share_up,
height: 1, text: 'Share App'.tr,
color: CupertinoColors.systemGrey4, 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 IconData icon,
required String text, required String text,
required VoidCallback onTap, required VoidCallback onTap,
bool isDestructive = false,
}) { }) {
return CupertinoButton( return Container(
onPressed: onTap, margin: const EdgeInsets.symmetric(horizontal: 8, vertical: 2),
child: Row( decoration: BoxDecoration(
children: [ color: CupertinoColors.white,
Icon(icon, color: CupertinoColors.activeBlue), borderRadius: BorderRadius.circular(10),
const SizedBox(width: 10), ),
Text(text, style: const TextStyle(color: CupertinoColors.label)), child: CupertinoButton(
const Spacer(), padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
const Icon(CupertinoIcons.right_chevron, onPressed: onTap,
color: CupertinoColors.systemGrey), 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 @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Container( return Container(
padding: const EdgeInsets.all(16), padding: const EdgeInsets.fromLTRB(20, 20, 20, 24),
decoration: const BoxDecoration( decoration: BoxDecoration(
gradient: LinearGradient( gradient: const LinearGradient(
colors: [AppColor.blueColor, AppColor.twitterColor], colors: [AppColor.blueColor, Color(0xFF2196F3)],
begin: Alignment.topLeft, begin: Alignment.topLeft,
end: Alignment.bottomRight, end: Alignment.bottomRight,
), ),
boxShadow: [
BoxShadow(
color: Colors.black.withAlpha(10),
blurRadius: 10,
spreadRadius: 2,
),
],
), ),
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
@@ -185,83 +466,122 @@ class UserAccountHeader extends StatelessWidget {
builder: (imageController) { builder: (imageController) {
return Stack( return Stack(
children: [ children: [
imageController.isloading Container(
? const CupertinoActivityIndicator() width: 100,
: Container( height: 100,
width: 100, decoration: BoxDecoration(
height: 100, shape: BoxShape.circle,
decoration: BoxDecoration( border: Border.all(color: Colors.white, width: 3),
shape: BoxShape.circle, boxShadow: [
image: DecorationImage( 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, fit: BoxFit.cover,
image: NetworkImage(
'${AppLink.seferCairoServer}/portrate_captain_image/${box.read(BoxName.driverID)}.jpg',
),
), ),
), ),
), ),
Positioned( Positioned(
right: 0, right: 0,
top: 0, bottom: 0,
child: CupertinoButton( child: CupertinoButton(
padding: EdgeInsets.zero,
onPressed: () { onPressed: () {
imageController.choosImagePicture( imageController.choosImagePicture(
AppLink.uploadImage1, 'portrait'); AppLink.uploadImage1, 'portrait');
}, },
child: const Icon(CupertinoIcons.pencil_circle_fill, child: Container(
color: CupertinoColors.white), 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( Text(
'${box.read(BoxName.nameDriver).toString().split(' ')[0]} ${box.read(BoxName.nameDriver).toString().split(' ')[1]}', '${box.read(BoxName.nameDriver).toString().split(' ')[0]} ${box.read(BoxName.nameDriver).toString().split(' ')[1]}',
style: const TextStyle( style: const TextStyle(
color: CupertinoColors.white, color: Colors.white,
fontSize: 18, fontSize: 24,
fontWeight: FontWeight.bold), fontWeight: FontWeight.bold,
shadows: [
Shadow(
color: Colors.black26,
blurRadius: 2,
offset: Offset(0, 1),
),
],
),
), ),
const SizedBox(height: 5), const SizedBox(height: 4),
Text( Text(
box.read(BoxName.emailDriver), 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), const SizedBox(height: 12),
Row( Container(
children: [ padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
Text( decoration: BoxDecoration(
Get.find<HomeCaptainController>().rating.toString(), color: Colors.white.withOpacity(0.15),
style: const TextStyle( borderRadius: BorderRadius.circular(20),
color: CupertinoColors.systemYellow, fontSize: 16), ),
), child: Row(
const SizedBox(width: 5), mainAxisSize: MainAxisSize.min,
// You might want to replace this with a Cupertino-style rating widget children: [
// For now, we'll use text to represent stars // const Icon(
// const Text('★★★★★', // CupertinoIcons.star_fill,
// style: TextStyle(color: CupertinoColors.systemYellow)), // color: CupertinoColors.systemYellow,
// size: 18,
Container( // ),
padding: const EdgeInsets.symmetric(horizontal: 4, vertical: 1), // const SizedBox(width: 4),
color: AppColor.greenColor, Text(
child: RatingBar.builder( Get.find<HomeCaptainController>().rating.toString(),
style: const TextStyle(
color: Colors.white,
fontSize: 16,
fontWeight: FontWeight.w600,
),
),
const SizedBox(width: 8),
RatingBar.builder(
initialRating: double.parse( initialRating: double.parse(
Get.find<HomeCaptainController>().rating.toString()), Get.find<HomeCaptainController>().rating.toString()),
minRating: 1, minRating: 1,
direction: Axis.horizontal, direction: Axis.horizontal,
itemCount: 5, itemCount: 5,
itemSize: 20, itemSize: 16,
itemPadding: const EdgeInsets.symmetric(horizontal: 2), ignoreGestures: true,
itemBuilder: (context, _) => const Icon( itemBuilder: (context, _) => const Icon(
Icons.star, CupertinoIcons.star_fill,
color: Colors.amber, color: CupertinoColors.systemYellow,
), ),
onRatingUpdate: (rating) {}, onRatingUpdate: (rating) {},
), ),
), ],
], ),
), ),
], ],
), ),

View File

@@ -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: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/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 { class HelpCaptain extends StatelessWidget {
HelpCaptain({super.key}); HelpCaptain({super.key});
@@ -13,116 +18,131 @@ class HelpCaptain extends StatelessWidget {
Get.put(HelpController()); Get.put(HelpController());
return CupertinoPageScaffold( return CupertinoPageScaffold(
navigationBar: CupertinoNavigationBar( navigationBar: CupertinoNavigationBar(
middle: Text('Helping Page'.tr), middle: Text(
'Helping Page'.tr,
style: const TextStyle(fontWeight: FontWeight.bold),
),
leading: CupertinoButton( leading: CupertinoButton(
padding: EdgeInsets.zero, padding: EdgeInsets.zero,
child: Icon(CupertinoIcons.back),
onPressed: () => Navigator.pop(context), onPressed: () => Navigator.pop(context),
child: const Icon(CupertinoIcons.back),
), ),
), ),
child: SafeArea( child: SafeArea(
child: Padding( child: Padding(
padding: const EdgeInsets.all(16.0), padding: const EdgeInsets.all(
child: Column( 20.0), // Increased padding around the content
child: ListView(
// crossAxisAlignment:
// CrossAxisAlignment.stretch, // Stretch children to full width
children: [ children: [
Padding( Container(
padding: const EdgeInsets.symmetric(vertical: 12.0), padding:
child: Container( const EdgeInsets.all(18.0), // Slightly increased padding
padding: const EdgeInsets.all(16.0), decoration: BoxDecoration(
decoration: BoxDecoration( color:
borderRadius: BorderRadius.circular(12.0), CupertinoTheme.of(context).brightness == Brightness.light
border: Border.all( ? CupertinoColors.systemGrey6
color: CupertinoColors.systemGrey2, : CupertinoColors.darkBackgroundGray,
), borderRadius:
), BorderRadius.circular(15.0), // More rounded corners
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,
),
), ),
), child: Text(
Card( 'If you need any help or have questions, this is the right place to do that. You are welcome!'
elevation: 3, .tr,
color: CupertinoColors.systemGrey6, style:
shape: RoundedRectangleBorder( CupertinoTheme.of(context).textTheme.textStyle.copyWith(
borderRadius: BorderRadius.circular(12.0), fontSize: 16, // Slightly larger font size
), color: CupertinoColors.label.resolveFrom(
child: Padding( context), // Ensure text color adapts to theme
padding: const EdgeInsets.all(16.0),
child: GetBuilder<HelpController>(
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), textAlign: TextAlign.center,
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), const SizedBox(height: 20),
CupertinoFormSection.insetGrouped(
// Using CupertinoFormSection for better styling
header: Text('Submit Your Question'.tr),
margin: EdgeInsets.zero,
children: [
GetBuilder<HelpController>(
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<HelpController>(
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( Expanded(
child: GetBuilder<HelpController>( child: GetBuilder<HelpController>(
builder: (helpController) => Padding( builder: (helpController) =>
padding: const EdgeInsets.all(10), CupertinoListSection.insetGrouped(
child: Container( margin: EdgeInsets.zero,
decoration: BoxDecoration( children: helpController.helpQuestionDate['message'] != null
border: Border.all( ? List.generate(
color: CupertinoColors.systemGrey2, helpController.helpQuestionDate['message'].length,
), (index) {
borderRadius: BorderRadius.circular(12.0), var list = helpController
), .helpQuestionDate['message'][index];
child: ListView.builder( return CupertinoListTile(
itemCount: helpController.helpQuestionDate['message'] != title: Text(
null list['helpQuestion'],
? helpController.helpQuestionDate['message'].length overflow: TextOverflow.ellipsis,
: 0, ),
itemBuilder: (BuildContext context, int index) { trailing: Row(
var list = mainAxisSize: MainAxisSize.min,
helpController.helpQuestionDate['message'][index]; children: [
return Padding( Text(
padding: const EdgeInsets.all(3), list['datecreated'],
child: Container( style: CupertinoTheme.of(context)
padding: const EdgeInsets.symmetric( .textTheme
vertical: 12, horizontal: 16), .tabLabelTextStyle,
decoration: BoxDecoration( ),
border: Border.all( const Icon(CupertinoIcons.chevron_forward),
color: CupertinoColors.activeGreen, ],
width: 2,
), ),
borderRadius: BorderRadius.circular(12),
),
child: GestureDetector(
onTap: () { onTap: () {
helpController.getIndex( helpController.getIndex(
list['id'], list['helpQuestion']); list['id'], list['helpQuestion']);
@@ -130,33 +150,14 @@ class HelpCaptain extends StatelessWidget {
.getHelpRepley(list['id'].toString()); .getHelpRepley(list['id'].toString());
Get.to(() => const HelpDetailsReplayPage()); Get.to(() => const HelpDetailsReplayPage());
}, },
child: Row( );
mainAxisAlignment: },
MainAxisAlignment.spaceBetween, )
children: [ : [
Expanded( Center(
child: Text( child: Text('No questions asked yet.'.tr),
list['helpQuestion'],
style: CupertinoTheme.of(context)
.textTheme
.textStyle,
overflow: TextOverflow.ellipsis,
),
),
Text(
list['datecreated'],
style: CupertinoTheme.of(context)
.textTheme
.tabLabelTextStyle,
),
],
),
),
), ),
); ],
},
),
),
), ),
), ),
), ),
@@ -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<HelpController>(
// 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<HelpController>(
// 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,
// ),
// ],
// ),
// ),
// ),
// );
// },
// ),
// ),
// ),
// ),
// ),
// ],
// ),
// ),
// ),
// );
// }
// }

View File

@@ -47,22 +47,92 @@ class HomeCaptain extends StatelessWidget {
}); });
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
// backgroundColor: AppColor.accentColor, elevation: 2,
elevation: 1, flexibleSpace: Container(
title: Text( decoration: BoxDecoration(
'SEFER'.tr, gradient: LinearGradient(
style: AppStyle.title.copyWith(fontSize: 22), 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: [ actions: [
MyCircleContainer( Padding(
child: Text( padding: const EdgeInsets.symmetric(horizontal: 4),
homeCaptainController.countRefuse.toString(), child: MyCircleContainer(
style: AppStyle.title, 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<LocationController>().myLocation.latitude,
Get.find<LocationController>().myLocation.longitude,
)));
},
),
],
),
),
const SizedBox(width: 8),
], ],
), ),
drawer: CupertinoDrawerCaptain(),
drawer:
CupertinoDrawerCaptain(), // Add this widget at the bottom of the file
body: Stack( body: Stack(
children: [ children: [
GetBuilder<HomeCaptainController>(builder: (homeCaptainController) { GetBuilder<HomeCaptainController>(builder: (homeCaptainController) {
@@ -419,28 +489,34 @@ class HomeCaptain extends StatelessWidget {
border: Border.all(color: AppColor.blueColor), border: Border.all(color: AppColor.blueColor),
color: AppColor.secondaryColor, color: AppColor.secondaryColor,
borderRadius: BorderRadius.circular(15)), borderRadius: BorderRadius.circular(15)),
child: IconButton( child: GestureDetector(
onPressed: () { onLongPress: () {
box.read(BoxName.rideStatus) == 'Applied' box.write(BoxName.rideStatus, 'delete');
? { homeCaptainController.update();
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( child: IconButton(
Icons.rice_bowl, onPressed: () {
size: 29, box.read(BoxName.rideStatus) == 'Applied'
color: AppColor.blueColor, ? {
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() { void _markAsNotFirstTime() {
box.write(BoxName.isFirstTime, 'false'); 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,
),
),
),
),
);
}
}

View File

@@ -1,18 +1,14 @@
import 'package:sefer_driver/constant/box_name.dart'; import 'package:sefer_driver/constant/box_name.dart';
import 'package:sefer_driver/controller/firebase/local_notification.dart'; import 'package:sefer_driver/controller/firebase/local_notification.dart';
import 'package:sefer_driver/main.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:sefer_driver/views/home/Captin/orderCaptin/vip_order_page.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_font_icons/flutter_font_icons.dart'; import 'package:flutter_font_icons/flutter_font_icons.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:sefer_driver/controller/home/captin/home_captain_controller.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 '../../../../../constant/colors.dart';
import '../../../../Rate/ride_calculate_driver.dart'; import '../../../../Rate/ride_calculate_driver.dart';
import '../../../../../controller/functions/location_controller.dart';
import '../../../../widgets/mydialoug.dart';
GetBuilder<HomeCaptainController> leftMainMenuCaptainIcons() { GetBuilder<HomeCaptainController> leftMainMenuCaptainIcons() {
return GetBuilder<HomeCaptainController>( return GetBuilder<HomeCaptainController>(
@@ -21,113 +17,6 @@ GetBuilder<HomeCaptainController> leftMainMenuCaptainIcons() {
left: 6, left: 6,
child: Column( child: Column(
children: [ 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<LocationController>().myLocation.latitude,
Get.find<LocationController>().myLocation.longitude,
)));
},
icon: const Icon(
Icons.location_on,
size: 29,
color: AppColor.blueColor,
),
),
),
const SizedBox(
height: 5,
),
AnimatedContainer( AnimatedContainer(
duration: const Duration(microseconds: 200), duration: const Duration(microseconds: 200),
width: controller.widthMapTypeAndTraffic, width: controller.widthMapTypeAndTraffic,
@@ -211,7 +100,7 @@ GetBuilder<HomeCaptainController> leftMainMenuCaptainIcons() {
// child: Builder(builder: (context) { // child: Builder(builder: (context) {
// return IconButton( // return IconButton(
// onPressed: () async { // onPressed: () async {
// Get.to(EgyptCardAI()); // MyCircularProgressIndicator();
// }, // },
// icon: const Icon( // icon: const Icon(
// FontAwesome5.grin_tears, // FontAwesome5.grin_tears,

View File

@@ -6,93 +6,253 @@ import 'package:sefer_driver/views/widgets/my_scafold.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:get/get.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<MaintainCenterController>(
// 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 { class MaintainCenterPage extends StatelessWidget {
MaintainCenterPage({super.key}); MaintainCenterPage({super.key});
MaintainCenterController maintainCenterController = final MaintainCenterController maintainCenterController =
Get.put(MaintainCenterController()); Get.put(MaintainCenterController());
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return MyScafolld( return MyScafolld(
title: "Maintenance Center".tr, title: "Maintenance Center".tr,
body: [ body: [
GetBuilder<MaintainCenterController>( GetBuilder<MaintainCenterController>(
builder: (maintainCenterController) { builder: (controller) {
return Padding( return Padding(
padding: const EdgeInsets.all(8.0), padding: const EdgeInsets.all(16.0),
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
// Introduction Text with better styling
Text( Text(
"When you complete 600 trips, you will be eligible to receive offers for maintenance of your car." "When you complete 600 trips, you will be eligible to receive offers for maintenance of your car."
.tr), .tr,
const SizedBox( style: Theme.of(context).textTheme.titleMedium!.copyWith(
height: 10, color: Colors.grey[700],
height: 1.4,
),
), ),
Row( const SizedBox(height: 20),
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [ // Trip Count Section in a Card
MyElevatedButton( Card(
title: "Show My Trip Count".tr, elevation: 4,
onPressed: () async { shape: RoundedRectangleBorder(
maintainCenterController.getTripCountByCaptain(); borderRadius: BorderRadius.circular(12),
}), ),
_buildPriceAvatar(
maintainCenterController.tripCount['count'] == null
? '0'
: maintainCenterController.tripCount['count']
.toString())
],
),
const SizedBox(
height: 10,
),
Container(
decoration: AppStyle.boxDecoration,
child: Padding( child: Padding(
padding: const EdgeInsets.all(14), padding: const EdgeInsets.all(16.0),
child: Text( child: Row(
"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." mainAxisAlignment: MainAxisAlignment.spaceBetween,
.tr, children: [
style: AppStyle.title, 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( const SizedBox(height: 20),
height: 10,
// 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, title: 'Show maintenance center near my location'.tr,
onPressed: () { 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 { } else {
Get.snackbar("You should complete 600 trips".tr, '', Get.snackbar(
backgroundColor: AppColor.yellowColor); "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) { Widget _buildPriceAvatar(String count) {
return Container( return Container(
width: 80, width: 70, // Slightly reduced size
height: 80, height: 70,
decoration: BoxDecoration( decoration: BoxDecoration(
shape: BoxShape.circle, shape: BoxShape.circle,
gradient: const RadialGradient( gradient: const LinearGradient(
// Changed to LinearGradient
colors: [Color(0xFF4CAF50), Color(0xFF2E7D32)], colors: [Color(0xFF4CAF50), Color(0xFF2E7D32)],
center: Alignment.center, begin: Alignment.topLeft,
radius: 0.8, end: Alignment.bottomRight,
), ),
boxShadow: [ boxShadow: [
BoxShadow( BoxShadow(
color: Colors.black.withOpacity(0.2), color: Colors.black.withOpacity(0.15), // Reduced opacity
blurRadius: 8, blurRadius: 6, // Slightly reduced blur
offset: const Offset(0, 4), offset: const Offset(0, 3),
), ),
], ],
), ),
@@ -100,7 +260,7 @@ class MaintainCenterPage extends StatelessWidget {
child: Text( child: Text(
count, count,
style: const TextStyle( style: const TextStyle(
fontSize: 22, fontSize: 20, // Slightly reduced size
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
color: Colors.white, color: Colors.white,
), ),

View File

@@ -13,215 +13,249 @@ import '../../../widgets/elevated_btn.dart';
GetBuilder<MapDriverController> driverEndRideBar() { GetBuilder<MapDriverController> driverEndRideBar() {
return GetBuilder<MapDriverController>( return GetBuilder<MapDriverController>(
builder: (mapDriverController) => mapDriverController.isRideStarted builder: (mapDriverController) => mapDriverController.isRideStarted
? Positioned( ? Positioned(
left: 5, left: 5,
top: 5, top: 5,
right: 5, right: 5,
child: Container( child: Container(
decoration: AppStyle.boxDecoration1, decoration: AppStyle.boxDecoration1.copyWith(
height: mapDriverController.remainingTimeTimerRideBegin < 60 borderRadius: BorderRadius.circular(15),
? mapDriverController.driverEndPage = 190 boxShadow: [
: mapDriverController.carType == 'Mishwar Vip' BoxShadow(
? 120 color: Colors.black.withOpacity(0.1),
: 170, blurRadius: 10,
// width: 240, offset: Offset(0, 5),
child: Column( ),
mainAxisAlignment: MainAxisAlignment.spaceAround, ],
children: [ ),
mapDriverController.carType != 'Mishwar Vip' padding: const EdgeInsets.all(10),
? Row( height: mapDriverController.remainingTimeTimerRideBegin < 60
mainAxisAlignment: MainAxisAlignment.spaceEvenly, ? mapDriverController.driverEndPage = 190
children: [ : mapDriverController.carType == 'Mishwar Vip'
Column( ? 120
children: [ : 170,
const Icon(Icons.social_distance), child: Column(
Text( mainAxisAlignment: MainAxisAlignment.spaceAround,
'${mapDriverController.distance} ${'KM'.tr}', children: [
style: AppStyle.title, if (mapDriverController.carType != 'Mishwar Vip')
), Row(
], mainAxisAlignment: MainAxisAlignment.spaceEvenly,
), children: [
Column( _buildInfoColumn(
children: [ icon: Icons.social_distance,
const Icon(Icons.timelapse), text: '${mapDriverController.distance} ${'KM'.tr}',
Text( ),
mapDriverController.hours > 1 _buildInfoColumn(
? '${'${mapDriverController.hours}${' H and'.tr}'} ${mapDriverController.minutes} m' icon: Icons.timelapse,
: '${mapDriverController.minutes} ${'m'.tr}', text: mapDriverController.hours > 1
style: AppStyle.title), ? '${mapDriverController.hours} ${'H and'.tr} ${mapDriverController.minutes} m'
], : '${mapDriverController.minutes} ${'m'.tr}',
), ),
Column( _buildInfoColumn(
children: [ icon: Icons.money_sharp,
const Icon(Icons.money_sharp), text:
Text( '${mapDriverController.paymentAmount} ${'\$'.tr}',
'${mapDriverController.paymentAmount} ${'\$'.tr}', ),
style: AppStyle.title), ],
], ),
), if (mapDriverController.carType != 'Speed' &&
], mapDriverController.carType != 'Awfar Car' &&
) mapDriverController.carType != 'Scooter')
: 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,
// ),
// )
// ],
// )
// :
Row( Row(
mainAxisAlignment: MainAxisAlignment.spaceAround, mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [ children: [
// mapDriverController.remainingTimeTimerRideBegin < _buildInfoBox(
// 60 icon: Icons.timer,
// ? text:
SlideAction( mapDriverController.stringRemainingTimeRideBegin1,
text: 'End Ride'.tr, ),
textStyle: const TextStyle( _buildInfoBox(
fontSize: 18, icon: Icons.location_on,
fontWeight: FontWeight.bold, text:
color: Colors.white, '${mapDriverController.recentDistanceToDash.toStringAsFixed(0)} ${'KM'.tr}',
), ),
outerColor: AppColor.redColor, _buildInfoBox(
innerColor: Colors.white, icon: Icons.attach_money,
sliderButtonIcon: const Icon( text: mapDriverController.price.toStringAsFixed(2),
Icons.arrow_forward,
color: AppColor.redColor,
),
onSubmit: () {
mapDriverController.finishRideFromDriver();
},
), ),
// 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' && _builtTimerAndCarType(),
mapDriverController.carType != 'Mishwar Vip' && Container(
mapDriverController.carType != 'Lady' width: Get.width * 0.8,
? Stack( decoration: BoxDecoration(
children: [ borderRadius: BorderRadius.circular(15),
SizedBox( boxShadow: [
width: Get.width * .9, BoxShadow(
child: Center( color: AppColor.redColor.withOpacity(0.3),
child: LinearProgressIndicator( blurRadius: 8,
backgroundColor: AppColor.greyColor, offset: Offset(0, 4),
color: mapDriverController ),
.remainingTimeTimerRideBegin < ],
60 ),
? AppColor.redColor child: SlideAction(
: AppColor.greenColor, height: 50,
minHeight: 25, borderRadius: 15,
borderRadius: BorderRadius.circular(6), elevation: 4,
value: mapDriverController text: 'Slide to End Trip'.tr,
.progressTimerRideBegin textStyle: AppStyle.title.copyWith(
.toDouble(), fontSize: 18,
), fontWeight: FontWeight.bold,
), color: Colors.white,
), ),
Center( outerColor: AppColor.redColor,
child: Text( innerColor: Colors.white,
mapDriverController sliderButtonIcon: const Icon(
.stringRemainingTimeRideBegin, Icons.arrow_forward_ios,
style: AppStyle.title, color: AppColor.redColor,
), size: 24,
) ),
], sliderRotate: false,
) onSubmit: () {
: const SizedBox(), HapticFeedback.mediumImpact();
], mapDriverController.finishRideFromDriver();
},
),
)
],
),
),
)
: const SizedBox(),
);
}
class _builtTimerAndCarType extends StatelessWidget {
const _builtTimerAndCarType({
super.key,
});
@override
Widget build(BuildContext context) {
final mapDriverController = Get.find<MapDriverController>();
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<Color>(
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<MapDriverController> speedCircle() { GetBuilder<MapDriverController> speedCircle() {

View File

@@ -452,9 +452,12 @@ class PassengerInfoWindow extends StatelessWidget {
kolor: AppColor.greenColor, kolor: AppColor.greenColor,
onPressed: () { onPressed: () {
MyDialog().getDialog( MyDialog().getDialog(
"Is the Passenger in your Car ?" "Is the Passenger in your Car?"
.tr, .tr, // "هل الراكب في سيارتك؟"
"Don't start trip if not".tr,
"Don't start trip if passenger not in your car"
.tr, // "لا تبدأ الرحلة إذا لم يكن الراكب في سيارتك"
() async { () async {
await controller await controller
.startRideFromDriver(); .startRideFromDriver();

View File

@@ -1,9 +1,7 @@
import 'package:sefer_driver/constant/style.dart'; import 'package:flutter/cupertino.dart';
import 'package:sefer_driver/views/home/Captin/home_captain/home_captin.dart';
import 'package:flutter/material.dart';
import 'package:get/get.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 'package:sefer_driver/views/widgets/elevated_btn.dart';
import '../../controller/local/local_controller.dart'; import '../../controller/local/local_controller.dart';
class Language extends StatelessWidget { class Language extends StatelessWidget {
@@ -11,203 +9,122 @@ class Language extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return CupertinoPageScaffold(
body: GetBuilder<LocaleController>( navigationBar: CupertinoNavigationBar(
builder: (controller) => Center( middle: Text('Choose Language'.tr),
child: Container( border: null,
padding: const EdgeInsets.all(15), ),
child: ListView( child: SafeArea(
// mainAxisAlignment: MainAxisAlignment.spaceEvenly, child: GetBuilder<LocaleController>(
children: [ builder: (controller) => Center(
Text( child: Padding(
"Choose Language".tr, padding: const EdgeInsets.all(16),
style: Theme.of(context).textTheme.headlineLarge, 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());
},
),
],
),
);
},
));
} }
} }

View File

@@ -5,7 +5,9 @@ import 'package:sefer_driver/constant/style.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:vibration/vibration.dart'; import 'package:vibration/vibration.dart';
import '../../constant/box_name.dart';
import '../../constant/colors.dart'; import '../../constant/colors.dart';
import '../../main.dart';
class MyElevatedButton extends StatelessWidget { class MyElevatedButton extends StatelessWidget {
final String title; final String title;
@@ -22,17 +24,25 @@ class MyElevatedButton extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
bool vibrate = box.read(BoxName.isvibrate) ?? true;
return ElevatedButton( return ElevatedButton(
style: ButtonStyle( 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 { onPressed: () async {
// Handle haptic feedback for both iOS and Android // Handle haptic feedback for both iOS and Android
if (Platform.isIOS) { if (vibrate == true) {
HapticFeedback.selectionClick(); if (Platform.isIOS) {
} else { HapticFeedback.selectionClick();
Vibration.vibrate(duration: 100); } else if (Platform.isAndroid) {
// Vibrate.vibrateWithPauses(pauses); await Vibration.vibrate(duration: vibrateDuration);
} else {}
} }
// Ensure the onPressed callback is called after haptic feedback // Ensure the onPressed callback is called after haptic feedback

View File

@@ -1,69 +1,123 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import '../../constant/colors.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) { SnackbarController mySnackeBarError(String message) {
// Trigger error haptic feedback
HapticFeedback.mediumImpact();
return Get.snackbar( return Get.snackbar(
'Error'.tr, 'Error'.tr,
message, message,
backgroundColor: AppColor.redColor.withOpacity(0.9), backgroundColor: AppColor.redColor.withOpacity(0.95),
colorText: AppColor.secondaryColor, 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, shouldIconPulse: true,
snackPosition: SnackPosition.TOP, snackPosition: SnackPosition.TOP,
margin: const EdgeInsets.all(10), margin: SnackbarConfig.margin,
borderRadius: 10, borderRadius: SnackbarConfig.borderRadius,
animationDuration: const Duration(milliseconds: 500), duration: SnackbarConfig.duration,
forwardAnimationCurve: Curves.easeOutBack, animationDuration: SnackbarConfig.animationDuration,
reverseAnimationCurve: Curves.easeInBack, forwardAnimationCurve: Curves.easeOutCirc,
reverseAnimationCurve: Curves.easeInCirc,
boxShadows: [SnackbarConfig.shadow],
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 12),
titleText: Text( titleText: Text(
'Error'.tr, 'Error'.tr,
style: const TextStyle( style: const TextStyle(
fontWeight: FontWeight.bold, fontWeight: FontWeight.w700,
color: Colors.white, color: Colors.white,
fontSize: 16, fontSize: 16,
letterSpacing: 0.2,
), ),
), ),
messageText: Text( messageText: Text(
message, message,
style: TextStyle( style: TextStyle(
color: Colors.white.withOpacity(0.9), color: Colors.white.withOpacity(0.95),
fontSize: 14, 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) { SnackbarController mySnackbarSuccess(String message) {
// Trigger success haptic feedback
HapticFeedback.lightImpact();
return Get.snackbar( return Get.snackbar(
'Success'.tr, 'Success'.tr,
message, message,
backgroundColor: AppColor.greenColor backgroundColor: AppColor.greenColor.withOpacity(0.95),
.withOpacity(0.9), // Assuming green color for success
colorText: AppColor.secondaryColor, 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, shouldIconPulse: true,
snackPosition: SnackPosition.TOP, snackPosition: SnackPosition.TOP,
margin: const EdgeInsets.all(10), margin: SnackbarConfig.margin,
borderRadius: 10, borderRadius: SnackbarConfig.borderRadius,
animationDuration: const Duration(milliseconds: 500), duration: SnackbarConfig.duration,
forwardAnimationCurve: Curves.easeOutBack, animationDuration: SnackbarConfig.animationDuration,
reverseAnimationCurve: Curves.easeInBack, forwardAnimationCurve: Curves.easeOutCirc,
reverseAnimationCurve: Curves.easeInCirc,
boxShadows: [SnackbarConfig.shadow],
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 12),
titleText: Text( titleText: Text(
'Success'.tr, 'Success'.tr,
style: const TextStyle( style: const TextStyle(
fontWeight: FontWeight.bold, fontWeight: FontWeight.w700,
color: Colors.white, color: Colors.white,
fontSize: 16, fontSize: 16,
letterSpacing: 0.2,
), ),
), ),
messageText: Text( messageText: Text(
message, message,
style: TextStyle( style: TextStyle(
color: Colors.white.withOpacity(0.9), color: Colors.white.withOpacity(0.95),
fontSize: 14, fontSize: 14,
height: 1.3,
), ),
), ),
onTap: (_) {
HapticFeedback.lightImpact();
Get.closeCurrentSnackbar();
},
isDismissible: true,
dismissDirection: DismissDirection.horizontal,
overlayBlur: 0.8,
overlayColor: Colors.black12,
); );
} }

View File

@@ -1,36 +1,131 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class MyCircularProgressIndicator extends StatelessWidget { class MyCircularProgressIndicator extends StatefulWidget {
final Color backgroundColor; final Color backgroundColor;
final double size;
final Color progressColor;
final double strokeWidth;
const MyCircularProgressIndicator({ const MyCircularProgressIndicator({
super.key, super.key,
this.backgroundColor = Colors.transparent, this.backgroundColor = Colors.transparent,
this.size = 110,
this.progressColor = Colors.blue,
this.strokeWidth = 3.0,
}); });
@override
State<MyCircularProgressIndicator> createState() =>
_MyCircularProgressIndicatorState();
}
class _MyCircularProgressIndicatorState
extends State<MyCircularProgressIndicator>
with SingleTickerProviderStateMixin {
late AnimationController _controller;
late Animation<double> _scaleAnimation;
late Animation<double> _rotationAnimation;
@override
void initState() {
super.initState();
_controller = AnimationController(
duration: const Duration(seconds: 2),
vsync: this,
)..repeat(reverse: true);
_scaleAnimation = Tween<double>(
begin: 0.95,
end: 1.05,
).animate(CurvedAnimation(
parent: _controller,
curve: Curves.easeInOut,
));
_rotationAnimation = Tween<double>(
begin: 0,
end: 2,
).animate(CurvedAnimation(
parent: _controller,
curve: Curves.linear,
));
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Center( return Center(
child: Container( child: AnimatedBuilder(
width: 110, animation: _controller,
height: 110, builder: (context, child) {
decoration: BoxDecoration( return Transform.scale(
color: backgroundColor, scale: _scaleAnimation.value,
shape: BoxShape.circle, child: Container(
), width: widget.size,
child: Stack( height: widget.size,
children: [ decoration: BoxDecoration(
const Center(child: CircularProgressIndicator()), color: widget.backgroundColor,
Column( shape: BoxShape.circle,
children: [ boxShadow: [
Align( BoxShadow(
alignment: Alignment.center, color: widget.progressColor.withAlpha(30),
child: Image.asset('assets/images/logo.gif'), 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<Color>(
widget.progressColor,
),
),
),
// Inner static progress indicator
CircularProgressIndicator(
strokeWidth: widget.strokeWidth * 0.7,
valueColor: AlwaysStoppedAnimation<Color>(
widget.progressColor.withAlpha(150),
),
),
// Logo container with scale animation
ScaleTransition(
scale: Tween<double>(
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,
),
),
),
],
),
), ),
], );
), },
), ),
); );
} }

View File

@@ -1,58 +1,139 @@
import 'dart:ui'; import 'dart:ui';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:sefer_driver/constant/colors.dart'; import 'package:sefer_driver/constant/colors.dart';
import 'package:sefer_driver/constant/style.dart'; import 'package:sefer_driver/constant/style.dart';
import 'package:sefer_driver/controller/functions/tts.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 { class MyDialog extends GetxController {
void getDialog(String title, String? midTitle, VoidCallback onPressed) { void getDialog(String title, String? midTitle, VoidCallback onPressed) {
final textToSpeechController = Get.put(TextToSpeechController()); final textToSpeechController = Get.put(TextToSpeechController());
HapticFeedback.mediumImpact();
Get.dialog( Get.dialog(
BackdropFilter( TweenAnimationBuilder<double>(
filter: ImageFilter.blur(sigmaX: 5, sigmaY: 5), duration: DialogConfig.animationDuration,
child: CupertinoAlertDialog( tween: Tween(begin: 0.0, end: 1.0),
title: Text( builder: (context, value, child) {
title, return Transform.scale(
style: AppStyle.title.copyWith( scale: 0.95 + (0.05 * value),
fontSize: 20, child: Opacity(opacity: value, child: child),
fontWeight: FontWeight.bold, );
},
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) { void getDialog(String title, Widget? content, VoidCallback onPressed) {
final textToSpeechController = Get.put(TextToSpeechController()); final textToSpeechController = Get.put(TextToSpeechController());
HapticFeedback.mediumImpact();
Get.dialog( Get.dialog(
BackdropFilter( TweenAnimationBuilder<double>(
filter: ImageFilter.blur(sigmaX: 5, sigmaY: 5), duration: DialogConfig.animationDuration,
child: CupertinoAlertDialog( tween: Tween(begin: 0.0, end: 1.0),
title: Text( builder: (context, value, child) {
title, return Transform.scale(
style: AppStyle.title.copyWith( scale: 0.95 + (0.05 * value),
fontSize: 20, child: Opacity(opacity: value, child: child),
fontWeight: FontWeight.bold, );
), },
child: BackdropFilter(
filter: ImageFilter.blur(
sigmaX: DialogConfig.blurStrength,
sigmaY: DialogConfig.blurStrength,
), ),
content: Column( child: Theme(
children: [ data: ThemeData.light().copyWith(
CupertinoButton( dialogBackgroundColor: CupertinoColors.systemBackground,
onPressed: () async { ),
await textToSpeechController.speakText(title); child: CupertinoAlertDialog(
}, title: Column(
child: const Icon(CupertinoIcons.headphones, children: [
color: AppColor.primaryColor), 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
); );
} }
} }